Esempio n. 1
0
File: user.py Progetto: pegasy/Titan
def patreon_sync_post():
    if "patreon" not in session:
        abort(401)
    api_client = patreon.API(session["patreon"]["access_token"])
    user_response = api_client.fetch_user(
        None, {
            'pledge': [
                "amount_cents", "total_historical_amount_cents",
                "declined_since", "created_at", "pledge_cap_cents",
                "patron_pays_fees", "outstanding_payment_amount_cents"
            ]
        })
    user = user_response.data()
    if not (user):
        abort(403)
    usr = format_patreon_user(user)
    if usr["titan"]["eligible_tokens"] <= 0:
        return ('', 402)
    dbpatreon = db.session.query(Patreon).filter(
        Patreon.user_id == usr["id"]).first()
    if not dbpatreon:
        dbpatreon = Patreon(usr["id"])
    dbpatreon.total_synced = usr["titan"]["total_cents_pledged"]
    db.session.add(dbpatreon)
    set_titan_token(
        session["user_id"], usr["titan"]["eligible_tokens"],
        "PATREON {} [{}]".format(usr["attributes"]["full_name"], usr["id"]))
    add_badge(session["user_id"], "supporter")
    session["tokens"] = get_titan_token(session["user_id"])
    return ('', 204)
Esempio n. 2
0
def index():
    if User.query.count() == 0:
        load_config()
        return render_template("setup.html")
    projects = sorted(Project.query.all(), key=lambda p: p.name)
    avatar = "//www.gravatar.com/avatar/" + hashlib.md5(
        _cfg("your-email").encode("utf-8")).hexdigest()
    selected_project = request.args.get("project")
    if selected_project:
        try:
            selected_project = int(selected_project)
        except:
            selected_project = None
    active_recurring = (Donation.query.filter(
        Donation.type == DonationType.monthly).filter(
            Donation.active == True).filter(Donation.hidden == False))
    recurring_count = active_recurring.count()
    recurring_sum = sum([d.amount for d in active_recurring])

    access_token = _cfg("patreon-access-token")
    campaign = _cfg("patreon-campaign")
    if access_token and campaign:
        try:
            import patreon
            client = patreon.API(access_token)
            campaign = client.fetch_campaign()
            attrs = campaign.json_data["data"][0]["attributes"]
            patreon_count = attrs["patron_count"]
            patreon_sum = attrs["pledge_sum"]
        except:
            patreon_count = 0
            patreon_sum = 0
    else:
        patreon_count = 0
        patreon_sum = 0

    liberapay = _cfg("liberapay-campaign")
    if liberapay:
        lp = (requests.get(
            "https://liberapay.com/{}/public.json".format(liberapay))).json()
        lp_count = lp['npatrons']
        lp_sum = int(float(lp['receiving']['amount']) * 100)
        # Convert from weekly to monthly
        lp_sum = lp_sum * 52 // 12
    else:
        lp_count = 0
        lp_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)
Esempio n. 3
0
 def authenticate(self):
     """Authenticate with Patreon API"""
     oauth_client = patreon.OAuth(self.client_id, self.client_secret)
     tokens = oauth_client.get_tokens(request.args.get('code'),
                                      '/oauth/redirect')
     access_token = tokens['access_token']
     api_client = patreon.API(access_token)
     return api_client
Esempio n. 4
0
    def getApiClient(self, request):
        """ Called after callback was triggered to fetch acccess_token and
        API instance.
        Returns (token, api)
        """
        oauth_client = patreon.OAuth(self.client_id, self.client_secret)
        tokens = oauth_client.get_tokens(request.query.code, self.callback)
        access_token = tokens['access_token']

        return access_token, patreon.API(access_token)
