forked from dhtdht020/osc-dl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathosc-dl.py
162 lines (132 loc) · 5.77 KB
/
osc-dl.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
151
152
153
154
155
156
157
158
159
160
161
162
import argparse
import io
import os
from datetime import datetime
import requests
import download
import metadata
import wiiload
import updater
import hosts as repos
if os.name == 'nt':
# Initialize color on Windows
os.system('color')
repos = repos.Hosts()
parser = argparse.ArgumentParser(add_help=False,
description=f"Open Shop Channel Downloader v{updater.current_version()} {updater.get_branch()}",
epilog="OSCDL, Open Source Software by dhtdht020. https://github.com/dhtdht020.")
subparser = parser.add_subparsers(dest='cmd')
# Set help information
parser._positionals.title = 'The following commands are available'
parser._optionals.title = 'The following options are available'
parser.add_argument('-h', '--help', action='help', default=argparse.SUPPRESS,
help='Displays an help screen like this one.')
# Get - downloads application
get = subparser.add_parser(name='get', help="Download application.")
# Send - downloads and sends application
send = subparser.add_parser(name='send', help="Send application to Wii.")
# Show - displays information about an application
show = subparser.add_parser(name='show', help="Show information about an application.")
# Hosts - displays available repositories
hosts = subparser.add_parser(name='hosts', help="List available hosts.")
# Get arguments
get.add_argument("app", type=str,
help="App to download. (e.g. WiiVNC)")
get.add_argument("-r", "--host", type=str,
help="Repository name (e.g. primary)", default="primary")
# Send arguments
send.add_argument("app", type=str,
help="App to send. (e.g. WiiVNC)")
send.add_argument("-d", "--destination", type=str,
help="Wii IP address (e.g. 192.168.1.10)", required=True)
send.add_argument("-r", "--host", type=str,
help="Repository name (e.g. primary)", default="primary")
# Show arguments
show.add_argument("app", type=str,
help="App to show. (e.g. WiiVNC)")
show.add_argument("-r", "--host", type=str,
help="Repository name (e.g. primary)", default="primary")
args = parser.parse_args()
# Get
if args.cmd == "get":
if args.app == "all":
OpenShopChannel = metadata.API()
OpenShopChannel.set_host(args.host)
print(f"Starting download of all packages from \"{args.host}\" @ {repos.name(args.host)['host']}..")
for package in OpenShopChannel.packages:
download.get(app_name=package["internal_name"], repo=repos.name(args.host)["host"])
else:
download.get(app_name=args.app, repo=repos.name(args.host)["host"])
# Send
if args.cmd == "send":
# get hostname of host
host_url = repos.name(args.host)["host"]
ok = wiiload.validate_ip_regex(ip=args.destination)
if not ok:
print(f"Error: The address '{args.destination}' is invalid! Please correct it!")
exit(1)
url = f"https://{host_url}/hbb/{args.app}/{args.app}.zip"
r = requests.get(url)
zipped_app = io.BytesIO(r.content)
zip_buf = io.BytesIO()
# Our zip file should only contain one directory with the app data in it,
# but the downloaded file contains an apps/ directory. We're removing that here.
wiiload.organize_zip(zipped_app, zip_buf)
# preparing
print("Preparing app..")
prep = wiiload.prepare(zip_buf)
file_size = prep[0]
compressed_size = prep[1]
chunks = prep[2]
# connecting
print('Connecting to the Homebrew Channel..')
try:
conn = wiiload.connect(args.destination)
except Exception as e:
print('Connection error: Error while connecting to the Homebrew Channel.\n'
'Please check the IP address and try again.')
print(f'Exception: {e}')
print('Error: Could not connect to the Homebrew Channel. :(')
exit(1)
wiiload.handshake(conn, compressed_size, file_size)
# Sending file
print('[ 0%] Sending app..')
chunk_num = 1
for chunk in chunks:
conn.send(chunk)
chunk_num += 1
progress = round(chunk_num / len(chunks) * 50) + 50
if progress < 100:
print(f'[ {progress}%] Sending app..')
if progress == 100:
print(f'[{progress}%] Sending app..')
file_name = f'{args.app}.zip'
conn.send(bytes(file_name, 'utf-8') + b'\x00')
print(f'App sent to Wii at {args.destination} successfully!')
# Hosts
if args.cmd == "show":
metadata_api = metadata.API()
metadata_api.set_host(args.host)
information = metadata_api.information(args.app)
if information:
print("Found \"{}\" [{}]".format(information["display_name"], information["internal_name"]))
print("Category: {}".format(information["category"]))
print("Version: {}".format(information["version"]))
print("Description: {}".format(information["long_description"]))
print("Short Description: {}".format(information["short_description"]))
print("Release Date: {}".format(datetime.fromtimestamp
(int(information["release_date"])).strftime('%B %e, %Y at %R')))
print("Publisher: {}".format(information["coder"]))
print("Package:")
print(" Type: {}".format(information["package_type"]))
print(" Download Size: {}".format(metadata.file_size(information["zip_size"])))
print(" Extracted Size: {}".format(metadata.file_size(information["extracted"])))
# Hosts
if args.cmd == "hosts":
print(f"Total of {len(repos.list())} hosts found:")
n = 1
for host in repos.list():
print("\n{}. {} ({}):".format(n, host["display_name"], host["name"]))
print(" Description: {}".format(host["description"]))
print(" Example Usage: \"oscdl get WiiVNC -r {}\"".format(host["name"]))
n += 1