TechDev commited on
Commit
0c20b62
·
verified ·
1 Parent(s): b688a2d

Upload 5 files

Browse files
Files changed (5) hide show
  1. Dockerfile +31 -0
  2. FastTelethon.py +308 -0
  3. app.py +41 -0
  4. main.py +255 -0
  5. requirements.txt +8 -0
Dockerfile ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM ubuntu
2
+
3
+ RUN apt-get update && \
4
+ apt-get install -y sudo && \
5
+ apt-get clean
6
+ RUN apt-get update && apt-get install -y python3 python3-pip python3.12-venv
7
+ RUN apt-get update && apt-get install -y \
8
+ curl \
9
+ ca-certificates \
10
+ megatools \
11
+ gnupg && \
12
+ curl -fsSL https://deb.nodesource.com/setup_16.x | bash -
13
+ RUN rm -rf /var/lib/apt/lists/*
14
+
15
+ # Añadir un usuario llamado 'appuser'
16
+ RUN useradd -ms /bin/bash appuser
17
+ RUN usermod -aG sudo appuser
18
+ RUN echo "appuser ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
19
+
20
+ USER appuser
21
+
22
+ WORKDIR /app
23
+
24
+ COPY . /app
25
+
26
+ RUN sudo chmod -R 777 /app
27
+
28
+ RUN python3 -m venv venv
29
+ RUN /bin/bash -c "source venv/bin/activate && pip3 install -r requirements.txt"
30
+
31
+ CMD ["venv/bin/gunicorn", "--worker-class", "eventlet", "-w", "1", "-b", "0.0.0.0:7860", "app:app"]
FastTelethon.py ADDED
@@ -0,0 +1,308 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # copied from https://github.com/tulir/mautrix-telegram/blob/master/mautrix_telegram/util/parallel_file_transfer.py
2
+ # Copyright (C) 2021 Tulir Asokan
3
+ import asyncio
4
+ import hashlib
5
+ import inspect
6
+ import logging
7
+ import math
8
+ import os
9
+ from collections import defaultdict
10
+ from typing import Optional, List, AsyncGenerator, Union, Awaitable, DefaultDict, Tuple, BinaryIO
11
+
12
+ from telethon import utils, helpers, TelegramClient
13
+ from telethon.crypto import AuthKey
14
+ from telethon.network import MTProtoSender
15
+ from telethon.tl.alltlobjects import LAYER
16
+ from telethon.tl.functions import InvokeWithLayerRequest
17
+ from telethon.tl.functions.auth import ExportAuthorizationRequest, ImportAuthorizationRequest
18
+ from telethon.tl.functions.upload import (GetFileRequest, SaveFilePartRequest,
19
+ SaveBigFilePartRequest)
20
+ from telethon.tl.types import (Document, InputFileLocation, InputDocumentFileLocation,
21
+ InputPhotoFileLocation, InputPeerPhotoFileLocation, TypeInputFile,
22
+ InputFileBig, InputFile)
23
+
24
+ try:
25
+ from mautrix.crypto.attachments import async_encrypt_attachment
26
+ except ImportError:
27
+ async_encrypt_attachment = None
28
+
29
+ log: logging.Logger = logging.getLogger("telethon")
30
+
31
+ TypeLocation = Union[Document, InputDocumentFileLocation, InputPeerPhotoFileLocation,
32
+ InputFileLocation, InputPhotoFileLocation]
33
+
34
+
35
+ class DownloadSender:
36
+ client: TelegramClient
37
+ sender: MTProtoSender
38
+ request: GetFileRequest
39
+ remaining: int
40
+ stride: int
41
+
42
+ def __init__(self, client: TelegramClient, sender: MTProtoSender, file: TypeLocation, offset: int, limit: int,
43
+ stride: int, count: int) -> None:
44
+ self.sender = sender
45
+ self.client = client
46
+ self.request = GetFileRequest(file, offset=offset, limit=limit)
47
+ self.stride = stride
48
+ self.remaining = count
49
+
50
+ async def next(self) -> Optional[bytes]:
51
+ if not self.remaining:
52
+ return None
53
+ result = await self.client._call(self.sender, self.request)
54
+ self.remaining -= 1
55
+ self.request.offset += self.stride
56
+ return result.bytes
57
+
58
+ def disconnect(self) -> Awaitable[None]:
59
+ return self.sender.disconnect()
60
+
61
+
62
+ class UploadSender:
63
+ client: TelegramClient
64
+ sender: MTProtoSender
65
+ request: Union[SaveFilePartRequest, SaveBigFilePartRequest]
66
+ part_count: int
67
+ stride: int
68
+ previous: Optional[asyncio.Task]
69
+ loop: asyncio.AbstractEventLoop
70
+
71
+ def __init__(self, client: TelegramClient, sender: MTProtoSender, file_id: int, part_count: int, big: bool,
72
+ index: int,
73
+ stride: int, loop: asyncio.AbstractEventLoop) -> None:
74
+ self.client = client
75
+ self.sender = sender
76
+ self.part_count = part_count
77
+ if big:
78
+ self.request = SaveBigFilePartRequest(file_id, index, part_count, b"")
79
+ else:
80
+ self.request = SaveFilePartRequest(file_id, index, b"")
81
+ self.stride = stride
82
+ self.previous = None
83
+ self.loop = loop
84
+
85
+ async def next(self, data: bytes) -> None:
86
+ if self.previous:
87
+ await self.previous
88
+ self.previous = self.loop.create_task(self._next(data))
89
+
90
+ async def _next(self, data: bytes) -> None:
91
+ self.request.bytes = data
92
+ log.debug(f"Sending file part {self.request.file_part}/{self.part_count}"
93
+ f" with {len(data)} bytes")
94
+ await self.client._call(self.sender, self.request)
95
+ self.request.file_part += self.stride
96
+
97
+ async def disconnect(self) -> None:
98
+ if self.previous:
99
+ await self.previous
100
+ return await self.sender.disconnect()
101
+
102
+
103
+ class ParallelTransferrer:
104
+ client: TelegramClient
105
+ loop: asyncio.AbstractEventLoop
106
+ dc_id: int
107
+ senders: Optional[List[Union[DownloadSender, UploadSender]]]
108
+ auth_key: AuthKey
109
+ upload_ticker: int
110
+
111
+ def __init__(self, client: TelegramClient, dc_id: Optional[int] = None) -> None:
112
+ self.client = client
113
+ self.loop = self.client.loop
114
+ self.dc_id = dc_id or self.client.session.dc_id
115
+ self.auth_key = (None if dc_id and self.client.session.dc_id != dc_id
116
+ else self.client.session.auth_key)
117
+ self.senders = None
118
+ self.upload_ticker = 0
119
+
120
+ async def _cleanup(self) -> None:
121
+ await asyncio.gather(*[sender.disconnect() for sender in self.senders])
122
+ self.senders = None
123
+
124
+ @staticmethod
125
+ def _get_connection_count(file_size: int, max_count: int = 20,
126
+ full_size: int = 100 * 1024 * 1024) -> int:
127
+ if file_size > full_size:
128
+ return max_count
129
+ return math.ceil((file_size / full_size) * max_count)
130
+
131
+ async def _init_download(self, connections: int, file: TypeLocation, part_count: int,
132
+ part_size: int) -> None:
133
+ minimum, remainder = divmod(part_count, connections)
134
+
135
+ def get_part_count() -> int:
136
+ nonlocal remainder
137
+ if remainder > 0:
138
+ remainder -= 1
139
+ return minimum + 1
140
+ return minimum
141
+
142
+ # The first cross-DC sender will export+import the authorization, so we always create it
143
+ # before creating any other senders.
144
+ self.senders = [
145
+ await self._create_download_sender(file, 0, part_size, connections * part_size,
146
+ get_part_count()),
147
+ *await asyncio.gather(
148
+ *[self._create_download_sender(file, i, part_size, connections * part_size,
149
+ get_part_count())
150
+ for i in range(1, connections)])
151
+ ]
152
+
153
+ async def _create_download_sender(self, file: TypeLocation, index: int, part_size: int,
154
+ stride: int,
155
+ part_count: int) -> DownloadSender:
156
+ return DownloadSender(self.client, await self._create_sender(), file, index * part_size, part_size,
157
+ stride, part_count)
158
+
159
+ async def _init_upload(self, connections: int, file_id: int, part_count: int, big: bool
160
+ ) -> None:
161
+ self.senders = [
162
+ await self._create_upload_sender(file_id, part_count, big, 0, connections),
163
+ *await asyncio.gather(
164
+ *[self._create_upload_sender(file_id, part_count, big, i, connections)
165
+ for i in range(1, connections)])
166
+ ]
167
+
168
+ async def _create_upload_sender(self, file_id: int, part_count: int, big: bool, index: int,
169
+ stride: int) -> UploadSender:
170
+ return UploadSender(self.client, await self._create_sender(), file_id, part_count, big, index, stride,
171
+ loop=self.loop)
172
+
173
+ async def _create_sender(self) -> MTProtoSender:
174
+ dc = await self.client._get_dc(self.dc_id)
175
+ sender = MTProtoSender(self.auth_key, loggers=self.client._log)
176
+ await sender.connect(self.client._connection(dc.ip_address, dc.port, dc.id,
177
+ loggers=self.client._log,
178
+ proxy=self.client._proxy))
179
+ if not self.auth_key:
180
+ log.debug(f"Exporting auth to DC {self.dc_id}")
181
+ auth = await self.client(ExportAuthorizationRequest(self.dc_id))
182
+ self.client._init_request.query = ImportAuthorizationRequest(id=auth.id,
183
+ bytes=auth.bytes)
184
+ req = InvokeWithLayerRequest(LAYER, self.client._init_request)
185
+ await sender.send(req)
186
+ self.auth_key = sender.auth_key
187
+ return sender
188
+
189
+ async def init_upload(self, file_id: int, file_size: int, part_size_kb: Optional[float] = None,
190
+ connection_count: Optional[int] = None) -> Tuple[int, int, bool]:
191
+ connection_count = connection_count or self._get_connection_count(file_size)
192
+ part_size = (part_size_kb or utils.get_appropriated_part_size(file_size)) * 1024
193
+ part_count = (file_size + part_size - 1) // part_size
194
+ is_large = file_size > 10 * 1024 * 1024
195
+ await self._init_upload(connection_count, file_id, part_count, is_large)
196
+ return part_size, part_count, is_large
197
+
198
+ async def upload(self, part: bytes) -> None:
199
+ await self.senders[self.upload_ticker].next(part)
200
+ self.upload_ticker = (self.upload_ticker + 1) % len(self.senders)
201
+
202
+ async def finish_upload(self) -> None:
203
+ await self._cleanup()
204
+
205
+ async def download(self, file: TypeLocation, file_size: int,
206
+ part_size_kb: Optional[float] = None,
207
+ connection_count: Optional[int] = None) -> AsyncGenerator[bytes, None]:
208
+ connection_count = connection_count or self._get_connection_count(file_size)
209
+ part_size = (part_size_kb or utils.get_appropriated_part_size(file_size)) * 1024
210
+ part_count = math.ceil(file_size / part_size)
211
+ log.debug("Starting parallel download: "
212
+ f"{connection_count} {part_size} {part_count} {file!s}")
213
+ await self._init_download(connection_count, file, part_count, part_size)
214
+
215
+ part = 0
216
+ while part < part_count:
217
+ tasks = []
218
+ for sender in self.senders:
219
+ tasks.append(self.loop.create_task(sender.next()))
220
+ for task in tasks:
221
+ data = await task
222
+ if not data:
223
+ break
224
+ yield data
225
+ part += 1
226
+ log.debug(f"Part {part} downloaded")
227
+
228
+ log.debug("Parallel download finished, cleaning up connections")
229
+ await self._cleanup()
230
+
231
+
232
+ parallel_transfer_locks: DefaultDict[int, asyncio.Lock] = defaultdict(lambda: asyncio.Lock())
233
+
234
+
235
+ def stream_file(file_to_stream: BinaryIO, chunk_size=1024):
236
+ while True:
237
+ data_read = file_to_stream.read(chunk_size)
238
+ if not data_read:
239
+ break
240
+ yield data_read
241
+
242
+
243
+ async def _internal_transfer_to_telegram(client: TelegramClient,
244
+ response: BinaryIO,
245
+ progress_callback: callable
246
+ ) -> Tuple[TypeInputFile, int]:
247
+ file_id = helpers.generate_random_long()
248
+ file_size = os.path.getsize(response.name)
249
+
250
+ hash_md5 = hashlib.md5()
251
+ uploader = ParallelTransferrer(client)
252
+ part_size, part_count, is_large = await uploader.init_upload(file_id, file_size)
253
+ buffer = bytearray()
254
+ for data in stream_file(response):
255
+ if progress_callback:
256
+ r = progress_callback(response.tell(), file_size)
257
+ if inspect.isawaitable(r):
258
+ await r
259
+ if not is_large:
260
+ hash_md5.update(data)
261
+ if len(buffer) == 0 and len(data) == part_size:
262
+ await uploader.upload(data)
263
+ continue
264
+ new_len = len(buffer) + len(data)
265
+ if new_len >= part_size:
266
+ cutoff = part_size - len(buffer)
267
+ buffer.extend(data[:cutoff])
268
+ await uploader.upload(bytes(buffer))
269
+ buffer.clear()
270
+ buffer.extend(data[cutoff:])
271
+ else:
272
+ buffer.extend(data)
273
+ if len(buffer) > 0:
274
+ await uploader.upload(bytes(buffer))
275
+ await uploader.finish_upload()
276
+ if is_large:
277
+ return InputFileBig(file_id, part_count, "upload"), file_size
278
+ else:
279
+ return InputFile(file_id, part_count, "upload", hash_md5.hexdigest()), file_size
280
+
281
+
282
+ async def download_file(client: TelegramClient,
283
+ location: TypeLocation,
284
+ out: BinaryIO,
285
+ progress_callback: callable = None
286
+ ) -> BinaryIO:
287
+ size = location.size
288
+ dc_id, location = utils.get_input_location(location)
289
+ # We lock the transfers because telegram has connection count limits
290
+ downloader = ParallelTransferrer(client, dc_id)
291
+ downloaded = downloader.download(location, size)
292
+ async for x in downloaded:
293
+ out.write(x)
294
+ if progress_callback:
295
+ r = progress_callback(out.tell(), size)
296
+ if inspect.isawaitable(r):
297
+ await r
298
+
299
+ return out
300
+
301
+
302
+ async def upload_file(client: TelegramClient,
303
+ file: BinaryIO,
304
+ progress_callback: callable = None,
305
+
306
+ ) -> TypeInputFile:
307
+ res = (await _internal_transfer_to_telegram(client, file, progress_callback))[0]
308
+ return res
app.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from flask import Flask, send_file
3
+ from flask_socketio import SocketIO
4
+ import threading
5
+
6
+ app = Flask(__name__)
7
+ socketio = SocketIO(app, async_mode='eventlet')
8
+ base_dir = os.path.abspath('files')
9
+
10
+ @socketio.on('request_dir_structure')
11
+ def send_dir_structure():
12
+ structure = {}
13
+ for root, dirs, files in os.walk(base_dir):
14
+ rel_path = os.path.relpath(root, base_dir)
15
+ structure[rel_path] = {
16
+ 'dirs': dirs,
17
+ 'files': [{'name': f, 'size': os.path.getsize(os.path.join(root, f))} for f in files]
18
+ }
19
+ socketio.emit('dir_structure', structure)
20
+
21
+ @socketio.on('download_file')
22
+ def send_file_chunk(data):
23
+ file_path = os.path.join(base_dir, data['path'])
24
+ offset = data.get('offset', 0)
25
+ chunk_size = 1024 * 64 # 64KB chunks
26
+
27
+ with open(file_path, 'rb') as f:
28
+ f.seek(offset)
29
+ while True:
30
+ chunk = f.read(chunk_size)
31
+ if not chunk:
32
+ break
33
+ socketio.emit('file_chunk', {
34
+ 'path': data['path'],
35
+ 'offset': f.tell(),
36
+ 'data': chunk
37
+ })
38
+ socketio.sleep(0.01) # Evita bloquear el hilo del servidor
39
+
40
+ if __name__ == '__main__':
41
+ socketio.run(app, port=5000)
main.py ADDED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from telethon import events, utils, Button, TelegramClient
2
+ import asyncio, os, time, re, sys, threading, random, subprocess, json, base64, requests, shutil, zipfile
3
+ from bs4 import BeautifulSoup
4
+ from FastTelethon import download_file, upload_file
5
+ import subprocess
6
+
7
+ api_id = 9024532
8
+ api_hash = "131b576240be107210aace99a5f5c5b0"
9
+ token = "7829277186:AAGZKtL06JxT5yp0FVNMjFy9yBKJiRpM-Y0"
10
+
11
+ client = TelegramClient("AutoD", api_id, api_hash)
12
+
13
+ class Timer:
14
+ def __init__(self, time_between=2):
15
+ self.start_time = time.time()
16
+ self.time_between = time_between
17
+
18
+ def can_send(self):
19
+ if time.time() > (self.start_time + self.time_between):
20
+ self.start_time = time.time()
21
+ return True
22
+ return False
23
+
24
+ def execute_command(command):
25
+ try:
26
+ result = subprocess.run(command, shell=True, capture_output=True, text=True)
27
+ if result.stdout:
28
+ return str(result.stdout)
29
+ if result.stderr:
30
+ return str(result.stderr)
31
+ except Exception as e:
32
+ return str(f"Error: {e}")
33
+
34
+ def folder_size(folder_path):
35
+ total_size = 0
36
+ for dirpath, dirnames, filenames in os.walk(folder_path):
37
+ for f in filenames:
38
+ fp = os.path.join(dirpath, f)
39
+ total_size += os.path.getsize(fp)
40
+ return total_size
41
+
42
+ def split_ext(file=None, dir="./",size=3):
43
+ size = size * 1024 * 1024
44
+ files = []
45
+ tamano_archivo = os.path.getsize(file)
46
+ if tamano_archivo < size:
47
+ files.append(file)
48
+ else:
49
+ with open(file, 'rb') as archivo_original:
50
+ parte = 1
51
+ totalparte = (tamano_archivo//size)+1
52
+ while True:
53
+ contenido_parte = archivo_original.read(size)
54
+ if not contenido_parte:
55
+ break
56
+ nombre_parte = f"{file.split('/')[-1].split('.')[0]}.7z.{str(parte).zfill(3)}"
57
+ with open(dir+"/"+nombre_parte, 'wb') as archivo_parte:
58
+ archivo_parte.write(contenido_parte)
59
+ files.append(nombre_parte)
60
+ parte += 1
61
+ os.unlink(file)
62
+ return files
63
+
64
+ def sizeof_fmt(num, suffix='B'):
65
+ for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
66
+ if abs(num) < 1024.0:
67
+ return "%3.2f%s%s" % (num, unit, suffix)
68
+ num /= 1024.0
69
+ return "%.2f%s%s" % (num, 'Yi', suffix)
70
+
71
+ if not os.path.exists("./files"):
72
+ os.mkdir("./files")
73
+
74
+ client.start(bot_token=token)
75
+
76
+ users = []
77
+ process = []
78
+ basedata = {}
79
+ cdpaths = []
80
+
81
+ @client.on(events.NewMessage())
82
+ async def mybot(event):
83
+ global basedata
84
+ global process
85
+ global cdpaths
86
+ if len(cdpaths) > 0:
87
+ cd = "/"+"/".join(cdpaths)
88
+ else:
89
+ cd = "/"
90
+ text = event.raw_text
91
+ user_id = event.message.chat.id
92
+ msg_id = event.message.id
93
+ user_name = event.message.chat.username
94
+ mode = "auto"
95
+ try:
96
+ mode = basedata[f"{user_id}_mode"]
97
+ except:
98
+ None
99
+ if len(users) == 0:
100
+ users.append(user_id)
101
+ if not user_id in users:
102
+ await event.reply("<b>¡Acceso no autorizado!</b>", parse_mode="HTML")
103
+ raise ValueError(f"({user_id}) No es un usuario autorizado")
104
+ if not os.path.exists(f"./files"):
105
+ os.mkdir(f"./files")
106
+ if not os.path.exists(f"./files_temp"):
107
+ os.mkdir(f"./files_temp")
108
+ directorio = f'./files'+cd
109
+ files = [(archivo, os.path.getmtime(os.path.join(directorio, archivo))) for archivo in os.listdir(directorio)]
110
+ file = sorted(files, key=lambda x: x, reverse=True)
111
+ files = []
112
+ for f in file:
113
+ x,y = f
114
+ files.append(x)
115
+ if "/start" == text:
116
+ basedata[f"{user_id}_username"] = user_name
117
+ await event.reply(f"<code>AUTOD • TechDev</code>", parse_mode="HTML", buttons=[[Button.inline('?', b'')]])
118
+ elif "/add " in text:
119
+ user = int(text.replace("/add", ""))
120
+ users.append(user)
121
+ await event.reply("Usuario añadido")
122
+ elif "/ban " in text:
123
+ user = int(text.replace("/ban", ""))
124
+ users.append(user)
125
+ await event.reply("Usuario borrado")
126
+ elif "/ls" in text:
127
+ msg = f"#LISTDIR #GOOD\n<code>{'/'.join(cdpaths)}</code>\n<b>LÍMITE - {sizeof_fmt(folder_size('./files'))}/100.0GiB</b>\n\n"
128
+ for f in files:
129
+ if os.path.isfile("./files"+cd+"/"+f):
130
+ msg += f" 📃 <code>{f}</code>\n"
131
+ else:
132
+ msg += f" 📁 <code>{f}</code>\n"
133
+ if len(files) == 0:
134
+ msg += "<i>No hay archivos</i>"
135
+ await event.reply(msg, parse_mode="HTML")
136
+ elif "/rm " in text:
137
+ path = text.replace("/rm ", "")
138
+ try:
139
+ if os.path.isfile("./files"+cd+"/"+path):
140
+ os.unlink("./files"+cd+"/"+path)
141
+ else:
142
+ shutil.rmtree("./files"+cd+"/"+path)
143
+ msg = "#REMOVE #GOOD\n\n<b>✓ ¡Directorio Eliminado!</b>"
144
+ except:
145
+ msg = "#REMOVE #ERROR\n\n<b>No existe el directorio</b>"
146
+ await event.reply(msg, parse_mode="HTML")
147
+ elif "/cd " in text:
148
+ path = text.replace("/cd ", "")
149
+ if not os.path.isdir("./files/"+cd+"/"+path):
150
+ cdpaths = []
151
+ msg = "#CHANGEDIR #ERROR\n\n<b>No existe el directorio</b>"
152
+ else:
153
+ cdpaths = path.split("/")
154
+ msg = "#CHANGEDIR #GOOD\n\n<b>✓ ¡Directorio abierto!</b>"
155
+ directorio = f'./files/'+"/".join(cdpaths)
156
+ files = [(archivo, os.path.getmtime(os.path.join(directorio, archivo))) for archivo in os.listdir(directorio)]
157
+ file = sorted(files, key=lambda x: x, reverse=True)
158
+ files = []
159
+ for f in file:
160
+ x,y = f
161
+ files.append(x)
162
+ msg = f"\n\n<code>{'/'.join(cdpaths)}</code>\n<b>LÍMITE - {sizeof_fmt(folder_size('./files'))}/100.0GiB</b>\n\n"
163
+ for f in files:
164
+ if os.path.isfile("./files"+cd+"/"+f):
165
+ msg += f" 📃 <code>{f}</code>\n"
166
+ else:
167
+ msg += f" 📁 <code>{f}</code>\n"
168
+ if len(files) == 0:
169
+ msg += "<i>No hay archivos</i>"
170
+ await event.reply(msg, parse_mode="HTML")
171
+ elif "/mkdir " in text:
172
+ dir = text.replace("/mkdir ", "")
173
+ os.mkdir("./files"+cd+"/"+dir)
174
+ msg = "#MAKEDIR #GOOD\n\n<b>✓ ¡DIRECTORIO CREADO!</b>"
175
+ cdpaths.append(dir)
176
+ directorio = f'./files/'+"/".join(cdpaths)
177
+ files = [(archivo, os.path.getmtime(os.path.join(directorio, archivo))) for archivo in os.listdir(directorio)]
178
+ file = sorted(files, key=lambda x: x, reverse=True)
179
+ files = []
180
+ for f in file:
181
+ x,y = f
182
+ files.append(x)
183
+ msg = f"\n\n<code>{'/'.join(cdpaths)}</code>\n<b>LÍMITE - {sizeof_fmt(folder_size('./files'))}/100.0GiB</b>\n\n"
184
+ for f in files:
185
+ if os.path.isfile("./files"+cd+"/"+f):
186
+ msg += f" 📃 <code>{f}</code>\n"
187
+ else:
188
+ msg += f" 📁 <code>{f}</code>\n"
189
+ if len(files) == 0:
190
+ msg += "<i>No hay archivos</i>"
191
+ await event.reply(msg, parse_mode="HTML")
192
+ elif event.document and user_id in users:
193
+ code = str(random.randint(100000,999999))
194
+ process.append(code)
195
+ while not code == process[0]:
196
+ await asyncio.sleep(3)
197
+ msging = "<b>PREPARANDO</b>"
198
+ msg = await event.reply(msging, parse_mode="HTML",buttons=[Button.inline("CANCELAR",b'del|'+code.encode('utf-8'))])
199
+ await msg.edit("<b>DESCARGANDO</b>", parse_mode="HTML",buttons=[Button.inline("CANCELAR",b'del|'+code.encode('utf-8'))])
200
+ basedata[code] = "down:0/0"+"|CARGANDO..."
201
+ basedata[code+"auto-act"] = True
202
+ caption = event.message.message
203
+ mime_type = str(event.media.document.mime_type)
204
+ extension = mime_type.split("/")[1]
205
+ if event.file.name:
206
+ name = event.file.name
207
+ else:
208
+ if caption:
209
+ name = str(caption).split("\n")[0]+"."+extension
210
+ else:
211
+ name = "document_"+str(time.strftime("%d_%H_%M_%S"))+"."+extension
212
+ if os.path.exists("./files/"+name):
213
+ name = name.replace(".", f"_{str(time.strftime('%d%H%M%S'))}.")
214
+ timer = Timer()
215
+ async def progress_bar(current, total):
216
+ if not code in process:
217
+ raise ValueError(f"Se detuvo el proceso {code}")
218
+ basedata[code] = "down:"+str(current)+"/"+str(total)
219
+ if basedata[code+"auto-act"]:
220
+ text1 = "<b>DESCARGANDO</b>"
221
+ bar = f"<i>{round((current/total)*100,1)}%</i> <b>[</b>"
222
+ prog = round(int(15*(current/total)),0)
223
+ deprog = 15-prog
224
+ bar += ("-"*prog)+"|"
225
+ bar += ("-"*deprog)+"<b>]</b>"
226
+ if len(process) > 1:
227
+ infopro = f"\n+{len(process)-1} procesos..."
228
+ else:
229
+ infopro = ""
230
+ if timer.can_send():
231
+ await msg.edit(f"{text1}\n\n<b>Nombre:</b> <code>{name}</code>\n<b>Progreso:</b> {bar}\n<b>Tamaño:</b> <code>{sizeof_fmt(total)}</code>\n\n{infopro}", parse_mode="HTML", buttons=[Button.inline("CANCELAR", b'del|'+code.encode("utf8"))])
232
+ with open("./files_temp/"+name, "wb") as out:
233
+ await download_file(event.client, event.document, out, progress_callback=progress_bar)
234
+ os.rename("./files_temp/"+name, "./files"+cd+"/"+name)
235
+ upmsg = await event.reply(f"#DOWNLOAD #GOOD\n\n<b>✓ ¡Proceso completado!</b>", parse_mode="HTML")
236
+ await client.delete_messages(user_id, msg.id)
237
+ basedata[code] = None
238
+ process.remove(code)
239
+ @client.on(events.CallbackQuery)
240
+ async def callback_query(event):
241
+ global basedata
242
+ global process
243
+ user_id = event.query.user_id
244
+ msg_id = event.query.msg_id
245
+ data = event.query.data.decode("utf-8")
246
+ orden = str(data).split("|")[0]
247
+ if orden == "del":
248
+ code = str(data).split("|")[1]
249
+ try:
250
+ process.remove(code)
251
+ except:
252
+ None
253
+ await client.delete_messages(user_id, msg_id)
254
+ print("CONECTADO")
255
+ client.run_until_disconnected()
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ flask-socketio>=5.3.4
2
+ eventlet>=0.33.3
3
+ gunicorn>=20.1.0
4
+ requests
5
+ bs4
6
+ flask
7
+ psutil
8
+ telethon