internal.py 7.03 KB
Newer Older
1 2 3
# Copyright (C) 2012 Lukas Lalinsky
# Distributed under the MIT license, see the LICENSE file for details.

Lukáš Lalinský's avatar
Lukáš Lalinský committed
4
import datetime
5
import logging
6 7 8 9 10 11 12
from acoustid.data.stats import (
    update_lookup_stats,
    update_user_agent_stats,
    find_application_lookup_stats_multi,
)
from acoustid.data.application import (
    find_applications_by_apikeys,
Lukáš Lalinský's avatar
Lukáš Lalinský committed
13 14 15 16 17 18
    insert_application,
    lookup_application_id,
    update_application_status,
)
from acoustid.data.account import (
    insert_account,
19
)
20 21 22 23 24 25 26 27
from acoustid.api import errors
from acoustid.api.v2 import APIHandler, APIHandlerParams

logger = logging.getLogger(__name__)


class UpdateLookupStatsHandlerParams(APIHandlerParams):

Lukáš Lalinský's avatar
Lukáš Lalinský committed
28 29
    def parse(self, values, db):
        super(UpdateLookupStatsHandlerParams, self).parse(values, db)
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
        self.secret = values.get('secret')
        self.application_id = values.get('application_id', type=int)
        self.date = values.get('date')
        self.hour = values.get('hour', type=int)
        self.type = values.get('type')
        self.count = values.get('count', type=int)


class UpdateLookupStatsHandler(APIHandler):

    params_class = UpdateLookupStatsHandlerParams

    def _handle_internal(self, params):
        if self.cluster.role != 'master':
            logger.warning('Trying to call update_lookup_stats on %s server', self.cluster.role)
            raise errors.NotAllowedError()
        if self.cluster.secret != params.secret:
            logger.warning('Invalid cluster secret')
            raise errors.NotAllowedError()
        with self.conn.begin():
            update_lookup_stats(self.conn, params.application_id, params.date,
                                params.hour, params.type, params.count)
        return {}

Lukáš Lalinský's avatar
Lukáš Lalinský committed
54 55 56 57 58 59 60 61 62 63

class UpdateUserAgentStatsHandlerParams(APIHandlerParams):

    def parse(self, values, conn):
        super(UpdateUserAgentStatsHandlerParams, self).parse(values, conn)
        self.secret = values.get('secret')
        self.application_id = values.get('application_id', type=int)
        self.date = values.get('date')
        self.user_agent = values.get('user_agent')
        self.ip = values.get('ip')
Lukáš Lalinský's avatar
Lukáš Lalinský committed
64
        self.count = values.get('count', type=int)
Lukáš Lalinský's avatar
Lukáš Lalinský committed
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82


class UpdateUserAgentStatsHandler(APIHandler):

    params_class = UpdateUserAgentStatsHandlerParams

    def _handle_internal(self, params):
        if self.cluster.role != 'master':
            logger.warning('Trying to call update_user_agent_stats on %s server', self.cluster.role)
            raise errors.NotAllowedError()
        if self.cluster.secret != params.secret:
            logger.warning('Invalid cluster secret')
            raise errors.NotAllowedError()
        with self.conn.begin():
            update_user_agent_stats(self.conn, params.application_id, params.date,
                                    params.user_agent, params.ip, params.count)
        return {}

83 84 85

class LookupStatsHandlerParams(APIHandlerParams):

Lukáš Lalinský's avatar
Lukáš Lalinský committed
86 87
    def parse(self, values, db):
        super(LookupStatsHandlerParams, self).parse(values, db)
88 89 90 91
        self.secret = values.get('secret')
        apikeys = values.getlist('client')
        if not apikeys:
            raise errors.InvalidAPIKeyError()
Lukáš Lalinský's avatar
Lukáš Lalinský committed
92
        self.applications = find_applications_by_apikeys(db.get_app_db(), apikeys)
93 94
        if not self.applications:
            raise errors.InvalidAPIKeyError()
