forked from ThatCakeID/tmcli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathzryte-cli.py
More file actions
165 lines (130 loc) · 4.97 KB
/
zryte-cli.py
File metadata and controls
165 lines (130 loc) · 4.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import argparse
import requests
import tabulate
from readchar import readkey, key
endpoints = {
'firestore': 'https://firestore.googleapis.com/v1'
}
firestore = {
'project': 'zrytezene-thatcakeid',
'database': '(default)'
}
def construct_final_endpoint(endpoint, project, db):
return f"{endpoint}/projects/{project}/databases/{db}"
def list(params: dict = { 'pageSize': 512 }, keyword: str = None):
global endpoints, firestore
# Send a GET request to Firestore service endpoints
request_url = construct_final_endpoint(endpoints['firestore'], firestore['project'], firestore['database'])
request = requests.get(f"{request_url}/documents/musics", params=params)
# check: status code (must be 200 OK)
if request.status_code != requests.codes.ok:
print("zryte-cli: error: Failed to retrieve music list")
return
# Create row arrays for "ID" and "Title" columns
rows_id = []
rows_title = []
# Populate the row arrays with the needed values
#
# If the prefix parameter is not empty, only the songs
# that start with it are only appended to the rows
for document in request.json()['documents']:
document_id = document['name'].split('/')[-1]
document_title = document['fields']['title']['stringValue']
if keyword is not None and keyword not in document_title.lower():
continue
rows_id.append(document_id)
rows_title.append(document_title)
# Combine both columns into a single dictionary for tabulate to output
table = {
'ID': rows_id,
'Title': rows_title
}
# Print the tabulated dictionary containing both ID and Title columns
if len(rows_title) > 0:
print(tabulate.tabulate(table, headers="keys"))
else:
print("zryte-cli: The list returned empty")
def stream(id):
global endpoints, firestore
try:
import vlc
except:
print("zryte-cli: error: Failed to import VLC module, ensure it's installed.")
return
# Send a GET request to Firestore service endpoints
request_url = construct_final_endpoint(endpoints['firestore'], firestore['project'], firestore['database'])
request = requests.get(f"{request_url}/documents/musics/{id}")
# check: status code (must be 200 OK)
if request.status_code != requests.codes.ok:
print("zryte-cli: error: Could not get music information")
return
# Output various music information
# Also give a hint to user for stopping the playback
fields = request.json()['fields']
field_title = fields['title']['stringValue']
field_url = fields['music_url']['stringValue']
print("zryte-cli: Tip: Press ESCAPE to stop playback")
print("zryte-cli: Tip: Press SPACE to toggle playback")
print(f"zryte-cli: Now streaming music: {field_title}")
# Initialize VLC instance and play the music URL
player = vlc.MediaPlayer(field_url)
player.play()
# Wait until the player's state is stopped
#
# While waiting, we can listen for certain keystrokes
# for controlling the playback, quite useful right?
while player.get_state() != vlc.State.Stopped:
try:
keystroke = readkey().lower()
except:
continue
match keystroke:
case key.SPACE:
if player.is_playing():
player.pause()
else:
player.play()
case key.ESC:
player.stop()
# Once the player is in stopped state, release it.
print("zryte-cli: Stream ended")
player.release()
def main():
# Create the top-level command-line argument parser
parser = argparse.ArgumentParser(prog='zryte-cli',
description="ZryteZene Python CLI")
subparsers = parser.add_subparsers(dest='subcommand',
required=True)
# Add subcommands with their arguments
# The "list" subcommand
subparsers.add_parser('list')
# The "stream" subcommand
subcommand_stream = subparsers.add_parser('stream', description="Play a song via ID")
subcommand_stream.add_argument('id', type=str, help="specify the song ID to play")
# The "search" subcommand
subcommand_search = subparsers.add_parser('search')
subcommand_search.add_argument('name', type=str, help="specify the song name to look for")
# The "config" subcommand
subcommand_config = subparsers.add_parser('config')
subcommand_config.add_argument('key', type=str, help="specify the config key")
subcommand_config.add_argument('value', help="specify the new value")
subcommand_config.add_argument('-s', '--save',
action='store_const',
const=True,
help="overwrite changes to config then exit")
# Parse the command-line, and use designated functions for which subcommands are used
args = parser.parse_args()
match args.subcommand:
case 'list':
list()
case 'stream':
stream(id=args.id)
pass
case 'search':
list(keyword=args.name)
case 'config':
# TODO: config(key, value, ...) function here
print("zryte-cli: warn: The config subcommand is not yet implemented")
pass
if __name__ == "__main__":
main()