Esempio n. 5
0
def patreon_callback():
    headers = {
        "User-Agent": user_agent_string(),
        "Content-Type": "application/x-www-form-urlencoded"
    }

    params = {
        "code": request.args.get('code'),
        "grant_type": "authorization_code",
        "client_id": config.patreon_id,
        "client_secret": config.patreon_secret,
        "redirect_uri": config.patreon_redirect
    }

    r = requests.post(config.patreon_token_url, headers=headers, data=params)

    session['patreon_oauth2_token'] = r.json()['access_token']
    session['patreon_refresh_token'] = r.json()['refresh_token']

    api_client = patreonlib.API(session['patreon_oauth2_token'])
    user_response = api_client.fetch_user()
    user = user_response.data()

    session['patreon_user_id'] = user.id()

    pledges = user.relationship('pledges')
    pledge = pledges[0] if pledges and len(pledges) > 0 else None

    headers = {
        "User-Agent": user_agent_string(),
        "Content-Type": "application/x-www-form-urlencoded"
    }

    params = {
        "grant_type": "refresh_token",
        "refresh_token": session['patreon_refresh_token'],
        "client_id": config.patreon_id,
        "client_secret": config.patreon_secret
    }

    r = requests.post(config.patreon_token_url, headers=headers, data=params)

    session['access_token'] = r.json()['access_token']
    session['refresh_token'] = r.json()['refresh_token']

    if pledge is not None:
        if pledge['attributes']['declined_since'] is None:
            if pledge['attributes']['amount_cents'] == 100:
                session['pledge'] = 1
            elif pledge['attributes']['amount_cents'] == 500:
                session['pledge'] = 2
            return check_pledge()
    else:
        del session['patreon_oauth2_token']
        return redirect('/nopledge')
Esempio n. 6
0
def patreon_payout():
    # Only perform on day 1 of a month
    if not datetime.now().day == 1:
        log.debug("Not first day of the month, not paying out patrons.")
        return None

    first_run = False

    if not os.path.exists(PAYOUTS_FILE_PATH):
        write_config('payouts', {'last_payout_month': datetime.now().month})
        first_run = True

    payout_data = read_config("payouts")
    if datetime.now().month != payout_data['last_payout_month'] or first_run:
        log.info("Paying out patrons...")
        api_client = patreon.API(read_config("config")["patreon_token"])
        pledges = {}
        users = {}
        all_data = api_client.fetch_campaign_and_patrons(
        )._all_resource_json_data()
        for data in all_data:
            if 'type' in data:
                if data['type'] == 'pledge':
                    pledges[data['relationships']['patron']['data']
                            ['id']] = data['attributes']
                elif data['type'] == 'user':
                    users[data['id']] = data['attributes']
        user_info = read_config("players")
        for user_id, pledge in pledges.items():
            active = pledge['declined_since'] == None
            log.info(
                f"{users[user_id]['email']} is paying {pledge['amount_cents'] / 100}$, active is {active}"
            )
            if user_info[users[user_id]['email']] == None:
                log.warning(
                    f"Tried to payout user with email {users[user_id]['email']} but it does not have SteamID set."
                )
                broadcast(
                    "There was a problem during payout to one of the patrons, SteamID not set, please contact administrator.",
                    True)
                continue
            if not active:
                log.warning(
                    f"User {users[user_id]['email']} canceled subscription. Not paying."
                )
                continue
            rcon_command(
                f"ScriptCommand TCsAR AddArcTotal {user_info[users[user_id]['email']]} {pledge['amount_cents'] / 100}"
            )

    else:
        log.debug(
            "Not paying out patrons because it's the same month as we payed already."
        )
Esempio n. 7
0
def patreon_sync_get():
    if "patreon" not in session:
        return redirect(url_for("user.patreon_landing"))
    api_client = patreon.API(session["patreon"]["access_token"])
    user_response = api_client.fetch_user(None, {
        'pledge': ["amount_cents", "total_historical_amount_cents", "declined_since", "created_at", "pledge_cap_cents", "patron_pays_fees", "outstanding_payment_amount_cents"]
    })
    user = user_response.data()
    if not (user):
        del session["patreon"]
        return redirect(url_for("user.patreon_landing"))
    return render_template("patreon.html.j2", state="prepare", user=format_patreon_user(user))
Esempio n. 8
0
    async def renew(self):
        async with self.pool.acquire() as connection:
            for user in await connection.fetch('SELECT * FROM premium'):
                if user['check'] is False:
                    return
                api_client = patreonlib.API(user['patreon_token'])
                user_response = api_client.fetch_user()
                patreon_user = user_response.data()
                pledges = patreon_user.relationship('pledges')
                pledge = pledges[0] if pledges and len(pledges) > 0 else None

                patreon_type = None

                if pledge is not None:
                    if pledge['attributes']['declined_since'] is None:
                        if pledge['attributes']['amount_cents'] == 100:
                            patreon_type = 1
                        elif pledge['attributes']['amount_cents'] == 500:
                            patreon_type = 2
                else:
                    statement = await connection.prepare(
                        'DELETE FROM premium WHERE user_id = $1')

                    return await statement.fetchval(user['user_id'])

                headers = {
                    "User-Agent": user_agent_string(),
                    "Content-Type": "application/x-www-form-urlencoded"
                }

                params = {
                    "grant_type": "refresh_token",
                    "refresh_token": user['refresh_token'],
                    "client_id": config.patreon_id,
                    "client_secret": config.patreon_secret
                }

                r = requests.post(config.patreon_token_url,
                                  headers=headers,
                                  data=params)

                token = r.json()['access_token']
                refresh_token = r.json()['refresh_token']

                statement = await connection.prepare(
                    'UPDATE premium SET patreon_token = $1, refresh_token = $2, type = $3'
                )

                await statement.fetchval(token, refresh_token, patreon_type)

                Timer(60 * 60 * 24, self.run_renew).start()
