Spaces:
Running
Running
<html> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<head> | |
<link rel="preload" href="{{ url_for('static', filename='map_populated.png') }}" as="image"> | |
<link rel="preload" href="{{ url_for('static', filename='loading.gif') }}" as="image"> | |
<link rel="icon" type="image/png" href="https://images.squarespace-cdn.com/content/v1/64790f5777b5d772678cce83/6d71eaee-f825-4324-be9b-2def32469eac/Untitled+drawing+%2811%29.png?format=100w"> | |
<title>a random unsecured camera</title> | |
<style> | |
body { | |
justify-content: left; | |
background-color: black; | |
padding-top: 3%; | |
margin-left: 5vw; | |
} | |
.pulse { | |
width: 40px; | |
height: 40px; | |
border-radius: 50%; | |
position: absolute; | |
background-color: yellow; | |
opacity: 0.5; | |
animation: pulse-animation 5s infinite; | |
margin-left: -20px; | |
margin-top: -20px; | |
} | |
.dot { | |
border-style: solid; | |
border-width: 2px; | |
border-color: black; | |
width: 5px; | |
height: 5px; | |
border-radius: 50%; | |
position: absolute; | |
background-color: yellow; | |
margin-left: -4.5px; | |
margin-top: -4.5px; | |
} | |
@keyframes pulse-animation { | |
0% { transform: scale(0.1); opacity: 0.4; } | |
100% { transform: scale(3); opacity: 0; } | |
} | |
.flex-container { | |
display: flex; | |
justify-content: left; | |
align-items: top; | |
} | |
.outer-container { | |
margin-left: 2%; | |
justify-content: left; | |
max-width: 85vw; | |
} | |
.feed { | |
padding: 1%; | |
border-style: solid; | |
border-width: 1px; | |
border-color: yellow; | |
margin-right: 3%; | |
margin-bottom: 3%; | |
width: 50%; | |
height: 65vh; | |
} | |
.map { | |
width: 100%; | |
height: 100%; | |
object-fit: cover; | |
margin: auto; | |
} | |
.map-div { | |
position: relative; | |
width: 450px; | |
height: 300px; | |
margin-top: 3%; | |
margin-bottom: 3%; | |
box-sizing: border-box; | |
} | |
.info { | |
display: flex; | |
flex-direction: column; | |
align-items: flex-start; | |
} | |
a:hover { | |
background-color: yellow; | |
color: black; | |
transition: 0.5s ease-in-out; | |
} | |
a { | |
text-decoration: none; | |
color:rgb(83, 83, 83); | |
} | |
@media only screen and (orientation: portrait) { | |
body { | |
margin-left: auto; | |
} | |
.h1 { | |
margin-bottom: 2%; | |
} | |
.flex-container { | |
flex-direction: column; | |
align-items: left; | |
} | |
.map-div { | |
width: 100%; | |
height: 100%; | |
} | |
.feed { | |
width: 90vw; | |
max-height: 45vh; | |
margin-right: 0; | |
} | |
.info { | |
width: 90vw; | |
height: 65vh; | |
} | |
} | |
</style> | |
</head> | |
<body style="background-color: black;"> | |
<div class="outer-container"> | |
<p style="color:rgb(83, 83, 83); font-family: 'Helvetica'; font-weight: 50;"> a random unsecured camera in</p> | |
<h1 style="color:rgb(83, 83, 83); font-family: 'Helvetica'; font-weight: 50; margin-bottom: 3%;"> {{ country }}</h1> | |
<div class="flex-container"> | |
<img id="feed" class="feed" src="" /> | |
<div class="info"> | |
<a href="{{ ip_link }}" target="_blank"> <h3 style="margin:0; border-bottom: 1px solid yellow; color:rgb(83, 83, 83); font-family: 'Helvetica'; font-weight: 50;">{{ name }}</h3></a> | |
<div style="display: flex; margin-top: 6%; margin-bottom: 3%;"> | |
<a href="?new=true" style="margin-right: 10px; display: inline-block;"> | |
<button class="hoverButton" style="border: 1px solid yellow; background-color: transparent; color: rgb(83, 83, 83); padding: 10px;"> | |
another | |
</button> | |
</a> | |
<a href="?new=false" id="refreshSameFeedButton" style="display: inline-block;"> | |
<button class="hoverButton" style="border: 1px solid rgb(83, 83, 83); background-color: transparent; color: rgb(83, 83, 83); padding: 10px;"> | |
refresh | |
</button> | |
</a> | |
</div> | |
<p style="color:rgb(83, 83, 83); font-family: 'Helvetica'; font-weight: 50;"> | |
ip: {{ ip }}<br> | |
lat, lon: {{ loc }}<br> | |
time: <span id="time"></span> | |
</p> | |
<div class="map-div"> | |
<img id="map" src="{{ url_for('static', filename='map_populated.png') }}" style="width: 100%; height: 100%;" /> | |
<div class="dot" style="left: {{ X }}%; top: {{ Y }}%;"></div> | |
<div class="pulse" style="left: {{ X }}%; top: {{ Y }}%;"></div> | |
</div> | |
<p style="color:rgb(83, 83, 83); font-family: 'Helvetica'; font-weight: 50; margin-top: 3%;"> | |
a brayden moore website | |
</p> | |
</div> | |
</div> | |
</div> | |
<script> | |
document.addEventListener("DOMContentLoaded", function() { | |
const feed = document.getElementById("feed"); | |
feed.src = "{{ url_for('static', filename='loading.gif') }}"; | |
const newUrl = "{{ url }}"; | |
function refreshImage() { | |
let xhr = new XMLHttpRequest(); | |
xhr.open('HEAD', newUrl + '?t=' + new Date().getTime(), true); | |
xhr.onreadystatechange = function() { | |
if (xhr.readyState === 4) { | |
if (xhr.status === 200) { | |
if (xhr.getResponseHeader('Content-Type') === 'image/jpeg') { | |
img.src = newUrl + '?t=' + new Date().getTime(); | |
} | |
} | |
} | |
}; | |
xhr.send(); | |
} | |
const img = new Image(); | |
img.onload = function() { | |
feed.src = this.src; | |
setTimeout(refreshImage, 1000); | |
}; | |
img.onerror = function() { | |
window.location.href = "?new=true"; | |
}; | |
img.src = newUrl; | |
}); | |
document.addEventListener("DOMContentLoaded", function() { | |
const timezone = "{{ timezone }}"; | |
setInterval(() => { | |
const now = new Date(); | |
const options = { | |
timeZone: timezone, | |
hour: '2-digit', | |
minute: '2-digit', | |
second: '2-digit', | |
hour12: true | |
}; | |
const timeString = now.toLocaleTimeString('en-US', options); | |
document.getElementById("time").textContent = timeString; | |
}, 200); | |
}); | |
</script> | |
</body> | |
</html> |