Fix random next bug

This commit is contained in:
Timothy Farrell 2026-04-23 21:23:59 -05:00
parent 9821d4330a
commit 9840804e40

56
main.py
View File

@ -29,7 +29,9 @@ security = HTTPBasic()
expected_password: str | None = None expected_password: str | None = None
async def get_current_username(credentials: Annotated[HTTPBasicCredentials, Depends(security)]) -> str: async def get_current_username(
credentials: Annotated[HTTPBasicCredentials, Depends(security)],
) -> str:
"""Verify Basic Authentication credentials""" """Verify Basic Authentication credentials"""
if expected_password is not None and credentials.password != expected_password: if expected_password is not None and credentials.password != expected_password:
raise HTTPException( raise HTTPException(
@ -187,7 +189,9 @@ async def root(username: str = Depends(get_current_username)):
@app.get("/{order}/{delay}") @app.get("/{order}/{delay}")
async def order_delay(order: str, delay: int, username: str = Depends(get_current_username)): async def order_delay(
order: str, delay: int, username: str = Depends(get_current_username)
):
"""Redirect to random file with order and delay""" """Redirect to random file with order and delay"""
random_hash = _get_random_hash() random_hash = _get_random_hash()
return RedirectResponse( return RedirectResponse(
@ -195,13 +199,27 @@ async def order_delay(order: str, delay: int, username: str = Depends(get_curren
) )
def _get_navigation_data(file_hash: str): def _get_navigation_data(file_hash: str, order: str | None = None):
"""Get navigation data for a file hash""" """Get navigation data for a file hash.
Args:
file_hash: The current file's hash.
order: Navigation order - 'next' for sequential, 'random' for random,
or None for default browse mode.
Returns:
Dictionary with navigation hashes and filename.
"""
keys = list(file_mapping.keys()) keys = list(file_mapping.keys())
idx = keys.index(file_hash) idx = keys.index(file_hash)
if order == "random":
next_hash = _get_random_hash()
prev_hash = _get_random_hash()
else:
next_hash = keys[(idx + 1) % len(keys)] next_hash = keys[(idx + 1) % len(keys)]
prev_hash = keys[idx - 1] if idx > 0 else keys[-1] prev_hash = keys[idx - 1] if idx > 0 else keys[-1]
next_random_hash = _get_random_hash()
indexer = _find_indexer_for_hash(file_hash) indexer = _find_indexer_for_hash(file_hash)
filename = indexer.get_filename_by_hash(file_hash) if indexer else "" filename = indexer.get_filename_by_hash(file_hash) if indexer else ""
@ -209,7 +227,6 @@ def _get_navigation_data(file_hash: str):
"file_hash": file_hash, "file_hash": file_hash,
"next_hash": next_hash, "next_hash": next_hash,
"prev_hash": prev_hash, "prev_hash": prev_hash,
"next_random_hash": next_random_hash,
"filename": filename, "filename": filename,
} }
@ -248,10 +265,7 @@ def _render_page(
content = template.substitute( content = template.substitute(
img_url="/api/{file_hash}/data".format(file_hash=navigation_data["file_hash"]), img_url="/api/{file_hash}/data".format(file_hash=navigation_data["file_hash"]),
image_click_url=image_click_url image_click_url=image_click_url or _get_random_hash(),
or "/{next_random_hash}".format(
next_random_hash=navigation_data["next_random_hash"]
),
next_url=next_url, next_url=next_url,
prev_url=prev_url, prev_url=prev_url,
filename=navigation_data["filename"], filename=navigation_data["filename"],
@ -268,7 +282,7 @@ async def hash_page(file_hash: str, username: str = Depends(get_current_username
if file_hash not in file_mapping: if file_hash not in file_mapping:
raise HTTPException(status_code=404, detail="File not found") raise HTTPException(status_code=404, detail="File not found")
navigation_data = _get_navigation_data(file_hash) navigation_data = _get_navigation_data(file_hash, order=None)
play_button = '<a href="/next/5/{file_hash}" class="play-btn" title="Play next 5">⏵</a>'.format( play_button = '<a href="/next/5/{file_hash}" class="play-btn" title="Play next 5">⏵</a>'.format(
file_hash=file_hash file_hash=file_hash
) )
@ -278,7 +292,12 @@ async def hash_page(file_hash: str, username: str = Depends(get_current_username
@app.get("/{order}/{delay}/{file_hash}") @app.get("/{order}/{delay}/{file_hash}")
async def hash_page_with_refresh(order: str, delay: int, file_hash: str, username: str = Depends(get_current_username)): async def hash_page_with_refresh(
order: str,
delay: int,
file_hash: str,
username: str = Depends(get_current_username),
):
"""Serve a page for a specific file hash with auto-refresh navigation""" """Serve a page for a specific file hash with auto-refresh navigation"""
if file_hash not in file_mapping: if file_hash not in file_mapping:
raise HTTPException(status_code=404, detail="File not found") raise HTTPException(status_code=404, detail="File not found")
@ -288,18 +307,11 @@ async def hash_page_with_refresh(order: str, delay: int, file_hash: str, usernam
status_code=400, detail="Invalid order. Must be 'next' or 'random'" status_code=400, detail="Invalid order. Must be 'next' or 'random'"
) )
navigation_data = _get_navigation_data(file_hash) navigation_data = _get_navigation_data(file_hash, order=order)
if order == "next":
refresh_url = "/{order}/{delay}/{next_hash}".format( refresh_url = "/{order}/{delay}/{next_hash}".format(
order=order, delay=delay, next_hash=navigation_data["next_hash"] order=order, delay=delay, next_hash=navigation_data["next_hash"]
) )
else:
refresh_url = "/{order}/{delay}/{next_random_hash}".format(
order=order,
delay=delay,
next_random_hash=navigation_data["next_random_hash"],
)
refresh_meta = f'<meta http-equiv="refresh" content="{delay};url={refresh_url}">' refresh_meta = f'<meta http-equiv="refresh" content="{delay};url={refresh_url}">'
image_click_url = "/{file_hash}".format(file_hash=file_hash) image_click_url = "/{file_hash}".format(file_hash=file_hash)
@ -347,7 +359,9 @@ if __name__ == "__main__":
parser.add_argument( parser.add_argument(
"--salt", type=str, default=None, help="Salt for hashing file paths" "--salt", type=str, default=None, help="Salt for hashing file paths"
) )
parser.add_argument("--password", type=str, default=None, help="Password for Basic Authentication") parser.add_argument(
"--password", type=str, default=None, help="Password for Basic Authentication"
)
args = parser.parse_args() args = parser.parse_args()
initialize_server(args) initialize_server(args)