mirror of
https://github.com/simple-login/app.git
synced 2025-09-27 00:48:30 +08:00
create Metric2 model
This commit is contained in:
parent
e9e97cea61
commit
ec1633d0d7
3 changed files with 89 additions and 128 deletions
|
@ -2132,6 +2132,41 @@ class Metric(db.Model, ModelMixin):
|
|||
NB_APP = "nb_app"
|
||||
|
||||
|
||||
class Metric2(db.Model, ModelMixin):
|
||||
"""
|
||||
For storing different metrics like number of users, etc
|
||||
Store each metric as a column as opposed to having different rows as in Metric
|
||||
"""
|
||||
|
||||
date = db.Column(ArrowType, default=arrow.utcnow, nullable=False)
|
||||
name = db.Column(db.String(256), nullable=False)
|
||||
|
||||
nb_user = db.Column(db.Float, nullable=True)
|
||||
nb_activated_user = db.Column(db.Float, nullable=True)
|
||||
|
||||
nb_premium = db.Column(db.Float, nullable=True)
|
||||
nb_apple_premium = db.Column(db.Float, nullable=True)
|
||||
nb_cancelled_premium = db.Column(db.Float, nullable=True)
|
||||
nb_manual_premium = db.Column(db.Float, nullable=True)
|
||||
nb_coinbase_premium = db.Column(db.Float, nullable=True)
|
||||
|
||||
# nb users who have been referred
|
||||
nb_referred_user = db.Column(db.Float, nullable=True)
|
||||
nb_referred_user_paid = db.Column(db.Float, nullable=True)
|
||||
|
||||
nb_alias = db.Column(db.Float, nullable=True)
|
||||
|
||||
nb_forward = db.Column(db.Float, nullable=True)
|
||||
nb_block = db.Column(db.Float, nullable=True)
|
||||
nb_reply = db.Column(db.Float, nullable=True)
|
||||
nb_bounced = db.Column(db.Float, nullable=True)
|
||||
nb_spam = db.Column(db.Float, nullable=True)
|
||||
|
||||
nb_verified_custom_domain = db.Column(db.Float, nullable=True)
|
||||
|
||||
nb_app = db.Column(db.Float, nullable=True)
|
||||
|
||||
|
||||
class Bounce(db.Model, ModelMixin):
|
||||
"""Record all bounces. Deleted after 7 days"""
|
||||
|
||||
|
|
129
cron.py
129
cron.py
|
@ -49,6 +49,7 @@ from app.models import (
|
|||
Metric,
|
||||
TransactionalEmail,
|
||||
Bounce,
|
||||
Metric2,
|
||||
)
|
||||
from server import create_app
|
||||
|
||||
|
@ -198,134 +199,6 @@ def poll_apple_subscription():
|
|||
LOG.d("Finish poll_apple_subscription")
|
||||
|
||||
|
||||
@dataclass
|
||||
class Stats:
|
||||
nb_user: int
|
||||
nb_alias: int
|
||||
|
||||
nb_forward: int
|
||||
nb_block: int
|
||||
nb_reply: int
|
||||
nb_bounced: int
|
||||
nb_spam: int
|
||||
|
||||
nb_custom_domain: int
|
||||
nb_app: int
|
||||
|
||||
nb_premium: int
|
||||
nb_apple_premium: int
|
||||
nb_cancelled_premium: int
|
||||
nb_manual_premium: int
|
||||
nb_coinbase_premium: int
|
||||
|
||||
# nb users who have been referred
|
||||
nb_referred_user: int
|
||||
nb_referred_user_upgrade: int
|
||||
|
||||
|
||||
def stats_before(moment: Arrow) -> Stats:
|
||||
"""return the stats before a specific moment, ignoring all stats come from users in IGNORED_EMAILS"""
|
||||
# nb user
|
||||
q = User.query
|
||||
for ie in IGNORED_EMAILS:
|
||||
q = q.filter(~User.email.contains(ie), User.created_at < moment)
|
||||
|
||||
nb_user = q.count()
|
||||
LOG.d("total number user %s", nb_user)
|
||||
|
||||
nb_referred_user = q.filter(User.referral_id.isnot(None)).count()
|
||||
nb_referred_user_upgrade = 0
|
||||
for user in q.filter(User.referral_id.isnot(None)):
|
||||
if user.is_paid():
|
||||
nb_referred_user_upgrade += 1
|
||||
|
||||
LOG.d(
|
||||
"%s nb_referred_user:%s nb_referred_user_upgrade:%s",
|
||||
moment,
|
||||
nb_referred_user,
|
||||
nb_referred_user_upgrade,
|
||||
)
|
||||
|
||||
# nb alias
|
||||
q = db.session.query(Alias, User).filter(
|
||||
Alias.user_id == User.id, Alias.created_at < moment
|
||||
)
|
||||
for ie in IGNORED_EMAILS:
|
||||
q = q.filter(~User.email.contains(ie))
|
||||
|
||||
nb_alias = q.count()
|
||||
LOG.d("total number alias %s", nb_alias)
|
||||
|
||||
# email log stats
|
||||
q = (
|
||||
db.session.query(EmailLog)
|
||||
.join(User, EmailLog.user_id == User.id)
|
||||
.filter(
|
||||
EmailLog.created_at < moment,
|
||||
)
|
||||
)
|
||||
for ie in IGNORED_EMAILS:
|
||||
q = q.filter(~User.email.contains(ie))
|
||||
|
||||
nb_spam = nb_bounced = nb_forward = nb_block = nb_reply = 0
|
||||
for email_log in q.yield_per(500):
|
||||
if email_log.bounced:
|
||||
nb_bounced += 1
|
||||
elif email_log.is_spam:
|
||||
nb_spam += 1
|
||||
elif email_log.is_reply:
|
||||
nb_reply += 1
|
||||
elif email_log.blocked:
|
||||
nb_block += 1
|
||||
else:
|
||||
nb_forward += 1
|
||||
|
||||
LOG.d(
|
||||
"nb_forward %s, nb_block %s, nb_reply %s, nb_bounced %s, nb_spam %s",
|
||||
nb_forward,
|
||||
nb_block,
|
||||
nb_reply,
|
||||
nb_bounced,
|
||||
nb_spam,
|
||||
)
|
||||
|
||||
nb_premium = Subscription.query.filter(
|
||||
Subscription.created_at < moment, Subscription.cancelled.is_(False)
|
||||
).count()
|
||||
nb_apple_premium = AppleSubscription.query.filter(
|
||||
AppleSubscription.created_at < moment
|
||||
).count()
|
||||
nb_cancelled_premium = Subscription.query.filter(
|
||||
Subscription.created_at < moment, Subscription.cancelled.is_(True)
|
||||
).count()
|
||||
|
||||
now = arrow.now()
|
||||
nb_manual_premium = ManualSubscription.query.filter(
|
||||
ManualSubscription.created_at < moment,
|
||||
ManualSubscription.end_at > now,
|
||||
ManualSubscription.is_giveaway.is_(False),
|
||||
).count()
|
||||
|
||||
nb_coinbase_premium = CoinbaseSubscription.query.filter(
|
||||
CoinbaseSubscription.created_at < moment, CoinbaseSubscription.end_at > now
|
||||
).count()
|
||||
|
||||
nb_custom_domain = CustomDomain.query.filter(
|
||||
CustomDomain.created_at < moment
|
||||
).count()
|
||||
|
||||
nb_app = Client.query.filter(Client.created_at < moment).count()
|
||||
|
||||
data = locals()
|
||||
# to keep only Stats field
|
||||
data = {
|
||||
k: v
|
||||
for (k, v) in data.items()
|
||||
if k in vars(Stats)["__dataclass_fields__"].keys()
|
||||
}
|
||||
return Stats(**data)
|
||||
|
||||
|
||||
def compute_metrics():
|
||||
now = arrow.now()
|
||||
|
||||
|
|
53
migrations/versions/2021_032310_9d6adad83936_.py
Normal file
53
migrations/versions/2021_032310_9d6adad83936_.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: 9d6adad83936
|
||||
Revises: 94f14eb0fe5b
|
||||
Create Date: 2021-03-23 10:23:17.879887
|
||||
|
||||
"""
|
||||
import sqlalchemy_utils
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '9d6adad83936'
|
||||
down_revision = '94f14eb0fe5b'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('metric2',
|
||||
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
||||
sa.Column('created_at', sqlalchemy_utils.types.arrow.ArrowType(), nullable=False),
|
||||
sa.Column('updated_at', sqlalchemy_utils.types.arrow.ArrowType(), nullable=True),
|
||||
sa.Column('date', sqlalchemy_utils.types.arrow.ArrowType(), nullable=False),
|
||||
sa.Column('name', sa.String(length=256), nullable=False),
|
||||
sa.Column('nb_user', sa.Float(), nullable=True),
|
||||
sa.Column('nb_activated_user', sa.Float(), nullable=True),
|
||||
sa.Column('nb_premium', sa.Float(), nullable=True),
|
||||
sa.Column('nb_apple_premium', sa.Float(), nullable=True),
|
||||
sa.Column('nb_cancelled_premium', sa.Float(), nullable=True),
|
||||
sa.Column('nb_manual_premium', sa.Float(), nullable=True),
|
||||
sa.Column('nb_coinbase_premium', sa.Float(), nullable=True),
|
||||
sa.Column('nb_referred_user', sa.Float(), nullable=True),
|
||||
sa.Column('nb_referred_user_paid', sa.Float(), nullable=True),
|
||||
sa.Column('nb_alias', sa.Float(), nullable=True),
|
||||
sa.Column('nb_forward', sa.Float(), nullable=True),
|
||||
sa.Column('nb_block', sa.Float(), nullable=True),
|
||||
sa.Column('nb_reply', sa.Float(), nullable=True),
|
||||
sa.Column('nb_bounced', sa.Float(), nullable=True),
|
||||
sa.Column('nb_spam', sa.Float(), nullable=True),
|
||||
sa.Column('nb_verified_custom_domain', sa.Float(), nullable=True),
|
||||
sa.Column('nb_app', sa.Float(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table('metric2')
|
||||
# ### end Alembic commands ###
|
Loading…
Add table
Reference in a new issue