Add infrastructure for generating reports

Fix workflow

Add gh token input to workflow

Fix paths and unterminated quotes in py script

Escape strikethrough markdown syntax

Populate action inputs for PR create
This commit is contained in:
syeopite 2021-07-19 18:41:40 -07:00
parent b2988757a7
commit 369badd56d
No known key found for this signature in database
GPG Key ID: 6FA616E5A5294A82
4 changed files with 159 additions and 0 deletions

52
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,52 @@
on:
workflow_dispatch:
schedule:
- cron: "30 0 1 * *"
jobs:
TemplateTransparencyReport:
runs-on: ubuntu-latest
name: Template the transparency report for iv-org
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.head_ref }}
- name: "Fetch data for report"
uses: syeopite/transparency-data-fetcher-for-iv-org@v1.1
id: data_fetch_step
with:
github-token: ${{ github.token }}
- name: "Setup python for templating report"
uses: actions/setup-python@v2
with:
python-version: 3.9.5
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r src/requirements.txt
- name: Template report
run: |
python src/generate.py '${{ steps.data_fetch_step.outputs.fetched-btc-bounty-data }}'
# Auto commit resulting md file
- name: "Auto commiting resulting markdown instance list"
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: Template transparency report for ${date -d "$(date +%Y-%m)-15 last month" '+%Y-%m'}
file_pattern: ${date -d "$(date +%Y-%m)-15 last month" '+%Y-%m'}.md
# https://github.com/iv-org/invidious/blob/ad7fefae1ca0b734fbe986eb8bb13f1996e2f5f8/.github/workflows/monthly_release.yml#L13
- id: fetch_date
run: echo ::set-output name=date::$(date -d "$(date +%Y-%m)-15 last month" '+%B-%Y')
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
delete-branch: true
body: This is the template for the ${{ steps.fetch_date.outputs.date }} transparency report
title: ${{ steps.fetch_date.outputs.date }} transparency report
branch: ${{ steps.fetch_date.outputs.date }}-Report

101
src/generate.py Normal file
View File

@ -0,0 +1,101 @@
import datetime
import json
import re
import sys
from urllib import request
from dateutil.parser import isoparse
from dateutil.relativedelta import relativedelta
from mdutils.mdutils import MdUtils
conversation_rate_in_time_regex = re.compile(r"avg: [$€](?P<rate>\d+)", re.MULTILINE)
def get_coin_conversion_rate(fiat, date=None):
# Request the converstion rate between BTC and the selected fiat currency
url = f"https://{fiat}.rate.sx/"
if date:
date = isoparse(date)
url += f"BTC@{date.strftime('%Y-%m-%d+%Hh%Mm%Ss')}" \
f"?T&q"
else:
url += "1BTC"
with request.urlopen(url) as connection:
conversion = connection.read().decode("utf-8")
if date:
return float(conversation_rate_in_time_regex.search(conversion)["rate"])
else:
return float(conversion)
def get_fiat_conversion_rate(fiat_a, fiat_b, date=None):
# Request frankfurter.app for the converstion rate between two currencies.
#
# Parameters:
# fiat_a: Fiat A (to convert from)
# fiat_b: Fiat B (to convert two)
# date:
# If specified, requests the converstion rate between the two given currencies at the given
#
url = f"https://api.frankfurter.app"
if date:
date = isoparse(date)
url += f"/{date.strftime('%Y-%m-%d')}"
else:
url += "/latest"
url += f"?from={fiat_a}&to={fiat_b}"
with request.urlopen(url) as connection:
return json.load(connection)["rates"][fiat_b.upper()]
current_time = datetime.datetime.utcnow()
with open("src/known-data.json", "r") as file:
known_data = json.load(file)
new_transparency_data = json.loads(sys.argv[1])
# Calculate new funds
current_funds = known_data["total_current_btc_funds"] + new_transparency_data["new_btc_previous_month"]
for bounty in new_transparency_data["bounty_costs"]:
current_funds - float(bounty["bounty_cost_crypto"].strip(" BTC"))
usd_to_btc = get_coin_conversion_rate("usd")
eur_to_btc = get_coin_conversion_rate("eur")
btc_price_str = f"~€{round(eur_to_btc, 2)} or \~${round(usd_to_btc, 2)}"
# Create header
md = MdUtils(file_name=f"finance/{(current_time - relativedelta(months=1)).strftime('%Y-%m')}.md")
md.new_header(level=1, title=f"Finances for {(current_time - relativedelta(months=1)).strftime('%B %Y')}")
# Donations section
md.new_header(level=2, title="Donations:")
if not new_transparency_data["new_btc_previous_month"]:
md.new_paragraph("Bitcoin (BTC): None")
else:
md.new_paragraph(f"Bitcoin (BTC): {new_transparency_data['new_btc_previous_month']} BTC worth"
f" ~€{round(new_transparency_data['new_btc_previous_month'] * eur_to_btc, 2)}"
f" at the time of publishing (Bitcoin price {btc_price_str})")
md.new_paragraph("Monero (XMR): X XMR worth ~€X at the time of publishing (Monero price \~€X or \~$X)")
md.new_header(level=2, title="Expenses:")
for bounty in new_transparency_data["bounty_costs"]:
usd_to_btc_rate_at_time = get_coin_conversion_rate("usd", date=bounty['date'])
usd_to_eur_rate_at_time = get_fiat_conversion_rate("usd", "eur", date=bounty['date'])
usd_bounty_cost = float(bounty['bounty_cost_crypto'].strip(' BTC')) * usd_to_btc_rate_at_time
md.new_paragraph(f"Bounty ({bounty['url']}): {bounty['bounty_cost_crypto']} worth ~ "
f"{round(usd_bounty_cost * usd_to_eur_rate_at_time, 2)} (~${round(usd_bounty_cost, 2)})")
md.new_header(level=2, title="Current funds:")
md.new_paragraph(f"Bitcoin (BTC): {current_funds} BTC worth ~€{round(current_funds * eur_to_btc, 2)} "
f"(\~${round(current_funds * usd_to_btc, 2)}) at the time of publishing "
f"(Bitcoin price {btc_price_str})")
md.new_paragraph("Monero (XMR): X XMR worth ~€X (\~$X) at the time of publishing (Monero price ~€X or \~$X)")
md.create_md_file()
# Now we update the known data
known_data["total_current_btc_funds"] = current_funds
with open("src/known-data.json", "w") as file:
json.dump(known_data, file)

1
src/known-data.json Normal file
View File

@ -0,0 +1 @@
{"total_current_btc_funds": 0.30957846}

5
src/requirements.txt Normal file
View File

@ -0,0 +1,5 @@
dateutils==0.6.12
mdutils==1.3.1
python-dateutil==2.8.2
pytz==2021.1
six==1.16.0