Skip to content

Commit

Permalink
Merge pull request #1 from Pasanlaksitha/dev
Browse files Browse the repository at this point in the history
Merge dev to main with New Release (CLI and GUI)
  • Loading branch information
Pasanlaksitha authored Feb 2, 2024
2 parents dd064fe + 5aa9390 commit c639f23
Show file tree
Hide file tree
Showing 12 changed files with 764 additions and 113 deletions.
101 changes: 99 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,104 @@
*.ini
log.txt
speed.txt
time_log.txt
*.json
main-v2.py
/sample
/sample

*.log
torrents
downloads

### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

# AWS User-specific
.idea/**/aws.xml

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr

# CMake
cmake-build-*/

# Mongo Explorer plugin
.idea/**/mongoSettings.xml

# File-based project format
*.iws

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# SonarLint plugin
.idea/sonarlint/

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Editor-based Rest Client
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

### VirtualEnv template
# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
.Python
[Bb]in
[Ii]nclude
[Ll]ib
[Ll]ib64
[Ll]ocal
[Ss]cripts
pyvenv.cfg
.venv
pip-selfcheck.json

62 changes: 53 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# **Seedr-Auto-Downloader - _AutoSeedr_**
# **Seedr Torrent Auto Downloader - _AutoSeedr_**

---

Expand Down Expand Up @@ -33,7 +33,7 @@ Seedr helps users avoid ISP throttling by downloading torrents to its servers in
**Server Locations and Network Speed:**
Seedr's servers may be located in data centers with high-speed internet connections. The proximity and quality of these servers can contribute to faster download speeds compared to using a local torrent client.

**Parallel Downloading:** Seedr may employ parallel downloading techniques, enabling the client to simultaneously download different parts of a file. This can optimize download speeds, especially for larger files.
**Parallel Downloading:** Seedr may employ parallel downloading techniques, enabling the client to download different parts of a file simultaneously. This can optimize download speeds, especially for larger files.

**Seedr's CDN (Content Delivery Network):**
Seedr may use a CDN to distribute content efficiently. CDNs cache content on multiple servers across different locations, reducing latency and improving download speeds for users accessing the same content from various locations.
Expand All @@ -56,21 +56,62 @@ Seedr uses encrypted HTTPS connections for data transfer. While encryption adds



### Getting Started:
### Getting Started `main.py`:

+ Install Python: Ensure you have Python 3.x installed on your system.
+ Install Dependencies:
+ Install Dependencies
```
pip install -r requirements.txt
```
+ Create a Seedr Account: Sign up for a Seedr account at https://www.seedr.cc/.

+ Enter your seedr credentials to cred.ini file in the repository
+ Configure Settings: in first when program execute it will ask for your seedr username, password, Download folder path, from 2nd execute it will automattically download all the torrents located in `torrent` folder

+ Run the Script:
```
python main.py
```
+ After input your Seedr Account credentials and App Settings run `main.py` file again

### Getting Started `cli.py`:
you should run and setup config.ini file before run this script
+ Run the Script for help:
```
python cli.py -h
```
+ Example Commands:
```
usage: cli.py [-h] [-C] [-L] [-f CONFIG_FILE] [-e EMAIL] [-p PASSWORD] [-td TORRENT_DIRECTORY]
[-dd DOWNLOAD_DIRECTORY] [-cs CHUNK_SIZE] [-ll {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-lf LOG_FILE]
AutoSeedr CLI
optional arguments:
-h, --help show this help message and exit
-C, --create-config Create a new config file
-L, --load-config Load an existing config file
Configuration Options:
-f CONFIG_FILE, --config-file CONFIG_FILE
INI file path for configuration (default: config.ini)
-e EMAIL, --email EMAIL
Seedr account email
-p PASSWORD, --password PASSWORD
Seedr account password
-td TORRENT_DIRECTORY, --torrent-directory TORRENT_DIRECTORY
Directory containing torrent files (default: torrents)
-dd DOWNLOAD_DIRECTORY, --download-directory DOWNLOAD_DIRECTORY
Directory to store downloaded files (default: downloads)
-cs CHUNK_SIZE, --chunk-size CHUNK_SIZE
Chunk size for downloading files in kilobytes (default: 1024)
Logging Options:
-ll {DEBUG,INFO,WARNING,ERROR,CRITICAL}, --log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
Logging level (default: ERROR)
-lf LOG_FILE, --log-file LOG_FILE
Log file path (default: auto_seedr_cli.log)
```

### Usage:

Expand All @@ -83,13 +124,16 @@ Feel free to contribute to the project by reporting issues, suggesting improveme
I hope this helps! Let me know if you have any other questions.

