first
This commit is contained in:
101
admin/index.php
Normal file
101
admin/index.php
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Admin Page</title>
|
||||||
|
<link rel="icon" href="../logo.png" type="image/x-icon">
|
||||||
|
<link rel="stylesheet" type="text/css" href="styles.css">
|
||||||
|
<link rel="stylesheet" href="https://use.typekit.net/rvs8lhv.css">
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<div class="center-container">
|
||||||
|
<div class="header">
|
||||||
|
<img src="../logo.png" class="logo">
|
||||||
|
<div class="header-content">
|
||||||
|
<h1>IP Pheasant</h1>
|
||||||
|
<p>Where the Pheasant shows all the IP!</p>
|
||||||
|
<h2>Admin Panel</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Table for displaying visit count -->
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Total Visit Count</th>
|
||||||
|
<td id="visitCount"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- Table for displaying last 50 lines of the gist -->
|
||||||
|
<br>
|
||||||
|
<table id="last50Table">
|
||||||
|
<!-- Table headers -->
|
||||||
|
|
||||||
|
</table>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
const apiKey = "<?php echo getenv('apiKey'); ?>";
|
||||||
|
const accessToken = "<?php echo getenv('accessToken'); ?>";
|
||||||
|
const gistId = "<?php echo getenv('gistId'); ?>" ;
|
||||||
|
const gistId2 = "<?php echo getenv('gistId2'); ?>" ;
|
||||||
|
|
||||||
|
fetch(`https://api.github.com/gists/${gistId2}`, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `token ${accessToken}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
// Extract content of the first file in the Gist
|
||||||
|
const filename = Object.keys(data.files)[0];
|
||||||
|
const content = data.files[filename].content;
|
||||||
|
const visitCount = parseInt(content) || 0; // Parse existing visit count from Gist, or default to 0
|
||||||
|
|
||||||
|
// Display visit count in the table
|
||||||
|
|
||||||
|
// Extract last 50 lines of the content
|
||||||
|
const lines = content.trim().split('\n');
|
||||||
|
const last50Lines = lines.slice(-50);
|
||||||
|
|
||||||
|
// Parse each line and add it to the last 50 lines table
|
||||||
|
const last50Table = document.getElementById('last50Table');
|
||||||
|
last50Lines.forEach(line => {
|
||||||
|
const [address, time] = line.split(',');
|
||||||
|
const row = last50Table.insertRow();
|
||||||
|
row.insertCell(0).innerText = address;
|
||||||
|
row.insertCell(1).innerText = time;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error fetching Gist:', error);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
fetch(`https://api.github.com/gists/${gistId}`, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `token ${accessToken}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
// Extract content of the first file in the Gist
|
||||||
|
const filename = Object.keys(data.files)[0];
|
||||||
|
const content = data.files[filename].content;
|
||||||
|
const visitCount = parseInt(content) || 0; // Parse existing visit count from Gist, or default to 0
|
||||||
|
// Display visit count in the table
|
||||||
|
document.getElementById('visitCount').innerText = visitCount;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error fetching Gist:', error);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
186
admin/styles.css
Normal file
186
admin/styles.css
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
body{
|
||||||
|
background-color: #1f2122;
|
||||||
|
color: #d9d5d0;
|
||||||
|
font-family: "semplicitapro","Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||||
|
font-weight: normal !important;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img{
|
||||||
|
max-width: 100%;
|
||||||
|
height: 10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.location{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.countryFlag{
|
||||||
|
height: auto;
|
||||||
|
margin-left: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
font-family: "semplicitapro", sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
|
||||||
|
padding: 0;
|
||||||
|
display: flex; /* Use flexbox */
|
||||||
|
align-items: center; /* Vertically center align items */
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
max-width: 100px;
|
||||||
|
height: auto;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content {
|
||||||
|
flex: 1; /* Expand to fill available space */
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-content {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content h1,
|
||||||
|
.header-content p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
font-size: 3em;
|
||||||
|
color: rgb(60, 134, 204);
|
||||||
|
}
|
||||||
|
.h2-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
h2{
|
||||||
|
font-size: 2em;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 1rem;
|
||||||
|
background-color: #484a4d;
|
||||||
|
padding: .5rem 1.5rem;
|
||||||
|
margin: auto 0;
|
||||||
|
display: inline-block; /* Keeps the box size around the text */
|
||||||
|
}
|
||||||
|
h3{
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p{
|
||||||
|
margin: 1rem;
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ipBlock{
|
||||||
|
background-color: #2d2f31;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 2rem;
|
||||||
|
max-width: 700px;
|
||||||
|
|
||||||
|
}
|
||||||
|
ul{list-style-type: none;}
|
||||||
|
code{
|
||||||
|
color: #1a7092;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
background-color: #2a2941;
|
||||||
|
border-radius: .5rem;
|
||||||
|
padding: .5rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ipv4{
|
||||||
|
color: #990000;
|
||||||
|
}
|
||||||
|
#ipv6{
|
||||||
|
color: rgb(10, 158, 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
|
||||||
|
border-collapse: separate; /* Use separate border model */
|
||||||
|
border-spacing: 10px;
|
||||||
|
width: 50%;
|
||||||
|
font-size: 2em;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 2.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
border: none;
|
||||||
|
background-color: #2d2f31;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 8px;
|
||||||
|
margin: 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
td{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#last50Table {
|
||||||
|
width: 90%;
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background-color: #333;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: center;
|
||||||
|
position: fixed; /* Position fixed for sticking to the bottom */
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%; /* Occupy full width */
|
||||||
|
font-size: .5rem;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 2000px) {
|
||||||
|
footer{
|
||||||
|
position: unset !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 800px) {
|
||||||
|
.header{padding: 0;}
|
||||||
|
.ipBlock{
|
||||||
|
margin: 1rem;
|
||||||
|
margin-left: 1.3rem;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{font-size: 2em;}
|
||||||
|
h2{
|
||||||
|
font-size: 1.5em;
|
||||||
|
padding: .5rem 1rem;}
|
||||||
|
h3{
|
||||||
|
margin: .5rem;
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
p{
|
||||||
|
margin: .5rem;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
.ip-address{margin-bottom: 1rem!important;}
|
||||||
|
code{
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
ul{margin-top: .5rem;}
|
||||||
|
table{
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
#last50Table {
|
||||||
|
width: 98%;
|
||||||
|
font-size: .8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
446
index.php
Normal file
446
index.php
Normal file
@@ -0,0 +1,446 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>IP Pheasant</title>
|
||||||
|
<link rel="icon" href="logo.png" type="image/x-icon">
|
||||||
|
<link rel="stylesheet" type="text/css" href="styles.css">
|
||||||
|
<link rel="stylesheet" href="https://use.typekit.net/rvs8lhv.css">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
const apiKey = "<?php echo getenv('apiKey'); ?>";
|
||||||
|
const accessToken = "<?php echo getenv('accessToken'); ?>";
|
||||||
|
const gistId = "<?php echo getenv('gistId'); ?>" ;
|
||||||
|
const gistId2 = "<?php echo getenv('gistId2'); ?>" ;
|
||||||
|
let ipv4Result, ipv6Result;
|
||||||
|
|
||||||
|
function checkUrl(url) {
|
||||||
|
return fetch(url, { method: 'HEAD' })
|
||||||
|
.then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentDateTime() {
|
||||||
|
// Create a new Date object
|
||||||
|
const currentDate = new Date();
|
||||||
|
|
||||||
|
// Extract date components
|
||||||
|
const year = currentDate.getFullYear();
|
||||||
|
const month = String(currentDate.getMonth() + 1).padStart(2, '0'); // Months are zero-based
|
||||||
|
const day = String(currentDate.getDate()).padStart(2, '0');
|
||||||
|
|
||||||
|
// Extract time components
|
||||||
|
const hours = String(currentDate.getHours()).padStart(2, '0');
|
||||||
|
const minutes = String(currentDate.getMinutes()).padStart(2, '0');
|
||||||
|
const seconds = String(currentDate.getSeconds()).padStart(2, '0');
|
||||||
|
|
||||||
|
// Construct the date and time string
|
||||||
|
const dateTimeString = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
|
|
||||||
|
// Return the date and time string
|
||||||
|
return dateTimeString;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateGist(address) {
|
||||||
|
// Fetch the current content of the Gist file
|
||||||
|
fetch(`https://api.github.com/gists/${gistId2}`, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `token ${accessToken}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
const filename = Object.keys(data.files)[0];
|
||||||
|
let content = data.files[filename].content;
|
||||||
|
|
||||||
|
// Remove existing header if present
|
||||||
|
if (content && content.startsWith('Address,Time\n')) {
|
||||||
|
content = content.slice(content.indexOf('\n') + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct the updated content with the new IP address entry at the top
|
||||||
|
const updatedContent = `Address,Time\n${address}\n${content || ''}`;
|
||||||
|
|
||||||
|
// Update the Gist file with the updated content
|
||||||
|
fetch(`https://api.github.com/gists/${gistId2}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `token ${accessToken}`,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
files: {
|
||||||
|
[filename]: {
|
||||||
|
content: updatedContent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to update Gist');
|
||||||
|
}
|
||||||
|
console.log('Gist updated successfully');
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error updating Gist:', error);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error fetching Gist:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
|
||||||
|
let visitCount = 0;
|
||||||
|
|
||||||
|
// Fetch Gist data
|
||||||
|
fetch(`https://api.github.com/gists/${gistId}`, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `token ${accessToken}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
// Extract content of the first file in the Gist
|
||||||
|
const filename = Object.keys(data.files)[0];
|
||||||
|
const content = data.files[filename].content;
|
||||||
|
visitCount = parseInt(content) || 0; // Parse existing visit count from Gist, or default to 0
|
||||||
|
|
||||||
|
// Increment visit count
|
||||||
|
visitCount++;
|
||||||
|
|
||||||
|
// Update Gist content
|
||||||
|
const updatedContent = visitCount.toString();
|
||||||
|
const updatedFiles = { ...data.files, [filename]: { ...data.files[filename], content: updatedContent } };
|
||||||
|
|
||||||
|
return fetch(`https://api.github.com/gists/${gistId}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `token ${accessToken}`,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
files: updatedFiles
|
||||||
|
})
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Failed to update Gist');
|
||||||
|
}
|
||||||
|
console.log('Gist updated successfully');
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error updating Gist:', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
|
||||||
|
if (navigator.onLine) {
|
||||||
|
let ipv4Fetch = fetch('https://ipv4.lafibre.info/ip.php')
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(res => {
|
||||||
|
ipv4Result = res;
|
||||||
|
console.log('IPv4 Result:', ipv4Result);
|
||||||
|
document.getElementById('ipv4-address').textContent = ipv4Result;
|
||||||
|
getv4info();
|
||||||
|
return true; // Resolve promise if IPv4 fetch is successful
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('IPv4 Fetch Error:', error);
|
||||||
|
return false; // Reject promise if IPv4 fetch fails
|
||||||
|
});
|
||||||
|
|
||||||
|
let ipv6Check = checkUrl('https://ipv6.lafibre.info/ip.php')
|
||||||
|
.then(isIPv6Online => {
|
||||||
|
if (isIPv6Online) {
|
||||||
|
return fetch('https://ipv6.lafibre.info/ip.php')
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(res => {
|
||||||
|
ipv6Result = res;
|
||||||
|
console.log('IPv6 Result:', ipv6Result);
|
||||||
|
document.getElementById('ipv6-address').textContent = ipv6Result;
|
||||||
|
getv6info();
|
||||||
|
return true; // Resolve promise if IPv6 fetch is successful
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('IPv6 Fetch Error:', error);
|
||||||
|
return false; // Reject promise if IPv6 fetch fails
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('IPv6 URL is offline.');
|
||||||
|
return false; // Reject promise if IPv6 URL is offline
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check if both IPv4 and IPv6 fetches/checks are successful
|
||||||
|
Promise.all([ipv4Fetch, ipv6Check])
|
||||||
|
.then(results => {
|
||||||
|
if (results[0] && results[1]) {
|
||||||
|
// Both IPv4 and IPv6 sites are working
|
||||||
|
console.log('Both IPv4 and IPv6 sites are working.');
|
||||||
|
updateGist(`${ipv4Result} | ${ipv6Result},${getCurrentDateTime()}`)
|
||||||
|
// You can perform further actions here
|
||||||
|
} else if (results[0]) {
|
||||||
|
// Only IPv4 site is working
|
||||||
|
console.log('Only IPv4 site is working.');
|
||||||
|
updateGist(`${ipv4Result},${getCurrentDateTime()}`)
|
||||||
|
// Perform action for scenario where only IPv4 is available (Echo 1)
|
||||||
|
console.log(1);
|
||||||
|
} else if (results[1]) {
|
||||||
|
// Only IPv6 site is working
|
||||||
|
console.log('Only IPv6 site is working.');
|
||||||
|
updateGist(`${ipv6Result},${getCurrentDateTime()}`)
|
||||||
|
// Perform action for scenario where only IPv6 is available (Echo 2)
|
||||||
|
console.log(2);
|
||||||
|
} else {
|
||||||
|
// Both IPv4 and IPv6 sites are not working
|
||||||
|
console.log('Both IPv4 and IPv6 sites are not working.');
|
||||||
|
updateGist(`Failed Client,${getCurrentDateTime()}`)
|
||||||
|
// Handle accordingly
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function getv4info(){
|
||||||
|
var request = new XMLHttpRequest();
|
||||||
|
url = 'https://api.ipdata.co/'+ ipv4Result +'?api-key=' + apiKey
|
||||||
|
console.log("URL:", url)
|
||||||
|
request.open('GET', url);
|
||||||
|
|
||||||
|
request.setRequestHeader('Accept', 'application/json');
|
||||||
|
|
||||||
|
request.onreadystatechange = function () {
|
||||||
|
if (this.readyState === 4) {
|
||||||
|
|
||||||
|
ipv4Json=JSON.parse(this.responseText)
|
||||||
|
console.log(ipv4Json);
|
||||||
|
|
||||||
|
var dataList = document.getElementById('asn-list-v4')
|
||||||
|
if (ipv4Json.asn) {
|
||||||
|
// Create an array of keys you want to display
|
||||||
|
var keysToDisplay = ["asn", "name", "route"];
|
||||||
|
|
||||||
|
function capitalizeFirstLetter(string) {
|
||||||
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through the keys and create <li> elements with the data
|
||||||
|
keysToDisplay.forEach(function(key) {
|
||||||
|
var listItem = document.createElement('li');
|
||||||
|
listItem.className = 'list-item';
|
||||||
|
|
||||||
|
var keyElement = document.createElement('p');
|
||||||
|
keyElement.className = 'key';
|
||||||
|
keyElement.textContent = capitalizeFirstLetter(key);
|
||||||
|
|
||||||
|
if (key === 'asn'){
|
||||||
|
keyElement.textContent = key.toUpperCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
var valueElement = document.createElement('code');
|
||||||
|
valueElement.textContent = ipv4Json.asn[key];
|
||||||
|
|
||||||
|
listItem.appendChild(keyElement);
|
||||||
|
listItem.appendChild(valueElement);
|
||||||
|
|
||||||
|
dataList.appendChild(listItem);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Create a list item indicating 'None'
|
||||||
|
var listItem = document.createElement('li');
|
||||||
|
listItem.textContent = 'None';
|
||||||
|
dataList.appendChild(listItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
var city = (ipv4Json.city + ", ");
|
||||||
|
var region = (ipv4Json.region_code + " ");
|
||||||
|
var postal = (ipv4Json.postal + " ")
|
||||||
|
var countryName = (ipv4Json.country_name);
|
||||||
|
var countryFlagURL = (ipv4Json.flag)
|
||||||
|
|
||||||
|
var fullLocation = (city + region + postal + countryName)
|
||||||
|
const locationv4 = document.getElementById('locationv4');
|
||||||
|
locationv4.textContent = fullLocation
|
||||||
|
|
||||||
|
const countryFlag = document.getElementById('countryFlagv4');
|
||||||
|
countryFlag.src = countryFlagURL;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
request.send();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getv6PTR(){
|
||||||
|
|
||||||
|
console.log("not yet setup for PTR")
|
||||||
|
}
|
||||||
|
|
||||||
|
function getv6info(){
|
||||||
|
var request = new XMLHttpRequest();
|
||||||
|
url = 'https://api.ipdata.co/'+ ipv6Result +'?api-key=' + apiKey
|
||||||
|
console.log("URL:", url)
|
||||||
|
request.open('GET', url);
|
||||||
|
|
||||||
|
request.setRequestHeader('Accept', 'application/json');
|
||||||
|
|
||||||
|
request.onreadystatechange = function () {
|
||||||
|
if (this.readyState === 4) {
|
||||||
|
|
||||||
|
ipv6Json=JSON.parse(this.responseText)
|
||||||
|
console.log(ipv6Json);
|
||||||
|
|
||||||
|
var dataList = document.getElementById('asn-list-v6')
|
||||||
|
if (ipv6Json.asn) {
|
||||||
|
// Create an array of keys you want to display
|
||||||
|
var keysToDisplay = ["asn", "name", "route"];
|
||||||
|
|
||||||
|
function capitalizeFirstLetter(string) {
|
||||||
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through the keys and create <li> elements with the data
|
||||||
|
keysToDisplay.forEach(function(key) {
|
||||||
|
var listItem = document.createElement('li');
|
||||||
|
listItem.className = 'list-item';
|
||||||
|
|
||||||
|
var keyElement = document.createElement('p');
|
||||||
|
keyElement.className = 'key';
|
||||||
|
keyElement.textContent = capitalizeFirstLetter(key);
|
||||||
|
|
||||||
|
if (key === 'asn'){
|
||||||
|
keyElement.textContent = key.toUpperCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
var valueElement = document.createElement('code');
|
||||||
|
valueElement.textContent = ipv6Json.asn[key];
|
||||||
|
|
||||||
|
listItem.appendChild(keyElement);
|
||||||
|
listItem.appendChild(valueElement);
|
||||||
|
|
||||||
|
dataList.appendChild(listItem);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Create a list item indicating 'None'
|
||||||
|
var listItem = document.createElement('li');
|
||||||
|
listItem.textContent = 'None';
|
||||||
|
dataList.appendChild(listItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipv6Json.city === null){
|
||||||
|
var city = ""
|
||||||
|
}else{
|
||||||
|
var city = (ipv6Json.city + ", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipv6Json.region_code === null){
|
||||||
|
var region = ""
|
||||||
|
}else{
|
||||||
|
var region = (ipv6Json.region_code + " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipv6Json.postal === null){
|
||||||
|
var postal = ""
|
||||||
|
}else{
|
||||||
|
var postal = (ipv6Json.postal + " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var countryName = (ipv6Json.country_name);
|
||||||
|
var countryFlagURL = (ipv6Json.flag)
|
||||||
|
|
||||||
|
var fullLocation = (city + region + postal + countryName)
|
||||||
|
const locationv6 = document.getElementById('locationv6');
|
||||||
|
locationv6.textContent = fullLocation
|
||||||
|
|
||||||
|
const countryFlag = document.getElementById('countryFlagv6');
|
||||||
|
countryFlag.src = countryFlagURL;
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
request.send();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//updateGist(ipv4Result, ipv6Result);
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<div class="center-container">
|
||||||
|
<div class="header">
|
||||||
|
<img src="logo.png" class="logo">
|
||||||
|
<div class="header-content">
|
||||||
|
<h1>IP Pheasant</h1>
|
||||||
|
<p>Where the Pheasant shows all the IP!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="ipv4Div" class="ipBlock">
|
||||||
|
<div class="h2-container">
|
||||||
|
<h2 id="ipv4">IPv4</h2>
|
||||||
|
</div>
|
||||||
|
<h3>Address:</h3>
|
||||||
|
<p class="ip-address">
|
||||||
|
<code id="ipv4-address">None</code>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>ASN Info:</h3>
|
||||||
|
<p>
|
||||||
|
<ul id="asn-list-v4"></ul>
|
||||||
|
</p>
|
||||||
|
<div class="location">
|
||||||
|
<span id="locationv4"></span>
|
||||||
|
<img id="countryFlagv4" class = "countryFlag">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="ipv6Div" class="ipBlock">
|
||||||
|
<div class="h2-container">
|
||||||
|
<h2 id="ipv6">IPv6</h2>
|
||||||
|
</div>
|
||||||
|
<h3>Address:</h3>
|
||||||
|
<p class="ip-address">
|
||||||
|
<code id="ipv6-address">None</code>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>ASN Info:</h3>
|
||||||
|
<p>
|
||||||
|
<ul id="asn-list-v6"></ul>
|
||||||
|
</p>
|
||||||
|
<div class="location">
|
||||||
|
<span id="locationv6"></span>
|
||||||
|
<img id="countryFlagv6" class = "countryFlag">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="footer">
|
||||||
|
<p>© 2024 ippheasant.com. All rights reserved.</p>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
186
styles.css
Normal file
186
styles.css
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
body{
|
||||||
|
background-color: #1f2122;
|
||||||
|
color: #d9d5d0;
|
||||||
|
font-family: "semplicitapro","Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||||
|
font-weight: normal !important;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img{
|
||||||
|
max-width: 100%;
|
||||||
|
height: 10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.location{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.countryFlag{
|
||||||
|
height: auto;
|
||||||
|
margin-left: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
font-family: "semplicitapro", sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
|
||||||
|
padding: 0;
|
||||||
|
display: flex; /* Use flexbox */
|
||||||
|
align-items: center; /* Vertically center align items */
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
max-width: 100px;
|
||||||
|
height: auto;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content {
|
||||||
|
flex: 1; /* Expand to fill available space */
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-content {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content h1,
|
||||||
|
.header-content p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
font-size: 3em;
|
||||||
|
color: rgb(60, 134, 204);
|
||||||
|
}
|
||||||
|
.h2-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
h2{
|
||||||
|
font-size: 2em;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 1rem;
|
||||||
|
background-color: #484a4d;
|
||||||
|
padding: .5rem 1.5rem;
|
||||||
|
margin: auto 0;
|
||||||
|
display: inline-block; /* Keeps the box size around the text */
|
||||||
|
}
|
||||||
|
h3{
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p{
|
||||||
|
margin: 1rem;
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ipBlock{
|
||||||
|
background-color: #2d2f31;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 2rem;
|
||||||
|
max-width: 700px;
|
||||||
|
|
||||||
|
}
|
||||||
|
ul{list-style-type: none;}
|
||||||
|
code{
|
||||||
|
color: #1a7092;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
background-color: #2a2941;
|
||||||
|
border-radius: .5rem;
|
||||||
|
padding: .5rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ipv4{
|
||||||
|
color: #990000;
|
||||||
|
}
|
||||||
|
#ipv6{
|
||||||
|
color: rgb(10, 158, 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
|
||||||
|
border-collapse: separate; /* Use separate border model */
|
||||||
|
border-spacing: 10px;
|
||||||
|
width: 50%;
|
||||||
|
font-size: 2em;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 2.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
border: none;
|
||||||
|
background-color: #2d2f31;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 8px;
|
||||||
|
margin: 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
td{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#last50Table {
|
||||||
|
width: 90%;
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background-color: #333;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: center;
|
||||||
|
position: fixed; /* Position fixed for sticking to the bottom */
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%; /* Occupy full width */
|
||||||
|
font-size: .5rem;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 2000px) {
|
||||||
|
footer{
|
||||||
|
position: unset !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 800px) {
|
||||||
|
.header{padding: 0;}
|
||||||
|
.ipBlock{
|
||||||
|
margin: 1rem;
|
||||||
|
margin-left: 1.3rem;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{font-size: 2em;}
|
||||||
|
h2{
|
||||||
|
font-size: 1.5em;
|
||||||
|
padding: .5rem 1rem;}
|
||||||
|
h3{
|
||||||
|
margin: .5rem;
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
p{
|
||||||
|
margin: .5rem;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
.ip-address{margin-bottom: 1rem!important;}
|
||||||
|
code{
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
ul{margin-top: .5rem;}
|
||||||
|
table{
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
#last50Table {
|
||||||
|
width: 98%;
|
||||||
|
font-size: .8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user