Skip to content

Commit

Permalink
Merge pull request #2277 from liberapay/various
Browse files Browse the repository at this point in the history
  • Loading branch information
Changaco authored Sep 23, 2023
2 parents 2e3736e + 7740c2c commit 5042335
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 9 deletions.
1 change: 1 addition & 0 deletions liberapay/billing/payday.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,7 @@ def update_stats(cls, payday_id):
FROM participants p
WHERE p.kind IN ('individual', 'organization')
AND p.join_time < %(ts_start)s
AND p.is_suspended IS NOT true
AND COALESCE((
SELECT payload::text
FROM events e
Expand Down
4 changes: 3 additions & 1 deletion liberapay/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
from liberapay.models.account_elsewhere import refetch_elsewhere_data
from liberapay.models.community import Community
from liberapay.models.participant import (
Participant, clean_up_closed_accounts, send_account_disabled_notifications,
Participant, clean_up_closed_accounts, free_up_usernames,
send_account_disabled_notifications,
generate_profile_description_missing_notifications
)
from liberapay.models.repository import refetch_repos
Expand Down Expand Up @@ -185,6 +186,7 @@ def default_body_parser(body_bytes, headers):
cron(Daily(hour=17), paypal.sync_all_pending_payments, True)
cron(Daily(hour=18), Payday.update_cached_amounts, True)
cron(Daily(hour=19), Participant.delete_old_feedback, True)
cron(Daily(hour=20), free_up_usernames, True)
cron(intervals.get('notify_patrons', 1200), Participant.notify_patrons, True)
if conf.ses_feedback_queue_url:
cron(intervals.get('fetch_email_bounces', 60), handle_email_bounces, True)
Expand Down
31 changes: 30 additions & 1 deletion liberapay/models/participant.py
Original file line number Diff line number Diff line change
Expand Up @@ -3199,10 +3199,17 @@ def get_tips_awaiting_payment(self, weeks_early=3, exclude_recipients_of=None):
SELECT t.*, p AS tippee_p
FROM current_tips t
JOIN participants p ON p.id = t.tippee
LEFT JOIN scheduled_payins sp ON sp.payer = t.tipper
AND sp.payin IS NULL
AND t.tippee::text IN (
SELECT tr->>'tippee_id'
FROM json_array_elements(sp.transfers) tr
)
WHERE t.tipper = %(tipper_id)s
AND t.renewal_mode > 0
AND ( t.paid_in_advance IS NULL OR
t.paid_in_advance < (t.amount * %(weeks_early)s)
t.paid_in_advance < (t.amount * %(weeks_early)s) OR
sp.execution_date <= (current_date + interval '%(weeks_early)s weeks')
)
AND p.status = 'active'
AND ( p.goal IS NULL OR p.goal >= 0 )
Expand Down Expand Up @@ -3747,6 +3754,28 @@ def clean_up_closed_accounts():
return len(participants)


def free_up_usernames():
n = website.db.one("""
WITH updated AS (
UPDATE participants
SET username = '~' || id::text
WHERE username NOT LIKE '~%'
AND marked_as IN ('fraud', 'spam')
AND kind IN ('individual', 'organization')
AND (
SELECT e.ts
FROM events e
WHERE e.participant = participants.id
AND e.type = 'flags_changed'
ORDER BY e.ts DESC
LIMIT 1
) < (current_timestamp - interval '3 weeks')
RETURNING id
) SELECT count(*) FROM updated;
""")
print(f"Freed up {n} username{'s' if n > 1 else ''}.")


def send_account_disabled_notifications():
"""Notify the owners of accounts that have been flagged as fraud or spam.
Expand Down
19 changes: 13 additions & 6 deletions liberapay/payin/stripe.py
Original file line number Diff line number Diff line change
Expand Up @@ -739,12 +739,19 @@ def settle_destination_charge(
tr = stripe.Transfer.retrieve(charge.transfer)
update_transfer_metadata(tr, pt)
if tr.amount_reversed < bt.fee:
tr.reversals.create(
amount=bt.fee,
description="Stripe fee",
metadata={'payin_id': payin.id},
idempotency_key='payin_fee_%i' % payin.id,
)
try:
tr.reversals.create(
amount=bt.fee,
description="Stripe fee",
metadata={'payin_id': payin.id},
idempotency_key='payin_fee_%i' % payin.id,
)
except stripe.error.StripeError as e:
# In some cases Stripe can refuse to create a reversal. This is
# a serious problem, it means that Liberapay is losing money,
# but it can't be properly resolved automatically, so here the
# error is merely sent to Sentry.
website.tell_sentry(e)
elif tr.amount_reversed > bt.fee:
reversed_amount = int_to_Money(tr.amount_reversed, tr.currency) - fee
record_reversals(db, pt, tr)
Expand Down
2 changes: 1 addition & 1 deletion www/%username/giving/pay/%payment_id.spt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ elif payin_id:
raise response.error(404, "unknown payin ID in URL path")
response.redirect(payer.path('giving/pay/stripe/%i' % payin.id))

weeks_early = request.qs.get_int('weeks_early', default=3)
weeks_early = request.qs.get_int('weeks_early', default=3, minimum=1, maximum=520)
donation_groups, n_fundable = payer.get_tips_awaiting_payment(weeks_early)
donations_not_fundable = (
donation_groups['no_provider'] +
Expand Down

0 comments on commit 5042335

Please sign in to comment.