internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: liberapay/liberapay.com

Issue:
"Translation incomplete" warning, but the page is translated
To reproduced visit a closed account like https://eo.liberapay.com/granduzanto/.


Discussion:
Confirmed (even with another language https://fr.liberapay.com/granduzanto/ ).

This is due to the HTTP status not being translated. When viewing the profile of a closed account the missing string ("Gone") isn't actually in the page, but in others you can see it, e.g. https://fr.liberapay.com/for/Python/subscribe returns a 405 error page containing the English words "Method Not Allowed".

Resolving patch:
diff --git a/liberapay/utils/i18n.py b/liberapay/utils/i18n.py
--- a/liberapay/utils/i18n.py
+++ b/liberapay/utils/i18n.py
@@ -256,6 +256,8 @@ def make_sorted_dict(keys, d):
 HTTP_ERRORS = {
     403: _("Forbidden"),
     404: _("Not Found"),
+    409: _("Conflict"),
+    410: _("Gone"),
     429: _("Too Many Requests"),
     500: _("Internal Server Error"),
     502: _("Upstream Error"),


Test patch:
Repository: liberapay/liberapay.com

Issue:
SEPA Direct Debit "The payment has been initiated."-page
Problem: After starting a donation with SEPA Direct Debit you go to the "The payment has been initiated."-page. On this page you get the details to start donating with credit card, see screenshot. The Initiate the payment button is weird to see when you just started donating with SEPA Direct Debit.

Expected behaviour: Only get the confirmation and thank you message for donation.

!["The payment has been initiated."-page](https://user-images.githubusercontent.com/7106279/49143443-531e2e00-f2fb-11e8-897c-05186a99ceba.jpg)



Discussion:
Same issue for PayPal:

![image](https://user-images.githubusercontent.com/3729038/49452764-61f75b80-f7a7-11e8-8e01-202e3e88e698.png)


Resolving patch:
diff --git a/liberapay/models/participant.py b/liberapay/models/participant.py
--- a/liberapay/models/participant.py
+++ b/liberapay/models/participant.py
@@ -2247,7 +2247,7 @@ def get_tips_awaiting_renewal(self):
                          FROM payin_transfers pt
                         WHERE pt.payer = t.tipper
                           AND COALESCE(pt.team, pt.recipient) = t.tippee
-                          AND pt.status = 'succeeded'
+                          AND pt.status <> 'failed'
                           AND pt.ctime > (current_timestamp - interval '6 hours')
                         LIMIT 1
                    )


Test patch:
Repository: liberapay/liberapay.com

Issue:
Cron fails to run
The weekly cron for `create_payday_issue` is no longer running successfully at the scheduled time.


Discussion:

Resolving patch:
diff --git a/liberapay/cron.py b/liberapay/cron.py
--- a/liberapay/cron.py
+++ b/liberapay/cron.py
@@ -21,7 +21,7 @@ def __init__(self, website):
         self.exclusive_jobs = []
 
     def __call__(self, period, func, exclusive=False):
-        if not self.website.env.run_cron_jobs:
+        if not self.website.env.run_cron_jobs or not period:
             return
         if exclusive and not self.has_lock:
             self.exclusive_jobs.append((period, func))
@@ -32,7 +32,7 @@ def f():
                 while True:
                     now = datetime.utcnow()
                     then = now.replace(hour=period.hour, minute=10, second=0)
-                    days = (now.isoweekday() - period.weekday) % 7
+                    days = (period.weekday - now.isoweekday()) % 7
                     if days:
                         then += timedelta(days=days)
                     seconds = (then - now).total_seconds()


Test patch:
Repository: liberapay/liberapay.com

Issue:
Apache fails to restart when it runs out of RAM
When I woke up this morning Liberapay was down (trying to access the homepage resulted in a Cloudflare 504). Once again fixing the issue only required restarting Apache (`sudo /usr/local/bin/supervisorctl -c /opt/python/etc/supervisord.conf restart httpd`). The following lines from Apache's error log indicate what the problem is:

```
02:49:02 [Sun Jan 27 02:49:01.835468 2019] [mpm_prefork:error] [pid 25362] (12)Cannot allocate memory: AH00159: fork: Unable to fork new process
02:49:14 libgcc_s.so.1 must be installed for pthread_cancel to work
02:49:14 libgcc_s.so.1 must be installed for pthread_cancel to work
02:49:15 [Sun Jan 27 02:49:14.961561 2019] [core:notice] [pid 25362] AH00052: child pid 23990 exit signal Aborted (6)
```


Discussion:
https://mmmsoftware.blogspot.com/2014/05/apache-fails-to-handle-requests-with.html gives a potential solution, but it's only a workaround, not a clean fix of the root issue.

`gcc --print-file-name=libgcc_s.so.1` returns `/lib/../lib64/libgcc_s.so.1` which is a valid symbolic link to `/lib64/libgcc_s-7-20170915.so.1`.

https://bugs.launchpad.net/ubuntu/+source/gcc-3.3/+bug/40285 reveals that the problem is in glibc itself.

Amazon Linux uses a patched variant of an old version of glibc:

```
$ sudo yum info glibc
Loaded plugins: priorities, update-motd, upgrade-helper
23 packages excluded due to repository priority protections
Installed Packages
Name        : glibc
Arch        : x86_64
Version     : 2.17
Release     : 260.175.amzn1
Size        : 14 M
Repo        : installed
From repo   : amzn-updates
[…]
```


Resolving patch:
diff --git a/liberapay/elsewhere/_base.py b/liberapay/elsewhere/_base.py
--- a/liberapay/elsewhere/_base.py
+++ b/liberapay/elsewhere/_base.py
@@ -176,9 +176,12 @@ def get_ratelimit_headers(self, response):
             reset = response.headers.get(prefix+'reset')
 
             try:
-                limit, remaining, reset = int(limit), int(remaining), int(reset)
-                reset = datetime.fromtimestamp(reset, tz=utc)
-            except (TypeError, ValueError):
+                limit, remaining = int(limit), int(remaining)
+                if reset.isdigit():
+                    reset = datetime.fromtimestamp(int(reset), tz=utc)
+                else:
+                    reset = parse_date(reset)
+            except (OverflowError, TypeError, ValueError):
                 d = dict(limit=limit, remaining=remaining, reset=reset)
                 url = response.request.url.split('?', 1)[0]
                 logger.warning('Got weird rate headers from <%s>: %s' % (url, d))


Test patch:
Repository: liberapay/liberapay.com

Issue:
Press kit for creators?
I'd like to promote my Liberapay profile on YouTube - I couldn't find an official "press kit" or "brand guidelines" - I think it's a good thing to develop this to help popularize Liberapay.

I have downloaded the Liberapay logo in SVG from the main page, though it'd be good to have this explicitly available somewhere in a ZIP. I'm a graphic designer so  I can handles this myself, but others might not be so lucky, and might need a PNG, JPG version etc...

What do you think?


Discussion:

Resolving patch:
diff --git a/liberapay/main.py b/liberapay/main.py
--- a/liberapay/main.py
+++ b/liberapay/main.py
@@ -44,7 +44,7 @@
 from liberapay.utils.state_chain import (
     attach_environ_to_request, create_response_object, reject_requests_bypassing_proxy,
     canonize, insert_constants, _dispatch_path_to_filesystem, enforce_rate_limits,
-    handle_negotiation_exception, merge_exception_into_response,
+    handle_negotiation_exception, add_content_disposition_header, merge_exception_into_response,
     bypass_csp_for_form_redirects, return_500_for_exception,
     turn_socket_error_into_50X, overwrite_status_code_of_gateway_errors,
 )
@@ -187,6 +187,7 @@ def _assert(x):
 
     algorithm['load_resource_from_filesystem'],
     algorithm['render_response'],
+    add_content_disposition_header,
     handle_negotiation_exception,
 
     tell_sentry,
diff --git a/liberapay/utils/state_chain.py b/liberapay/utils/state_chain.py
--- a/liberapay/utils/state_chain.py
+++ b/liberapay/utils/state_chain.py
@@ -153,6 +153,17 @@ def handle_negotiation_exception(exception):
     return {'response': response, 'exception': None}
 
 
+def add_content_disposition_header(request, response):
+    """Tell the browser if the response is meant to be saved into a file.
+
+    https://tools.ietf.org/html/rfc6266 and https://tools.ietf.org/html/rfc8187
+    """
+    save_as = request.qs.get('save_as')
+    if save_as:
+        save_as = urlquote(save_as, encoding='utf8').encode('ascii')
+        response.headers[b'Content-Disposition'] = b"attachment; filename*=UTF-8''" + save_as
+
+
 def merge_exception_into_response(state, exception, response=None):
     if response is None or not isinstance(exception, Response):
         return


Test patch:
Repository: liberapay/liberapay.com

Issue:
Requests access to GitHub private repos?
Hi. I'm a brand-new user. I have a question I didn't see in the FAQ or when I searched issues here.

I was going to connect my GitHub account and saw this:

> Liberapay by liberapay
> wants to access your greghendershott account
> 
> Organizations and teams
> Read-only access
>
> This application will be able to read your organization and team membership and private Projects.

I almost clicked OK, but noticed "**private** Projects". I stopped. I don't want to do that.

Is this as-intended?


Discussion:

Resolving patch:
diff --git a/liberapay/elsewhere/github.py b/liberapay/elsewhere/github.py
--- a/liberapay/elsewhere/github.py
+++ b/liberapay/elsewhere/github.py
@@ -18,7 +18,6 @@ class GitHub(PlatformOAuth2):
     auth_url = 'https://github.com/login/oauth/authorize'
     access_token_url = 'https://github.com/login/oauth/access_token'
     oauth_email_scope = 'user:email'
-    oauth_default_scope = ['read:org']
 
     # API attributes
     api_format = 'json'


Test patch:
diff --git a/tests/py/test_elsewhere.py b/tests/py/test_elsewhere.py
--- a/tests/py/test_elsewhere.py
+++ b/tests/py/test_elsewhere.py
@@ -260,7 +260,7 @@ def test_take_over(self):
         response = self.client.PxST('/on/take-over.html', data=data, auth_as=self.bob,
                                     cookies=self.connect_cookie)
         assert response.code == 302
-        assert response.headers[b'Location'] == b'/bob/edit'
+        assert response.headers[b'Location'].endswith(b'/bob/edit/elsewhere')
 
 
 class TestFriendFinder(Harness):
Repository: liberapay/liberapay.com

Issue:
In some cases the "Giving" page is completely empty
When one member doesn't give nothing, then [the giving page](https://liberapay.com/me/giving/) is kind of empty. Example:

![lpbug](https://user-images.githubusercontent.com/8705846/48138813-619d9a80-e2a5-11e8-863a-179905a19eec.png)

It could be great to add a message like the following: _"You're actually not giving anything. Be nice, find a project that is useful for you and give something, even a small donation."_, plus maybe a incentive to give to LiberaPay.



Discussion:
related to https://github.com/liberapay/liberapay.com/issues/1322

Resolving patch:
diff --git a/liberapay/models/participant.py b/liberapay/models/participant.py
--- a/liberapay/models/participant.py
+++ b/liberapay/models/participant.py
@@ -2285,7 +2285,7 @@ def get_giving_details(self):
                   FROM tips t
                   JOIN participants p ON p.id = t.tippee
                  WHERE tipper = %s
-                   AND p.status = 'active'
+                   AND p.status <> 'stub'
               ORDER BY tippee
                      , t.mtime DESC
 


Test patch:
Repository: liberapay/liberapay.com

Issue:
PayPal doesn't handle all currencies properly
In the past 6 months we've had 15 payments through PayPal fail with the error message `Currency is not supported`. The currencies were IDR, INR, MYR, CNY, ZAR and ISK.


Discussion:

Resolving patch:
diff --git a/liberapay/constants.py b/liberapay/constants.py
--- a/liberapay/constants.py
+++ b/liberapay/constants.py
@@ -353,6 +353,12 @@ def __missing__(self, currency):
     """.split()),  # https://stripe.com/global
 }
 
+# https://developer.paypal.com/docs/api/reference/currency-codes/
+PAYPAL_CURRENCIES = set("""
+    AUD CAD CHF CZK DKK EUR GBP HKD HUF ILS JPY MXN NOK NZD PHP PLN RUB SEK SGD
+    THB TWD USD
+""".split())
+
 PERIOD_CONVERSION_MAP = {
     ('weekly', 'weekly'): Decimal(1),
     ('monthly', 'weekly'): Decimal(12) / Decimal(52),
diff --git a/liberapay/models/participant.py b/liberapay/models/participant.py
--- a/liberapay/models/participant.py
+++ b/liberapay/models/participant.py
@@ -25,7 +25,7 @@
 from liberapay.constants import (
     ASCII_ALLOWED_IN_USERNAME, AVATAR_QUERY, BASE64URL_CHARS, CURRENCIES,
     DONATION_LIMITS, EMAIL_VERIFICATION_TIMEOUT, EVENTS, HTML_A,
-    PASSWORD_MAX_SIZE, PASSWORD_MIN_SIZE, PAYMENT_SLUGS,
+    PASSWORD_MAX_SIZE, PASSWORD_MIN_SIZE, PAYMENT_SLUGS, PAYPAL_CURRENCIES,
     PERIOD_CONVERSION_RATES, PRIVILEGES, PROFILE_VISIBILITY_ATTRS,
     PUBLIC_NAME_MAX_SIZE, SEPA, SESSION, SESSION_REFRESH, SESSION_TIMEOUT,
     USERNAME_MAX_SIZE, USERNAME_SUFFIX_BLACKLIST,
@@ -1724,10 +1724,17 @@ def get_currencies_for(self, tippee, tip):
             tip = tip.__dict__
         tip_currency = tip['amount'].currency
         accepted = tippee.accepted_currencies_set
+        fallback_currency = tippee.main_currency
+        if tippee.payment_providers == 2:
+            accepted = PAYPAL_CURRENCIES.intersection(accepted)
+            if not accepted:
+                # The tippee's currency preferences are unsatisfiable, ignore them.
+                accepted = PAYPAL_CURRENCIES
+                fallback_currency = 'USD'
         if tip_currency in accepted:
             return tip_currency, accepted
         else:
-            return tippee.main_currency, accepted
+            return fallback_currency, accepted
 
 
     # More Random Stuff


Test patch:
Repository: liberapay/liberapay.com

Issue:
Facebook link broken
[My profile](https://liberapay.com/revi/) has a link to FaceBook ([this](https://www.facebook.com/profile.php?id=1828376324056378)) but clicking the link produces 'not available' error.

I guess this is because I have a custom [username](https://fb.com/hym411) set, so the `profile.php?id=` doesn't work.

For the record, I once deleted the facebook integration and then re-added the credentials, no luck. (The username has been set since 2013 or 2014 so it's unlikely username was updated after joining liberapay.)


Discussion:
We've received an email saying that links to Facebook profiles are broken once again:

> Hi!
>
> The linking to Facebook acounts at Liberapay does not work anymore.
> Links are being created but they just lead to error messages at
> Facebook:
> 
> "Sorry, this content isn't available right now
> The link you followed may have expired, or the page may only be
> visible to an audience you're not in."
> 
> At least that's what I see on my account: […]
> 
> It seems that Facebook has shut off this functionality:
> 
> https://developers.facebook.com/blog/post/2018/04/19/facebook-login-changes-address-abuse/
Related issue: #664.

Resolving patch:
diff --git a/liberapay/elsewhere/facebook.py b/liberapay/elsewhere/facebook.py
--- a/liberapay/elsewhere/facebook.py
+++ b/liberapay/elsewhere/facebook.py
@@ -9,7 +9,7 @@ class Facebook(PlatformOAuth2):
     name = 'facebook'
     display_name = 'Facebook'
     fontawesome_name = 'facebook-square'
-    account_url = 'https://www.facebook.com/app_scoped_user_id/{user_id}/'
+    account_url = None
     optional_user_name = True
 
     # Auth attributes
diff --git a/liberapay/models/participant.py b/liberapay/models/participant.py
--- a/liberapay/models/participant.py
+++ b/liberapay/models/participant.py
@@ -1000,6 +1000,7 @@ def add_email(self, email, cursor=None):
                                 ELSE excluded.added_time
                             END)
                           , address = excluded.address
+                          , nonce = coalesce(e.nonce, excluded.nonce)
                   RETURNING *
             """, (email, str(uuid.uuid4()), self.id))
             if email_row.disavowed:


Test patch:
Repository: liberapay/liberapay.com

Issue:
Enhance 'too many failed logins' exception message
I recently got the ```There have been too many attempts to log in to this account recently, please try again in a few hours or log in via email.``` error message and didn't know how to login via email.

I'm happy to contribute and enhance the error message to something along the lines of;
```There have been too many failed attempts to log in to this account recently, please try again in a few hours. You can reset your password by entering your email address on the login page while leaving the password field empty.```

I can see the change needs to be made to ```liberapay/exceptions.py``` but would you suggest making the change in all the other i18n files where this appears, and if so, do I need to alert anyone else maintaining those translations.

Happy to take suggestions on rewording the message above, this is just a first stab. If there are any other considerations I need to take into account like the maximum length of the error message just let me know.


Discussion:
It's probably better to leave the error message as it is and add a "Log in via email" button under it.

Resolving patch:
diff --git a/liberapay/exceptions.py b/liberapay/exceptions.py
--- a/liberapay/exceptions.py
+++ b/liberapay/exceptions.py
@@ -226,9 +226,13 @@ def msg(self, _):
             "or contact support@liberapay.com."
         )
 
-class TooManyPasswordLogins(LazyResponseXXX):
-    code = 429
-    def msg(self, _):
+class TooManyPasswordLogins(LazyResponse):
+
+    def __init__(self, participant_id):
+        Response.__init__(self, 429, '')
+        self.html_template = 'templates/too-many-password-logins.html'
+
+    def lazy_body(self, _):
         return _(
             "There have been too many attempts to log in to this account recently, "
             "please try again in a few hours or log in via email."
diff --git a/liberapay/security/authentication.py b/liberapay/security/authentication.py
--- a/liberapay/security/authentication.py
+++ b/liberapay/security/authentication.py
@@ -57,7 +57,7 @@ def sign_in_with_form_data(body, state):
         src_addr, src_country = request.source, request.country
         website.db.hit_rate_limit('log-in.ip-addr', str(src_addr), TooManyLogInAttempts)
         website.db.hit_rate_limit('log-in.country', src_country, TooManyLogInAttempts)
-        id = body.pop('log-in.id').strip()
+        id = body['log-in.id'].strip()
         password = body.pop('log-in.password', None)
         k = 'email' if '@' in id else 'username'
         if password:
diff --git a/liberapay/website.py b/liberapay/website.py
--- a/liberapay/website.py
+++ b/liberapay/website.py
@@ -14,7 +14,7 @@
 env = Environment(
     ASPEN_CHANGES_RELOAD=is_yesish,
     ASPEN_PROJECT_ROOT=str,
-    ASPEN_SHOW_TRACEBACKS=str,
+    ASPEN_SHOW_TRACEBACKS=is_yesish,
     ASPEN_WWW_ROOT=str,
     AWS_ACCESS_KEY_ID=str,
     AWS_SECRET_ACCESS_KEY=str,


Test patch:
Repository: liberapay/liberapay.com

Issue:
Automatic renewal failure due to currency mismatch
Stripe error message: `The currency specified (gbp) does not match the currency on the source (eur). A payment can only be created for the same currency as the corresponding source. (request ID: req_PSmPQ85CKvW5kz)`.
SEPA Direct Debit failures
A European donor who tried to send money to a Canadian got the following error message from Stripe: `For 'sepa_debit' payments, we currently require your account to have a bank account in one of the following currencies: eur, usd, gbp, sek, nok, dkk, chf`.
SEPA Direct Debit failures
A European donor who tried to send money to a Canadian got the following error message from Stripe: `For 'sepa_debit' payments, we currently require your account to have a bank account in one of the following currencies: eur, usd, gbp, sek, nok, dkk, chf`.


Discussion:

Resolving patch:
diff --git a/liberapay/payin/cron.py b/liberapay/payin/cron.py
--- a/liberapay/payin/cron.py
+++ b/liberapay/payin/cron.py
@@ -159,6 +159,7 @@ def execute_scheduled_payins():
                   WHERE r.participant = sp.payer
                     AND r.status = 'chargeable'
                     AND r.network::text LIKE 'stripe-%%'
+                    AND ( sp.amount::currency = 'EUR' OR r.network <> 'stripe-sdd' )
                ORDER BY r.is_default NULLS LAST
                       , r.network = 'stripe-sdd' DESC
                       , r.ctime DESC


Test patch:
Repository: liberapay/liberapay.com

Issue:
"Your request has been rejected by our software"
On login, I keep getting this error:

```
URL: https://liberapay.com/~1609406/giving/
Method: POST
Referer: b'https://liberapay.com/~1609406/giving/'
Response code: 403
Response message: 'A security check has failed. Please make sure your browser is configured to allow cookies for liberapay.com, then try again.'
```

I have tried Android and Mac OS with Brave (Version 1.0.1 Chromium: 78.0.3904.108 (Official Build) (64-bit)), and have tried with all cookies enabled (including 3rd party cookies).


Discussion:
Same report here
Also happens in private navigation
It happens when you click on the confirmation link in the email.
If you login at the top of the page you don't have this issue
I've found the problem and I should be able to fix it soon. In the meantime the workaround is to log in via <https://liberapay.com/log-in>.
This is now fixed in production. I'm working on a proper patch including a regression test.

Resolving patch:
diff --git a/liberapay/main.py b/liberapay/main.py
--- a/liberapay/main.py
+++ b/liberapay/main.py
@@ -210,17 +210,16 @@ def _assert(x):
     turn_socket_error_into_50X,
     algorithm['get_response_for_exception'],
 
+    delegate_error_to_simplate,
+    tell_sentry,
+
     bypass_csp_for_form_redirects,
     authentication.add_auth_to_response,
     csrf.add_token_to_response,
     http_caching.add_caching_to_response,
-
-    delegate_error_to_simplate,
-    tell_sentry,
-    return_500_for_exception,
-
     overwrite_status_code_of_gateway_errors,
 
+    return_500_for_exception,
     tell_sentry,
 ]
 


Test patch:
diff --git a/tests/py/test_state_chain.py b/tests/py/test_state_chain.py
--- a/tests/py/test_state_chain.py
+++ b/tests/py/test_state_chain.py
@@ -152,6 +152,11 @@ def test_csrf_cookie_set_for_log_in_page(self):
         r = self.client.GET('/log-in')
         assert csrf.CSRF_TOKEN in r.headers.cookie
 
+    def test_csrf_cookie_set_in_LoginRequired_response(self):
+        r = self.client.GET('/~1/giving/', raise_immediately=False)
+        assert r.code == 403
+        assert csrf.CSRF_TOKEN in r.headers.cookie
+
     def test_no_csrf_cookie_set_for_homepage(self):
         r = self.client.GET('/')
         assert csrf.CSRF_TOKEN not in r.headers.cookie