示例#1
0
文件: utils.py 项目: kpelelis/onevone
 def get_matchup(champion_name, enemy_name, patch_version):
     champion = StaticDataContext.get_object_from_name(
         Champion, champion_name)
     enemy = StaticDataContext.get_object_from_name(Champion, enemy_name)
     versions = StaticDataContext.get_api_version()['versions'][:5]
     versions = list(
         map(lambda x: re.sub(xy_version_regex, r"\1", x), versions))
     if champion is None or enemy is None:
         raise errors.BadRequest('Both champions must be provided')
     with DBManager.create_session_scope(expire_on_commit=False) as session:
         matchup_avg = session.query(MatchupAverages).filter(
             (MatchupAverages.champion == champion['id'])
             & (MatchupAverages.enemy == enemy['id']))
         if patch_version is None:
             matchup_avg = matchup_avg.filter(
                 MatchupAverages.patch_version == versions[0])
         else:
             matchup_avg = matchup_avg.filter(
                 MatchupAverages.patch_version == patch_version)
         matchup_avg = matchup_avg.first()
         if matchup_avg is None:
             raise errors.MatchupNotFound('Matchup not Found')
         matchup_avg = matchup_avg
         return dict(MatchContext.process_matchup(matchup_avg),
                     champion=champion,
                     enemy=enemy,
                     versions=versions)
示例#2
0
文件: utils.py 项目: kpelelis/onevone
 def populate_matchups(cls, limit=50, region='EUNE'):
     session = DBManager.create_session(expire_on_commit=False)
     matches = session.query(QueuedMatch).filter_by(region=region).filter(
         ~exists().where(QueuedMatch.id == CheckedMatch.id))\
         .limit(limit).all()
     for match in matches:
         payload = {
             'api_key': RIOT_API_KEY,
             'includeTimeline': 'true',
         }
         log.debug('Fetching info for match {0}'.format(match.id))
         url = 'https://{0}.api.pvp.net/api/lol/{0}'.format(region.lower())
         endpoint = '/{0}/match/{1}'.format(api_versions['match'], match.id)
         try:
             result = riot_api.get(url=url,
                                   endpoint=endpoint,
                                   payload=payload)
         except ForbiddenException:
             continue
         except NotFound:
             continue
         cls.populate_single_matchup(result)
         checked_match = CheckedMatch({
             'id':
             match.id,
             'region':
             match.region,
             'checked_at':
             datetime.now(),
             'match_timestamp':
             match.match_timestamp
         })
         session.merge(checked_match)
         session.commit()
示例#3
0
文件: utils.py 项目: kpelelis/onevone
 def populate_static_table(endpoint='',
                           model=None,
                           payload={},
                           version=None):
     entity_name = model.__name__.lower()
     log.debug('Populating {0} table'.format(model.__tablename__))
     try:
         results = riot_static_api.get(endpoint=endpoint, payload=payload)
     except ForbiddenException:
         return
     results_length = len(results['data'].keys())
     log.info('Fetched {0} {1}s'.format(results_length, entity_name))
     with DBManager.create_session_scope() as session:
         status_cnt = 0
         for entity_data in results['data'].values():
             status_cnt += 1
             print('[*] Status {0}/{1}'.format(status_cnt, results_length),
                   end='\r')
             _process_ctx = getattr(DataProcessContext,
                                    'process_{0}_data'.format(entity_name))
             if _process_ctx is None:
                 raise Exception(
                     'No data process function for model {0} was '
                     'defined'.format(entity_name))
             _processed_data = _process_ctx(entity_data)
             session.merge(
                 model(**dict(_processed_data, patch_version=version)))
     log.debug('Done!')
