Something went wrong. Try again.
A badger 2350 micro python app loading who has scaned my youandme.at qr code
Something went wrong. Try again.
7.1 kB · 216 lines · Created 6mo ago
Python
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217import osimport sys
import urequestsimport wifi
# The badger has a framework that loads in a lot of things like screen, image, wifi, etc# This string does not have the images, like the qr code but you can change those out for your own# Can read more about the apis here https://badgewa.re/docs
# awkward, but loads the badge app directory for the qr codesys.path.insert(0, "/system/apps/badge")os.chdir("/system/apps/badge")
# this state is stored to disk on exit of the app or sleepstate = {"current_cursor": None, "cursor_stack": [], "show_messages": False, "limit": 2}
handle_cache = {}rear_view = False
USER_AGENT = "Bailey's badger"
# Badger 2350: 264x176SCREEN_W = screen.widthSCREEN_H = screen.height
# settings for the "ui"BORDER = 4HEADER_H = 18LINE_H = 16PADDING = 6CONTENT_X = BORDER + PADDINGCONTENT_RIGHT = SCREEN_W - BORDER - PADDING# Approximate character width for 14px fontCHAR_W = 7# Max characters that fit in the content area per lineMAX_CHARS_PER_LINE = (CONTENT_RIGHT - CONTENT_X) // CHAR_W
# Hardcoded constellation to my url to look for at.youandme.connection records that has my did as a subject fieldCONSTELLATION_URL = "https://constellation.microcosm.blue/xrpc/blue.microcosm.links.getBacklinks?subject=did%3Aplc%3Arnpkyqnmsw4ipey6eotbdnnf&source=at.youandme.connection%3Asubject"
# Stuff to load in a png and load it into the frameworkqr_photo = image.load("qr_code.png")qr_window = image(qr_photo.width, qr_photo.height)qr_window.blit(qr_photo, vec2(0, 0))qr_window.dither()
# Gets all the backlinks to my did from constellation. Takes into account pagination from statedef get_constellation_links(direction): url = CONSTELLATION_URL # Hard coded limit 4, looks awkward cause I was originaly dynamically changing it url += "&limit=4" if direction == "next" and state["current_cursor"]: state["cursor_stack"].append(state["current_cursor"]) url += f"&cursor={state['current_cursor']}" elif direction == "back" and state["cursor_stack"]: state["cursor_stack"].pop() if state["cursor_stack"]: url += f"&cursor={state['cursor_stack'][-1]}"
request = urequests.get( url, headers={"Accept": "application/json", "User-Agent": USER_AGENT} ) result = request.json() state["current_cursor"] = result.get("cursor") records = result["records"] request.close() return records
# Calls slingshot to get the user's minidoc (a mini did doc) to resolve handles from the backlinksdef get_handle(users_did): if users_did in handle_cache: return handle_cache[users_did] url = f"https://slingshot.microcosm.blue/xrpc/blue.microcosm.identity.resolveMiniDoc?identifier={users_did}" request = urequests.get( url, headers={"Accept": "application/json", "User-Agent": USER_AGENT} ) result = request.json() request.close() handle = result.get("handle") handle_cache[users_did] = handle return handle
# Makes a little border for a bit of a "ui"def draw_border(): screen.pen = color.black for i in range(2): screen.line(BORDER + i, BORDER, BORDER + i, SCREEN_H - BORDER) screen.line( SCREEN_W - BORDER - i, BORDER, SCREEN_W - BORDER - i, SCREEN_H - BORDER ) screen.line(BORDER, BORDER + i, SCREEN_W - BORDER, BORDER + i) screen.line( BORDER, SCREEN_H - BORDER - i, SCREEN_W - BORDER, SCREEN_H - BORDER - i )
# Draws the header with the urldef draw_header(page_num): screen.pen = color.black for row in range(BORDER + 2, BORDER + 2 + HEADER_H): screen.line(BORDER + 2, row, SCREEN_W - BORDER - 2, row)
screen.pen = color.white screen.text("youandme.at", CONTENT_X, BORDER - 4) screen.text(f"pg {page_num}", CONTENT_RIGHT - 30, BORDER - 4)
# Footer with some button text so I don't forget what button is whichdef draw_footer(): footer_y = SCREEN_H - BORDER - LINE_H - 10 screen.pen = color.black screen.line(BORDER + 2, footer_y - 3, SCREEN_W - BORDER - 2, footer_y - 3) screen.text("UP:back DOWN:next", CONTENT_X, footer_y)
# Clears the eink screen to a white background (or turns off the dots)def clear_screen(): screen.pen = color.white screen.clear()
# Loads the font and makes sure the "pen" is set to black/on when drawing text/images, It's a global parameter# That needs to be set before drawing to the screendef before_write(): screen.pen = color.black screen.font = pixel_font.load("/system/assets/fonts/manticore.ppf")
# Build in function called from the frame work to update every cycledef update(): global rear_view # Button checks before trying to connect to the wifi to get the value on wake up go_to_next = badge.pressed(BUTTON_DOWN) go_back = badge.pressed(BUTTON_UP)
if badge.pressed(BUTTON_B): rear_view = not rear_view
if badge.pressed(BUTTON_C): state["cursor_stack"] = [] state["current_cursor"] = None
clear_screen() before_write() # Rear view is the QR code (second screen), front is the list if not rear_view: screen.text("loading...", 100, 80) # This tells the badge to update the screen badge.update()
# Attempts to connect to wifi from the secrets file wifi.connect() while not wifi.tick(): pass # Clears and resets the font/pen color before writing the ui clear_screen() before_write()
# Decides how to get the links for pagination if go_to_next: records = get_constellation_links("next") elif go_back: records = get_constellation_links("back") else: records = get_constellation_links("initial")
page_num = len(state["cursor_stack"]) + 1 # Draws the ui draw_border() draw_header(page_num) draw_footer()
# Draws the list y = BORDER + 2 + HEADER_H + PADDING
for i, record in enumerate(records): if i > 0: screen.pen = color.black screen.line(CONTENT_X, y, CONTENT_RIGHT, y) y += PADDING
screen.pen = color.black
handle_text = ""
try: handle = get_handle(record["did"]) handle_text = f"@{handle}" except: handle_text = record["did"][:20]
# Line 1: @handle screen.text(handle_text, CONTENT_X, y) y += LINE_H
y += PADDING else: # If it's the rear screen just write the qr code to the badge screen.blit(qr_window, vec2(SCREEN_W / 2 - qr_photo.width / 2, 10)) # Updates the badge and tell it to wait for the RTC clock update or a button press badge.update() wait_for_button_or_alarm(timeout=5000)
# saves state to file system on exitdef on_exit(): State.save("pumpkin", state)
# Start up and loads the stateState.load("pumpkin", state)run(update)