Esempio n. 9
0
    async def init(self, access_token):
        """Init the Patreon api

        @param str access_token

        --

        @return None"""

        # Init the patreon api client
        if self.client is None:
            self.client = patreon.API(access_token)

        return
Esempio n. 10
0
def get_patrons():
    p_auth = PatreonAuth(PATREON_CONFIG_FILE)
    access_token = p_auth.auth()

    client = patreon.API(access_token=access_token)

    campaigns = client.get_campaigns(page_size=10)

    if not isinstance(campaigns, JSONAPIParser):
        raise Exception('Could not get campaigns')

    campaign_id = campaigns.data()[0].id()

    members = []
    cursor = None
    while True:
        members_response = client.get_campaigns_by_id_members(
            campaign_id,
            page_size=10,
            cursor=cursor,
            fields={
                'member': [
                    patreon.schemas.member.Attributes.full_name, patreon.
                    schemas.member.Attributes.currently_entitled_amount_cents,
                    patreon.schemas.member.Attributes.email,
                    patreon.schemas.member.Attributes.patron_status
                ]
            })
        members += members_response.data()
        try:
            cursor = client.extract_cursor(members_response)
        except Exception as e:
            if type(e) == Exception:
                break  # хак, чтобы либа завершила пагинацию

            raise

    res = [
        PatronInfo(
            name=member.attribute('full_name'),
            email=member.attribute('email'),
            pledge_cents=member.attribute('currently_entitled_amount_cents'),
        ) for member in members
        if member.attribute('patron_status') == 'active_patron'
    ]

    return res
Esempio n. 11
0
    def handle(self, *args, **options):
        api_client = patreon.API(os.getenv('PATREON_ACCESS_TOKEN'))
        per_page = 20
        processed = 0

        pledges, cursor = api_client.fetch_page_of_pledges(318380,
                                                           per_page,
                                                           return_cursor=True)
        processed += self.process_pledges(pledges)

        while 'next' in pledges['links']:
            # Get the next page
            pledges, cursor = api_client.fetch_page_of_pledges(
                318380, per_page, cursor, return_cursor=True)
            processed += self.process_pledges(pledges)

        assert processed == pledges['meta']['count']
Esempio n. 12
0
def update_user_for_tokens(patreon_refresh_token, patreon_access_token):
    # https://www.patreon.com/platform/documentation/oauth -- Step 4
    # Use the tokens to fetch the Patreon profile and pledge data, saving it all to the db.
    api_client = patreon.API(patreon_access_token)
    user_response = api_client.fetch_user()
    user = user_response.data()
    if not (patreon_refresh_token and patreon_access_token and user):
        return None

    db_user = get_or_create_user_for_patreon_user_id(
        patreon_user_data=user,
        patreon_refresh_token=patreon_refresh_token,
        patreon_access_token=patreon_access_token)

    pledges = user.relationship('pledges')
    if pledges and len(pledges) > 0:
        pledge = pledges[0]
        db_user.update(
            {'patreon_pledge_amount_cents': pledge.attribute('amount_cents')})
        db.session.commit()

    return db_user
Esempio n. 13
0
def page_patreon_oauth():

    try:
        code = request.args.get('code')
        ckey = request.args.get('state')

        if code != None and ckey != None:
            oauth_client = patreon.OAuth(
                cfg.PRIVATE["patreon"]["client_id"],
                cfg.PRIVATE["patreon"]["client_secret"])

            tokens = oauth_client.get_tokens(
                code, 'https://beestation13.com/patreonauth')

            access_token = tokens['access_token']

            api_client = patreon.API(access_token)

            user_identity = api_client.get_identity().data()

            user_id = user_identity.id()

            player = db.Player.from_ckey(ckey)

            if not player:
                return redirect("/linkpatreon?error=invalidckey")

            db.site_db.link_patreon(ckey, user_id)

            return redirect("/linkpatreon?success=true")

        else:
            return redirect("/linkpatreon?error=unknown")

    except Exception as E:
        return str(E)

    return redirect("/linkpatreon?error=unknown")
