diff --git a/freak/__init__.py b/freak/__init__.py index 7162627..b48c2e8 100644 --- a/freak/__init__.py +++ b/freak/__init__.py @@ -26,7 +26,7 @@ from suou import twocolon_list, WantsContentType from .colors import color_themes, theme_classes -__version__ = '0.5.0-dev36' +__version__ = '0.5.0-dev40' APP_BASE_DIR = os.path.dirname(os.path.dirname(__file__)) @@ -228,7 +228,9 @@ async def error_404(body): except Exception as e: logger.error(f'Exception in find_guild_or_user: {e}') pass - print(request.host) + if app_config.server_name not in (None, request.host): + logger.warning(f'request host {request.host!r} is different from configured server name {app_config.server_name}') + return redirect('//' + app_config.server_name + request.full_path), 307 return await error_handler_for(404, 'Not found', '404.html') @app.errorhandler(405) diff --git a/freak/algorithms.py b/freak/algorithms.py index 911b905..a5f3e3f 100644 --- a/freak/algorithms.py +++ b/freak/algorithms.py @@ -2,6 +2,7 @@ from flask_login import current_user from sqlalchemy import and_, distinct, func, select +from suou import not_implemented from .models import Comment, Member, Post, Guild, User @@ -29,10 +30,21 @@ def user_timeline(user: User): ).order_by(Post.created_at.desc()) def new_comments(p: Post): - return select(Comment).join(Post, Post.id == Comment.parent_post_id).join(User, User.id == Comment.author_id).where(Comment.parent_post_id == p.id, Comment.parent_comment_id == None, - Comment.not_removed(), User.has_not_blocked(Comment.author_id, cuser_id())).order_by(Comment.created_at.desc()) + return select(Comment).join(Post, Post.id == Comment.parent_post_id).join(User, User.id == Comment.author_id + ).where(Comment.parent_post_id == p.id, Comment.parent_comment_id == None, Comment.not_removed(), User.has_not_blocked(Comment.author_id, cuser_id()) + ).order_by(Comment.created_at.desc()) + +def top_guilds_query(): + q_post_count = func.count(distinct(Post.id)).label('post_count') + q_sub_count = func.count(distinct(Member.id)).label('sub_count') + qr = select(Guild, q_post_count, q_sub_count)\ + .join(Post, Post.topic_id == Guild.id, isouter=True)\ + .join(Member, and_(Member.guild_id == Guild.id, Member.is_subscribed == True), isouter=True)\ + .group_by(Guild).having(q_post_count > 5).order_by(q_post_count.desc(), q_sub_count.desc()) + return qr +@not_implemented() class Algorithms: """ Return SQL queries for algorithms. diff --git a/freak/models.py b/freak/models.py index ef44748..392f6ad 100644 --- a/freak/models.py +++ b/freak/models.py @@ -502,6 +502,15 @@ class Guild(Base): if typed: gg['type'] = 'guild' return gg + + async def sub_info(self): + """ + Guild info including subscriber count. + """ + gg = self.simple_info() + gg['subscriber_count'] = await self.subscriber_count() + gg['post_count'] = await self.post_count() + return gg Topic = deprecated('renamed to Guild')(Guild) diff --git a/freak/rest/__init__.py b/freak/rest/__init__.py index 903c055..233f4b6 100644 --- a/freak/rest/__init__.py +++ b/freak/rest/__init__.py @@ -13,7 +13,7 @@ from werkzeug.security import check_password_hash from suou.quart import add_rest from freak.accounts import LoginStatus, check_login -from freak.algorithms import topic_timeline, user_timeline +from freak.algorithms import public_timeline, top_guilds_query, topic_timeline, user_timeline from ..models import Guild, Post, User, db from .. import UserLoader, app, app_config, __version__ as freak_version, csrf @@ -222,3 +222,29 @@ async def logout(): logout_user() return '', 204 + +## HOME ## + +@bp.get('/home/feed') +@login_required +async def home_feed(): + async with db as session: + me = current_user.user + posts = await db.paginate(public_timeline()) + feed = [] + async for post in posts: + feed.append(post.feed_info()) + + return dict(feed=feed) + + +@bp.get('/top/guilds') +async def top_guilds(): + async with db as session: + top_g = [await x.sub_info() for x in + (await session.execute(top_guilds_query().limit(10))).scalars()] + + return dict(has=top_g) + + + diff --git a/freak/website/frontpage.py b/freak/website/frontpage.py index 48dcf3d..2cafeed 100644 --- a/freak/website/frontpage.py +++ b/freak/website/frontpage.py @@ -11,20 +11,13 @@ from freak.utils import get_request_form from ..search import SearchQuery from ..models import Guild, Member, Post, User, db -from ..algorithms import public_timeline, topic_timeline +from ..algorithms import public_timeline, top_guilds_query, topic_timeline current_user: UserLoader bp = Blueprint('frontpage', __name__) -def top_guilds_query(): - q_post_count = func.count(distinct(Post.id)).label('post_count') - q_sub_count = func.count(distinct(Member.id)).label('sub_count') - qr = select(Guild.name, q_post_count, q_sub_count)\ - .join(Post, Post.topic_id == Guild.id, isouter=True)\ - .join(Member, and_(Member.guild_id == Guild.id, Member.is_subscribed == True), isouter=True)\ - .group_by(Guild).having(q_post_count > 5).order_by(q_post_count.desc(), q_sub_count.desc()) - return qr + @bp.route('/') async def homepage(): diff --git a/pyproject.toml b/pyproject.toml index 3acc227..dab79c6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,7 @@ dependencies = [ "libsass", "setuptools>=78.1.0", "Hypercorn", - "sakuragasaki46-suou>=0.6.0" + "suou>=0.6.1" ] requires-python = ">=3.10" classifiers = [