Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Initial Release.
Browse files Browse the repository at this point in the history
  • Loading branch information
hyugogirubato committed Apr 2, 2023
1 parent 26f9cdb commit 729a8f7
Show file tree
Hide file tree
Showing 10 changed files with 940 additions and 283 deletions.
23 changes: 23 additions & 0 deletions .travis.yml
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
12 changes: 12 additions & 0 deletions CHANGELOG.md
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
899 changes: 617 additions & 282 deletions LICENSE

Large diffs are not rendered by default.

100 changes: 99 additions & 1 deletion README.md
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 &copy; Uptobox.
- The great community for their shared research and knowledge about Uptobox and its API.

## License

[GNU General Public License, Version 3.0](LICENSE)
3 changes: 3 additions & 0 deletions UptoboxSDK/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .client import Client

__version__ = "1.0.0"
107 changes: 107 additions & 0 deletions UptoboxSDK/client.py
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"]
10 changes: 10 additions & 0 deletions UptoboxSDK/exceptions.py
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."""
39 changes: 39 additions & 0 deletions UptoboxSDK/utils.py
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
Binary file added docs/images/uptobox_icon_24.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions setup.py
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"
]
)

0 comments on commit 729a8f7

Please sign in to comment.