Skip to content

Commit

Permalink
Couple minor tweaks. Orionoid still disabled for now.
Browse files Browse the repository at this point in the history
  • Loading branch information
Spoked authored and Spoked committed Dec 28, 2023
1 parent a141777 commit 284fa3d
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 70 deletions.
27 changes: 21 additions & 6 deletions backend/program/plex.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ def _update_items(self):
section.title, str(e)
)
continue
except requests.exceptions.ConnectionError as e:
logger.error(
"Connection aborted. Remote end closed connection with response: %s for item %s",
str(e), section.title
)
continue

processed_sections.add(section.key)
matched_items = self.match_items(items)
Expand Down Expand Up @@ -258,12 +264,20 @@ def _map_item_from_data(item):
)
aired_at = getattr(item, "originallyAvailableAt", None)

# All movies have imdb, but not all shows do
if item.type == "show" and not imdb_id:
tvdb_id = getattr(item, "guid", None).split("://")[-1].split("?")[0] or None
logger.debug("Found tvdb_id %s for %s", tvdb_id, title)
imdb_id = get_imdbid_from_tvdb(tvdb_id)
logger.debug("Found imdb_id %s for %s, from tvdb %s", imdb_id, title, tvdb_id)
# All movies have imdb, but not all shows do.
# This is due to season 0 (specials) not having imdb ids.
# Attempt to get the imdb id from the tvdb id if we don't have it.
# Needs more testing..
# if not imdb_id:
# logger.debug("Unable to find imdb, trying tvdb for %s", title)
# tvdb_id = next(
# (guid.id.split("://")[-1] for guid in guids if "tvdb" in guid.id), None
# )
# if tvdb_id:
# logger.debug("Unable to find imdb, but found tvdb: %s", tvdb_id)
# imdb_id = get_imdbid_from_tvdb(tvdb_id)
# if imdb_id:
# logger.debug("Found imdb from tvdb: %s", imdb_id)

