Skip to content

Commit b6cebb6

Browse files
committed
Initial commit
Signed-off-by: Stavros Avramidis <[email protected]>
0 parents  commit b6cebb6

File tree

4 files changed

+167
-0
lines changed

4 files changed

+167
-0
lines changed

README.md

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## TIDAL - Discord Rich Presence plug-in (UNOFFICIAL)
2+
3+
4+
Unofficial plug in to display current playing song to discord.
5+
6+
##Example Screenshot
7+
8+
![alt text](./assets/screenshot.jpg)
9+
10+
11+
### Instructions
12+
Because TIDAL does not have a public api, It's not possible to get the current playing song,
13+
except you connect your account to last.fm .
14+
15+
1. Make sure you have connected your last fm account with TIDAL.
16+
17+
2. Download the latest release from [here](https://github.com/purpl3F0x/TIDAL-Discord-Rich-Presence-UNOFFICIAL/releases)
18+
19+
3. Run the .exe, The first time you run the script it will ask you to allow permition to access last.fm api and your username
20+
21+
4. *Optional*: Place the exe in windows start-up folder to start when computer starts.
22+
23+
24+
The scripts gets the information form last.fm so if you connect last.fm with your phone (or any other device that) and the script is running in your pc it will RPC will still work.
25+
26+
27+
> Disclaimer: This project is Unofficial and it's not published from TIDAL.com &/ Aspiro.
28+
29+
---
30+
31+
#### Stavros Avramidis Never Settle & Keep Running

icon.ico

113 KB
Binary file not shown.

main.py

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
"""
2+
:filename: main.py
3+
:author: Stavros Avramidis
4+
:version:
5+
"""
6+
7+
from os import path
8+
from time import sleep, time
9+
10+
import psutil
11+
import pylast
12+
from pypresence import Presence
13+
14+
# configuration file containing API keys (provide your own)
15+
from config import *
16+
17+
SESSION_KEY_FILE = path.join(path.expanduser("~"), ".session_key")
18+
19+
last_output = None
20+
user_name = ''
21+
22+
23+
def ask_for_username():
24+
"""
25+
26+
Asks user for username
27+
:return:
28+
"""
29+
from tkinter import Tk
30+
from tkinter import ttk
31+
32+
def exit():
33+
global user_name
34+
user_name = txt.get()
35+
window.quit()
36+
37+
window = Tk()
38+
if path.exists('icon.ico'):
39+
window.iconbitmap('icon.ico')
40+
41+
window.title("Enter your Last.fm username")
42+
window.resizable(0, 0)
43+
window.geometry(
44+
"{}x{}+{}+{}".format(350, 180, window.winfo_screenwidth() // 2 - 175, window.winfo_screenheight() // 2 - 90))
45+
window.attributes('-topmost', True)
46+
47+
lbl = ttk.Label(window, text="Enter your Last.fm username", width=25)
48+
lbl.place(x=100, y=40)
49+
50+
txt = ttk.Entry(window, width=25)
51+
txt.place(x=100, y=70)
52+
53+
btn = ttk.Button(window, text="Ok", width=25, command=exit)
54+
btn.place(x=100, y=120)
55+
56+
window.mainloop()
57+
window.destroy()
58+
return
59+
60+
61+
if __name__ == "__main__":
62+
network = pylast.LastFMNetwork(API_KEY, API_SECRET)
63+
64+
if not path.exists(SESSION_KEY_FILE):
65+
skg = pylast.SessionKeyGenerator(network)
66+
url = skg.get_web_auth_url()
67+
68+
print(f"Please authorize the scrobbler to scrobble to your account: {url}\n")
69+
import webbrowser
70+
webbrowser.open(url)
71+
72+
while True:
73+
try:
74+
session_key = skg.get_web_auth_session_key(url)
75+
fp = open(SESSION_KEY_FILE, "w")
76+
ask_for_username()
77+
fp.writelines([user_name, '\n', session_key])
78+
fp.close()
79+
exit()
80+
break
81+
except pylast.WSError:
82+
sleep(1)
83+
else:
84+
try:
85+
with open(SESSION_KEY_FILE, 'r') as ss:
86+
user_name = ss.readline()[:-1]
87+
session_key = ss.readline()
88+
print('Found', user_name, session_key)
89+
except ...:
90+
print('Error reading session stage.')
91+
exit()
92+
93+
network.session_key = session_key
94+
user = network.get_user(user_name)
95+
96+
playing_track = None
97+
98+
client_id = '584458858731405315' # Discord BOT id, put your real one here
99+
RPC = Presence(client_id) # Initialize the client class
100+
RPC.connect() # Start the handshake loop
101+
102+
while True:
103+
try:
104+
new_track = user.get_now_playing()
105+
# A new, different track
106+
if new_track and new_track != playing_track:
107+
playing_track = new_track
108+
print(playing_track.get_name())
109+
print(playing_track.get_artist())
110+
dur = new_track.get_duration()
111+
112+
print(
113+
RPC.update(
114+
state=str(playing_track.get_name()),
115+
details=str(playing_track.get_artist()),
116+
large_image='fb_1200x627',
117+
# small_image='tidalogo_0',
118+
end=int(time()) + dur / 1000 if dur else None,
119+
start=int(time()),
120+
)
121+
) # Set the presence
122+
# check if song is played
123+
elif not new_track and playing_track and "TIDAL.exe" in (p.name() for p in psutil.process_iter()):
124+
print('song paused ?')
125+
126+
# clear status
127+
elif not new_track:
128+
RPC.clear()
129+
130+
except Exception as e:
131+
print("Error: %s" % repr(e))
132+
133+
sleep(2)

requirements.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pypresence
2+
pylast
3+
psutil

0 commit comments

Comments
 (0)