Add code
This commit is contained in:
parent
d52ac860d7
commit
218989cf8e
34
README.md
Normal file → Executable file
34
README.md
Normal file → Executable file
|
@ -1,2 +1,34 @@
|
||||||
# navpoint
|
# Navpoint Desktop
|
||||||
|
|
||||||
|
This is a simple Python program that will run two HTTP servers. One listens on
|
||||||
|
the computer's local IP address (e.g. `192.168.x.x`), port 8888, to receive
|
||||||
|
location updates from the [Navpoint
|
||||||
|
Mobile](https://gallery.appinventor.mit.edu/?galleryid=2c18ee4d-4eed-452a-9228-de8e813820d1)
|
||||||
|
Android app. The other listens on `127.0.0.1` (i.e. `localhost`), also on port
|
||||||
|
8888, for connections from a digital globe program such as [Google Earth
|
||||||
|
Pro](https://www.google.com/earth/about), allowing that program to track the
|
||||||
|
user's location. (Navpoint is not developed or endorsed by Google.)
|
||||||
|
|
||||||
|
Navpoint Desktop has a minimal GUI consisting only of a QR code. Simply scan
|
||||||
|
the code in Navpoint Mobile to establish a connection. The phone and computer
|
||||||
|
must be on the same Wi-Fi network; if a router is not available, enabling
|
||||||
|
mobile hotspot on the phone and connecting the computer to that network should
|
||||||
|
work well. An Internet connection is not needed; Navpoint works over a LAN.
|
||||||
|
|
||||||
|
Navpoint Desktop makes the geographic data available in KML format at
|
||||||
|
`http://127.0.0.1:8888/navpoint.kml`. The `navpoint_link.kml` file in this
|
||||||
|
repository contains a link to this URL configured to update every three
|
||||||
|
seconds; simply open this file in Google Earth or another compatible program to
|
||||||
|
connect to Navpoint Desktop.
|
||||||
|
|
||||||
|
## Licensing
|
||||||
|
|
||||||
|
Navpoint Desktop is released under the [GNU General Public License
|
||||||
|
v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html), except the file
|
||||||
|
`navpoint/get_ip.py`, which is released under [Creative Commons
|
||||||
|
Attribution-ShareAlike 4.0
|
||||||
|
International](https://creativecommons.org/licenses/by-sa/4.0/) due to use of
|
||||||
|
[code published on Stack Overflow](https://stackoverflow.com/a/28950776).
|
||||||
|
|
||||||
|
Navpoint Mobile is released under the [GNU General Public License
|
||||||
|
v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html).
|
||||||
|
|
40
build-linux.sh
Executable file
40
build-linux.sh
Executable file
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
arch=$(uname -p)
|
||||||
|
distDir=dist/navpoint-linux-$arch
|
||||||
|
|
||||||
|
rm -rf $distDir
|
||||||
|
mkdir $distDir
|
||||||
|
|
||||||
|
pyinstaller -w -F --hidden-import tornado.web main.py
|
||||||
|
|
||||||
|
mv dist/main $distDir/navpoint
|
||||||
|
cp icon.png $distDir/navpoint.png
|
||||||
|
|
||||||
|
cat > $distDir/navpoint.desktop << HERE
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Terminal=false
|
||||||
|
Name=Navpoint
|
||||||
|
Exec=/bin/sh -c "$HOME/.local/bin/navpoint"
|
||||||
|
Icon=navpoint
|
||||||
|
StartupWMClass=navpoint
|
||||||
|
HERE
|
||||||
|
|
||||||
|
cat > $distDir/install.sh << HERE
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
binary_target=~/.local/bin/
|
||||||
|
desktop_target=~/.local/share/applications/
|
||||||
|
icon_target=~/.local/share/icons/
|
||||||
|
|
||||||
|
cp navpoint \$binary_target/navpoint
|
||||||
|
chmod +x \$binary_target/navpoint
|
||||||
|
|
||||||
|
cp navpoint.desktop \$desktop_target/navpoint.desktop
|
||||||
|
|
||||||
|
cp navpoint.png \$icon_target/navpoint.png
|
||||||
|
HERE
|
||||||
|
chmod +x $distDir/install.sh
|
||||||
|
|
||||||
|
tar -czf $distDir.tar.gz $distDir
|
2
build-windows.bat
Executable file
2
build-windows.bat
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
pyinstaller -w -F --hidden-import tornado.web main.py
|
||||||
|
move dist/main.exe dist/navpoint-windows.exe
|
BIN
icon.ico
Executable file
BIN
icon.ico
Executable file
Binary file not shown.
After Width: | Height: | Size: 175 KiB |
6
icon.svg
Executable file
6
icon.svg
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" fill="none" stroke="#D00">
|
||||||
|
<circle cx="40" cy="40" stroke-width="8" r="36" stroke="#00F"/>
|
||||||
|
<circle cx="40" cy="40" stroke-width="8" r="20" stroke="#0A0"/>
|
||||||
|
<circle cx="40" cy="40" stroke-width="8" r="4" stroke="#F00"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 311 B |
0
navpoint/__init__.py
Executable file
0
navpoint/__init__.py
Executable file
3
navpoint/__main__.py
Executable file
3
navpoint/__main__.py
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
import navpoint.run
|
||||||
|
|
||||||
|
navpoint.run.run()
|
1
navpoint/content.py
Executable file
1
navpoint/content.py
Executable file
|
@ -0,0 +1 @@
|
||||||
|
content = """<?xml version='1.0' encoding='us-ascii'?><kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2"><Document><name>Navpoint (waiting for phone)</name><description>Navpoint Desktop waiting for connection from phone</description><open>1</open></Document></kml>"""
|
22
navpoint/get_ip.py
Executable file
22
navpoint/get_ip.py
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
# Copyright 2015-2021 Stack Overflow user "fatal_error"
|
||||||
|
# Copyright 2020 Stack Overflow user "user2561747"
|
||||||
|
#
|
||||||
|
# https://stackoverflow.com/a/28950776
|
||||||
|
#
|
||||||
|
# Used under CC BY-SA 4.0: https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
|
||||||
|
import socket
|
||||||
|
|
||||||
|
|
||||||
|
def get_ip():
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
s.settimeout(0)
|
||||||
|
try:
|
||||||
|
# doesn't even have to be reachable
|
||||||
|
s.connect(("10.254.254.254", 1))
|
||||||
|
IP = s.getsockname()[0]
|
||||||
|
except Exception:
|
||||||
|
IP = "127.0.0.1"
|
||||||
|
finally:
|
||||||
|
s.close()
|
||||||
|
return IP
|
27
navpoint/gui.py
Executable file
27
navpoint/gui.py
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
import tkinter as tk
|
||||||
|
import pyqrcode
|
||||||
|
|
||||||
|
|
||||||
|
def run(link):
|
||||||
|
window = tk.Tk(className="navpoint")
|
||||||
|
window.title("Navpoint")
|
||||||
|
window.resizable(width=False, height=False)
|
||||||
|
|
||||||
|
label = tk.Label(window, text="QR code here...")
|
||||||
|
label.pack()
|
||||||
|
|
||||||
|
image = tk.BitmapImage(
|
||||||
|
data=pyqrcode.create(link).xbm(scale=int(window.winfo_fpixels("2m")))
|
||||||
|
)
|
||||||
|
image.config(background="white")
|
||||||
|
image.config(foreground="black")
|
||||||
|
|
||||||
|
label.config(image=image)
|
||||||
|
|
||||||
|
try:
|
||||||
|
window.iconbitmap("icon.ico")
|
||||||
|
except tk.TclError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
window.mainloop()
|
23
navpoint/local_server.py
Executable file
23
navpoint/local_server.py
Executable file
|
@ -0,0 +1,23 @@
|
||||||
|
import threading
|
||||||
|
import asyncio
|
||||||
|
import tornado
|
||||||
|
import navpoint.content
|
||||||
|
|
||||||
|
|
||||||
|
class GetHandler(tornado.web.RequestHandler):
|
||||||
|
def get(self):
|
||||||
|
self.write(navpoint.content.content)
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
app = tornado.web.Application(
|
||||||
|
[
|
||||||
|
(r"/navpoint.kml", GetHandler),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
app.listen(8888, address="127.0.0.1")
|
||||||
|
await asyncio.Event().wait()
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
threading.Thread(target=asyncio.run, args=(main(),), daemon=True).start()
|
46
navpoint/phone_server.py
Executable file
46
navpoint/phone_server.py
Executable file
|
@ -0,0 +1,46 @@
|
||||||
|
import tornado
|
||||||
|
import navpoint.get_ip
|
||||||
|
import navpoint.content
|
||||||
|
import asyncio
|
||||||
|
import secrets
|
||||||
|
import threading
|
||||||
|
|
||||||
|
|
||||||
|
class PostHandler(tornado.web.RequestHandler):
|
||||||
|
def get(self):
|
||||||
|
self.write(
|
||||||
|
"<!DOCTYPE html><html><head><title>Navpoint</title></head><body><h1>Navpoint</h1><p>The Navpoint desktop app is working, but you need to scan the QR code from the Navpoint mobile app, not open it in your browser.</p></body></html>"
|
||||||
|
)
|
||||||
|
|
||||||
|
def post(self):
|
||||||
|
navpoint.content.content = self.request.body
|
||||||
|
self.write("Navpoint")
|
||||||
|
|
||||||
|
|
||||||
|
async def main_phone(ip, token):
|
||||||
|
app = tornado.web.Application(
|
||||||
|
[
|
||||||
|
(r"/" + token, PostHandler),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
app.listen(8888, address=ip)
|
||||||
|
await asyncio.Event().wait()
|
||||||
|
|
||||||
|
|
||||||
|
def run_in_thread(ip, token):
|
||||||
|
asyncio.run(main_phone(ip, token))
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
ip = navpoint.get_ip.get_ip()
|
||||||
|
token = secrets.token_urlsafe()
|
||||||
|
threading.Thread(
|
||||||
|
target=run_in_thread,
|
||||||
|
args=(
|
||||||
|
ip,
|
||||||
|
token,
|
||||||
|
),
|
||||||
|
daemon=True,
|
||||||
|
).start()
|
||||||
|
|
||||||
|
return f"http://{ip}:8888/{token}"
|
8
navpoint/run.py
Executable file
8
navpoint/run.py
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
import navpoint.local_server
|
||||||
|
import navpoint.phone_server
|
||||||
|
import navpoint.gui
|
||||||
|
|
||||||
|
def run():
|
||||||
|
navpoint.local_server.run()
|
||||||
|
link = navpoint.phone_server.run()
|
||||||
|
navpoint.gui.run(link)
|
13
navpoint_link.kml
Executable file
13
navpoint_link.kml
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||||
|
<NetworkLink>
|
||||||
|
<name>Navpoint</name>
|
||||||
|
<open>1</open>
|
||||||
|
<description>Connect to Navpoint Desktop running on the local machine to receive location updates from a phone running Navpoint Mobile.</description>
|
||||||
|
<Link>
|
||||||
|
<href>http://localhost:8888/navpoint.kml</href>
|
||||||
|
<refreshMode>onInterval</refreshMode>
|
||||||
|
<refreshInterval>3</refreshInterval>
|
||||||
|
</Link>
|
||||||
|
</NetworkLink>
|
||||||
|
</kml>
|
2
requirements.txt
Executable file
2
requirements.txt
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
pyqrcode
|
||||||
|
tornado
|
Loading…
Reference in New Issue
Block a user