media_item_data = {
"title": title,
Expand All @@ -290,5 +304,6 @@ def _map_item_from_data(item):
media_item_data["season_number"] = season_number
return Episode(media_item_data)
else:
# Specials may end up here..
logger.error("Unknown Item: %s with type %s", item.title, item.type)
return None
85 changes: 22 additions & 63 deletions backend/program/scrapers/orionoid.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@
from typing import Optional
from pydantic import BaseModel
from requests.exceptions import RequestException
from utils.logger import logger, get_data_path
from utils.logger import logger
from utils.request import RateLimitExceeded, RateLimiter, get
from utils.settings import settings_manager
from utils.utils import parser
import time
import pickle
import os


class OrionoidConfig(BaseModel):
Expand All @@ -24,61 +21,31 @@ class Orionoid:
def __init__(self):
self.settings = "orionoid"
self.class_settings = OrionoidConfig(**settings_manager.get(self.settings))
self.validate_settings()
self.data_path = get_data_path()
self.token_file = os.path.join(self.data_path, "orionoid_token.pkl")
self.client_id = "GPQJBFGJKAHVFM37LJDNNLTHKJMXEAJJ"
self.token = self.load_token()
if not self.token:
self.token = self.oauth()
if self.token:
self.keyapp = "D3CH6HMX9KD9EMD68RXRCDUNBDJV5HRR"
self.keyuser = self.class_settings.api_key
self.is_premium = False
self.initialized = False

if self.validate_settings():
self.is_premium = self.check_premium()
self.scrape_limit = None # TODO: Implement scrape limit based on user account
max_calls = (
50 if self.scrape_limit != "unlimited" else 2500
) # 50 calls a day default for free accounts.
self.minute_limiter = RateLimiter(
max_calls=max_calls, period=86400, raise_on_limit=True
)
self.second_limiter = RateLimiter(max_calls=1, period=1)
self.initialized = self.token is not None
max_calls = 50 if not self.is_premium else 2500
self.minute_limiter = RateLimiter(max_calls=max_calls, period=86400, raise_on_limit=True)
self.second_limiter = RateLimiter(max_calls=1, period=1)
self.initialized = True

def validate_settings(self):
def validate_settings(self) -> bool:
"""Validate the Orionoid class_settings."""
if not self.class_settings.api_key:
logger.info("Orionoid is not configured and will not be used.")

def oauth(self) -> Optional[str]:
"""Authenticate with Orionoid and return the token."""
logger.info("Starting OAuth process for Orionoid.")
url = f"https://api.orionoid.com?keyapp={self.client_id}&mode=user&action=authenticate"
response = get(url, retry_if_failed=False)
if response.is_ok and hasattr(response.data, "data"):
auth_code = response.data.data.code
direct_url = response.data.data.direct
logger.info(f"Please authenticate using the following URL: {direct_url}")
token_url = f"https://api.orionoid.com?keyapp={self.client_id}&mode=user&action=authenticate&code={auth_code}"
start_time = time.time()
timeout = 300 # 5 minutes timeout
while time.time() - start_time < timeout:
token_response = get(token_url, retry_if_failed=False)
if token_response.is_ok and hasattr(token_response.data, "data"):
token = token_response.data.data.token
self.save_token(token)
logger.info("Authentication Token Saved.")
return token
time.sleep(5)
logger.warning("Authentication timeout. Please try again.")
else:
logger.warning("Failed to initiate authentication process.")
return None
if self.class_settings.api_key:
return True
logger.info("Orionoid is not configured and will not be used.")
return False

def check_premium(self) -> bool:
"""
Check the user's status with the Orionoid API.
Returns True if the user is active, has a premium account, and has RealDebrid service enabled.
"""
url = f"https://api.orionoid.com?token={self.token}&mode=user&action=retrieve"
url = f"https://api.orionoid.com?keyapp={self.keyapp}&keyuser={self.keyuser}&mode=user&action=retrieve"
response = get(url, retry_if_failed=False)
if response.is_ok:
active = True if response.data.data.status == "active" else False
Expand All @@ -91,18 +58,6 @@ def check_premium(self) -> bool:
logger.error(f"Orionoid Free Account Detected.")
return False

def load_token(self):
"""Load the token from a file if it exists."""
if os.path.exists(self.token_file):
with open(self.token_file, "rb") as file:
return pickle.load(file)
return None

def save_token(self, token: str):
"""Save the token to a file for later use."""
with open(self.token_file, "wb") as file:
pickle.dump(token, file)

def run(self, item):
"""Scrape the Orionoid site for the given media items
and update the object with scraped streams"""
Expand Down Expand Up @@ -136,7 +91,8 @@ def construct_url(self, media_type, imdb_id, season=None, episode=1) -> str:
"""Construct the URL for the Orionoid API."""
base_url = "https://api.orionoid.com"
params = {
"token": self.token,
"keyapp": self.keyapp,
"keyuser": self.keyuser,
"mode": "stream",
"action": "retrieve",
"type": media_type,
Expand Down Expand Up @@ -170,6 +126,9 @@ def construct_url(self, media_type, imdb_id, season=None, episode=1) -> str:
return url

def _can_we_scrape(self, item) -> bool:
logger.debug("Checking if we can scrape %s", item.title)
logger.debug("Is released: %s", self._is_released(item))
logger.debug("Needs new scrape: %s", self._needs_new_scrape(item))
return self._is_released(item) and self._needs_new_scrape(item)

def _needs_new_scrape(self, item) -> bool:
Expand Down
2 changes: 1 addition & 1 deletion entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ fi
chown -R ${USERNAME}:${GROUPNAME} /iceberg

echo "Container Initialization complete."
exec su -m $USERNAME -c 'cd backend && source /venv/bin/activate && exec python /iceberg/backend/main.py & ORIGIN=http://0.0.0.0:3000 node /iceberg/frontend/build'
exec su -m $USERNAME -c 'cd backend && source /venv/bin/activate && exec python /iceberg/backend/main.py & ORIGIN=http://localhost:3000 node /iceberg/frontend/build'

0 comments on commit 284fa3d

Please sign in to comment.