## TODO
- [x] Cli.py Command line interface with more features.
- [ ] add a function to check if the file is already downloaded
- [ ] Multiple torrent downloads from multiple seedr accounts to use maximum bandwidth from ISP and avoid limits of seedr server bandwidth
- [ ] add argument parser using argparse (fastdownload, progressbar download,)
- [ ] few bugs while release 'independent .ini file
- [ ] Multiple torrent download from multiple seedr accounts to use maximum bandwidth from isp and avoid limits of seedr server bandwidth
- [x] add argument parser using argparse (fastdownload, progressbar download)
- [x] few bugs while release 'indipendent .ini file
- [ ] GUI interface and compiled exe file for windows users

[Send Email: [email protected]](mailto:[email protected])


## License

This project is licensed under the [MIT License](./LICENSE).
This project is licensed under the [MIT License](./LICENSE).
2 changes: 2 additions & 0 deletions auto_seedr/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from auto_seedr.client import AutoSeedrClient
from auto_seedr.utils import logging, setup_config, timeit
141 changes: 141 additions & 0 deletions auto_seedr/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
from os import makedirs, listdir
from os.path import join, exists
from time import sleep

import requests
from seedr_client import SeedrHandler
from tqdm import tqdm

from auto_seedr.exceptions import FolderNotReadyError, FolderNotFoundError


class AutoSeedrClient:
def __init__(self, email, password, torrent_directory: str = 'torrents', download_directory: str = 'downloads',
chunk_size: str = '1024', time_out: int = 100):
self.torrent_folder = torrent_directory
self.download_folder = download_directory
self.chunk_size = chunk_size
self.time_out = time_out

self.__seedr = SeedrHandler(email=email, password=password)

self._create_directories()

def _create_directories(self) -> None:
"""
Create the required directories for the torrent and download operations.
:return: None
"""
for directory in [self.torrent_folder, self.download_folder]:
if not exists(directory):
makedirs(directory)

def is_folder_ok(self, folder_name, folder_id=None):
"""
Checks if the specified Seedr folder is ready for use.
:param folder_name: Name of the Seedr folder.
:param folder_id: ID of the Seedr folder.
:return: Folder ID if the folder is ready, otherwise raises an exception.
"""

def get_folder_id(_folder_name):
data = self.__seedr.get_drive()
for _folder in data['folders']:
if _folder['folder_name'] == _folder_name:
return _folder['folder_id']
return None

if not folder_id:
folder_id = get_folder_id(folder_name)

count = 0
while count <= self.time_out:
try:
if self.__seedr.get_folder(folder_id):
return folder_id
except LookupError:
folder_id = get_folder_id(folder_name)
sleep(1)
count += 1

raise FolderNotReadyError(folder_name)

def upload_torrent(self, filename):
"""
Uploads a torrent file to Seedr.
:param filename: Name of the torrent file.
:return: Tuple containing the uploaded file's name and the folder ID.
"""
progression_data = self.__seedr.add_torrent(torrent=join(self.torrent_folder, filename))
file_name = progression_data.get('file_name')

count = 0
while count <= self.time_out:
if self.__seedr.get_drive()['torrents']:
return file_name, self.is_folder_ok(file_name)
count += 1
sleep(1)
raise FolderNotFoundError(file_name)

def download_torrent(self, folder_id, fast_download: bool = False):
"""
Downloads files from the specified Seedr folder.
:param folder_id: ID of the Seedr folder.
:param fast_download: If True, uses fast download; otherwise, uses tqdm for progress.
:return: None
"""

def download_file(url, path, file):
print(f"\033[92m Downloading {file} to {path} \033[0m")
if not exists(path):
makedirs(path)

with requests.get(url, stream=True) as r:
r.raise_for_status()
if fast_download:
with open(join(path, file), 'wb') as f:
for chunk in r.iter_content(chunk_size=1024):
f.write(chunk)
else:
total_size = int(r.headers.get('Content-Length', 0))
with open(join(path, file), 'wb') as file_stream, tqdm(total=total_size, unit='B',
unit_scale=True) as pbar:
for chunk in r.iter_content(chunk_size=int(self.chunk_size)):
file_stream.write(chunk)
pbar.update(len(chunk))

file_to_download = []
folders_to_look = [folder_id]
for _folder in folders_to_look:
_data = self.__seedr.get_folder(_folder)
file_to_download += _data["files"]
folders_to_look += [fol["folder_id"] for fol in _data["folders"]]

for _file in file_to_download:
download_file(self.__seedr.get_file(_file.get('folder_file_id'))['download_url'],
join(self.download_folder, _file.get('folder_path')), _file.get('file_name'))

def delete_folder(self, folder_id):
"""
Deletes the specified Seedr folder.
:param folder_id: ID of the parent folder containing the folder to be deleted.
:return: None
"""
self.__seedr.delete_folder(folder_id)

def directory_download(self):
"""
Uploads, downloads, and deletes torrents from the specified directory.
:return: None
"""
file_list = listdir(self.torrent_folder)
for i in file_list:
_, folder_id = self.upload_torrent(i)
self.download_torrent(folder_id)
self.delete_folder(folder_id)
Loading

0 comments on commit c639f23

Please sign in to comment.