示例#4
0
文件: utils.py 项目: kpelelis/onevone
    def populate_players(region='EUNE', league='challenger', player_limit=50):
        # Get a list with the top 50 challenger players (if any)
        log.debug('Fetching top {0} players from {1} in region '
                  '{2}'.format(player_limit, league, region))
        payload = {'api_key': RIOT_API_KEY, 'type': 'RANKED_SOLO_5x5'}
        url = 'https://{0}.api.pvp.net/api/lol/{0}'.format(region.lower())
        endpoint = '/{0}/league/{1}'.format(api_versions['league'], league)
        try:
            ladder = riot_api.get(url=url, endpoint=endpoint, payload=payload)
        except ForbiddenException:
            return

        if len(ladder.keys()) == 0:
            return

        players = [
            player for _, player in sorted([(player['leaguePoints'], player)
                                            for player in ladder['entries']],
                                           reverse=True,
                                           key=lambda x: x[0])[:player_limit]
        ]

        results_length = len(players)

        log.debug('[+] Fetched {0} players'.format(results_length))
        with DBManager.create_session_scope() as session:
            for player in players:
                player_data = {
                    'id': player.get('playerOrTeamId'),
                    'region': region.lower(),
                    'tier': league.lower(),
                    'name': player.get('playerOrTeamName')
                }
                session.merge(ProPlayer(player_data))
        log.debug('[+] Done!')
示例#5
0
文件: utils.py 项目: kpelelis/onevone
 def get_object_from_name(model, name):
     with DBManager.create_session_scope(expire_on_commit=False) as session:
         ret = session.query(model).filter_by(name=name).first()
         if ret is not None:
             ret = ret.serialize()
         return ret
     return None
示例#6
0
文件: utils.py 项目: kpelelis/onevone
 def get_objects_id_dict(model):
     with DBManager.create_session_scope(expire_on_commit=False) as session:
         ret = {
             str(o.id): o.serialize()
             for o in session.query(model).all()
         }
         return ret
     return None
示例#7
0
文件: utils.py 项目: kpelelis/onevone
    def populate_queued_matches(limit=50, region='EUNE'):
        matches = {}
        log.debug('Collecting match information for each player. This might '
                  'take a while...')
        with DBManager.create_session_scope(expire_on_commit=False) as session:
            payload = {
                'api_key': RIOT_API_KEY,
                'rankedQueues':
                'TEAM_BUILDER_DRAFT_RANKED_5x5,RANKED_SOLO_5x5',
                'seasons': 'SEASON2016,PRESEASON2016,PRESEASON2017',
                'beginIndex': 0,
                'endIndex': limit
            }

            latest_game = session.query(QueuedMatch).filter_by(
                region=region).order_by(
                    QueuedMatch.match_timestamp.desc()).first()

            if latest_game is not None:
                payload['beginTime'] = latest_game.match_timestamp

            players = session.query(ProPlayer).all()
            url = 'https://{0}.api.pvp.net/api/lol/{0}'.format(region.lower())
            for player in players:
                endpoint = '/{0}/matchlist/by-summoner/{1}'\
                           .format(api_versions['matchlist'], player.id)
                try:
                    result = riot_api.get(url=url,
                                          endpoint=endpoint,
                                          payload=payload)
                except ForbiddenException:
                    continue
                except NotFound:
                    continue
                for match in result.get("matches", []):
                    match_data = {
                        'id': match.get('matchId'),
                        'region': match.get('region'),
                        'match_timestamp': match.get('timestamp'),
                        'added_at': datetime.now()
                    }
                    session.merge(QueuedMatch(match_data))
                    session.commit()
示例#8
0
文件: app.py 项目: kpelelis/onevone
from onevone.db_manager import DBManager
from onevone import log

from flask import Flask

app = Flask(__name__)
app.config.from_object('onevone.configuration.DevelopmentConfig')
DBManager.init(app.config['DATABASE_URI'])

