mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-25 18:40:06 -04:00
Fixing local imports.
This commit is contained in:
parent
fa9fb9ab08
commit
79e0700609
6 changed files with 33 additions and 23 deletions
1
main.py
1
main.py
|
|
@ -372,6 +372,7 @@ async def perpetual_check_for_updates():
|
|||
Updates shared_ctx with update info for the /api/status endpoint.
|
||||
Only runs on native installs (not Docker).
|
||||
"""
|
||||
# Local import to avoid loading upgrade module at startup
|
||||
from wrolpi.upgrade import check_for_update
|
||||
|
||||
# Don't check for updates in Docker environments
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ async def get_upload_singlefile(request: Request):
|
|||
@register_switch_handler('singlefile_upload_switch_handler')
|
||||
async def singlefile_upload_switch_handler(url=None):
|
||||
"""Used by `post_upload_singlefile` to upload a single file"""
|
||||
# Local imports to avoid circular import: downloader -> archive -> api -> downloader
|
||||
from wrolpi.downloader import Download
|
||||
from . import ArchiveDownloader
|
||||
|
||||
|
|
@ -153,7 +154,6 @@ async def generate_screenshot_switch_handler(archive_id=None):
|
|||
try:
|
||||
await lib.generate_archive_screenshot(archive_id)
|
||||
# Always send success event since exceptions are raised on failure
|
||||
from modules.archive import Archive
|
||||
archive = lib.get_archive(archive_id=archive_id)
|
||||
location = archive.location
|
||||
name = archive.file_group.title or archive.file_group.url
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import base64
|
||||
import base64
|
||||
import gzip
|
||||
import json
|
||||
import os
|
||||
|
|
@ -14,19 +13,21 @@ from typing import Optional, Tuple, List, Union
|
|||
from urllib.parse import urlparse
|
||||
|
||||
import pytz
|
||||
from sqlalchemy import asc
|
||||
from sqlalchemy import asc, func, BigInteger
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from modules.archive.models import Archive
|
||||
from wrolpi import dates
|
||||
from wrolpi.cmd import READABILITY_BIN, run_command
|
||||
from wrolpi.collections import Collection
|
||||
from wrolpi.common import get_media_directory, logger, extract_domain, escape_file_name, aiohttp_post, \
|
||||
format_html_string, split_lines_by_length, get_html_soup, get_title_from_html, get_wrolpi_config, html_screenshot, \
|
||||
ConfigFile
|
||||
from wrolpi.common import get_media_directory, get_relative_to_media_directory, logger, extract_domain, \
|
||||
escape_file_name, aiohttp_post, format_html_string, split_lines_by_length, get_html_soup, get_title_from_html, \
|
||||
get_wrolpi_config, html_screenshot, ConfigFile
|
||||
from wrolpi.dates import now, Seconds
|
||||
from wrolpi.db import get_db_session, get_db_curs, optional_session
|
||||
from wrolpi.errors import UnknownArchive, InvalidOrderBy, InvalidDatetime
|
||||
from wrolpi.files.lib import handle_file_group_search_results
|
||||
from wrolpi.files.models import FileGroup
|
||||
from wrolpi.events import Events
|
||||
from wrolpi.switches import register_switch_handler, ActivateSwitchMethod
|
||||
from wrolpi.tags import tag_append_sub_select_where
|
||||
|
|
@ -607,8 +608,8 @@ def link_domain_and_downloads(session: Session):
|
|||
- Recurring downloads whose destination is within the domain collection's directory (including subdirectories)
|
||||
- RSS downloads with sub_downloader='archive' (matched by URL domain)
|
||||
"""
|
||||
# Local import to avoid circular import: downloader -> archive -> downloader
|
||||
from wrolpi.downloader import Download
|
||||
from wrolpi.collections.models import Collection
|
||||
|
||||
# Only Downloads with a frequency can be a Collection Download.
|
||||
downloads = list(session.query(Download).filter(Download.frequency.isnot(None)).all())
|
||||
|
|
@ -855,9 +856,6 @@ def get_domains():
|
|||
This is a thin wrapper around Collection queries that adds archive-specific statistics.
|
||||
Returns a list of dicts with collection id, domain name, url_count, and total size.
|
||||
"""
|
||||
from sqlalchemy import func, BigInteger
|
||||
from wrolpi.files.models import FileGroup
|
||||
|
||||
with get_db_session() as session:
|
||||
# Query all domain collections with archive statistics in a single query
|
||||
# This uses ORM for better maintainability while keeping performance
|
||||
|
|
@ -1032,7 +1030,6 @@ def search_archives(search_str: str, domain: str, limit: int, offset: int, order
|
|||
'''.strip()
|
||||
logger.debug(stmt, params)
|
||||
|
||||
from wrolpi.files.lib import handle_file_group_search_results
|
||||
results, total = handle_file_group_search_results(stmt, params)
|
||||
return results, total
|
||||
|
||||
|
|
@ -1058,7 +1055,6 @@ async def search_domains_by_name(name: str, limit: int = 5, session: Session = N
|
|||
.all()
|
||||
|
||||
# Convert to old Domain format for backward compatibility
|
||||
from wrolpi.common import get_relative_to_media_directory
|
||||
archive_dir = get_archive_directory()
|
||||
return [
|
||||
{
|
||||
|
|
@ -1155,8 +1151,6 @@ async def generate_archive_screenshot(archive_id: int) -> pathlib.Path:
|
|||
ValueError: If Archive has no singlefile
|
||||
RuntimeError: If screenshot generation fails
|
||||
"""
|
||||
from wrolpi.db import get_db_session
|
||||
|
||||
with get_db_session() as session:
|
||||
archive = Archive.find_by_id(archive_id, session=session)
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ class Archive(Base, ModelHelper):
|
|||
|
||||
@staticmethod
|
||||
def can_model(file_group: FileGroup) -> bool:
|
||||
# Local import to avoid circular import within archive module
|
||||
from modules.archive.lib import is_singlefile_file
|
||||
if file_group.mimetype.startswith('text') and is_singlefile_file(file_group.primary_path):
|
||||
return True
|
||||
|
|
@ -98,6 +99,7 @@ class Archive(Base, ModelHelper):
|
|||
|
||||
@staticmethod
|
||||
def do_model(file_group: FileGroup, session: Session) -> 'Archive':
|
||||
# Local import to avoid circular import within archive module
|
||||
from modules.archive import model_archive
|
||||
archive = model_archive(file_group, session)
|
||||
archive.validate()
|
||||
|
|
@ -155,6 +157,7 @@ class Archive(Base, ModelHelper):
|
|||
|
||||
@property
|
||||
def singlefile_file(self) -> Optional[dict]:
|
||||
# Local import to avoid circular import within archive module
|
||||
from modules.archive.lib import is_singlefile_file
|
||||
for file in self.file_group.my_html_files():
|
||||
if is_singlefile_file(file['path']):
|
||||
|
|
@ -315,6 +318,7 @@ class Archive(Base, ModelHelper):
|
|||
|
||||
def apply_domain(self):
|
||||
"""Get the domain collection from the URL."""
|
||||
# Local import to avoid circular import within archive module
|
||||
from modules.archive.lib import get_or_create_domain_collection
|
||||
collection = None
|
||||
if self.file_group.url:
|
||||
|
|
@ -332,6 +336,7 @@ class Archive(Base, ModelHelper):
|
|||
|
||||
def apply_metadata(self):
|
||||
"""Read and apply <meta> (and more) data from the Singlefile HTML."""
|
||||
# Local import to avoid circular import within archive module
|
||||
from modules.archive import lib
|
||||
contents = self.singlefile_path.read_bytes()
|
||||
|
||||
|
|
@ -365,6 +370,7 @@ class Archive(Base, ModelHelper):
|
|||
"""Create a new Archive and FileGroup from the provided paths.
|
||||
|
||||
The files will be read and Archive data extracted."""
|
||||
# Local import to avoid circular import within archive module
|
||||
from modules.archive import model_archive
|
||||
file_group = FileGroup.from_paths(session, *paths)
|
||||
archive = model_archive(file_group, session)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from wrolpi.errors import ValidationError
|
|||
from wrolpi.events import Events
|
||||
from wrolpi.tags import Tag
|
||||
from .errors import UnknownCollection
|
||||
from .models import Collection
|
||||
from .models import Collection, validate_collection_directory
|
||||
|
||||
logger = logger.getChild(__name__)
|
||||
|
||||
|
|
@ -68,6 +68,7 @@ def get_collections(kind: Optional[str] = None, session: Session = None) -> List
|
|||
# Add type-specific statistics
|
||||
if collection.kind == 'domain':
|
||||
# Add archive statistics for domain collections
|
||||
# Local imports to avoid circular import: collections -> archive -> collections
|
||||
from modules.archive import Archive
|
||||
from wrolpi.files.models import FileGroup
|
||||
|
||||
|
|
@ -86,6 +87,7 @@ def get_collections(kind: Optional[str] = None, session: Session = None) -> List
|
|||
|
||||
elif collection.kind == 'channel':
|
||||
# Add video statistics for channel collections
|
||||
# Local imports to avoid circular import: collections -> videos -> collections
|
||||
from modules.videos.models import Video, Channel
|
||||
from wrolpi.files.models import FileGroup
|
||||
|
||||
|
|
@ -144,6 +146,7 @@ def get_collection_with_stats(collection_id: int, session: Session = None) -> di
|
|||
# This can be extended for different collection types
|
||||
if collection.kind == 'domain':
|
||||
# Add archive statistics for domain collections
|
||||
# Local imports to avoid circular import: collections -> archive -> collections
|
||||
from modules.archive import Archive
|
||||
from wrolpi.files.models import FileGroup
|
||||
|
||||
|
|
@ -162,6 +165,7 @@ def get_collection_with_stats(collection_id: int, session: Session = None) -> di
|
|||
|
||||
elif collection.kind == 'channel':
|
||||
# Add video statistics for channel collections
|
||||
# Local imports to avoid circular import: collections -> videos -> collections
|
||||
from modules.videos.models import Video, Channel
|
||||
from wrolpi.files.models import FileGroup
|
||||
|
||||
|
|
@ -329,7 +333,6 @@ def update_collection(
|
|||
if directory is not None:
|
||||
if directory:
|
||||
# Convert relative path to absolute with validation
|
||||
from .models import validate_collection_directory
|
||||
directory_path = validate_collection_directory(directory)
|
||||
collection.directory = directory_path
|
||||
else:
|
||||
|
|
@ -362,6 +365,7 @@ def update_collection(
|
|||
|
||||
# Trigger domain config save if this is a domain collection
|
||||
if collection.kind == 'domain':
|
||||
# Local import to avoid circular import: collections -> archive -> collections
|
||||
from modules.archive.lib import save_domains_config
|
||||
save_domains_config.activate_switch()
|
||||
|
||||
|
|
@ -380,6 +384,7 @@ def refresh_collection(collection_id: int, send_events: bool = True) -> None:
|
|||
UnknownCollection: If collection not found
|
||||
ValidationError: If collection has no directory
|
||||
"""
|
||||
# Local import to avoid circular import: collections -> files -> collections
|
||||
from wrolpi.files.lib import refresh_files
|
||||
|
||||
with get_db_session() as session:
|
||||
|
|
@ -439,6 +444,7 @@ def tag_collection(
|
|||
|
||||
# Trigger domain config save if this is a domain collection
|
||||
if collection.kind == 'domain':
|
||||
# Local import to avoid circular import: collections -> archive -> collections
|
||||
from modules.archive.lib import save_domains_config
|
||||
save_domains_config.activate_switch()
|
||||
|
||||
|
|
@ -462,7 +468,6 @@ def tag_collection(
|
|||
# Determine target directory
|
||||
if directory:
|
||||
# User specified a directory - validate it
|
||||
from .models import validate_collection_directory
|
||||
target_directory = validate_collection_directory(directory)
|
||||
elif collection.directory:
|
||||
# Use existing directory
|
||||
|
|
@ -470,6 +475,7 @@ def tag_collection(
|
|||
else:
|
||||
# Suggest a directory based on collection type and name
|
||||
if collection.kind == 'domain':
|
||||
# Local import to avoid circular import: collections -> archive -> collections
|
||||
from modules.archive.lib import get_archive_directory
|
||||
base_dir = get_archive_directory()
|
||||
else:
|
||||
|
|
@ -485,6 +491,7 @@ def tag_collection(
|
|||
|
||||
# Trigger domain config save if this is a domain collection
|
||||
if collection.kind == 'domain':
|
||||
# Local import to avoid circular import: collections -> archive -> collections
|
||||
from modules.archive.lib import save_domains_config
|
||||
save_domains_config.activate_switch()
|
||||
|
||||
|
|
@ -595,14 +602,15 @@ def delete_collection(
|
|||
|
||||
# Orphan child Archives if this is a domain collection
|
||||
if collection.kind == 'domain':
|
||||
# Local imports to avoid circular import: collections -> archive -> collections
|
||||
from modules.archive.models import Archive
|
||||
from modules.archive.lib import save_domains_config
|
||||
archives = session.query(Archive).filter_by(collection_id=collection_id).all()
|
||||
for archive in archives:
|
||||
archive.collection_id = None
|
||||
session.flush()
|
||||
|
||||
# Trigger domain config save
|
||||
from modules.archive.lib import save_domains_config
|
||||
save_domains_config.activate_switch()
|
||||
|
||||
# Delete the collection
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ from sqlalchemy import Column, Integer, String, ForeignKey, Text, DateTime, Inde
|
|||
from sqlalchemy.orm import relationship, Session
|
||||
from sqlalchemy.orm.collections import InstrumentedList
|
||||
|
||||
from wrolpi.common import Base, ModelHelper, logger, get_media_directory
|
||||
from wrolpi.common import Base, ModelHelper, logger, get_media_directory, get_relative_to_media_directory
|
||||
from wrolpi.db import optional_session
|
||||
from wrolpi.errors import ValidationError
|
||||
from wrolpi.files.models import FileGroup
|
||||
from wrolpi.media_path import MediaPathType
|
||||
from wrolpi.tags import Tag
|
||||
|
|
@ -30,8 +31,6 @@ def validate_collection_directory(directory: pathlib.Path) -> pathlib.Path:
|
|||
Raises:
|
||||
ValidationError: If absolute path is outside media directory
|
||||
"""
|
||||
from wrolpi.errors import ValidationError
|
||||
|
||||
media_directory = get_media_directory()
|
||||
directory = pathlib.Path(directory)
|
||||
|
||||
|
|
@ -197,6 +196,7 @@ class Collection(ModelHelper, Base):
|
|||
Raises:
|
||||
InvalidDownload: If url or frequency is missing
|
||||
"""
|
||||
# Local imports to avoid circular import: collections -> downloader -> collections
|
||||
from wrolpi.downloader import Download, download_manager
|
||||
from wrolpi.errors import InvalidDownload
|
||||
|
||||
|
|
@ -683,8 +683,6 @@ class Collection(ModelHelper, Base):
|
|||
|
||||
Returns directory as a string relative to media directory if applicable.
|
||||
"""
|
||||
from wrolpi.common import get_relative_to_media_directory
|
||||
|
||||
# Get directory as string, relative to media directory
|
||||
directory_str = None
|
||||
if self.directory:
|
||||
|
|
@ -717,10 +715,12 @@ class Collection(ModelHelper, Base):
|
|||
archive/<Tag>/<Domain Name>
|
||||
"""
|
||||
if self.kind == 'channel':
|
||||
# Local import to avoid circular import: collections -> videos -> collections
|
||||
from modules.videos.lib import format_videos_destination
|
||||
return format_videos_destination(self.name, tag_name, None)
|
||||
elif self.kind == 'domain':
|
||||
# Use configured archive directory for domain collections
|
||||
# Local import to avoid circular import: collections -> archive -> collections
|
||||
from modules.archive.lib import get_archive_directory
|
||||
base = get_archive_directory()
|
||||
if tag_name:
|
||||
|
|
@ -737,6 +737,7 @@ class Collection(ModelHelper, Base):
|
|||
|
||||
Similar to Channel.move_channel but without download management.
|
||||
"""
|
||||
# Local imports to avoid circular import: collections -> files/events/flags -> collections
|
||||
from wrolpi.files.lib import move as move_files, refresh_files
|
||||
from wrolpi.events import Events
|
||||
from wrolpi import flags
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue