summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaindropsSys <contact@minteck.org>2023-03-24 08:55:08 +0100
committerRaindropsSys <contact@minteck.org>2023-03-24 08:55:08 +0100
commitf88d07d82f016d4ad843734eb18b9db1de4bdb88 (patch)
treec38dfcc2697b2cfaafdeb130138f077ec4cce415
downloadponybadge-f88d07d82f016d4ad843734eb18b9db1de4bdb88.tar.gz
ponybadge-f88d07d82f016d4ad843734eb18b9db1de4bdb88.tar.bz2
ponybadge-f88d07d82f016d4ad843734eb18b9db1de4bdb88.zip
Initial commit
-rw-r--r--.gitignore3
-rw-r--r--.idea/.gitignore8
-rw-r--r--.idea/badger-experiments.iml16
-rw-r--r--.idea/discord.xml7
-rw-r--r--.idea/inspectionProfiles/profiles_settings.xml6
-rw-r--r--.idea/libraries/MicroPython.xml11
-rw-r--r--.idea/misc.xml4
-rw-r--r--.idea/modules.xml8
-rw-r--r--WIFI_CONFIG.py3
m---------_upstream0
-rw-r--r--app.py123
-rw-r--r--badger2040w.py181
-rw-r--r--config.py1
-rw-r--r--data/auvwc.jpegbin0 -> 7087 bytes
-rw-r--r--data/bbrig.jpegbin0 -> 5944 bytes
-rw-r--r--data/ckqsw.jpegbin0 -> 7845 bytes
-rw-r--r--data/dogwu.jpegbin0 -> 7696 bytes
-rw-r--r--data/dorxa.jpegbin0 -> 6200 bytes
-rw-r--r--data/eebmh.jpegbin0 -> 5785 bytes
-rw-r--r--data/erefx.jpegbin0 -> 6083 bytes
-rw-r--r--data/erknz.jpegbin0 -> 6917 bytes
-rw-r--r--data/exudo.jpegbin0 -> 6034 bytes
-rw-r--r--data/fdaay.jpegbin0 -> 7191 bytes
-rw-r--r--data/fytvn.jpegbin0 -> 5367 bytes
-rw-r--r--data/gevde.jpegbin0 -> 5330 bytes
-rw-r--r--data/gfhsr.jpegbin0 -> 6411 bytes
-rw-r--r--data/ghrby.jpegbin0 -> 5171 bytes
-rw-r--r--data/hpwyq.jpegbin0 -> 6596 bytes
-rw-r--r--data/jnbae.jpegbin0 -> 5536 bytes
-rw-r--r--data/khsbb.jpegbin0 -> 6011 bytes
-rw-r--r--data/kkhbw.jpegbin0 -> 6431 bytes
-rw-r--r--data/ktrdb.jpegbin0 -> 6137 bytes
-rw-r--r--data/list.json1
-rw-r--r--data/lllfw.jpegbin0 -> 6727 bytes
-rw-r--r--data/lqolg.jpegbin0 -> 7908 bytes
-rw-r--r--data/mglyq.jpegbin0 -> 5872 bytes
-rw-r--r--data/mhnqy.jpegbin0 -> 6331 bytes
-rw-r--r--data/mvaws.jpegbin0 -> 6920 bytes
-rw-r--r--data/owmle.jpegbin0 -> 6384 bytes
-rw-r--r--data/pabmo.jpegbin0 -> 6430 bytes
-rw-r--r--data/pjpnb.jpegbin0 -> 6617 bytes
-rw-r--r--data/qaavw.jpegbin0 -> 5713 bytes
-rw-r--r--data/qaenj.jpegbin0 -> 5919 bytes
-rw-r--r--data/qbzxm.jpegbin0 -> 7196 bytes
-rw-r--r--data/qcemf.jpegbin0 -> 7165 bytes
-rw-r--r--data/qraku.jpegbin0 -> 7035 bytes
-rw-r--r--data/rirgf.jpegbin0 -> 6911 bytes
-rw-r--r--data/rpjok.jpegbin0 -> 5333 bytes
-rw-r--r--data/sbxze.jpegbin0 -> 5757 bytes
-rw-r--r--data/sehke.jpegbin0 -> 6834 bytes
-rw-r--r--data/slsjg.jpegbin0 -> 6143 bytes
-rw-r--r--data/tfbob.jpegbin0 -> 5911 bytes
-rw-r--r--data/ufadt.jpegbin0 -> 5754 bytes
-rw-r--r--data/umbyl.jpegbin0 -> 6224 bytes
-rw-r--r--data/vncoa.jpegbin0 -> 5533 bytes
-rw-r--r--data/vvsxf.jpegbin0 -> 6361 bytes
-rw-r--r--data/wnujv.jpegbin0 -> 3513 bytes
-rw-r--r--data/xbvwt.jpegbin0 -> 6495 bytes
-rw-r--r--data/xcjhj.jpegbin0 -> 7460 bytes
-rw-r--r--data/xdoql.jpegbin0 -> 8328 bytes
-rw-r--r--data/yhbrc.jpegbin0 -> 6662 bytes
-rw-r--r--data/zajrk.jpegbin0 -> 6287 bytes
-rw-r--r--data/zhtzs.jpegbin0 -> 7583 bytes
-rw-r--r--data/zkgjj.jpegbin0 -> 7751 bytes
-rw-r--r--data/zlnuo.jpegbin0 -> 7099 bytes
-rw-r--r--data/ztfjz.jpegbin0 -> 6851 bytes
-rw-r--r--data/zwtnn.jpegbin0 -> 6317 bytes
-rw-r--r--data/zzise.jpegbin0 -> 6175 bytes
-rw-r--r--download.php11
-rw-r--r--icon.php7
-rw-r--r--icons/_default.jpegbin0 -> 379 bytes
-rw-r--r--icons/about.jpegbin0 -> 533 bytes
-rw-r--r--icons/canteen.jpegbin0 -> 602 bytes
-rw-r--r--icons/developer.jpegbin0 -> 485 bytes
-rw-r--r--icons/help.jpegbin0 -> 557 bytes
-rw-r--r--icons/update.jpegbin0 -> 563 bytes
-rw-r--r--icons/weather.jpegbin0 -> 530 bytes
-rw-r--r--main.py1
-rw-r--r--network_manager.py108
-rw-r--r--os/apps.py5
-rw-r--r--os/ui.py80
-rw-r--r--state/apps.txt1
-rw-r--r--state/fronter.txt1
-rw-r--r--version.txt1
84 files changed, 587 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..338cde5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+stealth.jpeg
+stealth.psd
+roll
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/badger-experiments.iml b/.idea/badger-experiments.iml
new file mode 100644
index 0000000..e4770e6
--- /dev/null
+++ b/.idea/badger-experiments.iml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+ <component name="FacetManager">
+ <facet type="MicroPython" name="MicroPython">
+ <configuration>
+ <device name="Raspberry Pi Pico" />
+ </configuration>
+ </facet>
+ </component>
+ <component name="NewModuleRootManager">
+ <content url="file://$MODULE_DIR$" />
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="MicroPython" level="project" />
+ </component>
+</module> \ No newline at end of file
diff --git a/.idea/discord.xml b/.idea/discord.xml
new file mode 100644
index 0000000..d8e9561
--- /dev/null
+++ b/.idea/discord.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="DiscordProjectSettings">
+ <option name="show" value="PROJECT_FILES" />
+ <option name="description" value="" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+ <settings>
+ <option name="USE_PROJECT_PROFILE" value="false" />
+ <version value="1.0" />
+ </settings>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/MicroPython.xml b/.idea/libraries/MicroPython.xml
new file mode 100644
index 0000000..4e7358c
--- /dev/null
+++ b/.idea/libraries/MicroPython.xml
@@ -0,0 +1,11 @@
+<component name="libraryTable">
+ <library name="MicroPython" type="python">
+ <CLASSES>
+ <root url="file://$APPLICATION_PLUGINS_DIR$/intellij-micropython/typehints/stdlib" />
+ <root url="file://$APPLICATION_PLUGINS_DIR$/intellij-micropython/typehints/micropython" />
+ <root url="file://$APPLICATION_PLUGINS_DIR$/intellij-micropython/typehints/rpi_pico" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..dc9ea49
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10" project-jdk-type="Python SDK" />
+</project> \ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..cdc759d
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectModuleManager">
+ <modules>
+ <module fileurl="file://$PROJECT_DIR$/.idea/badger-experiments.iml" filepath="$PROJECT_DIR$/.idea/badger-experiments.iml" />
+ </modules>
+ </component>
+</project> \ No newline at end of file
diff --git a/WIFI_CONFIG.py b/WIFI_CONFIG.py
new file mode 100644
index 0000000..3cd5ada
--- /dev/null
+++ b/WIFI_CONFIG.py
@@ -0,0 +1,3 @@
+SSID = ""
+PSK = ""
+COUNTRY = "" \ No newline at end of file
diff --git a/_upstream b/_upstream
new file mode 160000
+Subproject aa7039449549c1d8a68d085cb158a43d702ddc4
diff --git a/app.py b/app.py
new file mode 100644
index 0000000..18e87b9
--- /dev/null
+++ b/app.py
@@ -0,0 +1,123 @@
+import badger2040w
+import picographics
+import jpegdec
+import json
+import sys
+import uos as os
+import machine
+
+sys.path.insert(0, './os')
+import ui
+
+global display
+global badger
+
+import config
+
+def update(index):
+ display.set_pen(15)
+ display.clear()
+
+ j = jpegdec.JPEG(display)
+ j.open_file("data/" + list[index]['id'] + ".jpeg")
+ j.decode(0, 0, jpegdec.JPEG_SCALE_FULL)
+
+ display.set_pen(0)
+ display.set_font("bitmap8")
+ display.text(list[index]['name'], 130, 20, scale=2)
+
+ display.set_font("bitmap6")
+ display.text(list[index]['pronouns'] + list[index]['age'], 130, 40, scale=2)
+
+ display.set_font("bitmap6")
+ display.text(list[index]['species'], 130, 55, scale=2)
+
+ display.update()
+
+ f = open("state/fronter.txt", "w")
+ f.write(str(current))
+ f.close()
+
+badger = badger2040w.Badger2040W()
+
+display = picographics.PicoGraphics(display=picographics.DISPLAY_INKY_PACK)
+
+try:
+ badger2040w.system_speed(badger2040w.SYSTEM_SLOW)
+except ValueError:
+ pass
+
+ try:
+ badger2040w.system_speed(badger2040w.SYSTEM_NORMAL)
+ except ValueError:
+ pass
+
+display.set_pen(15)
+display.clear()
+
+file = open("./data/list.json", "r+")
+list = json.loads(file.read())
+
+list = [i for i in list if i['system'] is config.SYSTEM]
+
+f = open("state/fronter.txt", "r")
+current = int(f.read().strip())
+f.close()
+
+if not (0 <= current < len(list)):
+ current = 0
+
+badger.set_update_speed(2)
+
+display.set_pen(15)
+display.clear()
+display.update()
+
+badger.set_update_speed(3)
+
+update(current)
+
+while True:
+ try:
+ badger2040w.system_speed(badger2040w.SYSTEM_SLOW)
+ except ValueError:
+ try:
+ badger2040w.system_speed(badger2040w.SYSTEM_NORMAL)
+ except ValueError:
+ pass
+
+ if badger.pressed(badger2040w.BUTTON_DOWN):
+ if current < len(list) - 1:
+ current += 1
+
+ update(current)
+ elif badger.pressed(badger2040w.BUTTON_UP):
+ if current > 0:
+ current -= 1
+
+ update(current)
+ elif badger.pressed(badger2040w.BUTTON_A):
+ badger.set_update_speed(0)
+
+ display.set_pen(15)
+
+ display.clear()
+ display.update()
+
+ display.clear()
+ display.update()
+
+ update(current)
+
+ badger.set_update_speed(3)
+ elif badger.pressed(badger2040w.BUTTON_B):
+ ui.view(badger, display)
+
+ badger.set_update_speed(1)
+
+ display.set_pen(15)
+ display.clear()
+ display.update()
+
+ badger.set_update_speed(3)
+ update(current)
diff --git a/badger2040w.py b/badger2040w.py
new file mode 100644
index 0000000..1b6f169
--- /dev/null
+++ b/badger2040w.py
@@ -0,0 +1,181 @@
+import machine
+import micropython
+from picographics import PicoGraphics, DISPLAY_INKY_PACK
+import network
+from network_manager import NetworkManager
+import WIFI_CONFIG
+import uasyncio
+import time
+import gc
+import wakeup
+
+
+BUTTON_DOWN = 11
+BUTTON_A = 12
+BUTTON_B = 13
+BUTTON_C = 14
+BUTTON_UP = 15
+BUTTON_USER = None # User button not available on W
+
+BUTTON_MASK = 0b11111 << 11
+
+SYSTEM_VERY_SLOW = 0
+SYSTEM_SLOW = 1
+SYSTEM_NORMAL = 2
+SYSTEM_FAST = 3
+SYSTEM_TURBO = 4
+
+UPDATE_NORMAL = 0
+UPDATE_MEDIUM = 1
+UPDATE_FAST = 2
+UPDATE_TURBO = 3
+
+LED = 22
+ENABLE_3V3 = 10
+BUSY = 26
+
+WIDTH = 296
+HEIGHT = 128
+
+SYSTEM_FREQS = [
+ 4000000,
+ 12000000,
+ 48000000,
+ 133000000,
+ 250000000
+]
+
+BUTTONS = {
+ BUTTON_DOWN: machine.Pin(BUTTON_DOWN, machine.Pin.IN, machine.Pin.PULL_DOWN),
+ BUTTON_A: machine.Pin(BUTTON_A, machine.Pin.IN, machine.Pin.PULL_DOWN),
+ BUTTON_B: machine.Pin(BUTTON_B, machine.Pin.IN, machine.Pin.PULL_DOWN),
+ BUTTON_C: machine.Pin(BUTTON_C, machine.Pin.IN, machine.Pin.PULL_DOWN),
+ BUTTON_UP: machine.Pin(BUTTON_UP, machine.Pin.IN, machine.Pin.PULL_DOWN),
+}
+
+WAKEUP_MASK = 0
+
+
+def woken_by_button():
+ return wakeup.get_gpio_state() & BUTTON_MASK > 0
+
+
+def pressed_to_wake(button):
+ return wakeup.get_gpio_state() & (1 << button) > 0
+
+
+def reset_pressed_to_wake():
+ wakeup.reset_gpio_state()
+
+
+def pressed_to_wake_get_once(button):
+ global WAKEUP_MASK
+ result = (wakeup.get_gpio_state() & ~WAKEUP_MASK & (1 << button)) > 0
+ WAKEUP_MASK |= (1 << button)
+ return result
+
+
+def system_speed(speed):
+ try:
+ machine.freq(SYSTEM_FREQS[speed])
+ except IndexError:
+ pass
+
+
+class Badger2040W():
+ def __init__(self):
+ self.display = PicoGraphics(DISPLAY_INKY_PACK)
+ self._led = machine.PWM(machine.Pin(LED))
+ self._led.freq(1000)
+ self._led.duty_u16(0)
+ self._update_speed = 0
+
+ def __getattr__(self, item):
+ # Glue to redirect calls to PicoGraphics
+ return getattr(self.display, item)
+
+ def update(self):
+ t_start = time.ticks_ms()
+ self.display.update()
+ t_elapsed = time.ticks_ms() - t_start
+
+ delay_ms = [4700, 2600, 900, 250][self._update_speed]
+
+ if t_elapsed < delay_ms:
+ time.sleep((delay_ms - t_elapsed) / 1000)
+
+ def set_update_speed(self, speed):
+ self.display.set_update_speed(speed)
+ self._update_speed = speed
+
+ def led(self, brightness):
+ brightness = max(0, min(255, brightness))
+ self._led.duty_u16(int(brightness * 256))
+
+ def invert(self, invert):
+ raise RuntimeError("Display invert not supported in PicoGraphics.")
+
+ def thickness(self, thickness):
+ raise RuntimeError("Thickness not supported in PicoGraphics.")
+
+ def halt(self):
+ time.sleep(0.05)
+ enable = machine.Pin(ENABLE_3V3, machine.Pin.OUT)
+ enable.off()
+ while not self.pressed_any():
+ pass
+
+ def pressed(self, button):
+ return BUTTONS[button].value() == 1 or pressed_to_wake_get_once(button)
+
+ def pressed_any(self):
+ for button in BUTTONS.values():
+ if button.value():
+ return True
+ return False
+
+ @micropython.native
+ def icon(self, data, index, data_w, icon_size, x, y):
+ s_x = (index * icon_size) % data_w
+ s_y = int((index * icon_size) / data_w)
+
+ for o_y in range(icon_size):
+ for o_x in range(icon_size):
+ o = ((o_y + s_y) * data_w) + (o_x + s_x)
+ bm = 0b10000000 >> (o & 0b111)
+ if data[o >> 3] & bm:
+ self.display.pixel(x + o_x, y + o_y)
+
+ def image(self, data, w, h, x, y):
+ for oy in range(h):
+ row = data[oy]
+ for ox in range(w):
+ if row & 0b1 == 0:
+ self.display.pixel(x + ox, y + oy)
+ row >>= 1
+
+ def status_handler(self, mode, status, ip):
+ print(mode, status, ip)
+ self.display.set_pen(15)
+ self.display.clear()
+ self.display.set_pen(0)
+ if status:
+ self.display.text("Connected!", 10, 10, 300, 0.5)
+ self.display.text(ip, 10, 30, 300, 0.5)
+ else:
+ self.display.text("Connecting...", 10, 10, 300, 0.5)
+ self.update()
+
+ def isconnected(self):
+ return network.WLAN(network.STA_IF).isconnected()
+
+ def ip_address(self):
+ return network.WLAN(network.STA_IF).ifconfig()[0]
+
+ def connect(self):
+ if WIFI_CONFIG.COUNTRY == "":
+ raise RuntimeError("You must populate WIFI_CONFIG.py for networking.")
+ self.display.set_update_speed(2)
+ network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=self.status_handler)
+ uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK))
+ gc.collect() \ No newline at end of file
diff --git a/config.py b/config.py
new file mode 100644
index 0000000..6285a2e
--- /dev/null
+++ b/config.py
@@ -0,0 +1 @@
+SYSTEM = "gdapd" \ No newline at end of file
diff --git a/data/auvwc.jpeg b/data/auvwc.jpeg
new file mode 100644
index 0000000..418ba7b
--- /dev/null
+++ b/data/auvwc.jpeg
Binary files differ
diff --git a/data/bbrig.jpeg b/data/bbrig.jpeg
new file mode 100644
index 0000000..da51ce8
--- /dev/null
+++ b/data/bbrig.jpeg
Binary files differ
diff --git a/data/ckqsw.jpeg b/data/ckqsw.jpeg
new file mode 100644
index 0000000..dd4b118
--- /dev/null
+++ b/data/ckqsw.jpeg
Binary files differ
diff --git a/data/dogwu.jpeg b/data/dogwu.jpeg
new file mode 100644
index 0000000..9e404c8
--- /dev/null
+++ b/data/dogwu.jpeg
Binary files differ
diff --git a/data/dorxa.jpeg b/data/dorxa.jpeg
new file mode 100644
index 0000000..1402caa
--- /dev/null
+++ b/data/dorxa.jpeg
Binary files differ
diff --git a/data/eebmh.jpeg b/data/eebmh.jpeg
new file mode 100644
index 0000000..247919d
--- /dev/null
+++ b/data/eebmh.jpeg
Binary files differ
diff --git a/data/erefx.jpeg b/data/erefx.jpeg
new file mode 100644
index 0000000..57c81c7
--- /dev/null
+++ b/data/erefx.jpeg
Binary files differ
diff --git a/data/erknz.jpeg b/data/erknz.jpeg
new file mode 100644
index 0000000..9f156c5
--- /dev/null
+++ b/data/erknz.jpeg
Binary files differ
diff --git a/data/exudo.jpeg b/data/exudo.jpeg
new file mode 100644
index 0000000..dee43bd
--- /dev/null
+++ b/data/exudo.jpeg
Binary files differ
diff --git a/data/fdaay.jpeg b/data/fdaay.jpeg
new file mode 100644
index 0000000..a7f15ee
--- /dev/null
+++ b/data/fdaay.jpeg
Binary files differ
diff --git a/data/fytvn.jpeg b/data/fytvn.jpeg
new file mode 100644
index 0000000..5094d29
--- /dev/null
+++ b/data/fytvn.jpeg
Binary files differ
diff --git a/data/gevde.jpeg b/data/gevde.jpeg
new file mode 100644
index 0000000..eda6193
--- /dev/null
+++ b/data/gevde.jpeg
Binary files differ
diff --git a/data/gfhsr.jpeg b/data/gfhsr.jpeg
new file mode 100644
index 0000000..9a0800c
--- /dev/null
+++ b/data/gfhsr.jpeg
Binary files differ
diff --git a/data/ghrby.jpeg b/data/ghrby.jpeg
new file mode 100644
index 0000000..3305b17
--- /dev/null
+++ b/data/ghrby.jpeg
Binary files differ
diff --git a/data/hpwyq.jpeg b/data/hpwyq.jpeg
new file mode 100644
index 0000000..3f13ca0
--- /dev/null
+++ b/data/hpwyq.jpeg
Binary files differ
diff --git a/data/jnbae.jpeg b/data/jnbae.jpeg
new file mode 100644
index 0000000..df01b2c
--- /dev/null
+++ b/data/jnbae.jpeg
Binary files differ
diff --git a/data/khsbb.jpeg b/data/khsbb.jpeg
new file mode 100644
index 0000000..0b40a83
--- /dev/null
+++ b/data/khsbb.jpeg
Binary files differ
diff --git a/data/kkhbw.jpeg b/data/kkhbw.jpeg
new file mode 100644
index 0000000..982af61
--- /dev/null
+++ b/data/kkhbw.jpeg
Binary files differ
diff --git a/data/ktrdb.jpeg b/data/ktrdb.jpeg
new file mode 100644
index 0000000..25fa2f7
--- /dev/null
+++ b/data/ktrdb.jpeg
Binary files differ
diff --git a/data/list.json b/data/list.json
new file mode 100644
index 0000000..1540b8c
--- /dev/null
+++ b/data/list.json
@@ -0,0 +1 @@
+[{"id":"wnujv","name":"Mysterious Pony","system":"ynmuc","pronouns":"None","species":"_","age":" - 53","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b9dcc3ce80e4941b2a9c970a35b7b2c32.png"},{"id":"gevde","name":"Sweetie Belle","system":"ynmuc","pronouns":"she\/her","species":"Unicorn","age":" - 5","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b91f6e79e36a14fd68cd962e8522661aa.png"},{"id":"umbyl","name":"Cozy Glow","system":"ynmuc","pronouns":"she\/her","species":"Pegasus","age":" - 9","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3bb5eb288b148843dcbe24566923cf08a1.png"},{"id":"xdoql","name":"Princess Celestia","system":"gdapd","pronouns":"she\/her","species":"Alicorn","age":" - Eternal","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f2983124780ffa5ac44c405daf9b611b8cd615bf.png"},{"id":"xbvwt","name":"Sunny Starscout","system":"ynmuc","pronouns":"she\/her","species":"Earth pony","age":" - 18","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3bef94e4972b6c4f8a95330b0a125874e1.png"},{"id":"fytvn","name":"Creamy Chocolate","system":"ynmuc","pronouns":"she\/her","species":"Pegasus","age":" - 18","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b2a8e7b2a86864b1da4c9802936e8fcd4.png"},{"id":"lqolg","name":"Cinnamon Fire","system":"gdapd","pronouns":"she\/pony","species":"Unicorn","age":" - 17","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f298312401f2ed945677411eb994f07c36616bb2.png"},{"id":"qaenj","name":"Peach Fizz","system":"gdapd","pronouns":"she\/her","species":"Unicorn","age":" - 9","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f2983124755172cd9264457fa0604b9770bffedf.png"},{"id":"rirgf","name":"Scootaloo","system":"gdapd","pronouns":"she\/her","species":"Pegasus","age":" - 11","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f2983124be0dbae711c84629a610815d71d2131b.png"},{"id":"zlnuo","name":"Applejack","system":"ynmuc","pronouns":"she\/her","species":"Earth pony","age":" - 19","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b7b32890557744dd1b76f080c6c8b0113.png"},{"id":"pabmo","name":"Babs Seed","system":"gdapd","pronouns":"she\/her","species":"Earth pony","age":" - 5","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f2983124602683be81354a00ae2b239fe46c6bfc.png"},{"id":"khsbb","name":"Posey Bloom","system":"gdapd","pronouns":"she\/her","species":"Earth pony","age":" - 17","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f29831240e10729240a340ce81587bc4657d409d.png"},{"id":"tfbob","name":"Violet Dawn","system":"gdapd","pronouns":"she\/her","species":"Bat pony","age":" - 18","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f2983124836fb0f735ce4c74927da578fc4f9cd3.png"},{"id":"xcjhj","name":"Blueberry Cloud","system":"ynmuc","pronouns":"she\/her","species":"Unicorn","age":" - 19","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3be7e3a371fa5f49ce8deb86f089579310.png"},{"id":"gfhsr","name":"Fluttershy","system":"ynmuc","pronouns":"she\/her","species":"Pegasus","age":" - 16","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b36c0f97dbb1545f3a4d4d23ad41f0e6f.png"},{"id":"sehke","name":"Windy Leaves","system":"ynmuc","pronouns":"she\/her","species":"Earth pony","age":" - 20","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b123edc54fe0e4f31b678a04defc79103.png"},{"id":"zajrk","name":"Mossy Storm","system":"gdapd","pronouns":"she\/they","species":"Pegasus","age":" - 18","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f29831245ddf123d40ba49fb81b98d77728dbb3a.png"},{"id":"ktrdb","name":"Forest Paint","system":"gdapd","pronouns":"she\/pony","species":"Earth pony","age":" - 18","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f29831248ee91598dcdc4a27ad3e5648358c6e60.png"},{"id":"dorxa","name":"Color Spray","system":"ynmuc","pronouns":"she\/her","species":"Unicorn","age":" - 18","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b6a9647fac08f4054b21f15a0cdf0f496.png"},{"id":"ghrby","name":"Thunder","system":"ynmuc","pronouns":"she\/her","species":"Pegasus","age":" - 21","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b341a0b0f6d7a4d958264b71d2f921eb7.png"},{"id":"zzise","name":"Sky Dream","system":"ynmuc","pronouns":"she\/it","species":"Bat pony","age":" - 19","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b198d3961240840b28f5930a8665693a5.png"},{"id":"owmle","name":"Ocean Trot","system":"ynmuc","pronouns":"she\/her","species":"Unicorn","age":" - 19","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3bd9a3dd6dc2d6481b96f5d77162f3417f.png"},{"id":"yhbrc","name":"Glory","system":"gdapd","pronouns":"she\/her","species":"Pegasus","age":" - 9","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f2983124fa2ba67ee82c482b8b69675bd9f5bf39.png"},{"id":"hpwyq","name":"Frost Crystals","system":"gdapd","pronouns":"she\/her","species":"Crystal pony","age":" - 15","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f2983124494e01975120494595db5a7bbcb943f8.png"},{"id":"mvaws","name":"Misty Brightdawn","system":"ynmuc","pronouns":"she\/her","species":"Unicorn","age":" - 20","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b255779c624c64875bc1f3e777e287716.png"},{"id":"erefx","name":"Izzy Moonbow","system":"ynmuc","pronouns":"she\/her","species":"Unicorn","age":" - 17","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b6deaba57be2b4d45979928a72bda38c1.png"},{"id":"auvwc","name":"Zoom Zephyrwing","system":"gdapd","pronouns":"she\/her","species":"Pegasus","age":" - 22","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f298312486baaa9ea4934b8b8936f01ad10bf5c6.png"},{"id":"qbzxm","name":"Cloudy Dreams","system":"gdapd","pronouns":"she\/it","species":"Earth pony","age":" - 22","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f29831244f9b04df07894729bca3c37c79d92f16.png"},{"id":"mglyq","name":"Velvet Cascade","system":"ynmuc","pronouns":"she\/her","species":"Earth pony","age":" - 19","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3bd25282c7e7c14052bc381cc6ebd07c10.png"},{"id":"qraku","name":"Starry Night","system":"gdapd","pronouns":"she\/pony","species":"Unicorn","age":" - 21","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f29831246d178626866d4cd496c999120dd3f927.png"},{"id":"jnbae","name":"Misty Cloud","system":"ynmuc","pronouns":"she\/her","species":"Pegasus","age":" - 18","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b7adba16fe0fe4b4bb5a2658d1d73581f.png"},{"id":"qcemf","name":"Princess Luna","system":"gdapd","pronouns":"she\/her","species":"Alicorn","age":" - Eternal","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f2983124e565159855ff49248ffd1703d8b7e423.png"},{"id":"ckqsw","name":"Rainbow Dash","system":"gdapd","pronouns":"she\/her","species":"Pegasus","age":" - 16","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f2983124df5cb301f984487cbe6fd2ec2e621c69.png"},{"id":"dogwu","name":"Lilac Bloom","system":"ynmuc","pronouns":"she\/her","species":"Pegasus","age":" - 7","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3bd3b7e0a5b56c43c789d41f997302af60.png"},{"id":"slsjg","name":"Rarity","system":"gdapd","pronouns":"she\/her","species":"Unicorn","age":" - 17","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f2983124bff871a27d0145118322478cd718ba4f.png"},{"id":"vvsxf","name":"Plushie","system":"ynmuc","pronouns":"she\/it","species":"Pegasus plush","age":" - 18","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3bd37ad25fcb724697a2d0b4bf0cef52ee.png"},{"id":"eebmh","name":"Seashell","system":"ynmuc","pronouns":"she\/her","species":"Earth pony","age":" - 8","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3bbdb3a49b5a964b2496f95b8cf46f7fc0.png"},{"id":"pjpnb","name":"Twilight Sparkle","system":"gdapd","pronouns":"she\/her","species":"Alicorn","age":" - Eternal","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f2983124676421cdba3142dead6e8b3ba3dc87ae.png"},{"id":"ztfjz","name":"Stuffie","system":"gdapd","pronouns":"it\/its","species":"Unicorn plush","age":" - 18","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f29831245ca268af06ef42af96133e24c3552d72.png"},{"id":"mhnqy","name":"Dusk Rainbow","system":"gdapd","pronouns":"she\/pony","species":"Unicorn","age":" - 18","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f298312493bc9946900a4e3c902da48ce37a894b.png"},{"id":"kkhbw","name":"Twi","system":"ynmuc","pronouns":"she\/pony","species":"Pegasus","age":" - 10","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b6fde856927e14c4db30566aa62915168.png"},{"id":"zkgjj","name":"Princess Cadance","system":"ynmuc","pronouns":"she\/her","species":"Alicorn","age":" - 53","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b1299db6f5caa4f029ff5ec9601654fd0.png"},{"id":"vncoa","name":"Minty Grape","system":"ynmuc","pronouns":"Ask for pronouns","species":"Earth pony","age":" - 20","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b98604b5b568d46d3aa9e17a3a7c70d3a.png"},{"id":"fdaay","name":"Floral Orchid","system":"ynmuc","pronouns":"she\/her","species":"Pegasus","age":" - 20","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b4c6e03c4419e46c280dab7a51d6eef38.png"},{"id":"lllfw","name":"Zipp Storm","system":"gdapd","pronouns":"she\/her","species":"Pegasus","age":" - 17","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f2983124477c7f1b547f476d91f590cf16eeea10.png"},{"id":"erknz","name":"Lavender","system":"ynmuc","pronouns":"she\/pony","species":"Unicorn","age":" - 21","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3bdd9ba9db08f24518aa90a479f6e60b7e.png"},{"id":"exudo","name":"Opaline Arcana","system":"gdapd","pronouns":"she\/her","species":"Alicorn","age":" - Eternal","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f2983124f9988737523643a8a208ab444b3073fa.png"},{"id":"zhtzs","name":"Pipp Petals","system":"ynmuc","pronouns":"she\/her","species":"Pegasus","age":" - 17","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3b5d092fbce3ce4bb19b59679e38413f4b.png"},{"id":"ufadt","name":"Coral","system":"gdapd","pronouns":"she\/her","species":"Pegasus","age":" - 19","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f29831245999b5cc6f78407ea3e1f335dc0f644e.png"},{"id":"rpjok","name":"Sweetie Bot","system":"ynmuc","pronouns":"she\/it","species":"Robot unicorn","age":" - 12","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3bd9b47929e368410eb1ed0cc3cb600b9b.png"},{"id":"qaavw","name":"Pinkie Pie","system":"ynmuc","pronouns":"she\/her","species":"Earth pony","age":" - 19","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3bfb1912a4f2ea4b7eb3a16a68a4aa847a.png"},{"id":"sbxze","name":"Windy","system":"ynmuc","pronouns":"she\/her","species":"Pegasus","age":" - 19","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/ade46823206b4b0cad3ccaae934a5f3bcc290a4bce1443afa0a2de0ffd40d7e6.png"},{"id":"zwtnn","name":"Flurry Heart","system":"gdapd","pronouns":"she\/her","species":"Alicorn","age":" - 2-12","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f298312405651aee54e846cdbf42f5e558addd63.png"},{"id":"bbrig","name":"Apple Bloom","system":"gdapd","pronouns":"she\/her","species":"Earth pony","age":" - 9","avatar":"https:\/\/ponies.equestria.horse\/assets\/heads\/7d9f543ef74240f69d0786c3f29831242ef157dded4549dabc7d38acd3b0fdd0.png"}] \ No newline at end of file
diff --git a/data/lllfw.jpeg b/data/lllfw.jpeg
new file mode 100644
index 0000000..5bf707e
--- /dev/null
+++ b/data/lllfw.jpeg
Binary files differ
diff --git a/data/lqolg.jpeg b/data/lqolg.jpeg
new file mode 100644
index 0000000..6392eaa
--- /dev/null
+++ b/data/lqolg.jpeg
Binary files differ
diff --git a/data/mglyq.jpeg b/data/mglyq.jpeg
new file mode 100644
index 0000000..1162d99
--- /dev/null
+++ b/data/mglyq.jpeg
Binary files differ
diff --git a/data/mhnqy.jpeg b/data/mhnqy.jpeg
new file mode 100644
index 0000000..a87cf15
--- /dev/null
+++ b/data/mhnqy.jpeg
Binary files differ
diff --git a/data/mvaws.jpeg b/data/mvaws.jpeg
new file mode 100644
index 0000000..31128ca
--- /dev/null
+++ b/data/mvaws.jpeg
Binary files differ
diff --git a/data/owmle.jpeg b/data/owmle.jpeg
new file mode 100644
index 0000000..0895d53
--- /dev/null
+++ b/data/owmle.jpeg
Binary files differ
diff --git a/data/pabmo.jpeg b/data/pabmo.jpeg
new file mode 100644
index 0000000..410706f
--- /dev/null
+++ b/data/pabmo.jpeg
Binary files differ
diff --git a/data/pjpnb.jpeg b/data/pjpnb.jpeg
new file mode 100644
index 0000000..06675e0
--- /dev/null
+++ b/data/pjpnb.jpeg
Binary files differ
diff --git a/data/qaavw.jpeg b/data/qaavw.jpeg
new file mode 100644
index 0000000..8101aec
--- /dev/null
+++ b/data/qaavw.jpeg
Binary files differ
diff --git a/data/qaenj.jpeg b/data/qaenj.jpeg
new file mode 100644
index 0000000..0e51fd0
--- /dev/null
+++ b/data/qaenj.jpeg
Binary files differ
diff --git a/data/qbzxm.jpeg b/data/qbzxm.jpeg
new file mode 100644
index 0000000..29d1e31
--- /dev/null
+++ b/data/qbzxm.jpeg
Binary files differ
diff --git a/data/qcemf.jpeg b/data/qcemf.jpeg
new file mode 100644
index 0000000..1b3be84
--- /dev/null
+++ b/data/qcemf.jpeg
Binary files differ
diff --git a/data/qraku.jpeg b/data/qraku.jpeg
new file mode 100644
index 0000000..3bc4fba
--- /dev/null
+++ b/data/qraku.jpeg
Binary files differ
diff --git a/data/rirgf.jpeg b/data/rirgf.jpeg
new file mode 100644
index 0000000..4652aeb
--- /dev/null
+++ b/data/rirgf.jpeg
Binary files differ
diff --git a/data/rpjok.jpeg b/data/rpjok.jpeg
new file mode 100644
index 0000000..d7ad890
--- /dev/null
+++ b/data/rpjok.jpeg
Binary files differ
diff --git a/data/sbxze.jpeg b/data/sbxze.jpeg
new file mode 100644
index 0000000..bf5b4fb
--- /dev/null
+++ b/data/sbxze.jpeg
Binary files differ
diff --git a/data/sehke.jpeg b/data/sehke.jpeg
new file mode 100644
index 0000000..fd30b3c
--- /dev/null
+++ b/data/sehke.jpeg
Binary files differ
diff --git a/data/slsjg.jpeg b/data/slsjg.jpeg
new file mode 100644
index 0000000..a6cf826
--- /dev/null
+++ b/data/slsjg.jpeg
Binary files differ
diff --git a/data/tfbob.jpeg b/data/tfbob.jpeg
new file mode 100644
index 0000000..43dbaf4
--- /dev/null
+++ b/data/tfbob.jpeg
Binary files differ
diff --git a/data/ufadt.jpeg b/data/ufadt.jpeg
new file mode 100644
index 0000000..da13b18
--- /dev/null
+++ b/data/ufadt.jpeg
Binary files differ
diff --git a/data/umbyl.jpeg b/data/umbyl.jpeg
new file mode 100644
index 0000000..669bba2
--- /dev/null
+++ b/data/umbyl.jpeg
Binary files differ
diff --git a/data/vncoa.jpeg b/data/vncoa.jpeg
new file mode 100644
index 0000000..73c4938
--- /dev/null
+++ b/data/vncoa.jpeg
Binary files differ
diff --git a/data/vvsxf.jpeg b/data/vvsxf.jpeg
new file mode 100644
index 0000000..09e99c7
--- /dev/null
+++ b/data/vvsxf.jpeg
Binary files differ
diff --git a/data/wnujv.jpeg b/data/wnujv.jpeg
new file mode 100644
index 0000000..4a3d61c
--- /dev/null
+++ b/data/wnujv.jpeg
Binary files differ
diff --git a/data/xbvwt.jpeg b/data/xbvwt.jpeg
new file mode 100644
index 0000000..0ddad9a
--- /dev/null
+++ b/data/xbvwt.jpeg
Binary files differ
diff --git a/data/xcjhj.jpeg b/data/xcjhj.jpeg
new file mode 100644
index 0000000..d132e66
--- /dev/null
+++ b/data/xcjhj.jpeg
Binary files differ
diff --git a/data/xdoql.jpeg b/data/xdoql.jpeg
new file mode 100644
index 0000000..f828ffc
--- /dev/null
+++ b/data/xdoql.jpeg
Binary files differ
diff --git a/data/yhbrc.jpeg b/data/yhbrc.jpeg
new file mode 100644
index 0000000..38f77ea
--- /dev/null
+++ b/data/yhbrc.jpeg
Binary files differ
diff --git a/data/zajrk.jpeg b/data/zajrk.jpeg
new file mode 100644
index 0000000..bc2a56b
--- /dev/null
+++ b/data/zajrk.jpeg
Binary files differ
diff --git a/data/zhtzs.jpeg b/data/zhtzs.jpeg
new file mode 100644
index 0000000..b4e6bee
--- /dev/null
+++ b/data/zhtzs.jpeg
Binary files differ
diff --git a/data/zkgjj.jpeg b/data/zkgjj.jpeg
new file mode 100644
index 0000000..f5a943a
--- /dev/null
+++ b/data/zkgjj.jpeg
Binary files differ
diff --git a/data/zlnuo.jpeg b/data/zlnuo.jpeg
new file mode 100644
index 0000000..315fa7e
--- /dev/null
+++ b/data/zlnuo.jpeg
Binary files differ
diff --git a/data/ztfjz.jpeg b/data/ztfjz.jpeg
new file mode 100644
index 0000000..eb93be4
--- /dev/null
+++ b/data/ztfjz.jpeg
Binary files differ
diff --git a/data/zwtnn.jpeg b/data/zwtnn.jpeg
new file mode 100644
index 0000000..a8c1cf4
--- /dev/null
+++ b/data/zwtnn.jpeg
Binary files differ
diff --git a/data/zzise.jpeg b/data/zzise.jpeg
new file mode 100644
index 0000000..e31e1ec
--- /dev/null
+++ b/data/zzise.jpeg
Binary files differ
diff --git a/download.php b/download.php
new file mode 100644
index 0000000..6668d0e
--- /dev/null
+++ b/download.php
@@ -0,0 +1,11 @@
+<?php
+
+if (!file_exists("data")) mkdir("data");
+
+$data = json_decode(file_get_contents("https://ponies.equestria.horse/api/badger"), true);
+file_put_contents("data/list.json", json_encode($data));
+
+foreach ($data as $pony) {
+ echo($pony['id'] . "\n");
+ exec('convert "' . $pony['avatar'] . '" -background "#ffffff" -flatten -scale 100 -gravity south -extent 128x128 data/' . $pony['id'] . ".jpeg");
+}
diff --git a/icon.php b/icon.php
new file mode 100644
index 0000000..25b3681
--- /dev/null
+++ b/icon.php
@@ -0,0 +1,7 @@
+<?php
+
+if (!file_exists("icons")) mkdir("icons");
+
+$name = $argv[1];
+$file = $argv[2] ?? $argv[1];
+exec('convert "' . $name . '" -background "#ffffff" -scale 24x24 -flatten icons/' . $file . ".jpeg");
diff --git a/icons/_default.jpeg b/icons/_default.jpeg
new file mode 100644
index 0000000..b002c10
--- /dev/null
+++ b/icons/_default.jpeg
Binary files differ
diff --git a/icons/about.jpeg b/icons/about.jpeg
new file mode 100644
index 0000000..709adc3
--- /dev/null
+++ b/icons/about.jpeg
Binary files differ
diff --git a/icons/canteen.jpeg b/icons/canteen.jpeg
new file mode 100644
index 0000000..9324d70
--- /dev/null
+++ b/icons/canteen.jpeg
Binary files differ
diff --git a/icons/developer.jpeg b/icons/developer.jpeg
new file mode 100644
index 0000000..1e93301
--- /dev/null
+++ b/icons/developer.jpeg
Binary files differ
diff --git a/icons/help.jpeg b/icons/help.jpeg
new file mode 100644
index 0000000..1a3285c
--- /dev/null
+++ b/icons/help.jpeg
Binary files differ
diff --git a/icons/update.jpeg b/icons/update.jpeg
new file mode 100644
index 0000000..2d7754c
--- /dev/null
+++ b/icons/update.jpeg
Binary files differ
diff --git a/icons/weather.jpeg b/icons/weather.jpeg
new file mode 100644
index 0000000..8493de2
--- /dev/null
+++ b/icons/weather.jpeg
Binary files differ
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..6473f8e
--- /dev/null
+++ b/main.py
@@ -0,0 +1 @@
+import app \ No newline at end of file
diff --git a/network_manager.py b/network_manager.py
new file mode 100644
index 0000000..c0f7f17
--- /dev/null
+++ b/network_manager.py
@@ -0,0 +1,108 @@
+import rp2
+import network
+import machine
+import uasyncio
+
+
+class NetworkManager:
+ _ifname = ("Client", "Access Point")
+
+ def __init__(self, country="GB", client_timeout=30, access_point_timeout=5, status_handler=None, error_handler=None):
+ rp2.country(country)
+ self._ap_if = network.WLAN(network.AP_IF)
+ self._sta_if = network.WLAN(network.STA_IF)
+
+ self._mode = network.STA_IF
+ self._client_timeout = client_timeout
+ self._access_point_timeout = access_point_timeout
+ self._status_handler = status_handler
+ self._error_handler = error_handler
+ self.UID = ("{:02X}" * 8).format(*machine.unique_id())
+
+ def isconnected(self):
+ return self._sta_if.isconnected() or self._ap_if.isconnected()
+
+ def config(self, var):
+ if self._sta_if.active():
+ return self._sta_if.config(var)
+ else:
+ if var == "password":
+ return self.UID
+ return self._ap_if.config(var)
+
+ def mode(self):
+ if self._sta_if.isconnected():
+ return self._ifname[0]
+ if self._ap_if.isconnected():
+ return self._ifname[1]
+ return None
+
+ def ifaddress(self):
+ if self._sta_if.isconnected():
+ return self._sta_if.ifconfig()[0]
+ if self._ap_if.isconnected():
+ return self._ap_if.ifconfig()[0]
+ return '0.0.0.0'
+
+ def disconnect(self):
+ if self._sta_if.isconnected():
+ self._sta_if.disconnect()
+ if self._ap_if.isconnected():
+ self._ap_if.disconnect()
+
+ async def wait(self, mode):
+ while not self.isconnected():
+ self._handle_status(mode, None)
+ await uasyncio.sleep_ms(1000)
+
+ def _handle_status(self, mode, status):
+ if callable(self._status_handler):
+ self._status_handler(self._ifname[mode], status, self.ifaddress())
+
+ def _handle_error(self, mode, msg):
+ if callable(self._error_handler):
+ if self._error_handler(self._ifname[mode], msg):
+ return
+ raise RuntimeError(msg)
+
+ async def client(self, ssid, psk):
+ if self._sta_if.isconnected():
+ self._handle_status(network.STA_IF, True)
+ return
+
+ self._ap_if.disconnect()
+ self._ap_if.active(False)
+
+ self._sta_if.active(True)
+ self._sta_if.connect(ssid, psk)
+ self._sta_if.config(pm=0xa11140)
+
+ try:
+ await uasyncio.wait_for(self.wait(network.STA_IF), self._client_timeout)
+ self._handle_status(network.STA_IF, True)
+
+ except uasyncio.TimeoutError:
+ self._sta_if.active(False)
+ self._handle_status(network.STA_IF, False)
+ self._handle_error(network.STA_IF, "WIFI Client Failed")
+
+ async def access_point(self):
+ if self._ap_if.isconnected():
+ self._handle_status(network.AP_IF, True)
+ return
+
+ self._sta_if.disconnect()
+ self._sta_if.active(False)
+
+ self._ap_if.ifconfig(("10.10.1.1", "255.255.255.0", "10.10.1.1", "10.10.1.1"))
+ self._ap_if.config(password=self.UID)
+ self._ap_if.active(True)
+
+ try:
+ await uasyncio.wait_for(self.wait(network.AP_IF), self._access_point_timeout)
+ self._handle_status(network.AP_IF, True)
+
+ except uasyncio.TimeoutError:
+ self._sta_if.active(False)
+ self._handle_status(network.AP_IF, False)
+ self._handle_error(network.AP_IF, "WIFI Client Failed") \ No newline at end of file
diff --git a/os/apps.py b/os/apps.py
new file mode 100644
index 0000000..42edb1a
--- /dev/null
+++ b/os/apps.py
@@ -0,0 +1,5 @@
+list = {
+ 'about': "About maneOS",
+ 't1': "Test app 1",
+ 't2': "Test app 2"
+} \ No newline at end of file
diff --git a/os/ui.py b/os/ui.py
new file mode 100644
index 0000000..47e7016
--- /dev/null
+++ b/os/ui.py
@@ -0,0 +1,80 @@
+import badger2040w
+from machine import ADC, Pin
+import time
+import machine
+import jpegdec
+
+import apps
+
+def get_vsys():
+ conversion_factor = 3 * 3.3 / 65535
+
+ try:
+ Pin(25, mode=Pin.OUT, pull=Pin.PULL_DOWN).high()
+
+ Pin(29, Pin.IN)
+
+ vsys = ADC(29)
+ return vsys.read_u16() * conversion_factor
+
+ finally:
+ Pin(29, Pin.ALT, pull=Pin.PULL_DOWN, alt=7)
+
+def version():
+ f = open("./version.txt")
+ ver = f.read().strip()
+ f.close()
+
+ return ver
+
+def update(display, current):
+ display.set_pen(15)
+ display.clear()
+
+ display.set_pen(0)
+ display.rectangle(0, 0, 296, 16)
+
+ display.set_pen(15)
+ display.set_font("bitmap8")
+ display.text("maneOS " + version(), 5, 5, scale=1)
+
+ charge = round((get_vsys() / 5) * 100)
+ charge = 100 if charge > 100 else charge
+
+ display.text(str(charge) + "%", 286 - (len(str(charge)) * 5), 5, scale=1)
+
+ display.set_pen(0)
+ display.line(0, 53, 296, 53, 2)
+ display.line(0, 90, 296, 90, 2)
+
+ j = jpegdec.JPEG(display)
+ j.open_file("icons/_default.jpeg")
+ j.decode(20, 60, jpegdec.JPEG_SCALE_FULL)
+
+ display.set_pen(0)
+ display.set_font("bitmap8")
+ display.text("Test item", 47, 64, scale=2)
+
+ display.update()
+
+ return current
+
+def view(badger, display):
+ badger.set_update_speed(1)
+
+ f = open("state/apps.txt", "r")
+ current = int(f.read().strip())
+ f.close()
+
+ if not (0 <= current < len(apps.list.keys())):
+ current = 0
+
+ current = update(display, current)
+
+ badger.set_update_speed(3)
+
+ while True:
+ if badger.pressed(badger2040w.BUTTON_A):
+ current = update(display, current)
+ elif badger.pressed(badger2040w.BUTTON_B):
+ break
diff --git a/state/apps.txt b/state/apps.txt
new file mode 100644
index 0000000..c227083
--- /dev/null
+++ b/state/apps.txt
@@ -0,0 +1 @@
+0 \ No newline at end of file
diff --git a/state/fronter.txt b/state/fronter.txt
new file mode 100644
index 0000000..9d60796
--- /dev/null
+++ b/state/fronter.txt
@@ -0,0 +1 @@
+11 \ No newline at end of file
diff --git a/version.txt b/version.txt
new file mode 100644
index 0000000..afaf360
--- /dev/null
+++ b/version.txt
@@ -0,0 +1 @@
+1.0.0 \ No newline at end of file