Skip to content

Commit

Permalink
Version [3.2.0]
Browse files Browse the repository at this point in the history
  • Loading branch information
I-am-PUID-0 committed Jul 30, 2024
1 parent 968d150 commit caaef3a
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 49 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0



## Version [3.2.0] - 2024-30-07 🚀

### Changed 🔄

- Update process: Refactored update process to apply updates to Zurg and Riven before starting the processes 🔄
- Zurg: Disabling plex_update.sh in config file has been disbaled, for now. Comment out the line in the config file to disable the Zurg based plex update process if desired 🔄

### Added ✨

- Zurg: Allow nightly release custom versions for ZURG_VERSION
- Zurg: Add plex_update.sh from Zurg to working directory for Zurg use 📦

### Fixed 🛠️

- Logging: Fixed logging for Zurg to ensure log levels are properly set 📝


## Version [3.1.0] - 2024-26-07 🚀

### Added ✨
Expand Down
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ WORKDIR /

ADD . / ./
ADD https://raw.githubusercontent.com/debridmediamanager/zurg-testing/main/config.yml /zurg/
ADD https://raw.githubusercontent.com/debridmediamanager/zurg-testing/main/plex_update.sh /zurg/

ENV \
XDG_CONFIG_HOME=/config \
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ of this parameter has the format `<VARIABLE_NAME>=<VALUE>`.
|`COLOR_LOG_ENABLED`| Enable color logging for DMB. | `false` | | | |
|`ZURG_ENABLED`| Set the value "true" to enable the Zurg process | `false ` | | | :heavy_check_mark:|
|`GITHUB_TOKEN`| GitHub Personal Token for use with Zurg private repo. Requires Zurg [sponsorship](https://github.com/sponsors/debridmediamanager) | `false ` | | | :heavy_check_mark:|
|`ZURG_VERSION`| The version of Zurg to use. If enabled, the value should contain v0.9.x or v0.9.x-hotfix.x format | `latest` | | | :heavy_check_mark: |
|`ZURG_VERSION`| The version of Zurg to use. If enabled, the value should contain v0.9.x or v0.9.x-hotfix.x format or "nightly" if wanting the nightly builds from Zurg private repo (requires GITHUB_TOKEN) | `latest` | | | :heavy_check_mark: |
|`ZURG_UPDATE`| Enable automatic updates of Zurg. Adding this variable will enable automatic updates to the latest version of Zurg locally within the container. | `false` | | | :heavy_check_mark:|
|`ZURG_LOG_LEVEL`| Set the log level for Zurg | `INFO` | | | :heavy_check_mark:|
|`SEERR_API_KEY`| The Overseerr API Key |`none`|| :heavy_check_mark:||
Expand Down
1 change: 1 addition & 0 deletions base/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from packaging.version import Version, parse as parse_version
import time
import os
import ast
import requests
import zipfile
import io
Expand Down
2 changes: 1 addition & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def shutdown(signum, frame):
def main():
logger = get_logger()

version = '3.1.0'
version = '3.2.0'

ascii_art = f'''
Expand Down
8 changes: 5 additions & 3 deletions utils/auto_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ class Update(ProcessHandler):
def __init__(self):
logger = get_logger()
super().__init__(logger)

def update_schedule(self, process_name):
self.update_check(process_name)
#self.update_check(process_name)
interval_minutes = int(self.auto_update_interval() * 60)
schedule.every(interval_minutes).minutes.do(self.update_check, process_name)

Expand All @@ -26,9 +26,11 @@ def auto_update_interval(self):
def auto_update(self, process_name, enable_update):
if enable_update:
self.logger.info(f"Automatic updates set to {format_time(self.auto_update_interval())} for {process_name}")
initial_update = self.update_check(process_name)
self.schedule_thread = threading.Thread(target=self.update_schedule, args=(process_name,))
self.schedule_thread.start()
self.start_process(process_name)
if not initial_update:
self.start_process(process_name)
else:
self.logger.info(f"Automatic update disabled for {process_name}")
self.start_process(process_name)
Expand Down
41 changes: 33 additions & 8 deletions utils/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,27 @@ def fetch_with_retries(self, url, headers, max_retries=5):
self.logger.error(f"Failed to fetch {url} after {max_retries} attempts.")
return None

def get_latest_release(self, repo_owner, repo_name):
def get_latest_release(self, repo_owner, repo_name, nightly=False):
self.logger.info(f"Fetching latest {repo_name} release.")
headers = self.get_headers()
api_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/releases/latest"
if nightly:
api_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/releases"
else:
api_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/releases/latest"
response = self.fetch_with_retries(api_url, headers)
if response and response.status_code == 200:
latest_release = response.json()
version_tag = latest_release['tag_name']
self.logger.info(f"{repo_name} latest release: {version_tag}")
return version_tag, None
releases = response.json()
if nightly:
nightly_releases = [release for release in releases if 'nightly' in release['tag_name']]
if nightly_releases:
latest_nightly = max(nightly_releases, key=lambda x: x['tag_name'])
return latest_nightly['tag_name'], None
return None, "No nightly releases found."
else:
latest_release = response.json()
version_tag = latest_release['tag_name']
self.logger.info(f"{repo_name} latest release: {version_tag}")
return version_tag, None
else:
return None, "Error: Unable to access the repository API."

Expand Down Expand Up @@ -136,7 +147,7 @@ def download_and_extract(self, url, target_dir, zip_folder_name=None, headers=No
shutil.copyfileobj(src, dst)
except Exception as e:
self.logger.error(f"Error while extracting {file_info.filename}: {e}")
self.logger.info(f"Successfully downloaded {zip_folder_name} and extracted to {target_dir}")
self.logger.debug(f"Successfully downloaded {zip_folder_name} and extracted to {target_dir}")
return True, None
except zipfile.BadZipFile as e:
self.logger.error(f"Failed to create ZipFile object: {e}")
Expand All @@ -150,7 +161,7 @@ def download_and_extract(self, url, target_dir, zip_folder_name=None, headers=No
def set_permissions(self, file_path, mode):
try:
os.chmod(file_path, mode)
self.logger.info(f"Set permissions for {file_path} to {oct(mode)}")
self.logger.debug(f"Set permissions for {file_path} to {oct(mode)}")
except Exception as e:
self.logger.error(f"Failed to set permissions for {file_path}: {e}")

Expand Down Expand Up @@ -178,4 +189,18 @@ def get_architecture(self):
except Exception as e:
self.logger.error(f"Error determining system architecture: {e}")
return 'unknown'

def parse_repo_info(self, repo_info):
if not repo_info:
raise ValueError(f"{repo_info} environment variable is not set.")

parts = repo_info.split(',')
if len(parts) < 2:
raise ValueError(f"{repo_info} environment variable must contain at least username and repository name.")

username = parts[0].strip()
repository = parts[1].strip()
branch = parts[2].strip() if len(parts) > 2 else 'main'
self.logger.debug(f"Repository: {username}/{repository} branch: {branch}, being used for plex_debrid")
return username, repository, branch

8 changes: 5 additions & 3 deletions utils/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ def parse_log_level_and_message(line, process_name):
else:
log_level = 'UNKNOWN'
message = line

date_time_prefix_pattern = re.compile(r'^\d{2}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} ')
message = date_time_prefix_pattern.sub('', message).strip()
message = date_time_prefix_pattern.sub('', message).strip()

return log_level, message

Expand Down Expand Up @@ -301,6 +301,8 @@ def get_logger(log_name='DMB', log_dir='./log'):
log_level_env = os.getenv('DMB_LOG_LEVEL')
if log_level_env:
log_level = log_level_env.upper()
os.environ['LOG_LEVEL'] = log_level
os.environ['RCLONE_LOG_LEVEL'] = log_level
else:
log_level = 'INFO'
numeric_level = getattr(logging, log_level, logging.INFO)
Expand Down Expand Up @@ -360,4 +362,4 @@ def get_logger(log_name='DMB', log_dir='./log'):
logger.removeHandler(hdlr)
logger.addHandler(handler)
logger.addHandler(stdout_handler)
return logger
return logger
16 changes: 10 additions & 6 deletions utils/processes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ def __init__(self, logger):
self.process = None
self.subprocess_logger = None

def start_process(self, process_name, config_dir, command, key_type):
def start_process(self, process_name, config_dir, command, key_type=None):
try:
if key_type:
if key_type is not None:
self.logger.info(f"Starting {process_name} w/ {key_type}")
process_description = f"{process_name} w/ {key_type}"
else:
self.logger.info(f"Starting {process_name}")
process_description = f"{process_name}"
self.process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
Expand All @@ -22,24 +24,26 @@ def start_process(self, process_name, config_dir, command, key_type):
universal_newlines=True,
bufsize=1
)
self.subprocess_logger = SubprocessLogger(self.logger, f"{process_name} w/ {key_type}")
self.subprocess_logger = SubprocessLogger(self.logger, f"{process_description}")
self.subprocess_logger.start_logging_stdout(self.process)
self.subprocess_logger.start_monitoring_stderr(self.process, key_type, process_name)
return self.process
except Exception as e:
self.logger.error(f"Error running subprocess for {process_name} w/ {key_type}: {e}")
self.logger.error(f"Error running subprocess for {process_description}: {e}")
return None

def stop_process(self, process_name, key_type):
def stop_process(self, process_name, key_type=None):
try:
if key_type:
self.logger.info(f"Stopping {process_name} w/ {key_type}")
process_description = f"{process_name} w/ {key_type}"
else:
self.logger.info(f"Stopping {process_name}")
process_description = f"{process_name}"
if self.process:
self.process.kill()
if self.subprocess_logger:
self.subprocess_logger.stop_logging_stdout()
self.subprocess_logger.stop_monitoring_stderr()
except Exception as e:
self.logger.error(f"Error stopping subprocess for {process_name} w/ {key_type}: {e}")
self.logger.error(f"Error stopping subprocess for {process_description}: {e}")
35 changes: 24 additions & 11 deletions zurg/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __lt__(self, other):
return self.subversion < other.subversion

def __eq__(self, other):
return (self.main_version, self.hotfix, self.subversion) == (other.main_version, other.hotfix, other.subversion)
return (self.main_version, self.hotfix, self.subversion) == (other.main_version, other.hotfix, self.subversion)

def __str__(self):
version_str = f'v{self.main_version}'
Expand All @@ -49,12 +49,12 @@ def parse_custom_version(version_str):
logger.error(f"Error parsing version string '{version_str}': {e}")
return None

def get_latest_release(repo_owner, repo_name):
return downloader.get_latest_release(repo_owner, repo_name)
def get_latest_release(repo_owner, repo_name, nightly=False):
return downloader.get_latest_release(repo_owner, repo_name, nightly=nightly)

def get_architecture():
return downloader.get_architecture()

def download_and_unzip_release(repo_owner, repo_name, release_version, architecture):
try:
headers = {}
Expand Down Expand Up @@ -83,26 +83,39 @@ def download_and_unzip_release(repo_owner, repo_name, release_version, architect
logger.error(f"Error in download and extraction: {e}")
return False


def version_check():
try:
architecture = get_architecture()
os.environ['CURRENT_ARCHITECTURE'] = architecture
if GHTOKEN:
repo_owner = 'debridmediamanager'
repo_name = 'zurg'
repo_name = 'zurg'
else:
repo_owner = 'debridmediamanager'
repo_name = 'zurg-testing'

repo_name = 'zurg-testing'

nightly = False

if ZURGVERSION:
release_version = ZURGVERSION if ZURGVERSION.startswith('v') else 'v' + ZURGVERSION
logger.info("Using release version from environment variable: %s", release_version)
else:
if "nightly" in ZURGVERSION.lower():
release_version = ZURGVERSION
logger.info("Using nightly release version from environment variable")
nightly = True
else:
release_version = ZURGVERSION if ZURGVERSION.startswith('v') else 'v' + ZURGVERSION
logger.info("Using release version from environment variable: %s", release_version)
else:
release_version, error = get_latest_release(repo_owner, repo_name)
if error:
logger.error(error)
raise Exception("Failed to get the latest release version.")

if nightly:
release_version, error = get_latest_release(repo_owner, repo_name, nightly=True)
if error:
logger.error(error)
raise Exception("Failed to get the latest nightly release version.")

if not download_and_unzip_release(repo_owner, repo_name, release_version, architecture):
raise Exception("Failed to download and extract the release.")

Expand Down
12 changes: 8 additions & 4 deletions zurg/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def zurg_setup():
zurg_app_base = '/zurg/zurg'
zurg_config_override = '/config/config.yml'
zurg_config_base = '/zurg/config.yml'
zurg_plex_update_base = '/zurg/plex_update.sh'

try:
if ZURGLOGLEVEL is not None: # Needs additional testing
Expand Down Expand Up @@ -73,7 +74,7 @@ def update_creds(file_path, zurguser, zurgpass):
file.write("# password:\n")
else:
file.write(line)

def check_and_set_zurg_version(dir_path):
zurg_binary_path = os.path.join(dir_path, 'zurg')
if os.path.exists(zurg_binary_path) and not ZURGVERSION:
Expand All @@ -96,6 +97,8 @@ def setup_zurg_instance(config_dir, token, key_type):
try:
zurg_executable_path = os.path.join(config_dir, 'zurg')
config_file_path = os.path.join(config_dir, 'config.yml')
plex_update_file_path = os.path.join(config_dir, 'plex_update.sh')
refresh_file_path = os.path.join(config_dir, 'plex_refresh.py')
logger.info(f"Preparing Zurg instance for {key_type}")

if os.path.exists(zurg_app_override):
Expand All @@ -119,7 +122,10 @@ def setup_zurg_instance(config_dir, token, key_type):
shutil.copy(zurg_config_base, config_file_path)
else:
logger.info(f"Using Zurg config found for {key_type} in {config_dir}")


if not os.path.exists(plex_update_file_path):
shutil.copy(zurg_plex_update_base,plex_update_file_path)

if ZURGPORT:
port = ZURGPORT
logger.debug(f"Setting port {port} for Zurg w/ {key_type} instance")
Expand All @@ -135,8 +141,6 @@ def setup_zurg_instance(config_dir, token, key_type):
logger.debug(f"Zurg w/ {key_type} instance configured to port: {port}")

update_token(config_file_path, token)
update_plex(config_file_path)

except Exception as e:
raise Exception(f"Error setting up Zurg instance for {key_type}: {e}")

Expand Down
Loading

0 comments on commit caaef3a

Please sign in to comment.