-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdlmods.py
201 lines (167 loc) · 6.22 KB
/
dlmods.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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
import time
import subprocess
import os
from bs4 import BeautifulSoup
import requests
import re
import json
from pathlib import Path
from shutil import rmtree, unpack_archive
import wget
import platform
import sys
def needsupdate(id, download_dir):
url = "https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1/"
data = requests.post(url, data={"itemcount": 1, "publishedfileids[0]": id})
data = json.loads(data.text)
try:
workshoptime = data['response']['publishedfiledetails'][0]['time_updated']
except Exception:
workshoptime = 0
try:
modtime = os.path.getmtime(download_dir)
except Exception:
return True
if workshoptime > modtime:
return True
else:
return False
def getlinkdirect(id):
def getstatus():
global status
status = requests.post(statusurl, json={"uuids": [data['uuid']]})
status = status.json()
# TODO Add switcher to second backend
statusurl = "https://node03.steamworkshopdownloader.io/prod/api/download/status"
urlreq = "https://node03.steamworkshopdownloader.io/prod/api/download/request"
urldl = "/prod//storage/"
data = requests.post(urlreq, json={"publishedFileId": int(id), "collectionId": None,"hidden":False, "downloadFormat": "raw", "autodownload":False})
data = json.loads(data.text)
link = ""
getstatus()
while status[data['uuid']]['status'] != "prepared":
getstatus()
try:
print(status[data['uuid']]['status'])
time.sleep(3)
except Exception as e:
print(e)
time.sleep(3)
continue
link += "https://" + status[data['uuid']]['storageNode'] + urldl + status[data['uuid']]['storagePath'] + "?uuid=" + data['uuid']
print("Downloading...")
print("Link: " + link)
return link
def steam_workshop_list(workshop_link, links_dict):
data = requests.get(workshop_link)
data = data.text
soup = BeautifulSoup(data, 'html.parser')
for div in soup.find_all('div', class_="collectionItemDetails"):
i = 0
for a in div.find_all('a', href=True):
if i == 0:
link = a['href']
i = i + 1
for d2 in a.find_all('div', class_="workshopItemTitle"):
title = d2.text
links_dict[title] = link
def downloader():
global pathcreated
while True:
Path(download_dir).mkdir(parents=True, exist_ok=True)
pathcreated = True
time.sleep(1)
print("Starting download for {} \n".format(key))
try:
wget.download(getlinkdirect(modid), download_dir)
break
except Exception:
print("Retrying... \n")
continue
linksnames = {}
if platform.system() == "Linux":
islinux = True
else:
islinux = False
if (len(sys.argv) == 3):
mods_main_folder = sys.argv[1]
steam_workshop_list(sys.argv[2],linksnames)
elif (len(sys.argv) == 1):
mods_main_folder = r"{}".format(input("Enter path to mods directory: \n"))
# Get the collection link and get all mod names + workshop links
steam_workshop_list(input("Enter workshop link: \n"), linksnames)
else:
print("Usage:")
print("This program takes two arguments: the path to the mod folder and the link to the steam collection.")
print("If no arguments are given the two arguments are asked in an interactive manner.")
exit()
for_progress_tracking = list(linksnames.values())
for key, value in linksnames.items():
modid = value[value.index("=") + 1:]
replace_list = ["\'", "[", "]", "(", ")", ".", ":", ",", "|"]
mod_dir = re.sub('\s+', '', key)
mod_dir = mod_dir.lower()
for i in replace_list:
mod_dir = mod_dir.replace(i, "")
if islinux:
download_dir = r"{}".format(mods_main_folder + "/@" + mod_dir)
else:
download_dir = r"{}".format(mods_main_folder + "\@" + mod_dir)
isemptyfolder = False
try:
if len(os.listdir(download_dir)) < 1:
isemptyfolder = True
except Exception:
pass
# These two check if folder doesn't exist or if
# an update has been released and downloads the mods.
if (os.path.exists(download_dir)) and not isemptyfolder:
modupdate = needsupdate(modid, download_dir)
if modupdate:
rmtree(download_dir)
elif isemptyfolder:
modupdate = True
else:
modupdate = True
pathcreated = False
if modupdate:
downloader()
pass
elif not modupdate:
print("Mod {} doesn't require an update. Skipping...".format(key))
time.sleep(1)
else:
print("Mod folder for {} already exists. \
Skipping, but this message shouldn't appear. \
Consider restarting the script.\n".format(key))
time.sleep(1)
if pathcreated and modupdate:
downloading = True
while downloading:
for fname in os.listdir(download_dir):
if fname.endswith('.zip') or fname.endswith('.rar'):
downloading = False
print("Download complete for: {}\n".format(key))
else:
downloading = True
time.sleep(1)
time.sleep(1)
if islinux:
toextract = os.listdir(download_dir)
os.chdir(download_dir)
if len(toextract) == 1:
subprocess.run(["unzip", toextract[0]])
subprocess.run(["rm", "-r", toextract[0]])
else:
for fname in os.listdir(download_dir):
if fname.endswith('.zip'):
format = "zip"
filename = fname
elif fname.endswith('.rar'):
format = "rar"
filename = fname
archivepath = download_dir + "\\" + filename
unpack_archive(archivepath, download_dir, format)
os.remove(archivepath)
print("\n Downloaded {} of {} mods..\n \n".format
(for_progress_tracking.index(value) + 1, len(linksnames)))