Skip to content

Commit

Permalink
Merge pull request #40 from 31December99/0.x.x
Browse files Browse the repository at this point in the history
Igdb; hide the optional configuration fields message
  • Loading branch information
31December99 authored Sep 22, 2024
2 parents 12ddf99 + 6e4e24c commit 22de330
Show file tree
Hide file tree
Showing 16 changed files with 300 additions and 73 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,23 @@ If you have not installed ffmpeg install it:
- Windows : unzip https://www.ffmpeg.org/download.html and add its folder to
PATH environment user variable

### Bot Installation
## Bot Installation

1. Download the updater (zip) [Download autoupdate.py](https://gist.github.com/31December99/8e51466feb9df1606fd4199141ac54bb)
2. run python3 autoupdate.py
3. run pip install -r requirements.txt
4. Set up the configuration .env file(s) service and itt ( rename .back in .env)
4. START the bot in order to create the service.env file
5. **Complete the service.env file.
The fields marked as optional are not required and are not essential for uploading media to the tracker**
## ! Note regarding the service.env file !
The service.env file is located in the home directory on Linux
or under the AppData folder on Windows

### Update Bot
python3 autoupdate.py

pip install -r requirements.txt

___
### Configuration

Expand Down
1 change: 1 addition & 0 deletions common/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def __init__(self):
parser.add_argument("-f", "--folder", type=str, help="Upload single folder")
parser.add_argument("-pw", "--pw", action="store_true", help="")
parser.add_argument("-ftp", "--ftp", action="store_true", help="")
parser.add_argument("-game", "--game", action="store_true", help="")

parser.add_argument(
"-t", "--tracker", type=str, default="itt", help="Tracker Name"
Expand Down
91 changes: 56 additions & 35 deletions common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,14 @@ def create_default_env_file(path):
ITT_URL=https://itatorrents.xyz
ITT_APIKEY=
# EXTERNAL SERVICE
TMDB_APIKEY=
IMGBB_KEY=
FREE_IMAGE_KEY=
PW_API_KEY=
PW_URL=http://localhost:9696/api/v1
FTPX_USER=
FTPX_PASS=
FTPX_IP=
FTPX_PORT=
# TORRENT CLIENT
QBIT_USER=
QBIT_PASS=
QBIT_URL=http://localhost:8080
QBIT_PORT=
QBIT_URL=http://localhost
QBIT_PORT=8080
############################################## USER PREFERENCES ##############################################
Expand All @@ -52,14 +43,30 @@ def create_default_env_file(path):
# Discard videos whose size deviates by more than the specified percentage (size_th) from the video in tracker
SIZE_TH=100
##############################################################################################################
# FTPx local path for the download
FTPX_LOCAL_PATH=
# FTP folder. Read from this folder when connecting to the server. Default = "."
FTPX_ROOT=
################ OPTIONAL #############
# PW
PW_API_KEY=
PW_URL=http://localhost:9696/api/v1
# FTPX
FTPX_USER=
FTPX_PASS=
FTPX_IP=
FTPX_PORT=2121
FTPX_LOCAL_PATH=
FTPX_ROOT=
FTPX_KEEP_ALIVE=False
# IGDB
IGDB_CLIENT_ID=
IGDB_ACCESS_TK=
"""
with open(path, "w") as f:
f.write(default_content.strip())
Expand Down Expand Up @@ -107,6 +114,8 @@ class Config(BaseSettings):
FTPX_PASS: str | None = Field(default=None, env="FTPX_PASS")
FTPX_IP: str | None = Field(default=None, env="FTPX_IP")
FTPX_PORT: str | None = Field(default="2121", env="FTPX_PORT")
IGDB_CLIENT_ID: str | None = Field(default=None, env="IGDB_CLIENT_ID")
IGDB_ACCESS_TK: str | None = Field(default=None, env="IGDB_ACCESS_TK")

# TORRENT CLIENT
QBIT_USER: str | None = Field(default=None, env="QBIT_USER")
Expand Down Expand Up @@ -157,10 +166,16 @@ def validate_qbit_url(cls, value):

@field_validator("PW_URL")
def validate_pw_url(cls, value):
if not value:
custom_console.bot_question_log("[Optional] No PW_URL provided\n")
# if not value:
# custom_console.bot_question_log("[Optional] No PW_URL provided\n")
return cls.validate_url(value, cls.__fields__["PW_URL"].default)

@field_validator("PW_API_KEY")
def validate_pw_apikey(cls, value):
# if not value:
# custom_console.bot_question_log("[Optional] No PW_API_KEY provided\n")
return value

@field_validator("TMDB_APIKEY")
def validate_tmdb_apikey(cls, value):
if not value:
Expand All @@ -179,12 +194,6 @@ def validate_freeimage_apikey(cls, value):
custom_console.bot_error_log("No FREE IMAGE API_KEY provided")
return value

@field_validator("PW_API_KEY")
def validate_pw_apikey(cls, value):
if not value:
custom_console.bot_question_log("[Optional] No PW_API_KEY provided\n")
return value

@field_validator("QBIT_USER")
def validate_qbit_user(cls, value):
if not value:
Expand Down Expand Up @@ -242,38 +251,50 @@ def validate_size_th(cls, value):

@field_validator("FTPX_USER")
def validate_ftpx_user(cls, value):
if not value:
custom_console.bot_question_log("[Optional] No FTPX_USER provided\n")
# if not value:
# custom_console.bot_question_log("[Optional] No FTPX_USER provided\n")
return value

@field_validator("FTPX_PASS")
def validate_ftpx_pass(cls, value):
if not value:
custom_console.bot_question_log("[Optional] No FTPX_PASS provided\n")
# if not value:
# custom_console.bot_question_log("[Optional] No FTPX_PASS provided\n")
return value

@field_validator("FTPX_IP")
def validate_ftpx_ip(cls, value):
if not value:
custom_console.bot_question_log("[Optional] No FTPX_IP provided\n")
# if not value:
# custom_console.bot_question_log("[Optional] No FTPX_IP provided\n")
return value

@field_validator("FTPX_PORT")
def validate_ftpx_port(cls, value):
if not value:
custom_console.bot_question_log("[Optional] No FTPX_PORT provided\n")
# if not value:
# custom_console.bot_question_log("[Optional] No FTPX_PORT provided\n")
return value

@field_validator("FTPX_LOCAL_PATH")
def validate_ftpx_local_path(cls, value):
if not value:
custom_console.bot_question_log("[Optional] No FTPX_LOCAL_PATH provided\n")
# if not value:
# custom_console.bot_question_log("[Optional] No FTPX_LOCAL_PATH provided\n")
return value

@field_validator("FTPX_ROOT")
def validate_ftpx_root(cls, value):
if not value:
custom_console.bot_question_log("[Optional] No FTPX_ROOT folder provided\n")
# if not value:
# custom_console.bot_question_log("[Optional] No FTPX_ROOT folder provided\n")
return value

@field_validator("IGDB_CLIENT_ID")
def validate_igdb_client_id(cls, value):
# if not value:
# custom_console.bot_question_log("[Optional] No IGDB_CLIENT_ID provided\n")
return value

@field_validator("IGDB_ACCESS_TK")
def validate_igdb_access_tk(cls, value):
# if not value:
# custom_console.bot_question_log("[Optional] No IGDB_ACCESS_TK provided\n")
return value


Expand Down
21 changes: 15 additions & 6 deletions common/external_services/Pw/core/pw_api.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-

from common.config import config
from common.external_services.sessions.agents import Agent
from common.external_services.sessions.session import MyHttp
from common.external_services.Pw.core.models.indexers import Indexer
from common.external_services.Pw.core.models.search import Search
from common.external_services.Pw.core.models.torrent_client_config import (
TorrentClientConfig,
)
from common.external_services.Pw.core.models.indexers import Indexer
from common.external_services.Pw.core.models.search import Search
from common.external_services.sessions.session import MyHttp
from common.external_services.sessions.agents import Agent
from common.custom_console import custom_console
from common.config import config


class PwAPI(MyHttp):
Expand All @@ -27,6 +28,14 @@ def __init__(self):
self.api_key = config.PW_API_KEY
self.dataclass = {f"{self.base_url}/indexer": Indexer}

if not config.PW_URL:
custom_console.bot_question_log("No PW_URL provided\n")
exit(1) # todo: classmathod

if not config.PW_API_KEY:
custom_console.bot_question_log("No PW_API_KEY provided\n")
exit(1) # todo: classmathod

def get_indexers(self) -> ["Indexer"]:
"""Get all indexers."""

Expand Down Expand Up @@ -73,7 +82,7 @@ def send_torrent_to_client(self, payload):
url = f"{self.base_url}/downloadclient/1"
response = self.get_url(url=url, body=payload, get_method=False)

# TODO: No errors, but does not load in qBittorrent
# TODO: Test again - get_url() updated 21/09/2024
if response.status_code == 202 or response.status_code == 200:
result = response.json()
else:
Expand Down
47 changes: 40 additions & 7 deletions common/external_services/ftpx/core/ftpx_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ def _execute_command(command_fn, *args, **kwargs):
try:
return command_fn(*args, **kwargs)
except Exception as e:
custom_console.bot_error_log(f"Error during {command_fn.__name__} command: {e}")
custom_console.bot_error_log(
f"Error during {command_fn.__name__} command: {e}"
)
exit(1)

def quit(self):
Expand All @@ -56,12 +58,38 @@ def quit(self):

@classmethod
def new(
cls,
host=config.FTPX_IP,
port=int(config.FTPX_PORT),
user=config.FTPX_USER,
passwd=config.FTPX_PASS,
cls,
host=config.FTPX_IP,
port=int(config.FTPX_PORT),
user=config.FTPX_USER,
passwd=config.FTPX_PASS,
):

validate_ftpx_config = True
if not config.FTPX_IP:
custom_console.bot_question_log("No FTPX_IP provided\n")
validate_ftpx_config = False

if not config.FTPX_PORT:
custom_console.bot_question_log("No FTPX_PORT provided\n")
validate_ftpx_config = False

if not config.FTPX_USER:
custom_console.bot_question_log("No FTPX_USER provided\n")
validate_ftpx_config = False

if not config.FTPX_PASS:
custom_console.bot_question_log("No FTPX_PASS provided\n")
validate_ftpx_config = False

if not config.FTPX_LOCAL_PATH:
custom_console.bot_question_log("No FTPX_LOCAL_PATH provided\n")
validate_ftpx_config = False

if not validate_ftpx_config:
custom_console.bot_error_log(f"Please check your service.env file or verify if the FTP server is online")
exit(1)

"""Create an instance of FtpXCmds and handle connection and login"""
ftp = cls()
try:
Expand All @@ -70,6 +98,9 @@ def new(
ftp.prot_p() # Enable SSL
except all_errors as e:
custom_console.bot_error_log(f"\nFTP Server Error: {e}")
custom_console.bot_error_log(
f"Please check your service.env file or verify if the FTP server is online"
)
exit(1)
return ftp

Expand Down Expand Up @@ -102,7 +133,9 @@ def write_chunk(chunk):

self.retrbinary(f"RETR {remote_path}", write_chunk)

return self._execute_command(self._send_pret, f"RETR {remote_path}") and self._execute_command(download)
return self._execute_command(
self._send_pret, f"RETR {remote_path}"
) and self._execute_command(download)

def _cwd(self, path):
# Change the working directory on the FTP server using PRET
Expand Down
Empty file.
74 changes: 74 additions & 0 deletions common/external_services/igdb/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
from urllib.parse import urljoin

from common.custom_console import custom_console
from common.external_services.sessions.session import MyHttp
from common.external_services.sessions.agents import Agent
from common.external_services.igdb.core.models.game import Game
from common.config import config

base_request_url = "https://api.igdb.com/v4/"
oauth = "https://id.twitch.tv/oauth2/token"


class IGdbServiceApi(MyHttp):
def __init__(self):
self.headers = Agent.headers()
self.headers.update({"Content-Type": "application/x-www-form-urlencoded"})
super().__init__(self.headers)

self.token_type: str = ""
self.expires: str = ""
self.access_token: str = ""

def login(self) -> bool:
params = {
"client_id": config.IGDB_CLIENT_ID,
"client_secret": config.IGDB_ACCESS_TK,
"grant_type": "client_credentials",
}

if not config.IGDB_CLIENT_ID:
custom_console.bot_question_log("No IGDB_CLIENT_ID provided\n")
return False

if not config.IGDB_ACCESS_TK:
custom_console.bot_question_log("No IGDB_ACCESS_TK provided\n")
return False

# Login
response = self.get_url(oauth, params=params, get_method=False)
if response:
authentication = response.json()
# Get the access token
self.access_token = authentication["access_token"]
self.expires = authentication["expires_in"]
self.token_type = authentication["token_type"]
return True
else:
return False

def request(self, title: str) -> list["Game"]:

from common.utility import title

header_access = {
"Client-ID": config.IGDB_CLIENT_ID,
"Authorization": f"Bearer {self.access_token}",
"Content-Type": "application/json",
}
print(title)
# query = f'fields *; search "Elden ring";'
query = f'fields id,name; search "{title}";'
build_request = urljoin(base_request_url, "games")
response = self.get_url(
build_request, get_method=False, headers=header_access, data=query
)
query = response.json()

guess_filename = title.Guessit(
"Dragon.Ball.FighterZ.v1.33.incl.DLC.PS4-CUSA09072"
)
print(guess_filename.guessit_title)

return [Game(**game_data) for game_data in query]
Empty file.
Empty file.
Loading

0 comments on commit 22de330

Please sign in to comment.