Restructure to mediahive.hivescan.
This commit is contained in:
@@ -1,61 +0,0 @@
|
|||||||
"""Entry point for hivescan — launches the scanning FastAPI server."""
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import os
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description="Hivescan server — continuous media scanning with live WS updates.",
|
|
||||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
||||||
epilog="""
|
|
||||||
Examples:
|
|
||||||
%(prog)s /path/to/torrents/* # Scan paths, auto-detect common root
|
|
||||||
%(prog)s /mnt/disk1/* /mnt/disk2/* # Scan multiple locations
|
|
||||||
%(prog)s /torrents/* -o /srv/media # Override output directory
|
|
||||||
%(prog)s /torrents/* --port 9000 # Custom port
|
|
||||||
|
|
||||||
The server exposes:
|
|
||||||
WS /ws Live index updates & task progress
|
|
||||||
POST /api/scan Trigger a new scan
|
|
||||||
GET /api/status Current server status
|
|
||||||
GET /api/index Full index as JSON (HTTP fallback)
|
|
||||||
""",
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"paths",
|
|
||||||
nargs="+",
|
|
||||||
help="Folders or glob patterns to scan for downloads",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"-o",
|
|
||||||
"--output-dir",
|
|
||||||
metavar="DIR",
|
|
||||||
help="Output directory for index and covers (default: .mediahive at common root)",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--host",
|
|
||||||
default="0.0.0.0",
|
|
||||||
help="Host to bind to (default: 0.0.0.0)",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--port",
|
|
||||||
type=int,
|
|
||||||
default=8421,
|
|
||||||
help="Port to listen on (default: 8421)",
|
|
||||||
)
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
# Pass configuration via environment variables (read by server.py lifespan)
|
|
||||||
os.environ["HIVESCAN_PATHS"] = os.pathsep.join(args.paths)
|
|
||||||
if args.output_dir:
|
|
||||||
os.environ["HIVESCAN_OUTPUT"] = args.output_dir
|
|
||||||
|
|
||||||
from hivescan.server import run
|
|
||||||
|
|
||||||
run(host=args.host, port=args.port)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1 +1,2 @@
|
|||||||
"""MediaHive - Media Browser Server"""
|
"""MediaHive - Media Browser Server"""
|
||||||
|
|
||||||
|
|||||||
+79
-25
@@ -9,42 +9,96 @@ DEVMODE = bool(os.getenv("MEDIAHIVE_FRONTEND_URL"))
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="Run the mediahive server.")
|
parser = argparse.ArgumentParser(description="MediaHive - Media scanning, indexing, and streaming")
|
||||||
parser.add_argument(
|
subparsers = parser.add_subparsers(dest='command', required=True, help='Available commands')
|
||||||
|
|
||||||
|
# Server subcommand
|
||||||
|
server_parser = subparsers.add_parser('server', help='Run the MediaHive streaming server')
|
||||||
|
server_parser.add_argument(
|
||||||
"media_folder",
|
"media_folder",
|
||||||
nargs="?",
|
nargs="?",
|
||||||
help="Path to the media folder (default: MEDIAHIVE_PATH or current directory)",
|
help="Path to the media folder (default: MEDIAHIVE_PATH or current directory)",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
server_parser.add_argument(
|
||||||
"-l",
|
"-l",
|
||||||
"--listen",
|
"--listen",
|
||||||
action="append",
|
action="append",
|
||||||
help=(f"Endpoint (default: localhost:{DEFAULT_PORT})."),
|
help=(f"Endpoint (default: localhost:{DEFAULT_PORT})."),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Scan subcommand
|
||||||
|
scan_parser = subparsers.add_parser('scan', help='Run the Hivescan media scanning server',
|
||||||
|
description="Hivescan server — continuous media scanning with live WS updates.",
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
epilog="""
|
||||||
|
Examples:
|
||||||
|
mediahive scan /path/to/torrents/* # Scan paths, auto-detect common root
|
||||||
|
mediahive scan /mnt/disk1/* /mnt/disk2/* # Scan multiple locations
|
||||||
|
mediahive scan /torrents/* -o /srv/media # Override output directory
|
||||||
|
mediahive scan /torrents/* --port 9000 # Custom port
|
||||||
|
|
||||||
|
The server exposes:
|
||||||
|
WS /ws Live index updates & task progress
|
||||||
|
POST /api/scan Trigger a new scan
|
||||||
|
GET /api/status Current server status
|
||||||
|
GET /api/index Full index as JSON (HTTP fallback)
|
||||||
|
""")
|
||||||
|
scan_parser.add_argument(
|
||||||
|
"paths",
|
||||||
|
nargs="+",
|
||||||
|
help="Folders or glob patterns to scan for downloads",
|
||||||
|
)
|
||||||
|
scan_parser.add_argument(
|
||||||
|
"-o",
|
||||||
|
"--output-dir",
|
||||||
|
metavar="DIR",
|
||||||
|
help="Output directory for index and covers (default: .mediahive at common root)",
|
||||||
|
)
|
||||||
|
scan_parser.add_argument(
|
||||||
|
"--host",
|
||||||
|
default="0.0.0.0",
|
||||||
|
help="Host to bind to (default: 0.0.0.0)",
|
||||||
|
)
|
||||||
|
scan_parser.add_argument(
|
||||||
|
"--port",
|
||||||
|
type=int,
|
||||||
|
default=8421,
|
||||||
|
help="Port to listen on (default: 8421)",
|
||||||
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Determine media folder
|
if args.command == 'server':
|
||||||
match Path(
|
# Determine media folder
|
||||||
args.media_folder or os.environ.get("MEDIAHIVE_PATH") or Path.cwd()
|
match Path(
|
||||||
).parts:
|
args.media_folder or os.environ.get("MEDIAHIVE_PATH") or Path.cwd()
|
||||||
case (*rest, ".mediahive", "index.json"):
|
).parts:
|
||||||
...
|
case (*rest, ".mediahive", "index.json"):
|
||||||
case (*rest, ".mediahive"):
|
...
|
||||||
...
|
case (*rest, ".mediahive"):
|
||||||
case rest:
|
...
|
||||||
...
|
case rest:
|
||||||
mediaroot = Path(*rest).resolve()
|
...
|
||||||
if not mediaroot.exists() or not mediaroot.is_dir():
|
mediaroot = Path(*rest).resolve()
|
||||||
print(f"Error: Folder does not exist: {mediaroot}")
|
if not mediaroot.exists() or not mediaroot.is_dir():
|
||||||
exit(1)
|
print(f"Error: Folder does not exist: {mediaroot}")
|
||||||
os.environ["MEDIAHIVE_PATH"] = mediaroot.as_posix()
|
exit(1)
|
||||||
dev = {"reload": True, "reload_dirs": ["mediahive"]}
|
os.environ["MEDIAHIVE_PATH"] = mediaroot.as_posix()
|
||||||
server.run(
|
dev = {"reload": True, "reload_dirs": ["mediahive"]}
|
||||||
"mediahive.server:app",
|
server.run(
|
||||||
listen=args.listen,
|
"mediahive.server:app",
|
||||||
default_port=DEFAULT_PORT,
|
listen=args.listen,
|
||||||
**(dev if DEVMODE else {}),
|
default_port=DEFAULT_PORT,
|
||||||
)
|
**(dev if DEVMODE else {}),
|
||||||
|
)
|
||||||
|
elif args.command == 'scan':
|
||||||
|
# Pass configuration via environment variables (read by server.py lifespan)
|
||||||
|
os.environ["HIVESCAN_PATHS"] = os.pathsep.join(args.paths)
|
||||||
|
if args.output_dir:
|
||||||
|
os.environ["HIVESCAN_OUTPUT"] = args.output_dir
|
||||||
|
|
||||||
|
from mediahive.hivescan.server import run
|
||||||
|
run(host=args.host, port=args.port)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -6,22 +6,22 @@ Usage:
|
|||||||
hivescan /path/* --port 9000 # Custom port
|
hivescan /path/* --port 9000 # Custom port
|
||||||
|
|
||||||
Or as a library:
|
Or as a library:
|
||||||
from hivescan.index_store import IndexStore
|
from mediahive.hivescan.index_store import IndexStore
|
||||||
from hivescan.structs import Movie, Series, TaskInfo
|
from mediahive.hivescan.structs import Movie, Series, TaskInfo
|
||||||
from hivescan.server import app
|
from mediahive.hivescan.server import app
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from hivescan.models import ContentType, ContentHash, ParsedContent
|
from mediahive.hivescan.models import ContentType, ContentHash, ParsedContent
|
||||||
from hivescan.scanning import (
|
from mediahive.hivescan.scanning import (
|
||||||
scan_downloads,
|
scan_downloads,
|
||||||
categorize_downloads,
|
categorize_downloads,
|
||||||
find_playable_file,
|
find_playable_file,
|
||||||
find_episode_files,
|
find_episode_files,
|
||||||
)
|
)
|
||||||
from hivescan.index_store import IndexStore
|
from mediahive.hivescan.index_store import IndexStore
|
||||||
from hivescan.utils import DEFAULT_OUTPUT_FOLDER, find_common_root
|
from mediahive.hivescan.utils import DEFAULT_OUTPUT_FOLDER, find_common_root
|
||||||
from hivescan.showreel import generate_showreel_images, generate_episode_reel
|
from mediahive.hivescan.showreel import generate_showreel_images, generate_episode_reel
|
||||||
from hivescan.structs import (
|
from mediahive.hivescan.structs import (
|
||||||
CastMember,
|
CastMember,
|
||||||
Episode,
|
Episode,
|
||||||
EpisodeRelease,
|
EpisodeRelease,
|
||||||
@@ -37,7 +37,7 @@ from hivescan.structs import (
|
|||||||
TMDbInfo,
|
TMDbInfo,
|
||||||
TMDbSeasonInfo,
|
TMDbSeasonInfo,
|
||||||
)
|
)
|
||||||
from hivescan.tmdb_client import (
|
from mediahive.hivescan.tmdb_client import (
|
||||||
fetch_movie_info,
|
fetch_movie_info,
|
||||||
fetch_series_info,
|
fetch_series_info,
|
||||||
fetch_season_details,
|
fetch_season_details,
|
||||||
@@ -83,3 +83,4 @@ __all__ = [
|
|||||||
"DEFAULT_OUTPUT_FOLDER",
|
"DEFAULT_OUTPUT_FOLDER",
|
||||||
"find_common_root",
|
"find_common_root",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ from typing import Optional
|
|||||||
|
|
||||||
from aiopathlib import AsyncPath
|
from aiopathlib import AsyncPath
|
||||||
|
|
||||||
from hivescan.utils import get_media_folder_path
|
from mediahive.hivescan.utils import get_media_folder_path
|
||||||
|
|
||||||
|
|
||||||
# TMDb image configuration
|
# TMDb image configuration
|
||||||
@@ -113,3 +113,4 @@ async def download_season_poster(
|
|||||||
await AsyncPath(media_folder).mkdir(parents=True, exist_ok=True)
|
await AsyncPath(media_folder).mkdir(parents=True, exist_ok=True)
|
||||||
url = f"{TMDB_IMAGE_BASE}/{DEFAULT_POSTER_SIZE}{poster_path}"
|
url = f"{TMDB_IMAGE_BASE}/{DEFAULT_POSTER_SIZE}{poster_path}"
|
||||||
return await _download_image(url, output_path, f"season {season_num} poster")
|
return await _download_image(url, output_path, f"season {season_num} poster")
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ import msgspec
|
|||||||
from aiopathlib import AsyncPath
|
from aiopathlib import AsyncPath
|
||||||
from fastapi import WebSocket
|
from fastapi import WebSocket
|
||||||
|
|
||||||
from hivescan.structs import (
|
from mediahive.hivescan.structs import (
|
||||||
IndexSnapshot,
|
IndexSnapshot,
|
||||||
MediaStats,
|
MediaStats,
|
||||||
Movie,
|
Movie,
|
||||||
@@ -250,3 +250,4 @@ class IndexStore:
|
|||||||
movies=movies_list,
|
movies=movies_list,
|
||||||
series=series_list,
|
series=series_list,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -6,11 +6,11 @@ import logging
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import AsyncIterator, Dict, List, Optional, Tuple
|
from typing import AsyncIterator, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
from hivescan.showreel import (
|
from mediahive.hivescan.showreel import (
|
||||||
get_expected_episode_reel_path,
|
get_expected_episode_reel_path,
|
||||||
get_expected_showreel_paths,
|
get_expected_showreel_paths,
|
||||||
)
|
)
|
||||||
from hivescan.structs import (
|
from mediahive.hivescan.structs import (
|
||||||
Episode,
|
Episode,
|
||||||
EpisodeRelease,
|
EpisodeRelease,
|
||||||
Movie,
|
Movie,
|
||||||
@@ -21,20 +21,20 @@ from hivescan.structs import (
|
|||||||
TMDbInfo,
|
TMDbInfo,
|
||||||
TMDbSeasonInfo,
|
TMDbSeasonInfo,
|
||||||
)
|
)
|
||||||
from hivescan.tmdb_client import (
|
from mediahive.hivescan.tmdb_client import (
|
||||||
fetch_movie_info,
|
fetch_movie_info,
|
||||||
fetch_series_info,
|
fetch_series_info,
|
||||||
fetch_season_details,
|
fetch_season_details,
|
||||||
)
|
)
|
||||||
|
|
||||||
from hivescan.models import ContentType, ParsedContent
|
from mediahive.hivescan.models import ContentType, ParsedContent
|
||||||
from hivescan.scanning import find_cover_image, find_episode_files, find_playable_file
|
from mediahive.hivescan.scanning import find_cover_image, find_episode_files, find_playable_file
|
||||||
from hivescan.images import (
|
from mediahive.hivescan.images import (
|
||||||
download_cover_image,
|
download_cover_image,
|
||||||
download_backdrop_image,
|
download_backdrop_image,
|
||||||
download_season_poster,
|
download_season_poster,
|
||||||
)
|
)
|
||||||
from hivescan.utils import (
|
from mediahive.hivescan.utils import (
|
||||||
get_added_timestamp,
|
get_added_timestamp,
|
||||||
get_directory_size,
|
get_directory_size,
|
||||||
get_media_folder_path,
|
get_media_folder_path,
|
||||||
@@ -739,3 +739,4 @@ async def _process_series(
|
|||||||
seasons=seasons_data,
|
seasons=seasons_data,
|
||||||
)
|
)
|
||||||
yield series, ep_reel_tasks
|
yield series, ep_reel_tasks
|
||||||
|
|
||||||
@@ -51,3 +51,4 @@ class ParsedContent:
|
|||||||
is_directory: bool = False
|
is_directory: bool = False
|
||||||
raw_parsed: dict = field(default_factory=dict)
|
raw_parsed: dict = field(default_factory=dict)
|
||||||
content_hash: Optional[ContentHash] = None
|
content_hash: Optional[ContentHash] = None
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ from typing import Optional, Tuple
|
|||||||
import PTN
|
import PTN
|
||||||
from aiopathlib import AsyncPath
|
from aiopathlib import AsyncPath
|
||||||
|
|
||||||
from hivescan.models import ContentHash, ContentType, ParsedContent
|
from mediahive.hivescan.models import ContentHash, ContentType, ParsedContent
|
||||||
|
|
||||||
|
|
||||||
def determine_content_type(parsed: dict) -> ContentType:
|
def determine_content_type(parsed: dict) -> ContentType:
|
||||||
@@ -78,3 +78,4 @@ def parse_episode_from_filename(filename: str) -> Optional[Tuple[int, int]]:
|
|||||||
return int(match.group(1)), int(match.group(2))
|
return int(match.group(1)), int(match.group(2))
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -7,9 +7,9 @@ from typing import Dict, List, Optional, Tuple
|
|||||||
|
|
||||||
from aiopathlib import AsyncPath
|
from aiopathlib import AsyncPath
|
||||||
|
|
||||||
from hivescan.models import ContentType, ParsedContent
|
from mediahive.hivescan.models import ContentType, ParsedContent
|
||||||
from hivescan.parsing import parse_download, parse_episode_from_filename
|
from mediahive.hivescan.parsing import parse_download, parse_episode_from_filename
|
||||||
from hivescan.utils import get_media_folder_path, sanitize_filename
|
from mediahive.hivescan.utils import get_media_folder_path, sanitize_filename
|
||||||
|
|
||||||
|
|
||||||
# Video file extensions
|
# Video file extensions
|
||||||
@@ -205,3 +205,4 @@ async def find_cover_image(
|
|||||||
return str(legacy_path)
|
return str(legacy_path)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -24,20 +24,20 @@ from fastapi.middleware.cors import CORSMiddleware
|
|||||||
|
|
||||||
import msgspec
|
import msgspec
|
||||||
from aiopathlib import AsyncPath
|
from aiopathlib import AsyncPath
|
||||||
from hivescan.index_store import IndexStore
|
from mediahive.hivescan.index_store import IndexStore
|
||||||
from hivescan.indexer import _process_movies, _process_series
|
from mediahive.hivescan.indexer import _process_movies, _process_series
|
||||||
from hivescan.structs import MsgspecResponse, ScanRequest, StatusResponse, TaskInfo
|
from mediahive.hivescan.structs import MsgspecResponse, ScanRequest, StatusResponse, TaskInfo
|
||||||
from hivescan.models import ContentType, ParsedContent
|
from mediahive.hivescan.models import ContentType, ParsedContent
|
||||||
from hivescan.parsing import parse_download
|
from mediahive.hivescan.parsing import parse_download
|
||||||
from hivescan.scanning import categorize_downloads
|
from mediahive.hivescan.scanning import categorize_downloads
|
||||||
from hivescan.showreel import (
|
from mediahive.hivescan.showreel import (
|
||||||
generate_episode_reel,
|
generate_episode_reel,
|
||||||
generate_showreel_images,
|
generate_showreel_images,
|
||||||
episode_reel_exists,
|
episode_reel_exists,
|
||||||
movie_showreels_exist,
|
movie_showreels_exist,
|
||||||
)
|
)
|
||||||
from hivescan.tmdb_client import set_cache_dir
|
from mediahive.hivescan.tmdb_client import set_cache_dir
|
||||||
from hivescan.utils import DEFAULT_OUTPUT_FOLDER, find_common_root, make_relative_path
|
from mediahive.hivescan.utils import DEFAULT_OUTPUT_FOLDER, find_common_root, make_relative_path
|
||||||
|
|
||||||
logger = logging.getLogger("hivescan.server")
|
logger = logging.getLogger("hivescan.server")
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ logger = logging.getLogger("hivescan.server")
|
|||||||
# Configuration (from environment)
|
# Configuration (from environment)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
SCAN_PATHS: List[str] = [] # set in lifespan from HIVESCAN_PATHS
|
SCAN_PATHS: List[str] = [] # set in lifespan from mediahive.hivescan_PATHS
|
||||||
OUTPUT_DIR: Optional[Path] = None # .mediahive folder
|
OUTPUT_DIR: Optional[Path] = None # .mediahive folder
|
||||||
MEDIA_ROOT: Optional[Path] = None # parent of OUTPUT_DIR
|
MEDIA_ROOT: Optional[Path] = None # parent of OUTPUT_DIR
|
||||||
|
|
||||||
@@ -409,7 +409,7 @@ async def _showreel_worker():
|
|||||||
# Update the movie item with generated showreel paths
|
# Update the movie item with generated showreel paths
|
||||||
if item_id in store.movies:
|
if item_id in store.movies:
|
||||||
movie = store.movies[item_id]
|
movie = store.movies[item_id]
|
||||||
from hivescan.showreel import get_expected_showreel_paths
|
from mediahive.hivescan.showreel import get_expected_showreel_paths
|
||||||
|
|
||||||
media_root_path = (
|
media_root_path = (
|
||||||
Path(store.media_root) if store.media_root else None
|
Path(store.media_root) if store.media_root else None
|
||||||
@@ -494,3 +494,4 @@ def run(host: str = "0.0.0.0", port: int = 8421):
|
|||||||
datefmt="%H:%M:%S",
|
datefmt="%H:%M:%S",
|
||||||
)
|
)
|
||||||
uvicorn.run(app, host=host, port=port, log_level="info")
|
uvicorn.run(app, host=host, port=port, log_level="info")
|
||||||
|
|
||||||
@@ -811,3 +811,4 @@ async def generate_episode_reel(
|
|||||||
episode_code = f"S{season_num:02d}E{episode_num:02d}"
|
episode_code = f"S{season_num:02d}E{episode_num:02d}"
|
||||||
logger.error("Error generating episode reel for %s: %s", episode_code, e)
|
logger.error("Error generating episode reel for %s: %s", episode_code, e)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -334,3 +334,4 @@ class MsgspecResponse(Response):
|
|||||||
|
|
||||||
def render(self, content: object) -> bytes:
|
def render(self, content: object) -> bytes:
|
||||||
return msgspec.json.encode(content)
|
return msgspec.json.encode(content)
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ from typing import Dict, Optional
|
|||||||
import httpx
|
import httpx
|
||||||
from aiopathlib import AsyncPath
|
from aiopathlib import AsyncPath
|
||||||
|
|
||||||
from hivescan.structs import (
|
from mediahive.hivescan.structs import (
|
||||||
CastMember,
|
CastMember,
|
||||||
SimilarMedia,
|
SimilarMedia,
|
||||||
TMDbEpisodeInfo,
|
TMDbEpisodeInfo,
|
||||||
@@ -101,7 +101,7 @@ async def _save_to_cache(cache_path: Path, data: Optional[Dict]):
|
|||||||
pass # Cache write failures are not critical
|
pass # Cache write failures are not critical
|
||||||
|
|
||||||
|
|
||||||
# TMDbEpisodeInfo, TMDbSeasonInfo, TMDbInfo imported from hivescan.structs
|
# TMDbEpisodeInfo, TMDbSeasonInfo, TMDbInfo imported from mediahive.hivescan.structs
|
||||||
|
|
||||||
|
|
||||||
async def tmdb_api_request(
|
async def tmdb_api_request(
|
||||||
@@ -562,3 +562,4 @@ async def fetch_series_info(title: str) -> Optional[TMDbInfo]:
|
|||||||
number_of_episodes=details.get("number_of_episodes"),
|
number_of_episodes=details.get("number_of_episodes"),
|
||||||
networks=networks if networks else None,
|
networks=networks if networks else None,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -194,3 +194,4 @@ def sort_by_quality(items: list, reverse: bool = True) -> None:
|
|||||||
),
|
),
|
||||||
reverse=reverse,
|
reverse=reverse,
|
||||||
)
|
)
|
||||||
|
|
||||||
+2
-1
@@ -18,7 +18,7 @@ from fastapi.middleware.cors import CORSMiddleware
|
|||||||
from fastapi.responses import FileResponse, StreamingResponse
|
from fastapi.responses import FileResponse, StreamingResponse
|
||||||
from fastapi_vue import Frontend
|
from fastapi_vue import Frontend
|
||||||
|
|
||||||
from hivescan.structs import PlayMediaRequest, OpenFolderRequest
|
from mediahive.hivescan.structs import PlayMediaRequest, OpenFolderRequest
|
||||||
|
|
||||||
from mediahive.__main__ import DEVMODE
|
from mediahive.__main__ import DEVMODE
|
||||||
|
|
||||||
@@ -262,3 +262,4 @@ async def serve_media_file(file_path: str):
|
|||||||
|
|
||||||
# Serve the Vue frontend (needs to be last if SPA catch-all is used)
|
# Serve the Vue frontend (needs to be last if SPA catch-all is used)
|
||||||
frontend.route(app, "/")
|
frontend.route(app, "/")
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -18,14 +18,13 @@ dependencies = [
|
|||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
mediahive = "mediahive.__main__:main"
|
mediahive = "mediahive.__main__:main"
|
||||||
hivescan = "hivescan.__main__:main"
|
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["hatchling"]
|
requires = ["hatchling"]
|
||||||
build-backend = "hatchling.build"
|
build-backend = "hatchling.build"
|
||||||
|
|
||||||
[tool.hatch.build]
|
[tool.hatch.build]
|
||||||
packages = ["mediahive", "hivescan"]
|
packages = ["mediahive"]
|
||||||
artifacts = ["mediahive/frontend-build"]
|
artifacts = ["mediahive/frontend-build"]
|
||||||
only-packages = true
|
only-packages = true
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user