Audiobook Maker Pro v4.2 — production ready
This commit is contained in:
133
routes/public_routes.py
Normal file
133
routes/public_routes.py
Normal file
@@ -0,0 +1,133 @@
|
||||
# routes/public_routes.py - Public (No Auth) Routes for Published Audiobooks
|
||||
|
||||
import json
|
||||
from flask import Blueprint, jsonify, send_from_directory, abort
|
||||
|
||||
from db import get_db
|
||||
|
||||
public_bp = Blueprint('public', __name__)
|
||||
|
||||
|
||||
@public_bp.route('/home')
|
||||
def public_home():
|
||||
"""Public homepage - Bookcase view of published audiobooks."""
|
||||
return send_from_directory('templates', 'public_home.html')
|
||||
|
||||
|
||||
@public_bp.route('/read/<int:project_id>')
|
||||
def public_reader(project_id):
|
||||
"""Public reader page for a published audiobook."""
|
||||
db = get_db()
|
||||
cursor = db.cursor()
|
||||
cursor.execute('SELECT id, is_published FROM projects WHERE id = ?', (project_id,))
|
||||
project = cursor.fetchone()
|
||||
|
||||
if not project or not project['is_published']:
|
||||
abort(404)
|
||||
|
||||
# Increment view count
|
||||
cursor.execute('UPDATE projects SET view_count = view_count + 1 WHERE id = ?', (project_id,))
|
||||
db.commit()
|
||||
|
||||
return send_from_directory('templates', 'public_reader.html')
|
||||
|
||||
|
||||
@public_bp.route('/api/public/books', methods=['GET'])
|
||||
def list_published_books():
|
||||
"""List all published audiobooks (no auth required)."""
|
||||
db = get_db()
|
||||
cursor = db.cursor()
|
||||
|
||||
cursor.execute('''
|
||||
SELECT p.id, p.name, p.description, p.author, p.category,
|
||||
p.thumbnail_data, p.thumbnail_format, p.published_at,
|
||||
p.view_count, p.created_at,
|
||||
(SELECT COUNT(*) FROM chapters WHERE project_id = p.id) as chapter_count
|
||||
FROM projects p
|
||||
WHERE p.is_published = 1
|
||||
ORDER BY p.published_at DESC
|
||||
''')
|
||||
|
||||
books = []
|
||||
for row in cursor.fetchall():
|
||||
books.append({
|
||||
'id': row['id'],
|
||||
'name': row['name'],
|
||||
'description': row['description'] or '',
|
||||
'author': row['author'] or '',
|
||||
'category': row['category'] or '',
|
||||
'thumbnail_data': row['thumbnail_data'],
|
||||
'thumbnail_format': row['thumbnail_format'] or 'png',
|
||||
'published_at': row['published_at'],
|
||||
'view_count': row['view_count'] or 0,
|
||||
'chapter_count': row['chapter_count']
|
||||
})
|
||||
|
||||
return jsonify({'books': books})
|
||||
|
||||
|
||||
@public_bp.route('/api/public/books/<int:project_id>', methods=['GET'])
|
||||
def get_published_book(project_id):
|
||||
"""Get full published book content for the reader."""
|
||||
db = get_db()
|
||||
cursor = db.cursor()
|
||||
|
||||
cursor.execute('''
|
||||
SELECT * FROM projects WHERE id = ? AND is_published = 1
|
||||
''', (project_id,))
|
||||
project = cursor.fetchone()
|
||||
|
||||
if not project:
|
||||
return jsonify({'error': 'Book not found or not published'}), 404
|
||||
|
||||
cursor.execute('''
|
||||
SELECT * FROM chapters WHERE project_id = ? ORDER BY chapter_number
|
||||
''', (project_id,))
|
||||
chapters = cursor.fetchall()
|
||||
|
||||
chapters_data = []
|
||||
for chapter in chapters:
|
||||
cursor.execute('''
|
||||
SELECT * FROM markdown_blocks WHERE chapter_id = ? ORDER BY block_order
|
||||
''', (chapter['id'],))
|
||||
blocks = cursor.fetchall()
|
||||
|
||||
blocks_data = []
|
||||
for block in blocks:
|
||||
cursor.execute('''
|
||||
SELECT * FROM block_images WHERE block_id = ? ORDER BY id
|
||||
''', (block['id'],))
|
||||
images = cursor.fetchall()
|
||||
|
||||
blocks_data.append({
|
||||
'id': block['id'],
|
||||
'block_order': block['block_order'],
|
||||
'block_type': block['block_type'],
|
||||
'content': block['content'],
|
||||
'audio_data': block['audio_data'],
|
||||
'audio_format': block['audio_format'],
|
||||
'transcription': json.loads(block['transcription']) if block['transcription'] else [],
|
||||
'images': [{
|
||||
'data': img['image_data'],
|
||||
'format': img['image_format'],
|
||||
'alt_text': img['alt_text'],
|
||||
'position': img['position']
|
||||
} for img in images]
|
||||
})
|
||||
|
||||
chapters_data.append({
|
||||
'id': chapter['id'],
|
||||
'chapter_number': chapter['chapter_number'],
|
||||
'title': chapter['title'],
|
||||
'blocks': blocks_data
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
'id': project['id'],
|
||||
'name': project['name'],
|
||||
'description': project['description'] or '',
|
||||
'author': project['author'] or '',
|
||||
'thumbnail_data': project['thumbnail_data'],
|
||||
'thumbnail_format': project['thumbnail_format'] or 'png',
|
||||
'chapters': chapters_data
|
||||
})
|
||||
Reference in New Issue
Block a user