from onevone import urls
示例#9
0
文件: utils.py 项目: kpelelis/onevone
    def populate_averages(cls):
        with DBManager.create_session_scope(expire_on_commit=False) as session:
            champions = [
                c.id for c in session.query(Champion).options(load_only(
                    'id')).order_by('id').all()
            ]
            total_champs = len(champions)
            versions = StaticDataContext.get_api_version()['versions'][:2]
            for version in versions:
                # Keep only the 2 majon numbers of the patch version
                patch_version = re.sub(r'^((?:\d+\.*){2})((?:\.\d*)*)$', r'\1',
                                       version)
                log.debug('Calculating Averages for patch : {0}'.format(
                    patch_version))
                for i in range(0, total_champs):
                    print('Status {0}/{1}'.format(i, total_champs), end='\r')
                    for j in range(0, total_champs):
                        if i == j:
                            continue
                        idA = champions[i]
                        idB = champions[j]
                        matchups = session.query(Matchup, SpellTimeLine, ItemTimeline)\
                            .join(SpellTimeLine,
                                  (Matchup.id == SpellTimeLine.matchup_id)) \
                            .join(ItemTimeline,
                                  (Matchup.id == ItemTimeline.matchup_id)) \
                            .filter(
                            (Matchup.champion == idA) & (Matchup.enemy == idB) &
                            (Matchup.checked == False) & (Matchup.patch_version == patch_version)
                        ).all()

                        total_games = len(matchups)
                        if total_games == 0:
                            continue

                        matchups, spell_timelines, item_timelines = zip(
                            *matchups)

                        kills = 0
                        deaths = 0
                        assists = 0
                        damage_dealt = 0
                        wins = 0
                        creep_score = 0
                        duration = 0
                        for matchup in matchups:
                            if matchup.won:
                                wins += 1
                            kills += matchup.kills
                            deaths += matchup.deaths
                            assists += matchup.assists
                            damage_dealt += matchup.damage_dealt
                            creep_score += matchup.creep_score
                            duration += matchup.duration

                        sts = [st.spell_timeline for st in spell_timelines]
                        avg_spells = cls.timelines_average(data=sts)

                        its = [it.item_timeline for it in item_timelines]
                        avg_items = cls.timelines_average(data=its)

                        mus = [(mu.masteries, mu.runes, mu.summoners)
                               for mu in matchups]
                        masteries, runes, summoners = zip(*mus)
                        avg_masteries = cls.timelines_average(masteries)
                        avg_runes = cls.timelines_average(runes)

                        summoners = [sorted(s.split(',')) for s in summoners]
                        avg_summoners = cls.timelines_average(summoners)

                        matchup_avgs = {
                            'champion': idA,
                            'enemy': idB,
                            'total_games': total_games,
                            'kills': float(kills / total_games),
                            'deaths': float(deaths / total_games),
                            'assists': float(assists / total_games),
                            'creep_score': float(creep_score / total_games),
                            'damage_dealt': float(damage_dealt / total_games),
                            'duration': float(duration / total_games),
                            'wins': wins,
                            'item_timeline': avg_items,
                            'spell_timeline': avg_spells,
                            'masteries': avg_masteries,
                            'runes': avg_runes,
                            'summoners': avg_summoners,
                            'patch_version': patch_version
                        }
                        try:
                            matchup_avgs = MatchupAverages(matchup_avgs)
                            session.merge(matchup_avgs)
                            session.commit()
                        except IntegrityError:
                            session.rollback()
                            log.warn('Average already {0}vs{1} patch {2}'
                                     'exists. Updating'.format(
                                         idA, idB, patch_version))
                            prev_matchup = session.query(
                                MatchupAverages).filter_by(
                                    champion=idA,
                                    enemy=idB,
                                    patch_version=patch_version).first()

                            session.merge(matchup_avgs)
                            session.commit()