Esempio n. 14
0
#get the Patreon API in the script
import patreon

#verify client with token
access_token = '<Your Token>'
api_client = patreon.API(access_token)

#Get the API to get information from 'campaign'
campaign_response = api_client.fetch_campaign()

#From that information we want the first item's id
campaign_id = campaign_response.data()[0].id()

#creating list where all patrons' information  will be stored
all_pledges = []

#cursor tells us if there are any pages left to paginate for us to know that we have to search through to get all patron names
#if cursor = none, then there are no pages left
cursor = None

#printing a sentence to check if script is working properly until now since fetching all data might take some time
print("Fetching Patron names...")

#looping cursor until we have paginated all pages and thus have fetched all patron names
while True:
    pledges_response = api_client.fetch_page_of_pledges(
        campaign_id, 25, cursor=cursor, fields={'pledge': ['declined_since']})
    all_pledges += pledges_response.data()
    cursor = api_client.extract_cursor(pledges_response)

    #breaking out of loop when cursor = none, when there are no pages left
Esempio n. 15
0
def patreon_payout():
    # Only perform on day 1 of a month
    now = datetime.now()

    payout_data = read_config("patreon")

    log.info("Checking payout information...")
    payout_emails = []
    for email, info in payout_data.items():
        if now.month > info['last_payout_month'] and now > info[
                'last_payout_date']:
            log.info(f"User {email} added for payout check.")
            payout_emails.append(email)

    log.info(f"Payout emails {payout_emails}")

    if len(payout_emails) > 0:
        log.info(f"Gathering patreon api info...")
        api_client = patreon.API(read_config("config")["patreon_token"])
        pledges = {}
        users = {}
        all_data = api_client.fetch_campaign_and_patrons(
        )._all_resource_json_data()
        for data in all_data:
            if 'type' in data:
                if data['type'] == 'pledge':
                    pledges[data['relationships']['patron']['data']
                            ['id']] = data['attributes']
                elif data['type'] == 'user':
                    users[data['id']] = data['attributes']
        user_info = read_config("players")
        for user_id, pledge in pledges.items():
            active = pledge['declined_since'] == None
            if users[user_id]['email'] not in payout_emails:
                log.warning(
                    f"User {users[user_id]['email']} already received payout this month. Skip."
                )
                continue
            if user_info[users[user_id]['email']] == None:
                log.warning(
                    f"Tried to payout user with email {users[user_id]['email']} but it does not have SteamID set."
                )
                broadcast(
                    "There was a problem during payout to one of the patrons, SteamID not set, please contact administrator.",
                    True)
                continue
            if not active:
                log.warning(
                    f"User {users[user_id]['email']} canceled subscription. Not paying."
                )
                continue
            log.info(
                f"{users[user_id]['email']} is paying {pledge['amount_cents'] / 100}$, active is {active}"
            )
            if users[user_id]['email'].strip() in payout_emails:
                log.info(f"Paying out user {users[user_id]['email'].strip()}")
                rcon_command(
                    f"ScriptCommand TCsAR AddArcTotal {user_info[users[user_id]['email']]} {pledge['amount_cents'] / 100}"
                )
                log.debug(
                    f"Setting user payout date for {users[user_id]['email']}..."
                )
                payout_data[users[user_id]['email']][
                    'last_payout_month'] = datetime.now().month
                payout_data[users[user_id]
                            ['email']]['last_payout_date'] = datetime.now()
            else:
                log.info(
                    f"NOT paying out user {users[user_id]['email'].strip()} because it was not found in payout_emails - probably already payed."
                )
        write_config('patreon', payout_data)
    else:
        log.info("Looks like everyone received their payment, exit.")
