Spaces:
Paused
Paused
BinaryONe commited on
Commit ·
1330377
1
Parent(s): ea2f54e
Initial Commit
Browse files- DBFiles/___init__.py +7 -0
- DBFiles/database.py +78 -0
- Dockerfile +33 -0
- Tools/__init__.py +1 -0
- Tools/calculator.py +10 -0
- __init__.py +0 -0
- main.py +7 -0
- requirements.txt +4 -0
- server/__init__.py +11 -0
- server/app.py +11 -0
- server/config.py +9 -0
- server/listing.py +73 -0
DBFiles/___init__.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
from .database import PUBLICFilesDB
|
| 3 |
+
from FileStream.config import Telegram
|
| 4 |
+
|
| 5 |
+
DB_Controller = PUBLICFilesDB(Telegram.DATABASE_URL, Telegram.SESSION_NAME)
|
| 6 |
+
|
| 7 |
+
|
DBFiles/database.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import re
|
| 2 |
+
import time
|
| 3 |
+
import pymongo
|
| 4 |
+
import motor.motor_asyncio
|
| 5 |
+
from bson.objectid import ObjectId
|
| 6 |
+
from bson.errors import InvalidId
|
| 7 |
+
from bson.json_util import dumps
|
| 8 |
+
|
| 9 |
+
from pymongo.errors import PyMongoError
|
| 10 |
+
|
| 11 |
+
class PUBLICFilesDB:
|
| 12 |
+
def __init__(self, uri, database_name):
|
| 13 |
+
self._client = motor.motor_asyncio.AsyncIOMotorClient(uri)
|
| 14 |
+
self.db = self._client[database_name]
|
| 15 |
+
self.files = self.db.Public_Files
|
| 16 |
+
|
| 17 |
+
async def GetSeriesAllBy10(self, offset=None):
|
| 18 |
+
try:
|
| 19 |
+
filter = {"type": "TVSeries"} # Define the filter for movies
|
| 20 |
+
total_results = await self.files.count_documents(filter)
|
| 21 |
+
offset=int( offset if offset else 0)
|
| 22 |
+
next_offset = offset + 10
|
| 23 |
+
if next_offset >= total_results: # Changed > to >= to handle the last page correctly
|
| 24 |
+
next_offset = ''
|
| 25 |
+
cursor = self.files.find(filter) # Apply the filter
|
| 26 |
+
cursor.sort('$natural', pymongo.DESCENDING) # Use pymongo.DESCENDING
|
| 27 |
+
cursor.skip(offset).limit(10)
|
| 28 |
+
files = await cursor.to_list(length=10)
|
| 29 |
+
return files, next_offset
|
| 30 |
+
|
| 31 |
+
except PyMongoError as e:
|
| 32 |
+
print(f"MongoDB error: {e}")
|
| 33 |
+
return [], '' # Return empty list and '' on error
|
| 34 |
+
except Exception as e:
|
| 35 |
+
print(f"An unexpected error occurred: {e}")
|
| 36 |
+
return [], ''
|
| 37 |
+
|
| 38 |
+
async def GetMoviesAllBy10(self, offset=None):
|
| 39 |
+
try:
|
| 40 |
+
filter = {"type": "Movie"} # Define the filter for movies
|
| 41 |
+
total_results = await self.files.count_documents(filter)
|
| 42 |
+
offset=int( offset if offset else 0)
|
| 43 |
+
next_offset = offset + 10
|
| 44 |
+
if next_offset >= total_results: # Changed > to >= to handle the last page correctly
|
| 45 |
+
next_offset = ''
|
| 46 |
+
cursor = self.files.find(filter) # Apply the filter
|
| 47 |
+
cursor.sort('$natural', pymongo.DESCENDING) # Use pymongo.DESCENDING
|
| 48 |
+
cursor.skip(offset).limit(10)
|
| 49 |
+
files = await cursor.to_list(length=10)
|
| 50 |
+
return files, next_offset
|
| 51 |
+
|
| 52 |
+
except PyMongoError as e:
|
| 53 |
+
print(f"MongoDB error: {e}")
|
| 54 |
+
return [], '' # Return empty list and '' on error
|
| 55 |
+
except Exception as e:
|
| 56 |
+
print(f"An unexpected error occurred: {e}")
|
| 57 |
+
return [], ''
|
| 58 |
+
|
| 59 |
+
async def GetLatestAllBy10(self, offset=None):
|
| 60 |
+
try:
|
| 61 |
+
total_results = await self.files.count_documents({})
|
| 62 |
+
offset=int( offset if offset else 0)
|
| 63 |
+
next_offset = offset + 10
|
| 64 |
+
if next_offset >= total_results: # Changed > to >= to handle the last page correctly
|
| 65 |
+
next_offset = ''
|
| 66 |
+
cursor = self.files.find({}, {"_id": 1, "poster": 1, "title": 1, "release_date": 1, "description": 1, "genre": 1, "IMDB_id": 1, "type": 1, "file": 1}) # Apply the filter with projection
|
| 67 |
+
|
| 68 |
+
cursor.sort('$natural', pymongo.DESCENDING ) # Use pymongo.DESCENDING
|
| 69 |
+
cursor.skip(offset).limit(10)
|
| 70 |
+
files = await cursor.to_list(length=10)
|
| 71 |
+
return files, next_offset
|
| 72 |
+
|
| 73 |
+
except PyMongoError as e:
|
| 74 |
+
print(f"MongoDB error: {e}")
|
| 75 |
+
return [], '' # Return empty list and '' on error
|
| 76 |
+
except Exception as e:
|
| 77 |
+
print(f"An unexpected error occurred: {e}")
|
| 78 |
+
return [], ''
|
Dockerfile
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM python:3.11
|
| 2 |
+
|
| 3 |
+
# Create and use a non-root user
|
| 4 |
+
RUN useradd -ms /bin/bash admin
|
| 5 |
+
|
| 6 |
+
# Set the working directory in the container
|
| 7 |
+
WORKDIR /app
|
| 8 |
+
|
| 9 |
+
# Copy only the necessary files first for better cache utilization
|
| 10 |
+
COPY requirements.txt /app/requirements.txt
|
| 11 |
+
|
| 12 |
+
# Install system dependencies and clean up in a single RUN step to reduce layers
|
| 13 |
+
RUN apt-get update -y && apt-get upgrade -y \
|
| 14 |
+
&& apt-get install -y \
|
| 15 |
+
&& apt-get clean \
|
| 16 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 17 |
+
|
| 18 |
+
RUN pip3 install --no-cache-dir --upgrade -r requirements.txt
|
| 19 |
+
|
| 20 |
+
# Copy the rest of the application code after installing dependencies for better cache
|
| 21 |
+
COPY . /app
|
| 22 |
+
|
| 23 |
+
# Set ownership and permissions for the app directory
|
| 24 |
+
RUN chown -R admin:admin /app && chmod -R 777 /app
|
| 25 |
+
|
| 26 |
+
# Switch to the non-root user for better security
|
| 27 |
+
USER admin
|
| 28 |
+
|
| 29 |
+
# Expose the port the application will run on
|
| 30 |
+
EXPOSE 7860
|
| 31 |
+
|
| 32 |
+
# Command to run the application
|
| 33 |
+
CMD ["python", "-u", "-m", "/app/main.py"]
|
Tools/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
from .calculator import size_calculator
|
Tools/calculator.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
def size_calculator(size):
|
| 2 |
+
if not size:
|
| 3 |
+
return ""
|
| 4 |
+
power = 2**10
|
| 5 |
+
n = 0
|
| 6 |
+
Dic_powerN = {0: ' ', 1: 'Ki', 2: 'Mi', 3: 'Gi', 4: 'Ti'}
|
| 7 |
+
while size > power:
|
| 8 |
+
size /= power
|
| 9 |
+
n += 1
|
| 10 |
+
return str(round(size, 2)) + " " + Dic_powerN[n] + 'B'
|
__init__.py
ADDED
|
File without changes
|
main.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import FastAPI
|
| 2 |
+
|
| 3 |
+
from server import app
|
| 4 |
+
|
| 5 |
+
if __name__ == "__main__":
|
| 6 |
+
import uvicorn
|
| 7 |
+
uvicorn.run(app, host="0.0.0.0", port=7860)
|
requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
fastapi
|
| 2 |
+
uvicorn
|
| 3 |
+
motor
|
| 4 |
+
pymongo
|
server/__init__.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import FastAPI
|
| 2 |
+
from .listing import router as listing_router
|
| 3 |
+
|
| 4 |
+
app = FastAPI()
|
| 5 |
+
|
| 6 |
+
@app.get("/")
|
| 7 |
+
def read_root():
|
| 8 |
+
return {"message": "Welcome to the API"}
|
| 9 |
+
|
| 10 |
+
# Include the router from Listing.py
|
| 11 |
+
app.include_router(listing_router)
|
server/app.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import FastAPI
|
| 2 |
+
from DBFiles.Listing import router as listing_router
|
| 3 |
+
|
| 4 |
+
app = FastAPI()
|
| 5 |
+
|
| 6 |
+
@app.get("/")
|
| 7 |
+
def read_root():
|
| 8 |
+
return {"message": "Welcome to the API"}
|
| 9 |
+
|
| 10 |
+
# Include the router from Listing.py
|
| 11 |
+
app.include_router(listing_router)
|
server/config.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from os import environ as env
|
| 2 |
+
from dotenv import load_dotenv
|
| 3 |
+
|
| 4 |
+
load_dotenv()
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class Server:
|
| 8 |
+
MONGO_DB_URI=str(env.get('DATABASE_URL','mongodb+srv://privateone:6GtbFfj0LK69TQDO@teledb.nxjviws.mongodb.net/?retryWrites=true&w=majority&appName=TeleDB'))
|
| 9 |
+
DB_NAME=str(env.get('DB_NAME', "FileStream"))
|
server/listing.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import APIRouter, Query
|
| 2 |
+
from fastapi.responses import JSONResponse
|
| 3 |
+
from DBFiles.database import PUBLICFilesDB
|
| 4 |
+
from Tools import size_calculator
|
| 5 |
+
from .config import Server
|
| 6 |
+
#from config import
|
| 7 |
+
|
| 8 |
+
router = APIRouter()
|
| 9 |
+
db = PUBLICFilesDB(Server.MONGO_DB_URI, Server.DB_NAME) # Replace with actual URI and database name
|
| 10 |
+
|
| 11 |
+
@router.get("/movies")
|
| 12 |
+
async def all_movies(offset: int = Query(0)):
|
| 13 |
+
results = []
|
| 14 |
+
files, next_offset = await db.GetMoviesAllBy10(offset=offset)
|
| 15 |
+
for file in files:
|
| 16 |
+
results.append({
|
| 17 |
+
"id": f"{file['_id']}",
|
| 18 |
+
"poster": file['poster'],
|
| 19 |
+
"title": file['title'],
|
| 20 |
+
"release_date": file['release_date'],
|
| 21 |
+
"genre": file['genre'],
|
| 22 |
+
"imdb_id": file['IMDB_id'],
|
| 23 |
+
"type": file['type'],
|
| 24 |
+
"file_name": file['file']['file_name'],
|
| 25 |
+
"document_file_id": file['file']['file_id'],
|
| 26 |
+
"caption": file['file']['file_name'] or "",
|
| 27 |
+
"size":size_calculator(file['file']['file_size']),
|
| 28 |
+
"video_type": file['file']['mime_type']
|
| 29 |
+
})
|
| 30 |
+
return JSONResponse(content={"count": len(results), "results": results, "next_offset": next_offset})
|
| 31 |
+
|
| 32 |
+
@router.get("/series")
|
| 33 |
+
async def all_series(offset: int = Query(0)):
|
| 34 |
+
results = []
|
| 35 |
+
files, next_offset = await db.GetSeriesAllBy10(offset=offset)
|
| 36 |
+
for file in files:
|
| 37 |
+
results.append({
|
| 38 |
+
"id": f"{file['_id']}",
|
| 39 |
+
"poster": file['poster'],
|
| 40 |
+
"title": file['title'],
|
| 41 |
+
"release_date": file['release_date'],
|
| 42 |
+
"genre": file['genre'],
|
| 43 |
+
"imdb_id": file['IMDB_id'],
|
| 44 |
+
"type": file['type'],
|
| 45 |
+
"file_name": file['file']['file_name'],
|
| 46 |
+
"document_file_id": file['file']['file_id'],
|
| 47 |
+
"caption": file['file']['file_name'] or "",
|
| 48 |
+
"size":size_calculator(file['file']['file_size']),
|
| 49 |
+
"video_type": file['file']['mime_type']
|
| 50 |
+
})
|
| 51 |
+
return JSONResponse(content={"count": len(results), "results": results, "next_offset": next_offset})
|
| 52 |
+
|
| 53 |
+
@router.get("/latest")
|
| 54 |
+
async def latest(offset: int = Query(0)):
|
| 55 |
+
results = []
|
| 56 |
+
files, next_offset = await db.GetLatestAllBy10(offset=offset)
|
| 57 |
+
for file in files:
|
| 58 |
+
results.append({
|
| 59 |
+
"id": f"{file['_id']}",
|
| 60 |
+
"poster": file['poster'],
|
| 61 |
+
"title": file['title'],
|
| 62 |
+
"release_date": file['release_date'],
|
| 63 |
+
"description": file['description'],
|
| 64 |
+
"genre": file['genre'],
|
| 65 |
+
"imdb_id": file['IMDB_id'],
|
| 66 |
+
"type": file['type'],
|
| 67 |
+
"file_name": file['file']['file_name'],
|
| 68 |
+
"document_file_id": file['file']['file_id'],
|
| 69 |
+
"caption": file['file']['file_name'] or "",
|
| 70 |
+
"size":size_calculator(file['file']['file_size']),
|
| 71 |
+
"video_type": file['file']['mime_type']
|
| 72 |
+
})
|
| 73 |
+
return JSONResponse(content={"count": len(results), "results": results, "next_offset": next_offset})
|