M config.ini.example => config.ini.example +5 -0
@@ 66,5 66,10 @@ patreon-campaign=
# Optional LiberaPay integration, fill in your username here
liberapay-campaign=
+# Optional GitHub sponsors integration
+# Generate personal access key at https://github.com/settings/tokens
+# Must have "user" access.
+github-token=
+
# Command to reload fosspay (send it a SIGHUP)
reload-command=kill -HUP $(pgrep -xf '/usr/bin/python3.*app.py' | tail -n 1)
M cronjob.py => cronjob.py +1 -1
@@ 12,7 12,7 @@ import subprocess
stripe.api_key = _cfg("stripe-secret")
-print("Processing monthly donations")
+print("Processing monthly donations at " + str(datetime.utcnow()))
donations = Donation.query \
.filter(Donation.type == DonationType.monthly) \
M fosspay/blueprints/html.py => fosspay/blueprints/html.py +41 -6
@@ 70,14 70,49 @@ def index():
lp_count = 0
lp_sum = 0
+ github_token = _cfg("github-token")
+ if github_token:
+ query = """
+ {
+ viewer {
+ login
+ sponsorsListing {
+ tiers(first:100) {
+ nodes {
+ monthlyPriceInCents
+ adminInfo {
+ sponsorships(includePrivate:true) {
+ totalCount
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ """
+ r = requests.post("https://api.github.com/graphql", json={
+ "query": query
+ }, headers={
+ "Authorization": f"bearer {github_token}"
+ })
+ result = r.json()
+ nodes = result["data"]["viewer"]["sponsorsListing"]["tiers"]["nodes"]
+ cnt = lambda n: n["adminInfo"]["sponsorships"]["totalCount"]
+ gh_count = sum(cnt(n) for n in nodes)
+ gh_sum = sum(n["monthlyPriceInCents"] * cnt(n) for n in nodes)
+ gh_user = result["data"]["viewer"]["login"]
+ else:
+ gh_count = 0
+ gh_sum = 0
+
return render_template("index.html", projects=projects,
avatar=avatar, selected_project=selected_project,
- recurring_count=recurring_count,
- recurring_sum=recurring_sum,
- patreon_count=patreon_count,
- patreon_sum=patreon_sum,
- lp_count=lp_count,
- lp_sum=lp_sum, currency=currency)
+ recurring_count=recurring_count, recurring_sum=recurring_sum,
+ patreon_count=patreon_count, patreon_sum=patreon_sum,
+ lp_count=lp_count, lp_sum=lp_sum,
+ gh_count=gh_count, gh_sum=gh_sum, gh_user=gh_user,
+ currency=currency)
@html.route("/setup", methods=["POST"])
def setup():
M templates/goal.html => templates/goal.html +21 -2
@@ 2,8 2,8 @@
<div class="container" style="padding-top: 5rem">
<div class="row">
<div class="col-md-8 col-md-offset-2">
- {% set total_sum = recurring_sum + patreon_sum + lp_sum %}
- {% set total_count = recurring_count + patreon_count + lp_count %}
+ {% set total_sum = recurring_sum + patreon_sum + lp_sum + gh_sum %}
+ {% set total_count = recurring_count + patreon_count + lp_count + gh_count %}
{% if _cfg("goal") %}
{% set goal = int(_cfg("goal")) %}
@@ 17,6 17,7 @@
{% set recurring_progress = recurring_sum / adjusted_goal %}
{% set patreon_progress = patreon_sum / adjusted_goal %}
{% set lp_progress = lp_sum / adjusted_goal %}
+ {% set gh_progress = gh_sum / adjusted_goal %}
{% set progress = total_sum / goal %}
<div class="progress" style="height: 3rem">
<div
@@ 39,6 40,13 @@
>
<span>{{ currency.amount("{:.0f}".format(lp_sum / 100)) }}</span>
</div>
+
+ <div
+ class="progress-bar progress-bar-primary"
+ style="width: {{ gh_progress * 100 }}%; line-height: 2.5"
+ >
+ <span>{{ currency.amount("{:.0f}".format(gh_sum / 100)) }}</span>
+ </div>
</div>
{% endif %}
</div>
@@ 73,6 81,17 @@
</a></strong> ({{ lp_count }} supporter{{ "s" if lp_count != 1 else "" }})
</p>
{% endif %}
+ {% if gh_count %}
+ <p>
+ {{ currency.amount("{:.2f}".format(gh_sum / 100)) }}/mo
+ via
+ <strong><a
+ class="text-primary"
+ href="https://github.com/{{gh_user}}">
+ GitHub <i class="glyphicon glyphicon-share"></i>
+ </a></strong> ({{ gh_count }} supporter{{ "s" if lp_count != 1 else "" }})
+ </p>
+ {% endif %}
{% endif %}
{% if goal %}
<p class="{{ "text-center" if not patreon_sum else "" }}">