Semantic HTML and post feed #23
|
@ -4,8 +4,7 @@ Post query interface
|
||||||
|
|
||||||
from typing import Optional, Sequence, Tuple
|
from typing import Optional, Sequence, Tuple
|
||||||
|
|
||||||
from sqlalchemy import select, update, func
|
from sqlalchemy import select, update, func, or_, DateTime
|
||||||
from sqlalchemy.sql.sqltypes import DateTime
|
|
||||||
|
|
||||||
from amanuensis.db import DbContext, Post
|
from amanuensis.db import DbContext, Post
|
||||||
from amanuensis.db.models import Lexicon, Membership
|
from amanuensis.db.models import Lexicon, Membership
|
||||||
|
@ -87,3 +86,13 @@ def get_posts_for_membership(
|
||||||
).scalars()
|
).scalars()
|
||||||
|
|
||||||
return new_posts, old_posts
|
return new_posts, old_posts
|
||||||
|
|
||||||
|
|
||||||
|
def get_unread_count(db: DbContext, membership_id: int) -> int:
|
||||||
|
"""Get the number of posts that the member has not seen"""
|
||||||
|
return db(
|
||||||
|
select(func.count(Post.id))
|
||||||
|
.join(Membership, Membership.lexicon_id == Post.lexicon_id)
|
||||||
|
.where(or_(Membership.last_post_seen.is_(None), Post.created > Membership.last_post_seen))
|
||||||
|
.where(Membership.id == membership_id)
|
||||||
|
).scalar()
|
||||||
|
|
|
@ -656,7 +656,7 @@ class Post(ModelBase):
|
||||||
################
|
################
|
||||||
|
|
||||||
# The timestamp the post was created
|
# The timestamp the post was created
|
||||||
created = Column(DateTime, nullable=False, server_default=func.utcnow())
|
created = Column(DateTime, nullable=False, server_default=func.now())
|
||||||
|
|
||||||
# The body of the post
|
# The body of the post
|
||||||
body = Column(Text, nullable=False)
|
body = Column(Text, nullable=False)
|
||||||
|
|
|
@ -76,6 +76,7 @@ def get_app(
|
||||||
"memq": memq,
|
"memq": memq,
|
||||||
"charq": charq,
|
"charq": charq,
|
||||||
"indq": indq,
|
"indq": indq,
|
||||||
|
"postq": postq,
|
||||||
"current_lexicon": current_lexicon,
|
"current_lexicon": current_lexicon,
|
||||||
"current_membership": current_membership
|
"current_membership": current_membership
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
{% block sb_posts %}<a
|
{% block sb_posts %}<a
|
||||||
{% if current_page == "posts" %}class="current-page"
|
{% if current_page == "posts" %}class="current-page"
|
||||||
{% else %}href="{{ url_for('lexicon.posts.list', lexicon_name=g.lexicon.name) }}"
|
{% else %}href="{{ url_for('lexicon.posts.list', lexicon_name=g.lexicon.name) }}"
|
||||||
{% endif %}>Posts</a>{% endblock %}
|
{% endif %}>Posts{% set unread_count = postq.get_unread_count(g.db, current_membership.id) if current_membership else None %}{% if unread_count %} ({{ unread_count }}){% endif %}</a>{% endblock %}
|
||||||
{% block sb_rules %}<a
|
{% block sb_rules %}<a
|
||||||
{% if current_page == "rules" %}class="current-page"
|
{% if current_page == "rules" %}class="current-page"
|
||||||
{% else %}href="{{ url_for('lexicon.rules', lexicon_name=g.lexicon.name) }}"
|
{% else %}href="{{ url_for('lexicon.rules', lexicon_name=g.lexicon.name) }}"
|
||||||
|
|
Loading…
Reference in New Issue