aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2021-02-09 21:43:21 -0800
committerFuwn <[email protected]>2021-02-09 21:43:21 -0800
commitbaced0bf09b2c3df25aa44b3e333fb060b6e27f7 (patch)
tree46f2cdcd5f4553309b7abed1aad32ccf0d381969
parentCreate LICENSE (diff)
downloadworldsy-baced0bf09b2c3df25aa44b3e333fb060b6e27f7.tar.xz
worldsy-baced0bf09b2c3df25aa44b3e333fb060b6e27f7.zip
:star:1.0.0
-rw-r--r--README.md32
-rw-r--r--assets/worldsy.icobin0 -> 2238 bytes
-rw-r--r--assets/worldsy32x32.pngbin0 -> 219 bytes
-rw-r--r--assets/worldsy512x512.pngbin0 -> 72142 bytes
-rw-r--r--build.bat1
-rw-r--r--image_to_base64.py9
-rw-r--r--requirements.txt3
-rw-r--r--worldsy.py123
8 files changed, 167 insertions, 1 deletions
diff --git a/README.md b/README.md
index 0218c37..b699ad7 100644
--- a/README.md
+++ b/README.md
@@ -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
new file mode 100644
index 0000000..fb24c43
--- /dev/null
+++ b/assets/worldsy.ico
Binary files differ
diff --git a/assets/worldsy32x32.png b/assets/worldsy32x32.png
new file mode 100644
index 0000000..3407f7c
--- /dev/null
+++ b/assets/worldsy32x32.png
Binary files differ
diff --git a/assets/worldsy512x512.png b/assets/worldsy512x512.png
new file mode 100644
index 0000000..80edd99
--- /dev/null
+++ b/assets/worldsy512x512.png
Binary files differ
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