-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
150 lines (115 loc) · 4.12 KB
/
main.py
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
#
# This script scrapes roms from archive.org and downloads them to a local directory.
#
# Usage: python main.py
#
import requests as http
from clint.textui import progress
import os
from prompt_toolkit import prompt
from prompt_toolkit.completion import WordCompleter
from config import config
def get_system_game_ext(system):
if system == 'gc' or system == 'psp' or system == 'ps2':
return '.zip'
elif system == 'psx':
return '.chd'
elif system == 'vita':
return '.rar'
else:
# these systems use .7z
# nes, snes, n64, gb, gba, gbc, vb, tg-16
return '.7z'
def download_file(url, name, dest):
filename = url.split('/')[-1]
filename = decode_url(filename)
req = http.get(url, stream=True)
print(f'Downloading {url}')
with open(dest, 'wb') as f:
total_length = int(req.headers.get('content-length'))
for chunk in progress.bar(req.iter_content(chunk_size=1024), expected_size=(total_length/1024) + 1):
if chunk:
f.write(chunk)
f.flush()
def create_dest():
# set the destination directory. If the user supplied ROMS_DIR in the environment, use that.
# Otherwise, use ~/Downloads/roms
dest = os.environ.get('ROMS_DIR', os.path.join(
os.path.expanduser('~'), 'Downloads', 'roms'))
# create the destination directory if it doesn't exist
if not os.path.exists(dest):
os.makedirs(dest)
return dest
def get_systems():
return config.keys()
# decode a url string
def decode_url(url):
return http.utils.unquote(url)
# encode a url
def encode_url(url):
return http.utils.quote(url)
# return a list of a systems games
def get_games(system, ext):
urls = config[system]
games = []
for url in urls:
html = http.get(url).text
for href in html.split('href="')[1:]:
href = href.split('"')[0]
if href.endswith(ext):
game = href.split('/')[-1]
games.append([system, game, url])
return games
# create system directory if it doesn't exist
def create_system_dir(dest, system):
system_dir = os.path.join(dest, system)
if not os.path.exists(system_dir):
os.makedirs(system_dir)
return system_dir
def create_system_completer():
# create a prompt_toolkit WordCompleter for the systems
return WordCompleter(get_systems())
def main():
system_completer = create_system_completer()
system_input = prompt(
'Enter a system (use tab for autocopmlete): ', completer=system_completer)
print(f'Getting games for: {system_input}')
# get the games for the system
# Each game looks like this -> [system, game, url]
games = get_games(system_input, get_system_game_ext(system_input))
# extract the game names from the list
game_names = [game[1] for game in games]
# url decode the game names
game_names = [decode_url(game) for game in game_names]
# prompt the user to select a game
game_completer = WordCompleter(game_names)
game_input = prompt(
'Enter a game, (a) to download all: ', completer=game_completer)
if game_input == 'a':
# download all games
for game in games:
system = game[0]
game_name = game[1]
url = game[2]
dest = create_system_dir(create_dest(), system)
download_file(f'{url}/{game_name}', game_name,
os.path.join(dest, decode_url(game_name)))
# print the game the user selected
print(f'Getting game: {game_input}')
# get the url for the selected game
game_url = [game[2]
for game in games if game[1] == encode_url(game_input)][0]
# encode the game name
game_input = encode_url(game_input)
# construct the download url
download_url = f'{game_url}/{game_input}'
# create the destination directory
dest = create_dest()
system_dir = create_system_dir(dest, system_input)
# download the game
download_file(download_url, game_input,
os.path.join(system_dir, game_input))
exit()
if __name__ == '__main__':
main()
# TODO: Prompt validate