Esempio n. 16
0
def index():
    if User.query.count() == 0:
        load_config()
        return render_template("setup.html")
    projects = sorted(Project.query.all(), key=lambda p: p.name)

    if os.path.exists('static/logo.png'):
        avatar = os.path.join('static/logo.png')
    else:
        avatar = "//www.gravatar.com/avatar/" + hashlib.md5(_cfg("your-email").encode("utf-8")).hexdigest()

    selected_project = request.args.get("project")
    if selected_project:
        try:
            selected_project = int(selected_project)
        except:
            selected_project = None
    active_recurring = (Donation.query
            .filter(Donation.type == DonationType.monthly)
            .filter(Donation.active == True)
            .filter(Donation.hidden == False))
    recurring_count = active_recurring.count()
    recurring_sum = sum([d.amount for d in active_recurring])

    access_token = _cfg("patreon-access-token")
    campaign = _cfg("patreon-campaign")
    if access_token and campaign:
        try:
            import patreon
            client = patreon.API(access_token)
            campaign = client.fetch_campaign()
            attrs = campaign.json_data["data"][0]["attributes"]
            patreon_count = attrs["patron_count"]
            patreon_sum = attrs["pledge_sum"]
        except:
            import traceback
            traceback.print_exc()
            patreon_count = 0
            patreon_sum = 0
    else:
        patreon_count = 0
        patreon_sum = 0

    liberapay = _cfg("liberapay-campaign")
    if liberapay:
        lp = (requests
                .get("https://liberapay.com/{}/public.json".format(liberapay))
            ).json()
        lp_count = lp['npatrons']
        lp_sum = int(float(lp['receiving']['amount']) * 100)
        # Convert from weekly to monthly
        lp_sum = lp_sum * 52 // 12
    else:
        lp_count = 0
        lp_sum = 0
    
    opencollective = _cfg("opencollective-campaign")
    if opencollective:
        oc = requests.get("https://opencollective.com/{}.json".format(opencollective)).json()
        oc_count = oc['backersCount']
        oc_sum = int(oc['yearlyIncome'])
        # Convert from yearly to monthly
        oc_sum = oc_sum // 12
    else:
        oc_count = 0
        oc_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": "bearer {}".format(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
        gh_user = 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,
            gh_count=gh_count, gh_sum=gh_sum, gh_user=gh_user,
            oc_count=oc_count, oc_sum=oc_sum,
            currency=currency)
Esempio n. 17
0
def index():
    if User.query.count() == 0:
        load_config()
        return render_template("setup.html")
    projects = sorted(Project.query.all(), key=lambda p: p.name)

    if os.path.exists("static/logo.png"):
        avatar = os.path.join("static/logo.png")
    else:
        avatar = ("//www.gravatar.com/avatar/" +
                  hashlib.md5(_cfg("your-email").encode("utf-8")).hexdigest())

    selected_project = request.args.get("project")
    if selected_project:
        try:
            selected_project = int(selected_project)
        except Exception:
            current_app.logger.exception(
                "Error while trying to select project: %s" % selected_project,
                exc_info=True,
            )
            selected_project = None
    active_recurring = (Donation.query.filter(
        Donation.type == DonationType.monthly).filter(
            Donation.active == True).filter(Donation.hidden == False))
    recurring_count = active_recurring.count()
    recurring_sum = sum([d.amount for d in active_recurring])

    limit = datetime.now() - timedelta(days=30)
    month_onetime = Donation.query.filter(
        Donation.type == DonationType.one_time).filter(
            Donation.created > limit)
    onetime_count = month_onetime.count()
    onetime_sum = sum([d.amount for d in month_onetime])

    access_token = _cfg("patreon-access-token")
    campaign = _cfg("patreon-campaign")
    if access_token and campaign:
        try:
            import patreon

            client = patreon.API(access_token)
            campaign = client.fetch_campaign()
            attrs = campaign.json_data["data"][0]["attributes"]
            patreon_count = attrs["patron_count"]
            patreon_sum = attrs["pledge_sum"]
        except Exception as e:
            current_app.logger.warning("Error to get patreon information: %s" %
                                       e,
                                       exc_info=True)
            patreon_count = 0
            patreon_sum = 0
    else:
        patreon_count = 0
        patreon_sum = 0

    liberapay = _cfg("liberapay-campaign")
    if liberapay:
        try:
            lp = (requests.get(
                "https://liberapay.com/{}/public.json".format(liberapay),
                timeout=5)).json()
        except Exception:
            traceback.print_exc()
            print("Error while trying to get data from liberapay")
            lp_count = 0
            lp_sum = 0
        else:
            lp_count = lp["npatrons"]
            lp_sum = int(float(lp["receiving"]["amount"]) * 100)
            # Convert from weekly to monthly
            lp_sum = lp_sum * 52 // 12
    else:
        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
        gh_user = 0

    return render_template(
        "index.html",
        projects=projects,
        avatar=avatar,
        selected_project=selected_project,
        recurring_count=recurring_count,
        recurring_sum=recurring_sum,
        onetime_count=onetime_count,
        onetime_sum=onetime_sum,
        patreon_count=patreon_count,
        patreon_sum=patreon_sum,
        lp_count=lp_count,
        lp_sum=lp_sum,
        currency=currency,
        gh_count=gh_count,
        gh_sum=gh_sum,
        gh_user=gh_user,
        version=version(),
    )
Esempio n. 18
0
 def __init__(self, access_token):
     self._api = patreon.API(access_token)