mirror of
https://github.com/simple-login/app.git
synced 2024-09-20 23:16:00 +08:00
add highlighted alias in case it's not included in the result
This commit is contained in:
parent
b2ac1b537d
commit
48838eb176
|
@ -7,7 +7,15 @@ from sqlalchemy.orm import joinedload
|
|||
|
||||
from app.config import PAGE_LIMIT
|
||||
from app.extensions import db
|
||||
from app.models import Alias, Contact, EmailLog, Mailbox, AliasMailbox, CustomDomain
|
||||
from app.models import (
|
||||
Alias,
|
||||
Contact,
|
||||
EmailLog,
|
||||
Mailbox,
|
||||
AliasMailbox,
|
||||
CustomDomain,
|
||||
User,
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
|
@ -137,87 +145,7 @@ def get_alias_infos_with_pagination_v3(
|
|||
mailbox_id=None,
|
||||
directory_id=None,
|
||||
) -> [AliasInfo]:
|
||||
# subquery on alias annotated with nb_reply, nb_blocked, nb_forward, max_created_at, latest_email_log_created_at
|
||||
alias_activity_subquery = (
|
||||
db.session.query(
|
||||
Alias.id,
|
||||
func.sum(case([(EmailLog.is_reply, 1)], else_=0)).label("nb_reply"),
|
||||
func.sum(
|
||||
case(
|
||||
[(and_(EmailLog.is_reply.is_(False), EmailLog.blocked), 1)],
|
||||
else_=0,
|
||||
)
|
||||
).label("nb_blocked"),
|
||||
func.sum(
|
||||
case(
|
||||
[
|
||||
(
|
||||
and_(
|
||||
EmailLog.is_reply.is_(False),
|
||||
EmailLog.blocked.is_(False),
|
||||
),
|
||||
1,
|
||||
)
|
||||
],
|
||||
else_=0,
|
||||
)
|
||||
).label("nb_forward"),
|
||||
func.max(EmailLog.created_at).label("latest_email_log_created_at"),
|
||||
)
|
||||
.join(EmailLog, Alias.id == EmailLog.alias_id, isouter=True)
|
||||
.filter(Alias.user_id == user.id)
|
||||
.group_by(Alias.id)
|
||||
.subquery()
|
||||
)
|
||||
|
||||
alias_contact_subquery = (
|
||||
db.session.query(Alias.id, func.max(Contact.id).label("max_contact_id"))
|
||||
.join(Contact, Alias.id == Contact.alias_id, isouter=True)
|
||||
.filter(Alias.user_id == user.id)
|
||||
.group_by(Alias.id)
|
||||
.subquery()
|
||||
)
|
||||
|
||||
latest_activity = case(
|
||||
[
|
||||
(Alias.created_at > EmailLog.created_at, Alias.created_at),
|
||||
(Alias.created_at < EmailLog.created_at, EmailLog.created_at),
|
||||
],
|
||||
else_=Alias.created_at,
|
||||
)
|
||||
|
||||
q = (
|
||||
db.session.query(
|
||||
Alias,
|
||||
Contact,
|
||||
EmailLog,
|
||||
CustomDomain,
|
||||
alias_activity_subquery.c.nb_reply,
|
||||
alias_activity_subquery.c.nb_blocked,
|
||||
alias_activity_subquery.c.nb_forward,
|
||||
)
|
||||
.options(joinedload(Alias.hibp_breaches))
|
||||
.join(Contact, Alias.id == Contact.alias_id, isouter=True)
|
||||
.join(CustomDomain, Alias.custom_domain_id == CustomDomain.id, isouter=True)
|
||||
.join(EmailLog, Contact.id == EmailLog.contact_id, isouter=True)
|
||||
.filter(Alias.id == alias_activity_subquery.c.id)
|
||||
.filter(Alias.id == alias_contact_subquery.c.id)
|
||||
.filter(
|
||||
or_(
|
||||
EmailLog.created_at
|
||||
== alias_activity_subquery.c.latest_email_log_created_at,
|
||||
and_(
|
||||
# no email log yet for this alias
|
||||
alias_activity_subquery.c.latest_email_log_created_at.is_(None),
|
||||
# to make sure only 1 contact is returned in this case
|
||||
or_(
|
||||
Contact.id == alias_contact_subquery.c.max_contact_id,
|
||||
alias_contact_subquery.c.max_contact_id.is_(None),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
q = construct_alias_query(user)
|
||||
|
||||
if query:
|
||||
q = q.filter(
|
||||
|
@ -262,6 +190,13 @@ def get_alias_infos_with_pagination_v3(
|
|||
q = q.order_by(Alias.email.desc())
|
||||
else:
|
||||
# default sorting
|
||||
latest_activity = case(
|
||||
[
|
||||
(Alias.created_at > EmailLog.created_at, Alias.created_at),
|
||||
(Alias.created_at < EmailLog.created_at, EmailLog.created_at),
|
||||
],
|
||||
else_=Alias.created_at,
|
||||
)
|
||||
q = q.order_by(latest_activity.desc())
|
||||
|
||||
q = list(q.limit(PAGE_LIMIT).offset(page_id * PAGE_LIMIT))
|
||||
|
@ -374,3 +309,98 @@ def get_alias_contacts(alias, page_id: int) -> [dict]:
|
|||
res.append(serialize_contact(fe))
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def get_alias_info_v3(user: User, alias_id: int) -> AliasInfo:
|
||||
# use the same query construction in get_alias_infos_with_pagination_v3
|
||||
q = construct_alias_query(user)
|
||||
q = q.filter(Alias.id == alias_id)
|
||||
|
||||
for alias, contact, email_log, custom_domain, nb_reply, nb_blocked, nb_forward in q:
|
||||
return AliasInfo(
|
||||
alias=alias,
|
||||
mailbox=alias.mailbox,
|
||||
mailboxes=alias.mailboxes,
|
||||
nb_forward=nb_forward,
|
||||
nb_blocked=nb_blocked,
|
||||
nb_reply=nb_reply,
|
||||
latest_email_log=email_log,
|
||||
latest_contact=contact,
|
||||
custom_domain=custom_domain,
|
||||
)
|
||||
|
||||
|
||||
def construct_alias_query(user: User):
|
||||
# subquery on alias annotated with nb_reply, nb_blocked, nb_forward, max_created_at, latest_email_log_created_at
|
||||
alias_activity_subquery = (
|
||||
db.session.query(
|
||||
Alias.id,
|
||||
func.sum(case([(EmailLog.is_reply, 1)], else_=0)).label("nb_reply"),
|
||||
func.sum(
|
||||
case(
|
||||
[(and_(EmailLog.is_reply.is_(False), EmailLog.blocked), 1)],
|
||||
else_=0,
|
||||
)
|
||||
).label("nb_blocked"),
|
||||
func.sum(
|
||||
case(
|
||||
[
|
||||
(
|
||||
and_(
|
||||
EmailLog.is_reply.is_(False),
|
||||
EmailLog.blocked.is_(False),
|
||||
),
|
||||
1,
|
||||
)
|
||||
],
|
||||
else_=0,
|
||||
)
|
||||
).label("nb_forward"),
|
||||
func.max(EmailLog.created_at).label("latest_email_log_created_at"),
|
||||
)
|
||||
.join(EmailLog, Alias.id == EmailLog.alias_id, isouter=True)
|
||||
.filter(Alias.user_id == user.id)
|
||||
.group_by(Alias.id)
|
||||
.subquery()
|
||||
)
|
||||
|
||||
alias_contact_subquery = (
|
||||
db.session.query(Alias.id, func.max(Contact.id).label("max_contact_id"))
|
||||
.join(Contact, Alias.id == Contact.alias_id, isouter=True)
|
||||
.filter(Alias.user_id == user.id)
|
||||
.group_by(Alias.id)
|
||||
.subquery()
|
||||
)
|
||||
|
||||
return (
|
||||
db.session.query(
|
||||
Alias,
|
||||
Contact,
|
||||
EmailLog,
|
||||
CustomDomain,
|
||||
alias_activity_subquery.c.nb_reply,
|
||||
alias_activity_subquery.c.nb_blocked,
|
||||
alias_activity_subquery.c.nb_forward,
|
||||
)
|
||||
.options(joinedload(Alias.hibp_breaches))
|
||||
.join(Contact, Alias.id == Contact.alias_id, isouter=True)
|
||||
.join(CustomDomain, Alias.custom_domain_id == CustomDomain.id, isouter=True)
|
||||
.join(EmailLog, Contact.id == EmailLog.contact_id, isouter=True)
|
||||
.filter(Alias.id == alias_activity_subquery.c.id)
|
||||
.filter(Alias.id == alias_contact_subquery.c.id)
|
||||
.filter(
|
||||
or_(
|
||||
EmailLog.created_at
|
||||
== alias_activity_subquery.c.latest_email_log_created_at,
|
||||
and_(
|
||||
# no email log yet for this alias
|
||||
alias_activity_subquery.c.latest_email_log_created_at.is_(None),
|
||||
# to make sure only 1 contact is returned in this case
|
||||
or_(
|
||||
Contact.id == alias_contact_subquery.c.max_contact_id,
|
||||
alias_contact_subquery.c.max_contact_id.is_(None),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -4,7 +4,7 @@ from flask import render_template, request, redirect, url_for, flash
|
|||
from flask_login import login_required, current_user
|
||||
|
||||
from app import alias_utils
|
||||
from app.api.serializer import get_alias_infos_with_pagination_v3
|
||||
from app.api.serializer import get_alias_infos_with_pagination_v3, get_alias_info_v3
|
||||
from app.config import PAGE_LIMIT, ALIAS_LIMIT
|
||||
from app.dashboard.base import dashboard_bp
|
||||
from app.extensions import db, limiter
|
||||
|
@ -163,6 +163,16 @@ def index():
|
|||
)
|
||||
last_page = len(alias_infos) < PAGE_LIMIT
|
||||
|
||||
# add highlighted alias in case it's not included
|
||||
if highlight_alias_id and highlight_alias_id not in [
|
||||
alias_info.alias.id for alias_info in alias_infos
|
||||
]:
|
||||
highlight_alias_info = get_alias_info_v3(
|
||||
current_user, alias_id=highlight_alias_id
|
||||
)
|
||||
if highlight_alias_info:
|
||||
alias_infos.insert(0, highlight_alias_info)
|
||||
|
||||
return render_template(
|
||||
"dashboard/index.html",
|
||||
alias_infos=alias_infos,
|
||||
|
|
Loading…
Reference in a new issue