| <!DOCTYPE html> |
| <html> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <head> |
| |
| <meta property="og:title" content="a random unsecured camera" /> |
| <meta property="og:image" content="{{ url_for('static', filename='searching.png') }}" /> |
| <meta property="og:url" content="https://unsecuredcamera.com" /> |
|
|
| <link rel="icon" type="image/png" href="/static/favicon-96x96.png" sizes="96x96" /> |
| <link rel="icon" type="image/svg+xml" href="/static/favicon.svg" /> |
| <link rel="shortcut icon" href="/static/favicon.ico" /> |
| <link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png" /> |
| <meta name="apple-mobile-web-app-title" content="Unsecured Camera" /> |
| <link rel="manifest" href="/static/site.webmanifest" /> |
|
|
| <link rel="preconnect" href="https://fonts.googleapis.com"> |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> |
| <link href="https://fonts.googleapis.com/css2?family=Silkscreen:wght@400;700&display=swap" rel="stylesheet"> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"> |
| <link rel="preload" href="{{ url_for('static', filename='eye.gif') }}" as="image"> |
| <link rel="preload" href="{{ url_for('static', filename='andalemono.ttf') }}" as="font" type="font/ttf" crossorigin> |
|
|
| <title>{{ page_title|safe }}</title> |
| <style> |
| :root { |
| --text-color: white; |
| } |
| |
| button { |
| cursor: pointer; |
| } |
| |
| body { |
| font-size: 10pt !important; |
| justify-content: center; |
| background-color: black; |
| display: flex; |
| align-items:center; |
| height: 100vh; |
| margin: auto; |
| } |
| |
| ::-webkit-scrollbar { |
| width: 10px; |
| border-radius: 5px; |
| } |
| |
| ::-webkit-scrollbar-thumb { |
| background: black; |
| border-radius: 5px; |
| } |
| |
| ::-webkit-scrollbar-thumb:hover { |
| background: black; |
| } |
| |
| |
| * { |
| scrollbar-width: thin; |
| scrollbar-color: black black; |
| } |
| h3 { |
| margin-bottom: 0px; |
| margin-top: 0px !important; |
| color:var(--text-color); |
| font-family: 'Andale Mono'; |
| font-weight: normal; |
| font-size: 10pt |
| } |
| .pulse { |
| width: 40px; |
| height: 40px; |
| border-radius: 50%; |
| position: absolute; |
| background-color: black; |
| 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: black; |
| 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 { |
| display: inline-block; |
| justify-content: left; |
| max-width: 70vw; |
| } |
| #feed-div { |
| display: flex; |
| justify-content: right; |
| width: 90%; |
| height: 90%; |
| position: relative; |
| margin-right: 20px; |
| } |
| h1 { |
| margin: 0px; |
| margin-top: 20px; |
| font-weight: normal; |
| font-size: 10pt; |
| } |
| .feed { |
| transition: opacity 1s ease; |
| width: 100%; |
| height: 100%; |
| max-height: 80vh; |
| border-radius: 5px; |
| } |
| .map-div { |
| position: relative; |
| width: 280px; |
| height: 190px; |
| margin-top: 3%; |
| margin-bottom: 3%; |
| box-sizing: border-box; |
| } |
| .info { |
| cursor: default; |
| display: flex; |
| flex-direction: column; |
| align-items: flex-start; |
| width: 400px; |
| transition 0.5s ease; |
| } |
| @font-face {font-family: "Andale Mono";src: url("static/andalemono.ttf") format("truetype");} |
| #info { |
| transition 1s ease; |
| } |
| #info-text { |
| margin-top: 15px; |
| margin-bottom: 0px; |
| font-size: 10pt; |
| } |
| a:hover { |
| background-color: white; |
| color: black; |
| transition: 0.1s ease; |
| } |
| a { |
| background-color: transparent; |
| border-radius: 0px; |
| text-decoration: none; |
| color:var(--text-color); |
| transition: 0.1s ease; |
| font-size: 10pt; |
| } |
| .hoverButton { |
| text-align: left; |
| padding: 5px; |
| border: none; |
| font-size: 10pt; |
| font-family: 'Andale Mono'; |
| color: var(--text-color); |
| transition: 0.1s ease; |
| font-size: 10pt; |
| border-radius: 0px; |
| border: 1px yellow solid; |
| background-color: black; |
| |
| } |
| .hoverButton:hover { |
| color: black; |
| background-color: yellow; |
| } |
| .tag { |
| font-family: 'Andale Mono'; |
| margin: auto; |
| color:grey; |
| } |
| |
| #location-name:hover { |
| color: black; |
| } |
| |
| #share { |
| cursor: pointer; |
| margin: auto; |
| margin-left: 10px; |
| color: yellow; |
| transition: 0.1s ease; |
| } |
| #share:hover { |
| opacity: 0.5; |
| } |
| #show-more { |
| cursor: pointer; |
| } |
| #additional-info { |
| display: block; |
| height: 0px; |
| overflow: hidden; |
| transition: height 0.3s ease; |
| } |
| #additional-info.expanded { |
| height: auto; |
| } |
| |
| |
| @media only screen and (orientation: portrait) { |
| .body { |
| height: 85vh; |
| } |
| h1 { |
| margin-top: 20px !important; |
| } |
| .flex-container { |
| flex-direction: column; |
| align-items: left; |
| } |
| |
| .map-div { |
| width: 100%; |
| height: 100%; |
| } |
| .outer-container { |
| max-width: 85vw; |
| } |
| #feed-div { |
| justify-content: left; |
| width: 100%; |
| max-height: 45%; |
| margin-right: 0; |
| } |
| .feed { |
| height: 100%; |
| width: 100%; |
| max-height: 100%; |
| } |
| } |
| </style> |
| </head> |
|
|
| <body style="background-color: black;"> |
| <div class="outer-container"> |
| <div class="flex-container"> |
|
|
| <div id="feed-div"> |
| <img id="feed" class="feed" src="static/eye.gif" /> |
| </div> |
|
|
| |
| <div class="info" id="info"> |
| <h1 id="country" style="color:var(--text-color); margin-top: 10px; font-family: 'Andale Mono'; margin-bottom: 2px;"> searching...</h1> |
| <a href="{{ ip_link }}" target="_blank"> <h3 id="location-name">{{ page_title|safe }}</h3></a> |
|
|
| <div style="display: flex; margin-top: 15px; margin-bottom: 0%;"> |
| |
| <a href="?new=true" style="margin-right: 10px; display: inline-block;"> |
| <button class="hoverButton"> |
| another |
| </button> |
| </a> |
| |
| <a class="abortButton" href="?new=false&id={{ id }}" id="refreshSameFeedButton" style="display: inline-block;"> |
| <button class="hoverButton"> |
| refresh |
| </button> |
| </a> |
| |
| <i id="share" class="fa-solid fa-link" data-id="{{ id }}"></i> |
| <p id="copied" class="tag" style="visibility: hidden;">copied</p> |
| </div> |
| |
| <p id="info-text" style="color:var(--text-color); font-family: 'Andale Mono';"> |
| |
| time: <span id="time"></span><br> |
|
|
| <span id="additional-info"> |
| owner: {{ owner }}<br> |
| ip: {{ ip }}<br> |
| lat, lon: {{ loc }} |
| </span> |
|
|
| <br> |
| <span id="tag"> |
| this is UNSECURED CAMERA<br> |
| made by <a href=mailto:bmo@scudhouse.com>brayden moore</a><br> |
| please come again</span> |
| </p> |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| </div> |
|
|
| </div> |
| </div> |
|
|
|
|
| <script> |
| |
| |
| let loadingGif = "{{ url_for('static', filename='eye.gif') }}"; |
| let currentFeed; |
| let firstLoad = true; |
| document.addEventListener("DOMContentLoaded", function() { |
| const feed = document.getElementById("feed"); |
| feed.style.width = "80px"; |
| feed.style.height = "50px"; |
| feed.src = loadingGif; |
| feed.style.opacity = "0.5"; |
| const infoDiv = document.getElementById("info"); |
| const infoText = document.getElementById("info-text"); |
| infoText.style.opacity = "0%"; |
| infoText.style.height = "0%"; |
| |
| const countryElement = document.getElementById("country"); |
| |
| const locationName = document.getElementById('location-name'); |
| locationName.textContent = "{{ page_title|safe }}"; |
| |
| const newUrl = "{{ url|safe }}"; |
| |
| let contentTypeChecked = false; |
| let isJpeg = false; |
| function refreshImage() { |
| if (!isJpeg && !contentTypeChecked) { |
| let xhr = new XMLHttpRequest(); |
| xhr.open('HEAD', newUrl, true); |
| xhr.onreadystatechange = function() { |
| if (xhr.readyState === 4 && xhr.status === 200) { |
| if (xhr.getResponseHeader('Content-Type') === 'image/jpeg') { |
| img.src = newUrl + "?r=" + new Date().getTime(); |
| if (firstLoad){ |
| countryElement.textContent = "connecting..."; |
| } |
| isJpeg = true; |
| contentTypeChecked = true; |
| } |
| } |
| }; |
| xhr.send(); |
| } else if (isJpeg && contentTypeChecked) { |
| img.src = newUrl + "?r=" + new Date().getTime(); |
| } |
| } |
| |
| const img = new Image(); |
| img.onload = function() { |
| if (firstLoad) { |
| infoDiv.style.height = "0%"; |
| } |
| firstLoad = false; |
| old = newUrl; |
| feed.src = this.src; |
| |
| const pixelWidth = this.naturalWidth; |
| const pixelHeight = this.naturalHeight; |
| |
| country.textContent = "{{ country }}"; |
| |
| setTimeout(() => { |
| locationName.textContent = "{{ name|safe }}"; |
| feed.style.width = "100%"; |
| feed.style.height = "70%"; |
| feed.style.opacity = "1"; |
| infoDiv.style.height = "100%"; |
| infoText.style.opacity = "1"; |
| }, 100); |
| |
| setTimeout(refreshImage, 500); |
| }; |
| |
| img.onerror = function(event) { |
| feed.style.width = "80px"; |
| feed.style.height = "50px"; |
| feed.src = loadingGif; |
| feed.style.opacity = "0.5"; |
| infoText.style.opacity = "0%"; |
| locationName.textContent = "{{ page_title|safe }}"; |
| console.log("Image loading failed:", event); |
| |
| const urlParams = new URLSearchParams(window.location.search); |
| if (urlParams.get('new') === 'false') { |
| countryElement.textContent = "couldn't connect."; |
| } |
| else { |
| 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); |
| }); |
| |
| |
| document.addEventListener("DOMContentLoaded", function() { |
| const shareIcon = document.getElementById("share"); |
| const copiedText = document.getElementById("copied"); |
| |
| shareIcon.addEventListener("click", function() { |
| const id = this.getAttribute("data-id"); |
| const urlToCopy = `${window.location.origin}/?id=${id}`; |
| |
| navigator.clipboard.writeText(urlToCopy).then(() => { |
| console.log("URL copied to clipboard"); |
| shareIcon.className = "fa-solid fa-check"; |
| |
| }).catch(err => { |
| console.log("Could not copy text: ", err); |
| }); |
| }); |
| }); |
| |
| |
| document.addEventListener("DOMContentLoaded", function() { |
| const urlParams = new URLSearchParams(window.location.search); |
| const countryElement = document.getElementById("country"); |
| |
| if (urlParams.get('new') === 'false') { |
| countryElement.textContent = "connecting..."; |
| } |
| }); |
| |
| |
| |
| document.addEventListener("DOMContentLoaded", function() { |
| const feed = document.getElementById("feed"); |
| let isFullscreen = false; |
| |
| function toggleFullScreen() { |
| if (!isFullscreen) { |
| if (this.requestFullscreen) { |
| this.requestFullscreen(); |
| } else if (this.mozRequestFullScreen) { |
| this.mozRequestFullScreen(); |
| } else if (this.webkitRequestFullscreen) { |
| this.webkitRequestFullscreen(); |
| } else if (this.msRequestFullscreen) { |
| this.msRequestFullscreen(); |
| } |
| } else { |
| if (document.exitFullscreen) { |
| document.exitFullscreen(); |
| } else if (document.mozCancelFullScreen) { |
| document.mozCancelFullScreen(); |
| } else if (document.webkitExitFullscreen) { |
| document.webkitExitFullscreen(); |
| } else if (document.msExitFullscreen) { |
| document.msExitFullscreen(); |
| } |
| } |
| } |
| |
| feed.addEventListener("click", toggleFullScreen); |
| feed.addEventListener("touchstart", toggleFullScreen); |
| |
| document.addEventListener("fullscreenchange", function() { |
| isFullscreen = !isFullscreen; |
| }); |
| }); |
| |
| |
| document.addEventListener('keydown', function(event) { |
| if (event.keyCode === 32) { |
| window.location.href = '/?new=true'; |
| } |
| }); |
| |
| |
| document.addEventListener('DOMContentLoaded', function() { |
| const infoText = document.getElementById('info-text'); |
| const additionalInfo = document.getElementById('additional-info'); |
| const showMore = document.getElementById('show-more'); |
| const moreButton = document.getElementById('more-button'); |
| |
| |
| additionalInfo.style.height = '100%'; |
| additionalInfo.style.overflow = 'hidden'; |
| additionalInfo.style.transition = 'height 0.3s ease-in-out'; |
| |
| showMore.addEventListener('click', function() { |
| if (additionalInfo.style.height === '0px') { |
| const scrollHeight = additionalInfo.scrollHeight; |
| additionalInfo.style.height = `${scrollHeight}px`; |
| showMore.innerHTML = 'less <i style="margin-bottom:10px; color:var(--text-color);" id="more-button" class="fa-solid fa-caret-up"></i>'; |
| } else { |
| additionalInfo.style.height = '0'; |
| showMore.innerHTML = 'more <i style="margin-bottom:10px; color:var(--text-color);" id="more-button" class="fa-solid fa-caret-down"></i>'; |
| } |
| }); |
| }); |
| |
| |
| |
| |
| </script> |
| </body> |
|
|
| </html> |