示例#10
0
文件: utils.py 项目: kpelelis/onevone
    def populate_single_matchup(data):

        try:
            frames = data['timeline']['frames']
        except KeyError:
            log.error('No timeline data')
            return

        item_timelines = defaultdict(list)
        spell_timelines = defaultdict(list)

        for frame in frames:
            for ev in frame.get('events', []):
                if ev['eventType'] == 'ITEM_PURCHASED':
                    item_timelines[ev['participantId']].append(ev['itemId'])
                elif ev['eventType'] == 'SKILL_LEVEL_UP':
                    spell_timelines[ev['participantId']].append(
                        ev['skillSlot'])

        if data["teams"][0]["winner"] is True:
            winning_team = data["teams"][0]["teamId"]
        else:
            winning_team = data["teams"][1]["teamId"]

        results = {}
        # results = {
        #     'JUNGLE': {
        #         'vs': [{participant1}, {participant2}].
        #         'won': 202 -> champion id
        #     },
        #     ...
        # }
        for participant in data.get('participants', []):
            lane_role = '{0}:{1}'.format(participant['timeline']['lane'],
                                         participant['timeline']['role'])
            if results.get(lane_role) is None:
                results[lane_role] = {'vs': [], 'won': None}
            results[lane_role]['vs'].append(participant)
            if participant['teamId'] == winning_team:
                results[lane_role]['won'] = participant['championId']

        with DBManager.create_session_scope(expire_on_commit=False) as session:
            for lane_role, result in results.items():

                # Sometimes there are no matchups
                if len(result['vs']) != 2:
                    continue

                for idx, participant in enumerate(result['vs']):
                    pid = participant['participantId']
                    enemy = result['vs'][(idx + 1) % 2]
                    try:
                        masteries = [
                            '{0}:{1}'.format(m['masteryId'], m['rank'])
                            for m in participant['masteries']
                        ]

                        runes = [
                            '{0}:{1}'.format(r['runeId'], r['rank'])
                            for r in participant['runes']
                        ]

                        summoners = '{0},{1}'.format(participant['spell1Id'],
                                                     participant['spell2Id'])

                        stats = participant.get('stats')

                        matchup_data = {
                            'champion':
                            participant['championId'],
                            'enemy':
                            enemy['championId'],
                            'won':
                            participant['championId'] == result['won'],
                            'kills':
                            stats.get('kills'),
                            'deaths':
                            stats.get('deaths'),
                            'assists':
                            stats.get('assists'),
                            'creep_score':
                            stats.get('minionsKilled'),
                            'damage_dealt':
                            stats.get('totalDamageDealtToChampions'),
                            'duration':
                            data.get('matchDuration'),
                            'patch_version':
                            '.'.join(data.get('matchVersion').split('.')[:2]),
                            'masteries':
                            masteries,
                            'runes':
                            runes,
                            'summoners':
                            summoners,
                        }
                    except KeyError:
                        continue

                    matchup = Matchup(matchup_data)
                    session.add(matchup)
                    session.flush()
                    session.refresh(matchup)
                    item_timeline_data = {
                        'matchup_id': matchup.id,
                        'item_timeline': item_timelines[pid]
                    }
                    item_timeline = ItemTimeline(item_timeline_data)
                    spell_timeline_data = {
                        'matchup_id': matchup.id,
                        'spell_timeline': spell_timelines[pid]
                    }
                    spell_timeline = SpellTimeLine(spell_timeline_data)
                    session.add(item_timeline)
                    session.add(spell_timeline)
                    session.commit()
