-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathrun.py
More file actions
136 lines (117 loc) · 5.54 KB
/
run.py
File metadata and controls
136 lines (117 loc) · 5.54 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
import argparse
import fnmatch
import hashlib
import logging
import os
import urllib.parse
from concurrent.futures import ThreadPoolExecutor, as_completed
from threading import Lock
import requests
from pathvalidate import sanitize_filename
import shutil
from tqdm import tqdm
logging.basicConfig(
level=logging.INFO,
format="[%(asctime)s][%(funcName)20s()][%(levelname)-8s]: %(message)s",
handlers=[logging.StreamHandler()],
)
logger = logging.getLogger("GoFile")
class File:
def __init__(self, link: str, dest: str):
self.link = link
self.dest = dest
def __str__(self):
return f"{self.dest} ({self.link})"
class Downloader:
def __init__(self, token):
self.token = token
# Método para obtener el enlace de descarga del archivo
def get_download_link(self, file: File):
link = file.link
return link # Solo retorna el enlace de descarga directo
class GoFileMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
instance = super().__call__(*args, **kwargs)
cls._instances[cls] = instance
return cls._instances[cls]
class GoFile(metaclass=GoFileMeta):
def __init__(self) -> None:
self.token = ""
self.wt = ""
self.lock = Lock()
def update_token(self) -> None:
if self.token == "":
data = requests.post("https://api.gofile.io/accounts").json()
if data["status"] == "ok":
self.token = data["data"]["token"]
logger.info(f"updated token: {self.token}")
else:
raise Exception("cannot get token")
def update_wt(self) -> None:
if self.wt == "":
alljs = requests.get("https://gofile.io/dist/js/global.js").text
if 'appdata.wt = "' in alljs:
self.wt = alljs.split('appdata.wt = "')[1].split('"')[0]
logger.info(f"updated wt: {self.wt}")
else:
raise Exception("cannot get wt")
def execute(self, dir: str, content_id: str = None, url: str = None, password: str = None, excludes: list[str] = None) -> None:
files = self.get_files(dir, content_id, url, password, excludes)
for file in files:
download_link = Downloader(token=self.token).get_download_link(file)
logger.info(f"Enlace de descarga para {file.dest}: {download_link}")
def get_files(self, dir: str, content_id: str = None, url: str = None, password: str = None, excludes: list[str] = None) -> None:
if excludes is None:
excludes = []
files = list()
if content_id is not None:
self.update_token()
self.update_wt()
hash_password = hashlib.sha256(password.encode()).hexdigest() if password != None else ""
data = requests.get(
f"https://api.gofile.io/contents/{content_id}?wt={self.wt}&cache=true&password={hash_password}",
headers={
"Authorization": "Bearer " + self.token,
},
).json()
if data["status"] == "ok":
if data["data"].get("passwordStatus", "passwordOk") == "passwordOk":
if data["data"]["type"] == "folder":
dirname = data["data"]["name"]
dir = os.path.join(dir, sanitize_filename(dirname))
for (id, child) in data["data"]["children"].items():
if child["type"] == "folder":
self.execute(dir=dir, content_id=id, password=password)
else:
filename = child["name"]
if not any(fnmatch.fnmatch(filename, pattern) for pattern in excludes):
files.append(File(
link=urllib.parse.unquote(child["link"]),
dest=urllib.parse.unquote(os.path.join(dir, sanitize_filename(filename)))))
else:
filename = data["data"]["name"]
if not any(fnmatch.fnmatch(filename, pattern) for pattern in excludes):
files.append(File(
link=urllib.parse.unquote(data["data"]["link"]),
dest=urllib.parse.unquote(os.path.join(dir, sanitize_filename(filename)))))
else:
logger.error(f"invalid password: {data['data'].get('passwordStatus')}")
elif url is not None:
if url.startswith("https://gofile.io/d/"):
files = self.get_files(dir=dir, content_id=url.split("/")[-1], password=password, excludes=excludes)
else:
logger.error(f"invalid url: {url}")
else:
logger.error(f"invalid parameters")
return files
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("url")
parser.add_argument("-d", type=str, dest="dir", help="output directory")
parser.add_argument("-p", type=str, dest="password", help="password")
parser.add_argument("-e", action="append", dest="excludes", help="excluded files")
args = parser.parse_args()
dir = args.dir if args.dir is not None else "./output"
GoFile().execute(dir=dir, url=args.url, password=args.password, excludes=args.excludes)