├── app
├── __init__.py
├── config.py
├── teraboximp.py
├── __main__.py
└── teleboximp.py
├── .gitignore
├── requirements.txt
├── base.env
├── terabox
├── config.py
└── __init__.py
├── telebox
├── config.py
└── __init__.py
├── .github
└── FUNDING.yml
└── README.md
/app/__init__.py:
--------------------------------------------------------------------------------
1 | """xd"""
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .env
3 |
4 | .idea/
5 |
6 | __pycache__
7 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | python-dotenv~=1.0.0
2 | config==0.5.1
3 | requests~=2.35.0
4 | requests-toolbelt==1.0.0
5 | tqdm>=4.66.3
6 |
--------------------------------------------------------------------------------
/base.env:
--------------------------------------------------------------------------------
1 | # user variables
2 | USR_LIMIT_CONCURRENT=10
3 |
4 | TELEBOX_API=
5 | TELEBOX_BASEFOLDER=
6 |
7 | TERABOX_API=
8 | TERABOX_ROUTE=
9 |
--------------------------------------------------------------------------------
/terabox/config.py:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | """Config vars module"""
3 |
4 |
5 | class Config(object):
6 | TERABOX_BASE = 'https://www.terabox.com/rest/2.0/xpan/file'
7 | TERABOX_UPLOAD = 'https://c-jp.terabox.com/rest/2.0/pcs/superfile2'
8 | TERABOX_CHUNK_SIZE = 1024 * 1024 * 4 # 4MB
9 |
--------------------------------------------------------------------------------
/telebox/config.py:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | """Config vars module"""
3 |
4 |
5 | class Config(object):
6 | TELEBOX_BASE_URI = 'https://www.linkbox.to/'
7 | TELEBOX_SEARCH_FILE = 'api/open/file_search'
8 | TELEBOX_FOLDER_CREATE = 'api/open/folder_create'
9 | TELEBOX_FOLDER_DETAILS = 'api/open/folder_details'
10 | TELEBOX_UPLOAD_FASE1 = 'api/open/get_upload_url'
11 | TELEBOX_UPLOAD_FASE3 = 'api/open/folder_upload_file'
12 |
--------------------------------------------------------------------------------
/app/config.py:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | """Config vars module"""
3 | from dotenv import load_dotenv
4 | import os
5 |
6 | load_dotenv() # take environment variables from .env.
7 |
8 |
9 | class Config(object):
10 | USR_LIMIT_CONCURRENT = os.environ.get('USR_LIMIT_CONCURRENT')
11 | TELEBOX_API = os.environ.get('TELEBOX_API')
12 | TELEBOX_BASEFOLDER = os.environ.get('TELEBOX_BASEFOLDER')
13 | TERABOX_API = os.environ.get('TERABOX_API')
14 | TERABOX_ROUTE = os.environ.get('TERABOX_ROUTE')
15 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: TheWNetwork # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12 | polar: # Replace with a single Polar username
13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
15 |
--------------------------------------------------------------------------------
/app/teraboximp.py:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | """Terabox Implementation module"""
3 | import logging
4 | import os
5 | import sys
6 | from concurrent.futures import ThreadPoolExecutor
7 |
8 | from datetime import datetime
9 | from terabox import Terabox
10 | from .config import Config
11 |
12 |
13 | class TeraboxImpl:
14 | terabox = None
15 |
16 | def __init__(self, arguments):
17 | self.terabox = Terabox(Config.TERABOX_API, Config.TERABOX_ROUTE)
18 | self.main(arguments)
19 |
20 | def upload_file_and_print_status(self, i, total, directory, file):
21 | print(f'{i + 1}/{total} - {datetime.now().strftime("%Y-%m-%d %H:%M:%S")} - Uploading file: {file}')
22 | self.terabox.upload.invoke(directory + '/' + file)
23 |
24 | def main(self, arguments):
25 | print('Start Uploading....')
26 | file_list = os.listdir(arguments.dir)
27 | len_list = str(len(file_list))
28 | with ThreadPoolExecutor(max_workers=int(Config.USR_LIMIT_CONCURRENT)) as executor:
29 | for i, file in enumerate(file_list):
30 | executor.submit(self.upload_file_and_print_status, i, len_list, arguments.dir, file)
31 |
32 | # for file in file_list:
33 | # i += 1
34 | # print(str(i) + '/' + str(len(file_list)) + ' - Uploading file: ' + file)
35 | # telebox.upload.upload_file(arguments.dir + '/' + directory + '/' + file, subfolder_pid)
36 | print('End Uploading....')
37 |
--------------------------------------------------------------------------------
/app/__main__.py:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | """Main module"""
3 | import argparse
4 |
5 | from datetime import datetime
6 |
7 | from app.teleboximp import TeleboxImpl
8 | from app.teraboximp import TeraboxImpl
9 |
10 | if __name__ == '__main__':
11 | parser = argparse.ArgumentParser()
12 |
13 | parser.add_argument('--telebox', type=bool, help='Subir a Telebox', nargs='*')
14 | parser.add_argument('--terabox', type=bool, help='Subir a Terabox', nargs='*')
15 | parser.add_argument('--dir', type=str, help='Ruta donde se encuentra en tu equipo la carpeta con el nombre --foldername')
16 | parser.add_argument('--foldername', type=str, help='Indica el nombre de la carpeta a buscar. Recuerda que debe existir también en la ruta en la que usarás con el parametro --dir.')
17 | args = parser.parse_args()
18 | args.basefolder = None
19 | args.dir = args.dir.replace('\\', '\\\\')
20 | datetime1 = datetime.now()
21 | print(f'Current date is: {datetime1.strftime("%Y-%m-%d %H:%M:%S")}')
22 |
23 | if args.telebox != None:
24 | print('Telebox')
25 | TeleboxImpl(args)
26 |
27 | if args.terabox != None:
28 | print('Terabox')
29 | TeraboxImpl(args)
30 |
31 | datetime2 = datetime.now()
32 | print(f'Current date is: {datetime2.strftime("%Y-%m-%d %H:%M:%S")}')
33 | # Get the difference between the datetimes
34 | diff = abs(datetime2 - datetime1)
35 | # Extract days, hours, minutes, and seconds
36 | days, seconds = diff.days, diff.seconds
37 | hours = days * 24 + seconds // 3600
38 | minutes = (seconds % 3600) // 60
39 | seconds = (seconds % 60)
40 |
41 | print(f"Total Time: {str(hours).zfill(2)}:{str(minutes).zfill(2)}:{str(seconds).zfill(2)}")
42 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # twn-api-upload
2 | TheWNetwork bot to upload massively to a Telebox & Terabox folder.
3 | - Allow Pictures and Videos
4 |
5 | ## Preparation
6 | 1. ``pip install -Ur requirements.txt``
7 |
8 | 2. Copy base.env to .env and fill all the gaps
9 |
10 | 3. How to get the values for the .env file:
11 |
12 | | Variable | Description |
13 | | --- | --- |
14 | | TELEBOX_API | Access to https://www.linkbox.to/admin/account and copy "Token" |
15 | | TELEBOX_BASEFOLDER | Access to https://www.linkbox.to/admin/my-files, search the folder you wanna use and copy the ID.
Do it copying from the url bar.
Will have a format-like: https://www.linkbox.to/admin/share-folder/12345678 (12345678 is the ID) |
16 |
17 | - ``python -m app --dir --filename ``
18 |
19 | > ``--telebox`` upload to telebox (you need to configrue the .env) [Working]
20 | >
21 | > ``--terabox`` upload to terabox (you need to configrue the .env) [MayNotWork]
22 | >
23 | > ``--dir`` is the path to the folder where the files are located
24 | >
25 | > ``--filename`` is the name of the folder to be uploaded. will be created if not exists on Telebox
26 |
27 | Imagine you have a folder named "FolderToUpload" that have a list of subfolders with names (can be recursive also).
28 | You must put on "filename" the folder you wanna upload. This folder WONT be created. (as you already created it on Linkbox)
29 |
30 | - Example: ``python -m app --telebox --dir /home/user/Downloads --filename FolderToUpload``
31 |
32 | ### Notes
33 | Telebox speed is stupidly low, it may take a long time to upload large files.
34 | Also, the Telebox API does not give any information about how its working so, sorry
35 |
36 | ## Termux pre requisites
37 | - ``pkg update``
38 | - ``pkg in python-numpy -y``
39 | - ``pkg in opencv-python -y``
40 |
41 | # DISCLAIMER OF SOFTWARE WARRANTY
42 |
43 | THEWNETWORK PROVIDES THE SOFTWARE TO YOU "AS IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
44 |
45 | THE USER IS SOLELY RESPONSIBLE FOR THE ACTIONS CARRIED OUT WITH THIS CODE AND THE COMPANY IS NOT RESPONSIBLE FOR ANY MANIPULATION, INVONVENIENCE, ERROR OR PROBLEM, BOTH LEGAL AND OF ANY OTHER TYPE THAT THE USER MAY SUFFER USING THE CODE.
46 |
47 |
--------------------------------------------------------------------------------
/app/teleboximp.py:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | """Telebox Implementation module"""
3 | import logging
4 | import os
5 | import sys
6 | from concurrent.futures import ThreadPoolExecutor
7 |
8 | from datetime import datetime
9 | from telebox import Telebox
10 | from .config import Config
11 |
12 |
13 | class TeleboxImpl:
14 | telebox = None
15 |
16 | def __init__(self, arguments):
17 | self.telebox = Telebox(Config.TELEBOX_API, Config.TELEBOX_BASEFOLDER)
18 | self.main(arguments)
19 |
20 | def create_folder_if_not_exists(self, foldername, folder_id):
21 | if not (pid := self.telebox.search.folder_exists(foldername, folder_id)):
22 | # Folder not exists on telebox, create folder
23 | pid = self.telebox.folder.create(foldername, folder_id)
24 | return pid
25 |
26 | def upload_file_and_print_status(self, i, total, directory, file, subfolder_pid):
27 | print(f'{i + 1}/{total} - {datetime.now().strftime("%Y-%m-%d %H:%M:%S")} - Uploading file: {file}')
28 | self.telebox.upload.upload_file(directory + '/' + file, subfolder_pid)
29 |
30 | def doit(self, file_list, len_list, directory, folder_pid) -> bool:
31 | has_directory: bool = False
32 | with ThreadPoolExecutor(max_workers=int(Config.USR_LIMIT_CONCURRENT)) as executor:
33 | for i, file in enumerate(file_list):
34 | if os.path.isfile(directory + '/' + file):
35 | executor.submit(
36 | TeleboxImpl.upload_file_and_print_status,
37 | self,
38 | i,
39 | len_list,
40 | directory,
41 | file,
42 | folder_pid
43 | )
44 | if os.path.isdir(directory + '/' + file):
45 | has_directory = True
46 | return has_directory
47 |
48 | def main(self, arguments):
49 | logging.basicConfig(level=logging.ERROR)
50 |
51 | currentDir = arguments.dir
52 | currentName = arguments.foldername
53 |
54 | # Searching if the folder exists
55 | folder_pid = int(arguments.basefolder or Config.TELEBOX_BASEFOLDER)
56 |
57 | folder_data = self.telebox.search.search('', folder_pid)['data']['list']
58 |
59 | print('Get Main Folder PID for folder ' + arguments.foldername + ' is ' + str(folder_pid))
60 | if arguments.foldername != 'upload':
61 | self.doit(os.listdir(arguments.dir), str(len(os.listdir(arguments.dir))), arguments.dir, folder_pid)
62 |
63 | directories = [d for d in os.listdir(arguments.dir + '/' + arguments.foldername) if os.path.isdir(os.path.join(arguments.dir + '/' + arguments.foldername, d))]
64 | for directory in directories:
65 |
66 | # Create or get Folder IDs
67 | print('\n\n######################################')
68 |
69 | if folder_data:
70 | subfolder = list(filter(lambda d: d['name'] == directory, folder_data))
71 | else:
72 | subfolder = None
73 |
74 | if not subfolder:
75 | # Not created yet
76 | subfolder_pid = self.create_folder_if_not_exists(directory, folder_pid)
77 | if subfolder_pid == -1:
78 | sys.exit("Execution stopped. Folder not created")
79 | else:
80 | subfolder_pid = subfolder[0]['id']
81 |
82 | print('Creating or getting PID for folder: ' + currentName + '/' + directory + ' is ' + str(subfolder_pid))
83 |
84 | # Upload Files to Telebox
85 | print('Start Uploading....')
86 | file_list = os.listdir(currentDir + '/' + currentName + '/' + directory)
87 | len_list = str(len(file_list))
88 | ret: bool = self.doit(file_list, len_list, currentDir + '/' + currentName + '/' + directory, subfolder_pid)
89 | if ret:
90 | args2 = arguments
91 | args2.dir = currentDir + '/' + currentName
92 | args2.foldername = directory
93 | args2.basefolder = subfolder_pid
94 | self.main(args2)
95 |
96 | print('End Uploading....')
97 |
--------------------------------------------------------------------------------
/terabox/__init__.py:
--------------------------------------------------------------------------------
1 | # telebox.py
2 | import sys
3 |
4 | import os
5 | from pathlib import Path
6 |
7 | import json
8 | import requests
9 |
10 | import hashlib
11 |
12 | from tqdm import tqdm
13 |
14 | from .config import Config
15 | from urllib.parse import urlencode
16 |
17 |
18 | class Terabox:
19 |
20 | def __init__(self, token, folder_location):
21 | self.token = token
22 | self.folder_location = folder_location
23 | self.connect = HttpClientService(Config.TERABOX_BASE, self.token)
24 | self.upload = Upload(self.connect, folder_location, Config.TERABOX_CHUNK_SIZE)
25 |
26 |
27 | class HttpClientService:
28 |
29 | def __init__(self, base_url, token):
30 | self.base_url = base_url
31 | self.token = token
32 |
33 | def post_direct(self, endpoint, get_params=None, post_params=None, headers=None):
34 | get_params["access_tokenx"] = self.token
35 | response = requests.post(f"{self.add_params_to_url(endpoint, get_params)}", data=post_params, headers=headers)
36 | response.raise_for_status()
37 | return response.json()
38 |
39 | def post(self, endpoint, get_params=None, post_params=None):
40 | return self.post_direct(f"{self.base_url}/{endpoint}", get_params, post_params)
41 |
42 | @staticmethod
43 | def add_params_to_url(url, get_params=None):
44 | if get_params:
45 | url += '?' + urlencode(get_params)
46 | return url
47 |
48 |
49 | class Upload:
50 | def __init__(self, connect, file_location, chunk_size):
51 | self.chunk_hashes = None
52 | self.size = None
53 | self.connect = connect
54 | self.file_location = file_location
55 | self.chunk_size = chunk_size
56 |
57 | def invoke(self, filename):
58 | print(f"Uploading file: {filename}")
59 | try:
60 | prepare_response = self.prepare(filename)
61 | if prepare_response['errno'] < 0:
62 | print(f"Error occurred while preparing file: {filename}")
63 | return False
64 |
65 | upload_response = self.upload(filename, prepare_response['request_id'])
66 | if not upload_response:
67 | print(f"Error occurred while uploading file: {filename}")
68 | return False
69 |
70 | complete_response = self.complete(filename, prepare_response['request_id'])
71 | if complete_response['errno'] < 0:
72 | print(f"Error occurred while completing file: {filename}")
73 | return False
74 | except Exception as e:
75 | print(f"Error occurred while uploading file: {filename}")
76 | print(e)
77 | return False
78 | return True
79 |
80 | def prepare(self, filename):
81 | self.size = os.path.getsize(filename)
82 | chunk_hashes = []
83 | with open(filename, "rb") as f:
84 | while chunk := f.read(self.chunk_size):
85 | chunk_md5 = hashlib.md5(chunk).hexdigest()
86 | chunk_hashes.append(chunk_md5)
87 |
88 | # Call the Request method with all the MD5 blocks
89 | self.chunk_hashes = chunk_hashes
90 | return self.connect.post('', {'method': 'precreate'}, {'path': self.file_location, 'autoinit': 1, 'size': self.size, 'block_list': chunk_hashes})
91 |
92 | def upload(self, filename, request_id):
93 | file_size = os.path.getsize(filename)
94 |
95 | # Open file in binary mode
96 | with (open(filename, 'rb') as file):
97 | chunk_no = 1
98 | while True:
99 | progress = tqdm(total=len(self.chunk_hashes), ncols=70)
100 | # read only specified bytes amount (chunk_size)
101 | chunk = file.read(self.chunk_size)
102 | if not chunk:
103 | break
104 |
105 | # Here you can make a request with the chunk
106 | # update 'YOUR_API_URL' with your actual API which will receive chunk data
107 | get = {
108 | 'method': 'upload',
109 | 'path': self.file_location,
110 | 'uploadid': request_id,
111 | 'partseq': chunk_no
112 | }
113 |
114 | headers = {
115 | 'Content-Range': f'bytes {chunk_no * self.chunk_size}-{(chunk_no + 1) * self.chunk_size - 1}/{file_size}',
116 | # specify additional headers as per requirement of your API
117 | }
118 |
119 | progress.update(1)
120 | response = self.connect.post_direct(Config.TERABOX_UPLOAD, get_params=get, post_params={'file': chunk})
121 |
122 | print(response)
123 | #if response != 200:
124 | # print(f"Error occurred while uploading chunk: {chunk_no}")
125 | # return False
126 |
127 | chunk_no += 1
128 |
129 | return True
130 |
131 | def complete(self, filename, request_id):
132 | response = self.connect.post('',
133 | get_params={'method': 'create'},
134 | post_params={'path': self.file_location, 'size': self.size, 'uploadid': request_id, 'block_list': self.chunk_hashes})
135 | return response
136 |
--------------------------------------------------------------------------------
/telebox/__init__.py:
--------------------------------------------------------------------------------
1 | # telebox.py
2 | import sys
3 |
4 | import os
5 | from pathlib import Path
6 |
7 | import requests
8 | from tqdm import tqdm
9 | from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor
10 |
11 | import hashlib
12 | from .config import Config
13 |
14 |
15 | class Telebox:
16 | """
17 | The `Telebox` class represents a client to interact with the Telebox API.
18 |
19 | :param token: The access token required for authentication.
20 | :param folder_id: The ID of the folder to interact with.
21 |
22 | The class provides methods to connect, search, and perform various operations on the specified folder.
23 |
24 | Example usage:
25 | token = "your-access-token"
26 | folder_id = "your-folder-id"
27 | telebox = Telebox(token, folder_id)
28 |
29 | Methods:
30 | - connect: Connects to the Telebox server.
31 | - search: Searches for files in the specified folder.
32 | - folder: Retrieves information about the specified folder.
33 |
34 | Note:
35 | The class requires the Telebox library to be installed.
36 |
37 | """
38 |
39 | def __init__(self, token, folder_id):
40 | self.token = token
41 | self.folder_id = folder_id
42 | self.connect = Connect(Config.TELEBOX_BASE_URI, self.token)
43 | self.search = Search(self.connect)
44 | self.folder = Folder(self.connect)
45 | self.upload = Upload(self.connect)
46 | # self.upload_auth = UploadAuthorization(self.connect)
47 | # self.folder_details = FolderDetails(self.folder_id, self.connect)
48 | # self.folder_upload = FolderUploadFile(self.folder_id, self.connect)
49 |
50 |
51 | class HttpClientService:
52 | """
53 | .. class:: HttpClientService
54 |
55 | The HttpClientService class provides methods to make HTTP GET and POST requests.
56 |
57 | :param base_url: The base URL that will be used for all requests.
58 | :type base_url: str
59 |
60 | .. method:: __init__(base_url)
61 |
62 | Constructs a new HttpClientService object.
63 |
64 | :param base_url: The base URL that will be used for all requests.
65 | :type base_url: str
66 |
67 | .. method:: get(endpoint, params=None)
68 |
69 | Sends an HTTP GET request to the specified endpoint.
70 |
71 | :param endpoint: The endpoint to send the request to.
72 | :type endpoint: str
73 |
74 | :param params: (optional) The query parameters to include in the request.
75 | :type params: dict
76 |
77 | :return: The JSON response from the server.
78 | :rtype: dict
79 |
80 | :raises requests.exceptions.HTTPError: If the request fails.
81 |
82 | .. method:: post(endpoint, params=None)
83 |
84 | Sends an HTTP POST request to the specified endpoint.
85 |
86 | :param endpoint: The endpoint to send the request to.
87 | :type endpoint: str
88 |
89 | :param params: (optional) The query parameters to include in the request.
90 | :type params: dict
91 |
92 | :return: The JSON response from the server.
93 | :rtype: dict
94 |
95 | :raises requests.exceptions.HTTPError: If the request fails.
96 | """
97 |
98 | def __init__(self, base_url):
99 | self.base_url = base_url
100 |
101 | def get(self, endpoint, params=None):
102 | response = requests.get(f"{self.base_url}{endpoint}", params=params)
103 | response.raise_for_status()
104 | return response.json()
105 |
106 | def post(self, endpoint, params=None):
107 | response = requests.post(f"{self.base_url}/{endpoint}", params=params)
108 | response.raise_for_status()
109 | return response.json()
110 |
111 |
112 | class Connect:
113 | """
114 | Connect
115 |
116 | Class representing a connection to a remote server.
117 |
118 | Attributes:
119 | client (HttpClientService): The underlying HTTP client service.
120 | token (str): The authentication token.
121 |
122 | Methods:
123 | __init__(base_url, token)
124 | Initializes a new Connect instance.
125 |
126 | get_data(endpoint, params)
127 | Makes a GET request to the specified endpoint with the given parameters.
128 |
129 | post_data(endpoint, params)
130 | Makes a POST request to the specified endpoint with the given parameters.
131 | """
132 |
133 | def __init__(self, base_url, token):
134 | self.client = HttpClientService(base_url)
135 | self.token = token
136 |
137 | def get_data(self, endpoint, params):
138 | params["token"] = self.token
139 | return self.client.get(endpoint, params)
140 |
141 | def post_data(self, endpoint, params):
142 | params["token"] = self.token
143 | return self.client.post(endpoint, params)
144 |
145 |
146 | class Search:
147 | """
148 | Initialize a Search object.
149 |
150 | Args:
151 | connect: The connection object used for making API calls.
152 |
153 | Attributes:
154 | connect: The connection object used for making API calls.
155 | url: The URL of the search file.
156 | """
157 |
158 | def __init__(self, connect):
159 | self.connect = connect
160 | self.url = Config.TELEBOX_SEARCH_FILE
161 |
162 | def search(self, filename, folder_id):
163 | return self.connect.get_data(self.url, {'pid': folder_id, 'name': filename, 'pageNo': 1, 'pageSize': 50})
164 |
165 | def folder_exists(self, filename, folder_id):
166 | lot = self.search(filename, folder_id)
167 | if isinstance(lot['data']['list'], list) and len(lot['data']['list']) != 0:
168 | return lot['data']['list'][0]['id'] if lot['data']['list'][0]['type'] == 'dir' and lot['data']['list'][0]['pid'] == int(folder_id) else False
169 | return False
170 |
171 |
172 | class Upload:
173 | def __init__(self, connect):
174 | self.connect = connect
175 |
176 | def prepare(self, file_md5_of_pre_10m, file_size):
177 | return self.connect.get_data(Config.TELEBOX_UPLOAD_FASE1, {'fileMd5ofPre10m': file_md5_of_pre_10m, 'fileSize': file_size})
178 |
179 | @staticmethod
180 | def upload(url, file):
181 | size = os.path.getsize(file)
182 | with open(file, "rb") as file:
183 | # Send the PUT request
184 | response = requests.put(url, data=file)
185 | return response
186 |
187 | def finish_upload(self, file_md5_of_pre_10m, file_size, pid, name):
188 | return self.connect.get_data(Config.TELEBOX_UPLOAD_FASE3, {'fileMd5ofPre10m': file_md5_of_pre_10m, 'fileSize': file_size, 'pid': pid, 'diyName': name})
189 |
190 | def upload_file(self, file, folder_id):
191 | file_size = os.path.getsize(file)
192 | file_md5_of_pre_10m = self.get_md5_of_first_10mb(file)
193 | lot = self.prepare(file_md5_of_pre_10m, file_size)
194 | if lot['status'] == 600:
195 | return 1
196 |
197 | if lot['status'] != 1:
198 | sys.exit("Prepare: Execution stopped. Cannot upload files")
199 |
200 | url = lot['data']['signUrl']
201 | self.upload(url, file)
202 | lotf = self.finish_upload(file_md5_of_pre_10m, file_size, folder_id, os.path.basename(file))
203 | if lotf['status'] != 1:
204 | sys.exit("Finish Upload: Execution stopped. Cannot upload files")
205 |
206 | return lotf['data']['itemId']
207 |
208 | @staticmethod
209 | def get_md5_of_first_10mb(file_path):
210 | md5_hash = hashlib.md5()
211 |
212 | with open(file_path, 'rb') as file:
213 | chunk = file.read(10 * 1024 * 1024) # read first 10MB
214 | if chunk:
215 | md5_hash.update(chunk)
216 |
217 | return md5_hash.hexdigest()
218 |
219 |
220 | class Folder:
221 | """
222 | Class representing a folder.
223 |
224 | Args:
225 | connect: The connection object used to communicate with the server.
226 |
227 | Attributes:
228 | connect: The connection object used to communicate with the server.
229 |
230 | """
231 |
232 | def __init__(self, connect):
233 | self.connect = connect
234 |
235 | def create(self, filename, destination_folder_id):
236 | lot = self.connect.get_data(Config.TELEBOX_FOLDER_CREATE, {'pid': int(destination_folder_id),
237 | 'name': filename,
238 | 'isShare': 0,
239 | 'canInvite': 1,
240 | 'canShare': 1,
241 | 'withBodyImg': 0,
242 | 'desc': 'TheWNetwork Telebox Mass Creator'})
243 | if lot['status'] != 1:
244 | sys.exit("Execution stopped. Cannot create folders")
245 |
246 | return lot['data']['dirId']
247 |
248 | def get_details(self, destination_folder_id):
249 | return self.connect.get_data(Config.TELEBOX_FOLDER_DETAILS, {'dirId': destination_folder_id})
250 |
--------------------------------------------------------------------------------