added transcoding to mp4 in import to ensure web playback.
This commit is contained in:
+50
-17
@@ -2,8 +2,8 @@
|
||||
|
||||
from flask import Blueprint, render_template, flash, redirect, url_for, abort, send_from_directory, request, jsonify
|
||||
|
||||
from sqlalchemy import desc, func, text, extract
|
||||
from sqlalchemy.orm import joinedload
|
||||
from sqlalchemy import desc, func, text, extract, and_
|
||||
from sqlalchemy.orm import joinedload, aliased
|
||||
from collections import OrderedDict
|
||||
from datetime import datetime
|
||||
|
||||
@@ -400,11 +400,15 @@ def tag_list():
|
||||
/tags?kind=series -> only series tags
|
||||
/tags?kind=rating -> only rating tags
|
||||
Shows a few preview images per tag.
|
||||
|
||||
Optimized to use 2 queries instead of N+1:
|
||||
1. Get all tags with counts
|
||||
2. Get preview images for all tags at once using window function
|
||||
"""
|
||||
images_per_tag = 3
|
||||
kind = request.args.get('kind') # 'artist' | 'archive' | 'user' | 'character' | 'series' | 'rating' | None
|
||||
kind = request.args.get('kind')
|
||||
|
||||
# Get tags with image counts
|
||||
# Query 1: Get tags with image counts
|
||||
q = db.session.query(
|
||||
Tag,
|
||||
func.count(image_tags.c.image_id).label('img_count')
|
||||
@@ -415,26 +419,55 @@ def tag_list():
|
||||
|
||||
tags_with_counts = q.order_by(Tag.name.asc()).all()
|
||||
|
||||
tag_data = []
|
||||
# Build tag_id list and initialize tag_data dict
|
||||
tag_ids = [t.id for t, _ in tags_with_counts]
|
||||
tag_map = {}
|
||||
for t, count in tags_with_counts:
|
||||
imgs = (
|
||||
ImageRecord.query
|
||||
.join(ImageRecord.tags)
|
||||
.filter(Tag.id == t.id)
|
||||
.order_by(desc(func.coalesce(ImageRecord.taken_at, ImageRecord.imported_at)))
|
||||
.limit(images_per_tag)
|
||||
.all()
|
||||
)
|
||||
# Display label: for prefixed kinds use the part after ':', else full name
|
||||
label = t.name.split(":", 1)[1] if (":" in t.name) else t.name
|
||||
tag_data.append({
|
||||
tag_map[t.id] = {
|
||||
"id": t.id,
|
||||
"name": label,
|
||||
"tag": t.name,
|
||||
"images": imgs,
|
||||
"images": [],
|
||||
"kind": t.kind,
|
||||
"count": count
|
||||
})
|
||||
}
|
||||
|
||||
# Query 2: Get preview images for all tags at once using a subquery with row_number
|
||||
# This fetches the top N images per tag in a single query
|
||||
if tag_ids:
|
||||
# Subquery to rank images within each tag
|
||||
row_num = func.row_number().over(
|
||||
partition_by=image_tags.c.tag_id,
|
||||
order_by=desc(func.coalesce(ImageRecord.taken_at, ImageRecord.imported_at))
|
||||
).label('rn')
|
||||
|
||||
subq = (
|
||||
db.session.query(
|
||||
image_tags.c.tag_id,
|
||||
ImageRecord.id.label('image_id'),
|
||||
row_num
|
||||
)
|
||||
.join(ImageRecord, ImageRecord.id == image_tags.c.image_id)
|
||||
.filter(image_tags.c.tag_id.in_(tag_ids))
|
||||
.subquery()
|
||||
)
|
||||
|
||||
# Get only the top N images per tag
|
||||
preview_rows = (
|
||||
db.session.query(subq.c.tag_id, ImageRecord)
|
||||
.join(ImageRecord, ImageRecord.id == subq.c.image_id)
|
||||
.filter(subq.c.rn <= images_per_tag)
|
||||
.all()
|
||||
)
|
||||
|
||||
# Group images by tag_id
|
||||
for tag_id, img in preview_rows:
|
||||
if tag_id in tag_map:
|
||||
tag_map[tag_id]["images"].append(img)
|
||||
|
||||
# Convert to list maintaining original order
|
||||
tag_data = [tag_map[t.id] for t, _ in tags_with_counts]
|
||||
|
||||
return render_template('tags_list.html',
|
||||
tag_data=tag_data,
|
||||
|
||||
Reference in New Issue
Block a user