Skip to content
Snippets Groups Projects
Commit f622f5fb authored by kaiyou's avatar kaiyou
Browse files

Properly handle transition time for profiles

parent a41edc14
No related branches found
No related tags found
No related merge requests found
......@@ -12,17 +12,7 @@ tasks = cli.AppGroup("tasks")
def run_transitions():
# Handle profile transitions
profiles = models.Profile.query.filter(
models.Profile.transition_step.in_ (
[models.Profile.INIT, models.Profile.START, models.Profile.DONE]
)
).all()
for profile in profiles:
_, _, delay, _ = models.Profile.TRANSITIONS[profile.transition]
trigger = profile.updated_at + datetime.timedelta(seconds=delay)
if profile.transition_step == models.Profile.INIT and trigger > datetime.datetime.now():
continue
for profile in models.Profile.transition_ready().all():
print("Applying {}/{} to profile {}@{}".format(
profile.transition, profile.transition_step, profile.username, profile.service.name))
common.apply_transition(profile)
......
from passlib import context, hash
from flask import current_app as app
from sqlalchemy.ext import declarative, mutable
from datetime import datetime
from flask_babel import lazy_gettext as _
import flask_sqlalchemy
import flask_babel
import sqlalchemy
import datetime
import json
import uuid
......@@ -44,11 +44,11 @@ class Base(flask_sqlalchemy.Model):
@declarative.declared_attr
def created_at(cls):
return sqlalchemy.Column(sqlalchemy.DateTime, nullable=False, default=datetime.now)
return sqlalchemy.Column(sqlalchemy.DateTime, nullable=False, default=datetime.datetime.now)
@declarative.declared_attr
def updated_at(cls):
return sqlalchemy.Column(sqlalchemy.DateTime, nullable=True, onupdate=datetime.now)
return sqlalchemy.Column(sqlalchemy.DateTime, nullable=True, onupdate=datetime.datetime.now)
@declarative.declared_attr
def comment(cls):
......@@ -221,6 +221,7 @@ class Profile(db.Model):
server_status = db.Column(db.String(25))
transition = db.Column(db.String(25))
transition_step = db.Column(db.String(25))
transition_time = db.Column(db.DateTime())
extra = db.Column(mutable.MutableDict.as_mutable(JSONEncoded))
@property
......@@ -234,6 +235,16 @@ class Profile(db.Model):
user_uuid=user.uuid,
).filter(cls.status.in_((cls.ACTIVE, cls.BLOCKED, cls.REQUEST)))
@classmethod
def transition_ready(cls):
return cls.query.filter(
cls.transition_step.in_ ([cls.START, cls.DONE]) or
(
cls.transition_step == cls.INIT and
datetime.datetime.now() > cls.transition_time
)
)
def transitions(self, actor):
return {
name: transition for name, transition in Profile.TRANSITIONS.items()
......@@ -242,15 +253,16 @@ class Profile(db.Model):
}
def transition_delta(self, formatted=False):
delta = datetime.now() - self.updated_at
delta = self.transition_time - datetime.datetime.now() if self.transition_time else 0
return flask_babel.format_timedelta(delta) if formatted else delta
def set_transition(self, transition, actor):
""" Prepare the profile for transition
"""
_, _, delta, _, _ = Profile.TRANSITIONS[transition]
self.transition = transition
self.transition_step = Profile.INIT
self.transition_time = datetime.datetime.now() + datetime.timedelta(seconds=delta)
log(
category=History.TRANSITION,
value=transition,
......@@ -282,7 +294,7 @@ class ResetToken(db.Model):
user_uuid = db.Column(db.String(36), db.ForeignKey(User.uuid))
user = db.relationship(User)
expired_at = db.Column(db.DateTime, nullable=False)
expired_at = db.Column(sqlalchemy.DateTime, nullable=False)
class History(db.Model):
......@@ -303,7 +315,7 @@ class History(db.Model):
CREATE: _("created the profile {this.profile.username} on {this.service.name}"),
PASSWORD: _("changed this account password"),
STATUS: _("set the {this.service.name} profile {this.profile.username} as {this.value}"),
TRANSITION: _("did {this.transition[3]} the profile {this.profile.username} on {this.service.name}")
TRANSITION: _("did {this.transition[4]} the profile {this.profile.username} on {this.service.name}")
}
user_uuid = db.Column(db.String(36), db.ForeignKey(User.uuid))
......
......@@ -15,7 +15,7 @@ def apply_transition(profile):
"""
app = profile.service.application
transition = profile.transition
_, target, _, _ = models.Profile.TRANSITIONS[transition]
_, target, _, _, _ = models.Profile.TRANSITIONS[transition]
step = profile.transition_step
manual = app.apply_hooks(profile, transition, step)
profile.transition_step = {
......
......@@ -44,7 +44,7 @@
<td>{{ macros.profile_status(profile) }}</td>
<td>{{ profile.created_at.date() }}</td>
<td>
{% for transition, (_, _, _, _, label) in profile.transitions(current_user.is_admin).items() %}
{% for transition, (_, _, _, _, label) in profile.transitions(current_user).items() %}
<a href="{{ url_for("profile.start_transition", profile_uuid=profile.uuid, transition=transition) }}">{{ label | capitalize }}</a>
{% endfor %}
</td>
......
......@@ -39,7 +39,7 @@
<i class="fa fa-arrow-right"></i>
<span class="badge bg-{{ target[0] }}">{{ target[1] }}</span>
{% if profile.transition_step == profile.INIT %}
<i class="fa fa-clock-o"></i>
<i class="fa fa-clock-o"></i> {{ profile.transition_delta(True) }}
{% elif profile.transition_step == profile.START %}
<i class="fa fa-rocket"></i>
{% elif profile.transition_step == profile.DONE %}
......
""" Add a timestamp for profile transitions
Revision ID: 445033285d55
Revises: 99634916f37f
Create Date: 2020-12-20 11:58:00.642289
"""
from alembic import op
import sqlalchemy as sa
import hiboo
revision = '445033285d55'
down_revision = '99634916f37f'
branch_labels = None
depends_on = None
def upgrade():
with op.batch_alter_table('profile') as batch_op:
batch_op.add_column(sa.Column('transition_time', sa.DateTime(), nullable=True))
def downgrade():
with op.batch_alter_table('profile') as batch_op:
batch_op.drop_column('transition_time')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment