mirror of
https://github.com/iv-org/transparency.git
synced 2025-03-14 19:16:38 -04:00
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:
parent
b2988757a7
commit
369badd56d
52
.github/workflows/ci.yml
vendored
Normal file
52
.github/workflows/ci.yml
vendored
Normal 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
101
src/generate.py
Normal 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
1
src/known-data.json
Normal file
@ -0,0 +1 @@
|
||||
{"total_current_btc_funds": 0.30957846}
|
5
src/requirements.txt
Normal file
5
src/requirements.txt
Normal 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
|
Loading…
x
Reference in New Issue
Block a user