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; | |
align-items: left; | |
max-width: 70vw; | |
} | |
.feed { | |
padding: 1%; | |
border-style: solid; | |
border-width: 1px; | |
border-color: yellow; | |
margin-right: 3%; | |
margin-bottom: 3%; | |
min-width: 50%; | |
height: 65vh; | |
} | |
.map { | |
width: 100%; | |
height: 100%; | |
object-fit: cover; | |
margin: auto; | |
} | |
.map-div { | |
padding: 1%; | |
position: relative; | |
width: 100%; | |
height: 50%; | |
margin-top: 3%; | |
margin-bottom: 3%; | |
box-sizing: border-box; | |
} | |
.info { | |
min-width: 30vw; | |
display: flex; | |
flex-direction: column; | |
align-items: flex-start; | |
} | |
a:hover { | |
background-color: yellow; | |
color: black; | |
transition: 0.5s ease-in-out; | |
} | |
a { | |
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; | |
} | |
.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"> | |
<h3 style="border-bottom: 1px solid yellow; color:rgb(83, 83, 83); font-family: 'Helvetica'; font-weight: 50;">{{ name }}</h3> | |
<div style="display: flex; margin-top: 3%; 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;"> | |
<a href="{{ ip_link }}" target="_blank">raw data: {{ ip }}</a> <br> | |
lat, lon: {{ loc }}<br> | |
owner: {{ org }}<br> | |
time: {{ time }} | |
</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') }}"; | |
function setImageSource(url, isImage = false) { | |
const img = new Image(); | |
img.onload = function() { | |
feed.src = this.src; | |
if (isImage) { | |
setTimeout(() => setImageSource(url.replace("COUNTER", Math.random()), true), 500); | |
} | |
}; | |
img.onerror = function() { | |
feed.src = "{{ url_for('static', filename='error.png') }}"; | |
}; | |
img.src = url; | |
} | |
const newUrl = "{{ url }}"; | |
fetch(newUrl, { method: 'HEAD' }) | |
.then(response => { | |
const isImage = response.headers.get('Content-Type').startsWith('image/'); | |
setImageSource(newUrl.replace("COUNTER", Math.random()), isImage); | |
}); | |
}); | |
</script> | |
</body> | |
</html> |