Lukáš Lalinský's avatar
Lukáš Lalinský committed
95 96 97 98 99 100 101
        self.from_date = values.get('from')
        if self.from_date is not None:
            self.from_date = datetime.datetime.strptime(self.from_date, '%Y-%m-%d').date()
        self.to_date = values.get('to')
        if self.to_date is not None:
            self.to_date = datetime.datetime.strptime(self.to_date, '%Y-%m-%d').date()
        self.days = values.get('days', type=int)
102 103 104 105 106 107 108 109 110 111 112


class LookupStatsHandler(APIHandler):

    params_class = LookupStatsHandlerParams

    def _handle_internal(self, params):
        if self.cluster.secret != params.secret:
            logger.warning('Invalid cluster secret')
            raise errors.NotAllowedError()
        application_ids = dict((app['id'], app['apikey']) for app in params.applications)
Lukáš Lalinský's avatar
Lukáš Lalinský committed
113 114 115 116 117 118 119
        kwargs = {}
        if params.from_date is not None:
            kwargs['from_date'] = params.from_date
        if params.to_date is not None:
            kwargs['to_date'] = params.to_date
        if params.days is not None:
            kwargs['days'] = params.days
Lukáš Lalinský's avatar
Lukáš Lalinský committed
120
        stats = find_application_lookup_stats_multi(self.ctx.db.get_app_db(), application_ids.keys(), **kwargs)
121 122 123
        for entry in stats:
            entry['date'] = entry['date'].strftime('%Y-%m-%d')
        return {'stats': stats}
Lukáš Lalinský's avatar
Lukáš Lalinský committed
124 125 126 127


class CreateAccountHandlerParams(APIHandlerParams):

Lukáš Lalinský's avatar
Lukáš Lalinský committed
128 129
    def parse(self, values, db):
        super(CreateAccountHandlerParams, self).parse(values, db)
Lukáš Lalinský's avatar
Lukáš Lalinský committed
130 131 132 133 134 135 136 137 138 139 140
        self.secret = values.get('secret')


class CreateAccountHandler(APIHandler):

    params_class = CreateAccountHandlerParams

    def _handle_internal(self, params):
        if self.cluster.secret != params.secret:
            logger.warning('Invalid cluster secret')
            raise errors.NotAllowedError()
Lukáš Lalinský's avatar
Lukáš Lalinský committed
141
        account_id, account_api_key = insert_account(self.ctx.db.get_app_db(), {
Lukáš Lalinský's avatar
Lukáš Lalinský committed
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
            'name': 'External User',
            'anonymous': True,
        })
        return {'id': account_id, 'api_key': account_api_key}


class CreateApplicationHandlerParams(APIHandlerParams):

    def parse(self, values, conn):
        super(CreateApplicationHandlerParams, self).parse(values, conn)
        self.secret = values.get('secret')
        self.account_id = values.get('account_id', type=int)
        self.name = values.get('name')
        self.version = values.get('version')


class CreateApplicationHandler(APIHandler):

    params_class = CreateApplicationHandlerParams

    def _handle_internal(self, params):
        if self.cluster.secret != params.secret:
            logger.warning('Invalid cluster secret')
            raise errors.NotAllowedError()
        application_id, application_api_key = insert_application(self.conn, {
            'account_id': params.account_id,
            'name': params.name,
            'version': params.version,
        })
        return {'id': application_id, 'api_key': application_api_key}


class UpdateApplicationStatusHandlerParams(APIHandlerParams):

    def parse(self, values, conn):
        super(UpdateApplicationStatusHandlerParams, self).parse(values, conn)
        self.secret = values.get('secret')
        self.account_id = values.get('account_id', type=int)
        self.application_id = values.get('application_id', type=int)
        if not lookup_application_id(conn, self.application_id, self.account_id):
            raise errors.UnknownApplicationError()
        self.active = values.get('active', type=bool)


class UpdateApplicationStatusHandler(APIHandler):

    params_class = UpdateApplicationStatusHandlerParams

    def _handle_internal(self, params):
        if self.cluster.secret != params.secret:
            logger.warning('Invalid cluster secret')
            raise errors.NotAllowedError()
        update_application_status(self.conn, params.application_id, params.active)
        return {'id': params.application_id, 'active': params.active}