Skip to content

Commit

Permalink
Offline support
Browse files Browse the repository at this point in the history
  • Loading branch information
SavageCore committed Jun 16, 2023
1 parent 08f2618 commit 0eabbb3
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 12 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
state.json
__pycache__/
firmware/
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,10 @@ This guide assumes you're running a Raspberry Pi (< 4) with PiTFT and have follo
Also included is a script to create a systemd service to start the flasher on boot. To use it, run `./create-systemd-service.sh` and it will start on next boot. To stop it from starting on boot, run `sudo systemctl disable gp2040-flasher`. If you want to start it manually, run `sudo systemctl start gp2040-flasher`.

You can double press the bottom button to exit the program. Note if you installed the systemd service, it will restart the program.

## Offline Usage

1. Download the latest releases from the [releases page](https://github.com/OpenStickCommunity/GP2040-CE/releases) and place them in the `firmware` directory.
2. Start the app with `sudo python3 main.py --offline`.

The app will also fail gracefully if you're API rate limited or any other connection issue to GitHub and fallback to offline mode.
15 changes: 8 additions & 7 deletions github.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import requests
import urllib.request
import tempfile
import os


Expand All @@ -12,8 +11,11 @@ def __init__(self):

def get_latest_release_info(self):
url = f"https://api.github.com/repos/{self.owner}/{self.repo}/releases"
response = requests.get(url)
if response.status_code == 200:

try:
response = requests.get(url)
response.raise_for_status() # Raise exception for non-2xx status codes

releases = response.json()
for release in releases:
if not release.get("prerelease"):
Expand All @@ -25,11 +27,10 @@ def get_latest_release_info(self):
asset for asset in assets if asset["name"] != "flash_nuke.uf2"]

return version, release_date, assets
else:
# Handle API request error
print("Error:", response.status_code)
except requests.exceptions.RequestException as e:
print("Failed to fetch release info:", e)

return None, None, None
return None, None, None

def download_file(self, url):
# Extract the filename from the URL
Expand Down
40 changes: 35 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import pygame
import pyudev
import os
import sys
from splash_screen import SplashScreen
from button import Button
from picotool import Picotool
from github import Github
from state_manager import StateManager

offline_mode = False
# Hide pygame message
os.putenv('PYGAME_HIDE_SUPPORT_PROMPT', '1')
# Output to PiTFT screen
Expand All @@ -16,8 +18,16 @@
state_manager = StateManager()
selected_firmware = state_manager.get_value("selected_firmware") or 0

github = Github()
version, release_date, firmware_files = github.get_latest_release_info()
# If argument --offline is passed, force offline mode
if len(sys.argv) > 1 and sys.argv[1] == "--offline":
offline_mode = True
print("Forcing offline mode")

if offline_mode:
firmware_files = None
else:
github = Github()
version, release_date, firmware_files = github.get_latest_release_info()

# Initialise the pygame library
pygame.init()
Expand All @@ -29,7 +39,23 @@
# If no firmware files are found, exit
if firmware_files is None: # None is returned if the API request fails
print("Error looking up GitHub releases")
exit()
print("Assuming no internet connection")
offline_mode = True
# We're offline, recreate the firmware_files dictionary from files in the firmware directory, skipping flash_nuke.uf2

selected_firmware = 0
firmware_files = {}
for file in os.listdir("firmware"):
if file.endswith(".uf2") and not file == "flash_nuke.uf2":
firmware_files[len(firmware_files)] = {
"name": os.path.join('firmware', file)
}

# If no firmware files are found, exit
if len(firmware_files) == 0:
print("No firmware files found")
exit()



def clear_screen(screen):
Expand Down Expand Up @@ -62,14 +88,18 @@ def render_text(screen, text, font, color, padding=5):
def flash_drive_handler(action, device):
global selected_firmware
global splash
global offline_mode

device_name = device.sys_name.split('/')[-1]
if action == 'add' and device_name == "sda" and device.get('ID_VENDOR') == 'RPI' and device.get('ID_MODEL') == 'RP2':
picotool = Picotool()
splash.set_text("Pico detected")

download_url = firmware_files[selected_firmware]["browser_download_url"]
firmware_file = github.download_file(download_url)
if offline_mode:
firmware_file = firmware_files[selected_firmware]["name"]
else:
download_url = firmware_files[selected_firmware]["browser_download_url"]
firmware_file = github.download_file(download_url)

# If the firmware file is downloaded successfully, flash it to the Pico
if firmware_file is not None:
Expand Down

0 comments on commit 0eabbb3

Please sign in to comment.