4.65.5
Some checks failed
Build-Release-Image / Build-Image (linux/amd64) (push) Successful in 3m17s
Build-Release-Image / Build-Image (linux/arm64) (push) Failing after 7m47s
Build-Release-Image / Merge-Images (push) Has been skipped
Build-Release-Image / Create-Release (push) Has been skipped
Build-Release-Image / Notify (push) Has been skipped
Some checks failed
Build-Release-Image / Build-Image (linux/amd64) (push) Successful in 3m17s
Build-Release-Image / Build-Image (linux/arm64) (push) Failing after 7m47s
Build-Release-Image / Merge-Images (push) Has been skipped
Build-Release-Image / Create-Release (push) Has been skipped
Build-Release-Image / Notify (push) Has been skipped
This commit is contained in:
parent
0fa4b1b7ee
commit
ef9c09f76e
@ -71,13 +71,18 @@ def redeem_coupon(coupon_code: str, user: User) -> Optional[Coupon]:
|
|||||||
else:
|
else:
|
||||||
sub.end_at = arrow.now().shift(years=coupon.nb_year, days=1)
|
sub.end_at = arrow.now().shift(years=coupon.nb_year, days=1)
|
||||||
else:
|
else:
|
||||||
sub = ManualSubscription.create(
|
# There may be an expired manual subscription
|
||||||
user_id=user.id,
|
sub = ManualSubscription.get_by(user_id=user.id)
|
||||||
end_at=arrow.now().shift(years=coupon.nb_year, days=1),
|
end_at = arrow.now().shift(years=coupon.nb_year, days=1)
|
||||||
comment="using coupon code",
|
if sub:
|
||||||
is_giveaway=coupon.is_giveaway,
|
sub.end_at = end_at
|
||||||
commit=True,
|
else:
|
||||||
)
|
sub = ManualSubscription.create(
|
||||||
|
user_id=user.id,
|
||||||
|
end_at=end_at,
|
||||||
|
comment="using coupon code",
|
||||||
|
is_giveaway=coupon.is_giveaway,
|
||||||
|
)
|
||||||
emit_user_audit_log(
|
emit_user_audit_log(
|
||||||
user=user,
|
user=user,
|
||||||
action=UserAuditLogAction.Upgrade,
|
action=UserAuditLogAction.Upgrade,
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import argparse
|
import argparse
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import arrow
|
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func
|
||||||
|
|
||||||
|
from app.db import Session
|
||||||
from app.events.event_dispatcher import EventDispatcher
|
from app.events.event_dispatcher import EventDispatcher
|
||||||
from app.events.generated.event_pb2 import UserPlanChanged, EventContent
|
from app.events.generated.event_pb2 import UserPlanChanged, EventContent
|
||||||
from app.models import PartnerUser, User
|
from app.models import PartnerUser, User
|
||||||
from app.db import Session
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
prog="Backfill alias", description="Send lifetime users to proton"
|
prog="Backfill alias", description="Send lifetime users to proton"
|
||||||
@ -19,34 +19,69 @@ parser.add_argument(
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-e", "--end_pu_id", default=0, type=int, help="Last partner_user_id"
|
"-e", "--end_pu_id", default=0, type=int, help="Last partner_user_id"
|
||||||
)
|
)
|
||||||
|
parser.add_argument("-t", "--step", default=10000, type=int, help="Step to use")
|
||||||
|
parser.add_argument("-u", "--user", default="", type=str, help="User to sync")
|
||||||
|
parser.add_argument(
|
||||||
|
"-l", "--lifetime", action="store_true", help="Only sync lifetime users"
|
||||||
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
pu_id_start = args.start_pu_id
|
pu_id_start = args.start_pu_id
|
||||||
max_pu_id = args.end_pu_id
|
max_pu_id = args.end_pu_id
|
||||||
|
user_id = args.user
|
||||||
|
only_lifetime = args.lifetime
|
||||||
|
step = args.step
|
||||||
|
|
||||||
if max_pu_id == 0:
|
if max_pu_id == 0:
|
||||||
max_pu_id = Session.query(func.max(PartnerUser.id)).scalar()
|
max_pu_id = Session.query(func.max(PartnerUser.id)).scalar()
|
||||||
|
|
||||||
|
if user_id:
|
||||||
|
try:
|
||||||
|
user_id = int(user_id)
|
||||||
|
except ValueError:
|
||||||
|
user = User.get_by(email=user_id)
|
||||||
|
if not user:
|
||||||
|
print(f"User {user_id} not found")
|
||||||
|
sys.exit(1)
|
||||||
|
print(f"Limiting to user {user_id}")
|
||||||
|
user_id = user.id
|
||||||
|
# So we only have one loop
|
||||||
|
step = max_pu_id
|
||||||
|
|
||||||
print(f"Checking partner user {pu_id_start} to {max_pu_id}")
|
print(f"Checking partner user {pu_id_start} to {max_pu_id}")
|
||||||
step = 1000
|
|
||||||
done = 0
|
done = 0
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
with_lifetime = 0
|
with_lifetime = 0
|
||||||
|
with_plan = 0
|
||||||
|
with_free = 0
|
||||||
for batch_start in range(pu_id_start, max_pu_id, step):
|
for batch_start in range(pu_id_start, max_pu_id, step):
|
||||||
users = (
|
query = Session.query(User).join(PartnerUser, PartnerUser.user_id == User.id)
|
||||||
Session.query(User)
|
if user_id:
|
||||||
.join(PartnerUser, PartnerUser.user_id == User.id)
|
query = query.filter(User.id == user_id)
|
||||||
.filter(
|
else:
|
||||||
PartnerUser.id >= batch_start,
|
query = query.filter(
|
||||||
PartnerUser.id < batch_start + step,
|
PartnerUser.id >= batch_start, PartnerUser.id < batch_start + step
|
||||||
|
)
|
||||||
|
if only_lifetime:
|
||||||
|
query = query.filter(
|
||||||
User.lifetime == True, # noqa :E712
|
User.lifetime == True, # noqa :E712
|
||||||
)
|
)
|
||||||
).all()
|
users = query.all()
|
||||||
for user in users:
|
for user in users:
|
||||||
# Just in case the == True cond is wonky
|
# Just in case the == True cond is wonky
|
||||||
if not user.lifetime:
|
if user.lifetime:
|
||||||
continue
|
event = UserPlanChanged(lifetime=True)
|
||||||
with_lifetime += 1
|
with_lifetime += 1
|
||||||
event = UserPlanChanged(plan_end_time=arrow.get("2038-01-01").timestamp)
|
else:
|
||||||
|
plan_end = user.get_active_subscription_end(
|
||||||
|
include_partner_subscription=False
|
||||||
|
)
|
||||||
|
if plan_end:
|
||||||
|
event = UserPlanChanged(plan_end_time=plan_end.timestamp)
|
||||||
|
with_plan += 1
|
||||||
|
else:
|
||||||
|
event = UserPlanChanged()
|
||||||
|
with_free += 1
|
||||||
EventDispatcher.send_event(user, EventContent(user_plan_change=event))
|
EventDispatcher.send_event(user, EventContent(user_plan_change=event))
|
||||||
Session.flush()
|
Session.flush()
|
||||||
Session.commit()
|
Session.commit()
|
||||||
@ -57,6 +92,6 @@ for batch_start in range(pu_id_start, max_pu_id, step):
|
|||||||
time_remaining = remaining / time_per_alias
|
time_remaining = remaining / time_per_alias
|
||||||
hours_remaining = time_remaining / 60.0
|
hours_remaining = time_remaining / 60.0
|
||||||
print(
|
print(
|
||||||
f"\PartnerUser {batch_start}/{max_pu_id} {with_lifetime} {hours_remaining:.2f} mins remaining"
|
f"artnerUser {batch_start}/{max_pu_id} lifetime {with_lifetime} paid {with_plan} free {with_free} {hours_remaining:.2f} mins remaining"
|
||||||
)
|
)
|
||||||
print(f"With SL lifetime {with_lifetime}")
|
print(f"Sent lifetime {with_lifetime} paid {with_plan} free {with_free}")
|
||||||
|
@ -66,6 +66,31 @@ def test_use_coupon_extend_manual_sub():
|
|||||||
assert left.days > 364
|
assert left.days > 364
|
||||||
|
|
||||||
|
|
||||||
|
def test_use_coupon_extend_expired_manual_sub():
|
||||||
|
user = create_new_user()
|
||||||
|
initial_end = arrow.now().shift(days=-15)
|
||||||
|
ManualSubscription.create(
|
||||||
|
user_id=user.id,
|
||||||
|
end_at=initial_end,
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
code = random_string(10)
|
||||||
|
Coupon.create(code=code, nb_year=1, commit=True)
|
||||||
|
|
||||||
|
coupon = redeem_coupon(code, user)
|
||||||
|
assert coupon
|
||||||
|
|
||||||
|
coupon = Coupon.get_by(code=code)
|
||||||
|
assert coupon
|
||||||
|
assert coupon.used
|
||||||
|
assert coupon.used_by_user_id == user.id
|
||||||
|
|
||||||
|
sub = user.get_active_subscription()
|
||||||
|
assert isinstance(sub, ManualSubscription)
|
||||||
|
left = sub.end_at - initial_end
|
||||||
|
assert left.days > 364
|
||||||
|
|
||||||
|
|
||||||
def test_coupon_with_subscription():
|
def test_coupon_with_subscription():
|
||||||
user = create_new_user()
|
user = create_new_user()
|
||||||
end_at = arrow.utcnow().shift(days=1).replace(hour=0, minute=0, second=0)
|
end_at = arrow.utcnow().shift(days=1).replace(hour=0, minute=0, second=0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user