d
This commit is contained in:
@@ -70,11 +70,11 @@ class HIFI(Provider):
|
|||||||
"hifi.track": ["download-file"],
|
"hifi.track": ["download-file"],
|
||||||
}
|
}
|
||||||
QUERY_ARG_CHOICES = {
|
QUERY_ARG_CHOICES = {
|
||||||
"album": (),
|
|
||||||
"artist": (),
|
"artist": (),
|
||||||
"playlist": (),
|
"album": (),
|
||||||
"track": (),
|
"track": (),
|
||||||
"title": (),
|
"title": (),
|
||||||
|
"playlist": (),
|
||||||
"video": (),
|
"video": (),
|
||||||
}
|
}
|
||||||
INLINE_QUERY_FIELD_CHOICES = QUERY_ARG_CHOICES
|
INLINE_QUERY_FIELD_CHOICES = QUERY_ARG_CHOICES
|
||||||
@@ -272,7 +272,7 @@ class HIFI(Provider):
|
|||||||
title = self._stringify(detail.get("title")) or title
|
title = self._stringify(detail.get("title")) or title
|
||||||
|
|
||||||
return SearchResult(
|
return SearchResult(
|
||||||
table="hifi",
|
table="hifi.track",
|
||||||
title=title,
|
title=title,
|
||||||
path=f"hifi://track/{track_id}",
|
path=f"hifi://track/{track_id}",
|
||||||
detail=f"id:{track_id}",
|
detail=f"id:{track_id}",
|
||||||
@@ -792,7 +792,7 @@ class HIFI(Provider):
|
|||||||
md["_artist_name"] = artist_name
|
md["_artist_name"] = artist_name
|
||||||
|
|
||||||
return SearchResult(
|
return SearchResult(
|
||||||
table="hifi",
|
table="hifi.album",
|
||||||
title=title,
|
title=title,
|
||||||
path=path,
|
path=path,
|
||||||
detail="album",
|
detail="album",
|
||||||
@@ -1384,7 +1384,7 @@ class HIFI(Provider):
|
|||||||
if not isinstance(hit, dict):
|
if not isinstance(hit, dict):
|
||||||
continue
|
continue
|
||||||
hit_type = str(hit.get("type") or "").upper()
|
hit_type = str(hit.get("type") or "").upper()
|
||||||
if hit_type != "TRACKS":
|
if hit_type != "TRACKS" and hit_type != "TRACK":
|
||||||
continue
|
continue
|
||||||
value = hit.get("value")
|
value = hit.get("value")
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
@@ -1510,7 +1510,7 @@ class HIFI(Provider):
|
|||||||
if not isinstance(hit, dict):
|
if not isinstance(hit, dict):
|
||||||
continue
|
continue
|
||||||
hit_type = str(hit.get("type") or "").upper()
|
hit_type = str(hit.get("type") or "").upper()
|
||||||
if hit_type != "ARTISTS":
|
if hit_type != "ARTISTS" and hit_type != "ARTIST":
|
||||||
continue
|
continue
|
||||||
value = hit.get("value")
|
value = hit.get("value")
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
@@ -1557,10 +1557,10 @@ class HIFI(Provider):
|
|||||||
columns.append(("Popularity", popularity))
|
columns.append(("Popularity", popularity))
|
||||||
|
|
||||||
return SearchResult(
|
return SearchResult(
|
||||||
table="hifi",
|
table="hifi.artist",
|
||||||
title=name,
|
title=name,
|
||||||
path=path,
|
path=path,
|
||||||
detail="artist",
|
detail="hifi.artist",
|
||||||
annotations=["tidal", "artist"],
|
annotations=["tidal", "artist"],
|
||||||
media_kind="audio",
|
media_kind="audio",
|
||||||
columns=columns,
|
columns=columns,
|
||||||
@@ -1656,11 +1656,11 @@ class HIFI(Provider):
|
|||||||
tags = self._build_track_tags(full_md)
|
tags = self._build_track_tags(full_md)
|
||||||
|
|
||||||
result = SearchResult(
|
result = SearchResult(
|
||||||
table="hifi",
|
table="hifi.track",
|
||||||
title=title,
|
title=title,
|
||||||
path=path,
|
path=path,
|
||||||
detail=detail,
|
detail="hifi.track",
|
||||||
annotations=["tidal"],
|
annotations=["tidal", "track"],
|
||||||
media_kind="audio",
|
media_kind="audio",
|
||||||
tag=tags,
|
tag=tags,
|
||||||
columns=columns,
|
columns=columns,
|
||||||
@@ -1816,6 +1816,28 @@ class HIFI(Provider):
|
|||||||
def _build_track_tags(self, metadata: Dict[str, Any]) -> set[str]:
|
def _build_track_tags(self, metadata: Dict[str, Any]) -> set[str]:
|
||||||
return build_track_tags(metadata)
|
return build_track_tags(metadata)
|
||||||
|
|
||||||
|
def selection_auto_stage(
|
||||||
|
self,
|
||||||
|
table_type: str,
|
||||||
|
stage_args: Optional[Sequence[str]] = None,
|
||||||
|
) -> Optional[List[str]]:
|
||||||
|
"""Determine if selection should auto-run download-file."""
|
||||||
|
t = str(table_type or "").strip().lower()
|
||||||
|
|
||||||
|
# Explicit track tables always auto-download.
|
||||||
|
if t == "hifi.track":
|
||||||
|
return ["download-file"]
|
||||||
|
|
||||||
|
# For the generic "hifi" table (first-stage search results),
|
||||||
|
# only auto-download if we're selecting track items.
|
||||||
|
# Otherwise, let selector() handle navigation (artist -> album -> track).
|
||||||
|
if t == "hifi":
|
||||||
|
# If we can't see the items yet, we have to guess.
|
||||||
|
# Default to None so selector() gets a chance to run first.
|
||||||
|
return None
|
||||||
|
|
||||||
|
return super().selection_auto_stage(table_type, stage_args)
|
||||||
|
|
||||||
def selector(
|
def selector(
|
||||||
self,
|
self,
|
||||||
selected_items: List[Any],
|
selected_items: List[Any],
|
||||||
@@ -1836,11 +1858,11 @@ class HIFI(Provider):
|
|||||||
current_table = ctx.get_last_result_table()
|
current_table = ctx.get_last_result_table()
|
||||||
except Exception:
|
except Exception:
|
||||||
current_table = None
|
current_table = None
|
||||||
table_type = (
|
table_type = str(
|
||||||
current_table.table
|
current_table.table
|
||||||
if current_table and hasattr(current_table, "table")
|
if current_table and hasattr(current_table, "table")
|
||||||
else None
|
else ""
|
||||||
)
|
).strip().lower()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
debug(
|
debug(
|
||||||
@@ -1849,8 +1871,12 @@ class HIFI(Provider):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Unified selection logic: detect artist/album/track by inspecting path or metadata
|
||||||
|
# when the table name is just the generic "hifi" (from search-file).
|
||||||
|
is_generic_hifi = (table_type == "hifi")
|
||||||
|
|
||||||
# Artist selection: selecting @N should open an albums list.
|
# Artist selection: selecting @N should open an albums list.
|
||||||
if isinstance(table_type, str) and table_type.strip().lower() == "hifi.artist":
|
if table_type == "hifi.artist" or (is_generic_hifi and any(str(get_field(i, "path")).startswith("hifi://artist/") for i in selected_items)):
|
||||||
contexts = self._extract_artist_selection_context(selected_items)
|
contexts = self._extract_artist_selection_context(selected_items)
|
||||||
try:
|
try:
|
||||||
debug(f"[hifi.selector] artist contexts={len(contexts)}")
|
debug(f"[hifi.selector] artist contexts={len(contexts)}")
|
||||||
@@ -1911,7 +1937,7 @@ class HIFI(Provider):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
# Album selection: selecting @N should open the track list for that album.
|
# Album selection: selecting @N should open the track list for that album.
|
||||||
if isinstance(table_type, str) and table_type.strip().lower() == "hifi.album":
|
if table_type == "hifi.album" or (is_generic_hifi and any(str(get_field(i, "path")).startswith("hifi://album/") for i in selected_items)):
|
||||||
contexts = self._extract_album_selection_context(selected_items)
|
contexts = self._extract_album_selection_context(selected_items)
|
||||||
try:
|
try:
|
||||||
debug(f"[hifi.selector] album contexts={len(contexts)}")
|
debug(f"[hifi.selector] album contexts={len(contexts)}")
|
||||||
@@ -1978,7 +2004,7 @@ class HIFI(Provider):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if isinstance(table_type, str) and table_type.strip().lower() == "hifi.track":
|
if table_type == "hifi.track" or (is_generic_hifi and any(str(get_field(i, "path")).startswith("hifi://track/") for i in selected_items)):
|
||||||
try:
|
try:
|
||||||
meta = (
|
meta = (
|
||||||
current_table.get_table_metadata()
|
current_table.get_table_metadata()
|
||||||
@@ -2051,7 +2077,7 @@ class HIFI(Provider):
|
|||||||
url_value = self._stringify(detail.get("url"))
|
url_value = self._stringify(detail.get("url"))
|
||||||
|
|
||||||
result = SearchResult(
|
result = SearchResult(
|
||||||
table="hifi",
|
table="hifi.track",
|
||||||
title=title,
|
title=title,
|
||||||
path=resolved_path,
|
path=resolved_path,
|
||||||
detail=f"id:{track_id}",
|
detail=f"id:{track_id}",
|
||||||
|
|||||||
@@ -593,38 +593,61 @@ def main() -> int:
|
|||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def _update_config_value(root: Path, key: str, value: str) -> bool:
|
||||||
|
config_path = root / "config.conf"
|
||||||
|
if not config_path.exists():
|
||||||
|
fallback = root / "config.conf.remove"
|
||||||
|
if fallback.exists():
|
||||||
|
shutil.copy(fallback, config_path)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
content = config_path.read_text(encoding="utf-8")
|
||||||
|
pattern = rf'^(\s*{re.escape(key)}\s*=\s*)(.*)$'
|
||||||
|
if re.search(pattern, content, flags=re.MULTILINE):
|
||||||
|
new_content = re.sub(pattern, rf'\1"{value}"', content, flags=re.MULTILINE)
|
||||||
|
else:
|
||||||
|
section_pattern = r'\[store=hydrusnetwork\]'
|
||||||
|
if re.search(section_pattern, content):
|
||||||
|
new_content = re.sub(section_pattern, f'[store=hydrusnetwork]\n{key}="{value}"', content, count=1)
|
||||||
|
else:
|
||||||
|
new_content = content + f'\n\n[store=hydrusnetwork]\nname="hydrus"\n{key}="{value}"'
|
||||||
|
config_path.write_text(new_content, encoding="utf-8")
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error updating config: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
def _interactive_menu() -> str | int:
|
def _interactive_menu() -> str | int:
|
||||||
"""Show a simple interactive menu to choose install/uninstall or delegate."""
|
"""Show a simple interactive menu to choose install/uninstall or delegate."""
|
||||||
try:
|
try:
|
||||||
installed = _is_installed()
|
installed = _is_installed()
|
||||||
while True:
|
while True:
|
||||||
print("\nMedeia-Macina bootstrap - interactive menu")
|
os.system("cls" if os.name == "nt" else "clear")
|
||||||
|
print("====================================")
|
||||||
|
print(" MEDEIA MACINA BOOTSTRAP MENU")
|
||||||
|
print("====================================")
|
||||||
print("1) Install / Reinstall")
|
print("1) Install / Reinstall")
|
||||||
print("2) Extras")
|
print("2) Extras > HydrusNetwork")
|
||||||
if installed:
|
if installed:
|
||||||
print("3) Uninstall")
|
print("3) Uninstall")
|
||||||
print("4) Status")
|
print("4) Status")
|
||||||
print("q) Quit")
|
print("q) Quit")
|
||||||
|
|
||||||
choice = input("Choose an option: ").strip().lower()
|
choice = input("\nChoose an option: ").strip().lower()
|
||||||
|
|
||||||
if choice in ("1", "install", "reinstall"):
|
if choice in ("1", "install", "reinstall"):
|
||||||
return "install"
|
return "install"
|
||||||
|
|
||||||
if choice in ("2", "extras"):
|
if choice in ("2", "extras", "hydrus"):
|
||||||
print("\nExtras Menu:")
|
|
||||||
print(" 1) HydrusNetwork (Setup & Clone)")
|
|
||||||
print(" b) Back")
|
|
||||||
extra_choice = input("Choose an extra: ").strip().lower()
|
|
||||||
if extra_choice == "1":
|
|
||||||
return "extras_hydrus"
|
return "extras_hydrus"
|
||||||
continue # back to main menu
|
|
||||||
|
|
||||||
if installed and choice in ("3", "uninstall"):
|
if installed and choice in ("3", "uninstall"):
|
||||||
return "uninstall"
|
return "uninstall"
|
||||||
|
|
||||||
if installed and choice in ("4", "status"):
|
if installed and choice in ("4", "status"):
|
||||||
print("Installation detected." if installed else "Not installed.")
|
print("\nInstallation detected." if installed else "\nNot installed.")
|
||||||
|
input("\nPress Enter to continue...")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if choice in ("q", "quit", "exit"):
|
if choice in ("q", "quit", "exit"):
|
||||||
@@ -795,6 +818,15 @@ def main() -> int:
|
|||||||
if hydrus_script.exists():
|
if hydrus_script.exists():
|
||||||
try:
|
try:
|
||||||
subprocess.check_call([sys.executable, str(hydrus_script)])
|
subprocess.check_call([sys.executable, str(hydrus_script)])
|
||||||
|
|
||||||
|
# New: Prompt for location as requested
|
||||||
|
print("\n" + "="*40)
|
||||||
|
print(" HYDRUS CONFIGURATION")
|
||||||
|
print("="*40)
|
||||||
|
location = input("\nEnter the absolute path to your Hydrus git clone\n(to link it with Medios-Macina config): ").strip()
|
||||||
|
if location:
|
||||||
|
if _update_config_value(repo_root, "gitclone", location):
|
||||||
|
print(f"✅ Updated config.conf with gitclone=\"{location}\"")
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
print("\nHydrusNetwork setup exited with an error.")
|
print("\nHydrusNetwork setup exited with an error.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user