示例#11
0
文件: utils.py 项目: kpelelis/onevone
    def generate_static_images(cls):
        IMAGES_PER_LINE = 10
        IMAGE_SIZE = 64
        data = {}
        with DBManager.create_session_scope() as session:
            version = cls.get_api_version()['versions'][0]
            ddragon_api = RESTClient(base_url='http://ddragon.'
                                     'leagueoflegends.com/cdn',
                                     log=log)

            from PIL import Image
            import io
            models = [SummonerSpell, Champion, Mastery, Item, Rune]
            for model in models:
                if model == SummonerSpell:
                    model_name = 'spell'
                else:
                    model_name = model.__name__.lower()

                query_set = session.query(model)\
                                   .order_by('id')\
                                   .all()
                CONCAT_WIDTH = IMAGES_PER_LINE * IMAGE_SIZE
                CONCAT_HEIGHT = (int(len(query_set) / IMAGES_PER_LINE) +
                                 1) * IMAGE_SIZE
                sprite_img = Image.new('RGB', (CONCAT_WIDTH, CONCAT_HEIGHT))
                data[model_name] = []
                i, j = 0, 0
                for entry in query_set:
                    data[model_name].append({
                        'id': entry.id,
                        'xoffset_small': -j * 32,
                        'yoffset_small': -i * 32,
                        'xoffset_big': -j * 64,
                        'yoffset_big': -i * 64,
                    })
                    endpoint = '/{0}/img/{1}/{2}'.format(
                        entry.patch_version, model_name, entry.image_blob)
                    try:
                        image_stream = ddragon_api.get(
                            endpoint=endpoint, response_type='byte-stream')
                    except Exception:
                        continue
                    image = Image.open(image_stream).resize(
                        (IMAGE_SIZE, IMAGE_SIZE))
                    sprite_img.paste(image, (j * IMAGE_SIZE, i * IMAGE_SIZE))
                    j += 1
                    if j == IMAGES_PER_LINE:
                        i += 1
                        j = 0
                    splash_blob = getattr(entry, 'splash_blob', None)
                    if splash_blob is not None:
                        endpoint = '/{0}/loading/{1}'.format(
                            model_name, splash_blob)
                        try:
                            image_stream = ddragon_api.get(
                                url='http://ddragon.leagueoflegends.com/cdn/img'
                                .format(model_name, splash_blob),
                                endpoint=endpoint,
                                response_type='byte-stream')
                        except Exception:
                            continue
                        image = Image.open(image_stream)
                        image.save('./onevone/static/images/' + model_name +
                                   '-splash/' + splash_blob)

                sprite_img.save('./onevone/static/images/' + model_name +
                                '_sprite.png')
                sprite_img_s = sprite_img.copy().resize(
                    (int(CONCAT_WIDTH * 0.5), int(CONCAT_HEIGHT * 0.5)))
                sprite_img_s.save('./onevone/static/images/' + model_name +
                                  '_sprite.small.png')
                sprite_grey = sprite_img.copy().convert('L')
                sprite_grey.save('./onevone/static/images/' + model_name +
                                 '_sprite_grey.png')

        from jinja2 import Environment
        with open('./onevone/static/css/static_data.template.css', 'r') as t,\
                open('./onevone/static/css/static_data.css', 'w+') as f:
            template = t.read()
            f.write(
                Environment(trim_blocks=True,
                            lstrip_blocks=True).from_string(template).render(
                                data=data))
示例#12
0
文件: utils.py 项目: kpelelis/onevone
        def decorator(*args, **kwargs):
            cache_key = self.key_format.format(*args, **kwargs)
            ret = cache.get(cache_key)
            if ret is None:
                ret = f(*args, **kwargs)
                if ret is not None:
                    cache.set(cache_key, json.dumps(ret))
                    if self.timeout > 0:
                        cache.expire(cache_key, self.timeout)
                return ret
            return json.loads(ret.decode('utf-8'))

        return decorator


DBManager.init(os.environ['ONEVONE_PRODUCTION_DB'])
RIOT_GLOBAL_API = 'https://global.api.pvp.net/api/lol'
RIOT_API_KEY = os.environ['RIOT_API_KEY']
api_versions = {
    'static': 'v1.2',
    'matchlist': 'v2.2',
    'league': 'v2.5',
    'match': 'v2.2',
}

xy_version_regex = r'^((?:\d+\.*){2})((?:\.\d*)*)$'
xyz_version_regex = r'^((?:\d+\.*){3})((?:\.\d*)*)$'
static_url = '{0}/static-data/eune/{1}'.format(RIOT_GLOBAL_API,
                                               api_versions['static'])
riot_static_api = RESTClient(base_url=static_url, log=log)
riot_api = RESTClient(log=log)
示例#13
0
from onevone import log

__all__ = [
    'ChampionAPI',
    'MasteryAPI',
    'RunesAPI',
    'ItemsAPI',
    'MatchupAPI',
    'SummonerSpellAPI',
    'Index',
    'About',
    'Contact',
    'MatchupView',
]

view_session = DBManager.create_session(expire_on_commit=False)


def create_error_response(message, error_code):
    data = json.dumps({'error': True, 'message': message})
    response = Response(status=error_code, mimetype='application/json')
    response.set_data(data)
    return response


def create_success_response(payload):
    data = json.dumps({
        'data': payload,
    })
    response = Response(status=200, mimetype='application/json')
    response.set_data(data)