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