diff options
| author | Fuwn <[email protected]> | 2021-02-09 21:43:21 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2021-02-09 21:43:21 -0800 |
| commit | baced0bf09b2c3df25aa44b3e333fb060b6e27f7 (patch) | |
| tree | 46f2cdcd5f4553309b7abed1aad32ccf0d381969 | |
| parent | Create LICENSE (diff) | |
| download | worldsy-baced0bf09b2c3df25aa44b3e333fb060b6e27f7.tar.xz worldsy-baced0bf09b2c3df25aa44b3e333fb060b6e27f7.zip | |
:star:1.0.0
| -rw-r--r-- | README.md | 32 | ||||
| -rw-r--r-- | assets/worldsy.ico | bin | 0 -> 2238 bytes | |||
| -rw-r--r-- | assets/worldsy32x32.png | bin | 0 -> 219 bytes | |||
| -rw-r--r-- | assets/worldsy512x512.png | bin | 0 -> 72142 bytes | |||
| -rw-r--r-- | build.bat | 1 | ||||
| -rw-r--r-- | image_to_base64.py | 9 | ||||
| -rw-r--r-- | requirements.txt | 3 | ||||
| -rw-r--r-- | worldsy.py | 123 |
8 files changed, 167 insertions, 1 deletions
@@ -1,2 +1,32 @@ # worldsy -A Discord RPC client for Worlds. +A Discord RPC client for [Worlds](http://worldsonline.com/). + +# Why? +Honestly, I was bored... + +I was just sitting at GroundZero, chatting, and I know that there is quite a big Discord server for Worlds and this idea popped into my head and I said "Why the heck not.". + +I had to jump through some hoops to get this working as well, I had to learn Tkinter! Python isn't even ONE of my favourite languages so I made this while holding back tears. + +### Why Python then? +Honestly, it was because it the right tool for the right job. + +In the future, I might rewrite this in Rust or something but at the moment, it's fine. + +Plus, I'd bet there's more Python developers out there than just about any other language so that's a plus. + +### How much time did you spend writing this? +Around three to four hours, without getting up, without looking away... I need help. + +## Development +To get started with this project; + +1. Clone the repository. +2. Install the dependencies via `pip install -r requirements.txt`. + +To build an executable, execute `build.bat`. + +Note that this is only tested on Windows 10, there is no guarantee that this will work on other operating systems but be my guest in trying. + +### License +[MIT](./LICENSE)
\ No newline at end of file diff --git a/assets/worldsy.ico b/assets/worldsy.ico Binary files differnew file mode 100644 index 0000000..fb24c43 --- /dev/null +++ b/assets/worldsy.ico diff --git a/assets/worldsy32x32.png b/assets/worldsy32x32.png Binary files differnew file mode 100644 index 0000000..3407f7c --- /dev/null +++ b/assets/worldsy32x32.png diff --git a/assets/worldsy512x512.png b/assets/worldsy512x512.png Binary files differnew file mode 100644 index 0000000..80edd99 --- /dev/null +++ b/assets/worldsy512x512.png diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..c132d2b --- /dev/null +++ b/build.bat @@ -0,0 +1 @@ +pyinstaller worldsy.py --onefile --icon=worldsy.ico --noconsole
\ No newline at end of file diff --git a/image_to_base64.py b/image_to_base64.py new file mode 100644 index 0000000..b14a309 --- /dev/null +++ b/image_to_base64.py @@ -0,0 +1,9 @@ +import base64 + +open_icon = open("./assets/worldsy.ico", "rb") +b64str = base64.b64encode(open_icon.read()) +open_icon.close() +write_data = ("img = %s" % b64str) +f = open("icon.py", "w+") +f.write(write_data) +f.close()
\ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f844e27 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +requests +pyinstaller +pypresence
\ No newline at end of file diff --git a/worldsy.py b/worldsy.py new file mode 100644 index 0000000..c6fbbf8 --- /dev/null +++ b/worldsy.py @@ -0,0 +1,123 @@ +### Imports ### +import base64 +import time +import tkinter +from tkinter.constants import DISABLED, NORMAL +import pypresence +import webbrowser +from itertools import cycle +import requests +import json +import os + +B64_ICO = 'AAABAAEAICD/AAAAAACoCAAAFgAAACgAAAAgAAAAQAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM2b/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAABAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAEBAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAABAQAAAAAAAAAAAAAAAAAAAAEBAQEBAAAAAAAAAAAAAAAAAQEBAAAAAAAAAAAAAAEBAQEBAQAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM////+B////wH////Af///8B////wP////A////8H////gf///8D////wP///+B////wP///+B////wP///+B////wP///+B////wP///+B////gf///8A////AD///wIP//8DA///A8D//gfwH/gH/AAAD/8AAB//4AA///wA/' # b + +### Setup pypresence ### +RPC: pypresence.Presence = pypresence.Presence("808882523647508481") + +### Classes ### +class Worldsy(tkinter.Tk): + VERSION: str = "1.0.0" + + def __init__(self, master=None) -> None: + tkinter.Tk.__init__(self, master) + + # https://stackoverflow.com/questions/9929479/embed-icon-in-python-script + # Create temporary file for the icon. + icon_data = base64.b64decode(B64_ICO) + temp_file = "worldsy_temp.ico" + icon_file = open(temp_file, "wb") + icon_file.write(icon_data) + icon_file.close() + + self.title("worldsy") + self.iconbitmap(temp_file) + os.remove(temp_file) + self.geometry("400x250") + self.resizable(0, 0) + #self.wm_state("iconic") + + self.lb = tkinter.Label(self, text="").pack() + self.txt = tkinter.StringVar() + self.debug_console = tkinter.Text(self, state=DISABLED, width=45, height=5) + self.debug_console.pack() + + self.check_for_update() + + def debug_log(self, message: str) -> None: + self.debug_console['state'] = NORMAL + + # Yes, the space is intentional. + timestamp = time.strftime("%H:%M:%S ", time.gmtime()) + self.debug_console.insert("end", timestamp + message + "\n") + + self.debug_console.see("end") + self.debug_console['state'] = DISABLED + + def check_for_update(self) -> None: + api = requests.get(url="https://api.github.com/repos/fuwn/worldsy/releases") + data = json.loads(api.content) + latest_release: str = data[0]["tag_name"] + + if int(latest_release.replace('.', '')) > int(Worldsy.VERSION.replace('.', '')): + self.debug_log("New version available! Current: " + self.VERSION + + ", new: " + latest_release + ". To update, click on the GitHub link below" + + " and download the newest release.") + + +class Utilities(object): + def open_url(self, url: str) -> None: + webbrowser.open_new(url) + +class RPCHandler(object): + enabled: bool = False + + def toggle(self) -> None: + self.enabled = not self.enabled + status_button["text"] = "Stop RPC" if self.enabled == True else "Start RPC" + + if self.enabled: + worldsy.debug_log("Enabled RPC.") + RPC.connect() + worldsy.debug_log("Connected to websocket.") + RPC.update( + details="Exploring GroundZero", + large_image="worldsy512x512", + large_text="Worlds", + small_image="fuwn", + small_text="Created by fun#1337", + start=time.time()) + worldsy.debug_log("Updated RPC.") + elif not self.enabled: + worldsy.debug_log("Disabled RPC.") + RPC.close() + worldsy.debug_log("Closed websocket.") + +### Initialize Classes ### +utilities: Utilities = Utilities() +worldsy: Worldsy = Worldsy() +rpcHandler: RPCHandler = RPCHandler() + +### GUI ### +status_button: tkinter.Button = tkinter.Button( + worldsy, text="Start RPC", command=rpcHandler.toggle) +github_link: tkinter.Button = tkinter.Label( + worldsy, text="GitHub", fg="blue", cursor="hand2") +author_label: tkinter.Button = tkinter.Label( + worldsy, text="Created by fun#1337") +version_label: tkinter.Button = tkinter.Label( + worldsy, text="Version: " + worldsy.VERSION) +debug_console: tkinter.Text = tkinter.Text() + +### Pack Un-initialized GUI Components ### +tkinter.Label(worldsy, text="").pack() # Rudimentary line-break... +status_button.pack() +tkinter.Label(worldsy, text="").pack() +github_link.pack() +github_link.bind("<Button-1>", + lambda e: utilities.open_url("https://github.com/fuwn/worldsy")) +author_label.pack() +version_label.pack() + +### Main-loop ### +worldsy.mainloop()
\ No newline at end of file |