This repository has been archived by the owner on Feb 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
26f9cdb
commit 729a8f7
Showing
10 changed files
with
940 additions
and
283 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
language: python | ||
matrix: | ||
include: | ||
- python: 3.4 | ||
dist: trusty | ||
sudo: false | ||
- python: 3.5 | ||
dist: trusty | ||
sudo: false | ||
- python: 3.5-dev | ||
dist: trusty | ||
sudo: false | ||
- python: 3.6 | ||
dist: trusty | ||
sudo: false | ||
- python: 3.6-dev | ||
dist: trusty | ||
sudo: false | ||
- python: 3.7 | ||
dist: xenial | ||
sudo: true | ||
install: | ||
- python setup.py -q install |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Changelog | ||
|
||
All notable changes to this project will be documented in this file. | ||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
||
## [1.0.0] - 2023-04-02 | ||
|
||
Initial Release. | ||
|
||
[1.0.0]: https://github.com/hyugogirubato/UptoboxSDK/releases/tag/v1.0.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,99 @@ | ||
# UptoboxSDK | ||
<p align="center"> | ||
<img src="docs/images/uptobox_icon_24.png"> <a href="https://github.com/hyugogirubato/UptoboxSDK">UptoboxSDK</a> | ||
<br/> | ||
<sup><em>Python SDK to interact with Uptobox API.</em></sup> | ||
</p> | ||
|
||
<p align="center"> | ||
<a href="https://pypi.org/project/UptoboxSDK"> | ||
<img src="https://img.shields.io/badge/python-3.7%2B-informational" alt="Python version"> | ||
</a> | ||
<a href="https://deepsource.io/gh/hyugogirubato/UptoboxSDK"> | ||
<img src="https://deepsource.io/gh/hyugogirubato/UptoboxSDK.svg/?label=active+issues" alt="DeepSource"> | ||
</a> | ||
</p> | ||
|
||
## Features | ||
|
||
- 🛡️ Methode de connexion multiple | ||
- 📦 Direct use of the service, without restrictions | ||
- 🛠️ Easy implementation in other programs | ||
- 🧩 Plug-and-play installation via setup.py | ||
- ❤️ Forever FOSS! | ||
|
||
## Installation | ||
|
||
*Note: Requires [Python] 3.7.0 or newer with PIP installed.* | ||
|
||
```shell | ||
$ python setup.py install | ||
``` | ||
|
||
You now have the `UptoboxSDK` package installed and a `UptoboxSDK` executable is now available. | ||
|
||
|
||
### From Source Code | ||
|
||
The following steps are instructions on download, preparing, and running the code under a Venv environment. | ||
You can skip steps 3-5 with a simple `pip install .` call instead, but you miss out on a wide array of benefits. | ||
|
||
1. `git clone https://github.com/hyugogirubato/UptoboxSDK` | ||
2. `cd pydvdfab` | ||
3. `python -m venv env` | ||
4. `source env/bin/activate` | ||
5. `python setup.py install` | ||
|
||
As seen in Step 5, running the `UptoboxSDK` executable is somewhat different to a normal PIP installation. | ||
See [Venv's Docs] on various ways of making calls under the virtual-environment. | ||
|
||
[Python]: <https://python.org> | ||
[Venv's]: <https://docs.python.org/3/tutorial/venv.html> | ||
[Venv's Docs]: <https://docs.python.org/3/library/venv.html> | ||
|
||
## Usage | ||
|
||
The following is a minimal example of using UptoboxSDK in a script. It gets the download link of a | ||
file. There's various stuff not shown in this specific example like: | ||
|
||
- Searching for a file | ||
- Uploading a file | ||
- User information | ||
- and much more! | ||
|
||
Just take a look around the Client code to see what stuff does. Everything is documented quite well. | ||
There's also various functions in `utils.py` that showcases a lot of features. | ||
|
||
```py | ||
from UptoboxSDK.client import Client | ||
|
||
# Demo: https://uptobox.com/5w4rff6r17oz | ||
if __name__ == "__main__": | ||
# create client | ||
client = Client() | ||
|
||
# login | ||
data = client.login(token="USER_TOKEN") | ||
|
||
# get cached keys | ||
file_code = "5w4rff6r17oz" | ||
|
||
# get file info | ||
info = client.get_file_info(code=file_code) | ||
|
||
# get file download link | ||
link = client.get_link(code=file_code) | ||
|
||
print("I: Subscription: {}".format("PREMIUM" if data["premium"] == 1 else "FREE")) | ||
print("I: Name: {}".format(info["file_name"])) | ||
print("I: Size: {}".format(info["file_size"])) | ||
print("I: Link: {}".format(link)) | ||
``` | ||
|
||
## Credit | ||
|
||
- Uptobox Icon © Uptobox. | ||
- The great community for their shared research and knowledge about Uptobox and its API. | ||
|
||
## License | ||
|
||
[GNU General Public License, Version 3.0](LICENSE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from .client import Client | ||
|
||
__version__ = "1.0.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import json | ||
from pathlib import Path | ||
|
||
import requests | ||
from bs4 import BeautifulSoup | ||
from requests_toolbelt import MultipartEncoder | ||
|
||
from UptoboxSDK.exceptions import PremiumRequired | ||
from UptoboxSDK.utils import get_size, get_code, get_input_bool, countdown | ||
|
||
|
||
class Client: | ||
HEADERS = { | ||
"accept": "*/*", | ||
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.63" | ||
} | ||
|
||
def __init__(self): | ||
self._token = None | ||
self._session = requests.Session() | ||
self._web = "https://uptobox.com" | ||
self._api = f"{self._web}/api" | ||
|
||
def _request(self, **kwargs) -> dict: | ||
params = kwargs.get("params", {}) | ||
params["token"] = self._token | ||
|
||
r = self._session.request( | ||
method=kwargs.get("method", "GET").upper(), | ||
url=kwargs.get("url", self._api), | ||
params=params, | ||
data=kwargs.get("data", None), | ||
headers=kwargs.get("headers", Client.HEADERS)) | ||
content = r.json() | ||
code = content.get("statusCode", 1) | ||
if not r.ok or (code != 0 and code != 39): | ||
raise Exception(r.text) | ||
return content.get("data", None) or content | ||
|
||
def login(self, **kwargs) -> dict: | ||
login = kwargs.get("login", None) | ||
password = kwargs.get("password", None) | ||
token = kwargs.get("token", None) | ||
xfss = kwargs.get("xfss", None) | ||
if login is not None and password is not None: | ||
r = self._session.request( | ||
method="POST", | ||
url=f"{self._web}/login", | ||
data={"login": login, "password": password} | ||
) | ||
if "My account" not in r.text: | ||
raise Exception("Invalid password/login") | ||
elif token is not None: | ||
self._token = token | ||
elif xfss is not None: | ||
self._session.cookies.set("xfss", xfss) | ||
else: | ||
raise Exception("Invalid login credentials") | ||
|
||
if token is None: | ||
r = self._session.request(method="GET", url=f"{self._web}/my_account") | ||
soup = BeautifulSoup(r.content, "html.parser") | ||
content_wrapper_div = soup.find("div", {"id": "content-wrapper"}) | ||
data_ui = json.loads(content_wrapper_div.select_one('.width-content')['data-ui']) | ||
self._token = data_ui["token"] | ||
return self.get_user() | ||
|
||
def get_user(self) -> dict: | ||
return self._request(url=f"{self._api}/user/me") | ||
|
||
def get_file_info(self, code: str) -> dict: | ||
data = self._request(url=f"{self._api}/link/info", params={"fileCodes": get_code(code)})["list"][0] | ||
data["file_size"] = get_size(data["file_size"]) | ||
return data | ||
|
||
def file_search(self, path: str, search: str, limit: int = 10) -> dict: | ||
return self._request(url=f"{self._api}/user/files", params={ | ||
"path": path, | ||
"limit": limit, | ||
"searchField": "file_name", | ||
"search": search | ||
}) | ||
|
||
def get_link(self, code: str): | ||
code = get_code(code) | ||
data = self._request(url=f"{self._api}/link", params={"file_code": code}) | ||
link = data.get("dlLink", None) | ||
if link is None: | ||
waiting_time = data["waiting"] + 1 | ||
waiting_token = data["waitingToken"] | ||
print(f"W: You have to wait {waiting_time} seconds to generate a new link") | ||
if not get_input_bool(message="Do you want to wait?", default=True): | ||
raise PremiumRequired("Free account, you have to wait before you can generate a new link.") | ||
countdown(waiting_time) | ||
link = self._request(url=f"{self._api}/link", params={"file_code": code, "waiting_token": waiting_token})["dlLink"] | ||
return link | ||
|
||
def upload(self, file: Path) -> dict: | ||
multi = MultipartEncoder(fields={"files": (file.name, open(file, "rb"))}) | ||
headers = Client.HEADERS.copy() | ||
headers["content-type"] = multi.content_type | ||
return self._request( | ||
method="POST", | ||
url=self._request(url=f"{self._api}/upload")["uploadLink"], | ||
data=multi, | ||
headers=headers | ||
)["files"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
class UptoboxSDK(Exception): | ||
"""Exceptions used by UptoboxSDK.""" | ||
|
||
|
||
class InvalidFileCode(UptoboxSDK): | ||
"""The file code in the url or passed as a parameter is incorrect.""" | ||
|
||
|
||
class PremiumRequired(UptoboxSDK): | ||
"""Request file requires premium account.""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import math | ||
import re | ||
import time | ||
|
||
from UptoboxSDK.exceptions import InvalidFileCode | ||
|
||
|
||
def get_size(bytes_size: int) -> str: | ||
if bytes_size == 0: | ||
return "0B" | ||
name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") | ||
i = int(math.floor(math.log(bytes_size, 1024))) | ||
p = math.pow(1024, i) | ||
s = round(bytes_size / p, 2) | ||
return f"{s} {name[i]}" | ||
|
||
|
||
def get_code(code: str) -> str: | ||
if code.startswith("https://uptobox.com/") or code.startswith("https://uptostream.com/"): | ||
code = re.search(r"\.com/(\w+)", code).group(1) | ||
if code is None or len(code) != 12: | ||
raise InvalidFileCode("The file code format is invalid") | ||
return code | ||
|
||
|
||
def get_input_bool(message: str, default=True) -> bool: | ||
answer = str(input(f"{message} [{default}]: ")).lower() | ||
if answer == "": | ||
return default | ||
return answer in ["y", "yes", "t", "true", "1"] | ||
|
||
|
||
def countdown(wait_time: int) -> None: | ||
while wait_time: | ||
minutes, seconds = divmod(wait_time, 60) | ||
timer = f"{minutes}:{seconds}" | ||
print(timer, end="\r") | ||
time.sleep(1) | ||
wait_time -= 1 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
"""Setup module""" | ||
|
||
from setuptools import setup | ||
|
||
with open("README.md", mode="r", encoding="utf-8") as f: | ||
LONG_DESCRIPTION = f.read() | ||
|
||
setup( | ||
name="UptoboxSDK", | ||
version="1.0.0", | ||
description="Python SDK to interact with Uptobox API.", | ||
long_description=LONG_DESCRIPTION, | ||
long_description_content_type="text/markdown", | ||
url="https://github.com/hyugogirubato/UptoboxSDK", | ||
author="hyugogirubato", | ||
author_email="hyugogirubato@gmail.com", | ||
license="GNU GPLv3", | ||
packages=["UptoboxSDK"], | ||
install_requires=["requests", "requests_toolbelt", "beautifulsoup4"], | ||
classifiers=[ | ||
"Environment :: Console", | ||
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)", | ||
"Operating System :: OS Independent", | ||
"Programming Language :: Python :: 3.4", | ||
"Programming Language :: Python :: 3.5", | ||
"Programming Language :: Python :: 3.6", | ||
"Programming Language :: Python :: 3.7", | ||
"Topic :: Utilities" | ||
] | ||
) |