<s> """<STR_LIT>""" <EOL> import re <EOL> from decimal import Decimal <EOL> import requests <EOL> from aspen import json , log <EOL> from gratipay . exceptions import InvalidTeamName <EOL> from gratipay . models import add_event <EOL> from postgres . orm import Model <EOL> from gratipay . billing . exchanges import MINIMUM_CHARGE <EOL> TEAM_NAME_PATTERN = re . compile ( r'<STR_LIT>' ) <EOL> def slugize ( name ) : <EOL> """<STR_LIT>""" <EOL> if TEAM_NAME_PATTERN . match ( name ) is None : <EOL> raise InvalidTeamName <EOL> slug = name . strip ( ) <EOL> for c in ( '<STR_LIT:U+002C>' , '<STR_LIT:U+0020>' ) : <EOL> slug = slug . replace ( c , '<STR_LIT:->' ) <EOL> while '<STR_LIT>' in slug : <EOL> slug = slug . replace ( '<STR_LIT>' , '<STR_LIT:->' ) <EOL> slug = slug . strip ( '<STR_LIT:->' ) <EOL> return slug <EOL> class Team ( Model ) : <EOL> """<STR_LIT>""" <EOL> typname = '<STR_LIT>' <EOL> def __eq__ ( self , other ) : <EOL> if not isinstance ( other , Team ) : <EOL> return False <EOL> return self . id == other . id <EOL> def __ne__ ( self , other ) : <EOL> if not isinstance ( other , Team ) : <EOL> return True <EOL> return self . id != other . id <EOL> @ classmethod <EOL> def from_id ( cls , id ) : <EOL> """<STR_LIT>""" <EOL> return cls . _from_thing ( "<STR_LIT:id>" , id ) <EOL> @ classmethod <EOL> def from_slug ( cls , slug ) : <EOL> """<STR_LIT>""" <EOL> return cls . _from_thing ( "<STR_LIT>" , slug . lower ( ) ) <EOL> @ classmethod <EOL> def _from_thing ( cls , thing , value ) : <EOL> assert thing in ( "<STR_LIT:id>" , "<STR_LIT>" ) <EOL> return cls . db . one ( """<STR_LIT>""" . format ( thing ) , ( value , ) ) <EOL> @ classmethod <EOL> def insert ( cls , owner , ** fields ) : <EOL> fields [ '<STR_LIT>' ] = fields [ '<STR_LIT>' ] . lower ( ) <EOL> fields [ '<STR_LIT>' ] = owner . username <EOL> return cls . db . one ( """<STR_LIT>""" , fields ) <EOL> def get_payment_distribution ( self ) : <EOL> """<STR_LIT>""" <EOL> SQL = """<STR_LIT>""" <EOL> tip_amounts = [ ] <EOL> npatrons = <NUM_LIT:0.0> <EOL> total_amount = Decimal ( '<STR_LIT>' ) <EOL> for rec in self . db . all ( SQL , ( self . slug , ) ) : <EOL> tip_amounts . append ( [ rec . amount <EOL> , rec . nreceiving_from <EOL> , rec . amount * rec . nreceiving_from <EOL> ] ) <EOL> total_amount += tip_amounts [ - <NUM_LIT:1> ] [ <NUM_LIT:2> ] <EOL> npatrons += rec . nreceiving_from <EOL> for row in tip_amounts : <EOL> row . append ( ( row [ <NUM_LIT:1> ] / npatrons ) if npatrons > <NUM_LIT:0> else <NUM_LIT:0> ) <EOL> row . append ( ( row [ <NUM_LIT:2> ] / total_amount ) if total_amount > <NUM_LIT:0> else <NUM_LIT:0> ) <EOL> return tip_amounts , npatrons , total_amount <EOL> def update ( self , ** kw ) : <EOL> updateable = frozenset ( [ '<STR_LIT:name>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> cols , vals = zip ( * kw . items ( ) ) <EOL> assert set ( cols ) . issubset ( updateable ) <EOL> old_value = { } <EOL> for col in cols : <EOL> old_value [ col ] = getattr ( self , col ) <EOL> cols = '<STR_LIT:U+002CU+0020>' . join ( cols ) <EOL> placeholders = '<STR_LIT:U+002CU+0020>' . join ( [ '<STR_LIT:%s>' ] * len ( vals ) ) <EOL> with self . db . get_cursor ( ) as c : <EOL> c . run ( """<STR_LIT>""" . format ( cols , placeholders ) , vals + ( self . id , ) <EOL> ) <EOL> add_event ( c , '<STR_LIT>' , dict ( action = '<STR_LIT>' <EOL> , id = self . id <EOL> , ** old_value <EOL> ) ) <EOL> self . set_attributes ( ** kw ) <EOL> def get_dues ( self ) : <EOL> rec = self . db . one ( """<STR_LIT>""" , { '<STR_LIT>' : self . slug } ) <EOL> return rec . funded , rec . unfunded <EOL> def get_upcoming_payment ( self ) : <EOL> return self . db . one ( """<STR_LIT>""" , { '<STR_LIT>' : self . slug , '<STR_LIT>' : MINIMUM_CHARGE } ) <EOL> def create_github_review_issue ( self ) : <EOL> """<STR_LIT>""" <EOL> api_url = "<STR_LIT>" . format ( self . review_repo ) <EOL> data = json . dumps ( { "<STR_LIT:title>" : self . name <EOL> , "<STR_LIT:body>" : "<STR_LIT>" . format ( self . slug ) + <EOL> "<STR_LIT>" <EOL> } ) <EOL> out = '<STR_LIT>' <EOL> try : <EOL> r = requests . post ( api_url , auth = self . review_auth , data = data ) <EOL> if r . status_code == <NUM_LIT> : <EOL> out = r . json ( ) [ '<STR_LIT>' ] <EOL> else : <EOL> log ( r . status_code ) <EOL> log ( r . text ) <EOL> err = str ( r . status_code ) <EOL> except : <EOL> err = "<STR_LIT>" <EOL> if not out : <EOL> out = "<STR_LIT>" . format ( err ) <EOL> return out <EOL> def set_review_url ( self , review_url ) : <EOL> self . db . run ( "<STR_LIT>" , ( review_url , self . id ) ) <EOL> self . set_attributes ( review_url = review_url ) <EOL> def get_og_title ( self ) : <EOL> out = self . name <EOL> receiving = self . receiving <EOL> if receiving > <NUM_LIT:0> : <EOL> out += "<STR_LIT>" % receiving <EOL> else : <EOL> out += "<STR_LIT>" <EOL> return out + "<STR_LIT>" <EOL> def update_receiving ( self , cursor = None ) : <EOL> r = ( cursor or self . db ) . one ( """<STR_LIT>""" , dict ( slug = self . slug ) ) <EOL> from gratipay . models . participant import Participant <EOL> Participant . from_username ( self . owner ) . update_taking ( cursor or self . db ) <EOL> self . set_attributes ( receiving = r . receiving <EOL> , nreceiving_from = r . nreceiving_from <EOL> , distributing = r . distributing <EOL> , ndistributing_to = r . ndistributing_to <EOL> ) <EOL> @ property <EOL> def status ( self ) : <EOL> return { None : '<STR_LIT>' <EOL> , False : '<STR_LIT>' <EOL> , True : '<STR_LIT>' <EOL> } [ self . is_approved ] <EOL> def to_dict ( self ) : <EOL> return { <EOL> '<STR_LIT>' : self . homepage , <EOL> '<STR_LIT:name>' : self . name , <EOL> '<STR_LIT>' : self . nreceiving_from , <EOL> '<STR_LIT>' : self . onboarding_url , <EOL> '<STR_LIT>' : '<STR_LIT>' + self . owner , <EOL> '<STR_LIT>' : self . receiving , <EOL> '<STR_LIT>' : self . slug , <EOL> '<STR_LIT:status>' : self . status , <EOL> '<STR_LIT>' : self . todo_url <EOL> } <EOL> def migrate_tips ( self ) : <EOL> payment_instructions = self . db . all ( """<STR_LIT>""" , ( self . owner , ) ) <EOL> if payment_instructions : <EOL> raise AlreadyMigrated <EOL> return self . db . one ( """<STR_LIT>""" , { '<STR_LIT>' : self . slug , '<STR_LIT>' : self . owner } ) <EOL> IMAGE_SIZES = ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> def get_image_url ( self , size ) : <EOL> assert size in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) , size <EOL> return '<STR_LIT>' . format ( self . slug , size ) <EOL> def save_image ( self , original , large , small , image_type ) : <EOL> with self . db . get_cursor ( ) as c : <EOL> oids = { } <EOL> for size in self . IMAGE_SIZES : <EOL> lobject = c . connection . lobject ( getattr ( self , '<STR_LIT>' + size ) , mode = '<STR_LIT:wb>' ) <EOL> lobject . write ( locals ( ) [ size ] ) <EOL> oids [ size ] = lobject . oid <EOL> lobject . close ( ) <EOL> c . run ( """<STR_LIT>""" <EOL> , ( oids [ '<STR_LIT>' ] , oids [ '<STR_LIT>' ] , oids [ '<STR_LIT>' ] , image_type , self . id ) <EOL> ) <EOL> add_event ( c , '<STR_LIT>' , dict ( action = '<STR_LIT>' <EOL> , id = self . id <EOL> , ** oids <EOL> ) ) <EOL> self . set_attributes ( image_type = image_type <EOL> , ** { '<STR_LIT>' + size : oids [ size ] for size in oids } <EOL> ) <EOL> return oids <EOL> def load_image ( self , size ) : <EOL> assert size in self . IMAGE_SIZES , size <EOL> image = None <EOL> oid = getattr ( self , '<STR_LIT>' . format ( size ) ) <EOL> if oid != <NUM_LIT:0> : <EOL> with self . db . get_connection ( ) as c : <EOL> image = c . lobject ( oid , mode = '<STR_LIT:rb>' ) . read ( ) <EOL> return image <EOL> class AlreadyMigrated ( Exception ) : pass </s>
