<commit_before># -*- coding: utf-8 -*-
import datetime

from flask.ext.login import AnonymousUserMixin
from flask.globals import current_app

from werkzeug.local import LocalProxy

from model.constants import WEEKDAYS
from model.default import BaseUser
from model.property import active_prop, unsupported_prop

from sipa.utils.exceptions import PasswordInvalid, UserNotFound
from sipa.utils import argstr

import requests


endpoint = LocalProxy(lambda: current_app.extensions['gerok_api']['endpoint'])
token = LocalProxy(lambda: current_app.extensions['gerok_api']['token'])


# noinspection PyMethodMayBeStatic
class User(BaseUser):
    """User object will be created from LDAP credentials,
    only stored in session.

    the terms 'uid' and 'username' refer to the same thing.
    """

    datasource = 'gerok'

    def __init__(self, uid, id, name=None, mail=None):
        super(User, self).__init__(uid)
        self._id = id
        self.name = name
        self._mail = mail
        self.cache_information()

    def __repr__(self):
        return "{}.{}({})".format(__name__, type(self).__name__, argstr(
            uid=self.uid,
            id=self._id,
            name=self.name,
            mail=self._mail,
        ))

    can_change_password = False

    @classmethod
    def get(cls, username, **kwargs):
        """Static method for flask-login user_loader,
        used before _every_ request.
        """
        userData = do_api_call('find?login=' + str(username))

        if userData is None:
            raise UserNotFound

        uid = userData['login'] or username
        name = userData['name'] or username
        # TODO: Somehow access the entry in the datasource constructor
        mail = username + "@wh17.tu-dresden.de"

        return cls(uid, userData['id'], name, mail)

    @classmethod
    def authenticate(cls, username, password):
        auth = do_api_call('auth', 'post', {'login': username,
                                            'pass': password})

        if auth == 'NoAccount':
            raise UserNotFound

        if auth:
            return cls.get(username)
        else:
            raise PasswordInvalid

    @classmethod
    def from_ip(cls, ip):
        userData = do_api_call('find?ip=' + ip)

        if userData is not None:
            return cls(userData['login'], userData['name'], 'passive')
        else:
            return AnonymousUserMixin()

    def cache_information(self):
        user_data = do_api_call(str(self._id))

        self._id = user_data['id']
        self._login = user_data['login']
        self._address = user_data['address']
        self._mail = user_data['mail']
        self._status = user_data['status']

        hosts = user_data['hosts']
        self._ips = {h['ip'] for h in hosts} - {None}
        self._macs = {h['mac'] for h in hosts} - {None}
        self._hostnames = {h['hostname'] for h in hosts} - {None}
        self._hostaliases = {h['alias'] for h in hosts} - {None}

    def change_password(self):
        raise NotImplementedError

    @property
    def traffic_history(self):
        trafficData = do_api_call("{}/traffic".format(self._id))

        if (trafficData):
            hostOneTraffic = trafficData[0]['traffic']
            traffic = {'history': [], 'credit': 0}

            # loop through expected days ([-6..0])
            for d in range(-6, 1):
                date = datetime.date.today() + datetime.timedelta(d)
                day = date.weekday()
                # pick the to `date` corresponding data
                d = next((
                    x for x in hostOneTraffic
                    if x['date'] == date.strftime("%Y-%m-%d")
                ), None)
                if d:
                    # TODO: check whether `WEEKDAYS[day]` is correct
                    (input, output, credit) = (
                        round(d[param] / 1048576.0, 2)
                        for param in ['in', 'out', 'credit']
                    )
                    traffic['history'].append(
                        (WEEKDAYS[day], input, output, credit))
                else:
                    traffic['history'].append(
                        (WEEKDAYS[day], 0.0, 0.0, 0.0))

            traffic['credit'] = (lambda x: x['credit']/1048576)(
                hostOneTraffic[-1])

            return traffic
        else:
            return {'credit': 0,
                    'history': [(WEEKDAYS[day], 0, 0, 0)
                                for day in range(7)]}

    @property
    def credit(self):
        creditData = do_api_call(str(self._id) + '/credit')
        return creditData[0]['credit']/1048576 if creditData else 0

    @active_prop
    def id(self):
        return self._id

    @active_prop
    def login(self):
        return self._login

    @active_prop
    def status(self):
        return self._status

    @active_prop
    def address(self):
        return self._address
<commit_msg>Adapt `gerok.User.traffic_data` to the new api<commit_after># -*- coding: utf-8 -*-
import datetime

from flask.ext.login import AnonymousUserMixin
from flask.globals import current_app

from werkzeug.local import LocalProxy

from model.constants import WEEKDAYS
from model.default import BaseUser
from model.property import active_prop, unsupported_prop

from sipa.utils.exceptions import PasswordInvalid, UserNotFound
from sipa.utils import argstr

import requests


endpoint = LocalProxy(lambda: current_app.extensions['gerok_api']['endpoint'])
token = LocalProxy(lambda: current_app.extensions['gerok_api']['token'])


# noinspection PyMethodMayBeStatic
class User(BaseUser):
    """User object will be created from LDAP credentials,
    only stored in session.

    the terms 'uid' and 'username' refer to the same thing.
    """

    datasource = 'gerok'

    def __init__(self, uid, id, name=None, mail=None):
        super(User, self).__init__(uid)
        self._id = id
        self.name = name
        self._mail = mail
        self.cache_information()

    def __repr__(self):
        return "{}.{}({})".format(__name__, type(self).__name__, argstr(
            uid=self.uid,
            id=self._id,
            name=self.name,
            mail=self._mail,
        ))

    can_change_password = False

    @classmethod
    def get(cls, username, **kwargs):
        """Static method for flask-login user_loader,
        used before _every_ request.
        """
        userData = do_api_call('find?login=' + str(username))

        if userData is None:
            raise UserNotFound

        uid = userData['login'] or username
        name = userData['name'] or username
        # TODO: Somehow access the entry in the datasource constructor
        mail = username + "@wh17.tu-dresden.de"

        return cls(uid, userData['id'], name, mail)

    @classmethod
    def authenticate(cls, username, password):
        auth = do_api_call('auth', 'post', {'login': username,
                                            'pass': password})

        if auth == 'NoAccount':
            raise UserNotFound

        if auth:
            return cls.get(username)
        else:
            raise PasswordInvalid

    @classmethod
    def from_ip(cls, ip):
        userData = do_api_call('find?ip=' + ip)

        if userData is not None:
            return cls(userData['login'], userData['name'], 'passive')
        else:
            return AnonymousUserMixin()

    def cache_information(self):
        user_data = do_api_call(str(self._id))

        self._id = user_data['id']
        self._login = user_data['login']
        self._address = user_data['address']
        self._mail = user_data['mail']
        self._status = user_data['status']

        hosts = user_data['hosts']
        self._ips = {h['ip'] for h in hosts} - {None}
        self._macs = {h['mac'] for h in hosts} - {None}
        self._hostnames = {h['hostname'] for h in hosts} - {None}
        self._hostaliases = {h['alias'] for h in hosts} - {None}

    def change_password(self):
        raise NotImplementedError

    @property
    def traffic_history(self):
        trafficData = do_api_call("{}/traffic".format(self._id))

        if trafficData:
            hostOneTraffic = trafficData[0]['traffic']
            traffic_history = []

            # loop through expected days ([-6..0])
            for d in range(-6, 1):
                date = datetime.date.today() + datetime.timedelta(d)
                day = date.weekday()
                # pick the to `date` corresponding data
                host = next((
                    x for x in hostOneTraffic
                    if x['date'] == date.strftime("%Y-%m-%d")
                ), None)
                if host:
                    (input, output, credit) = (
                        round(host[param] / 1048576.0, 2)
                        for param in ['in', 'out', 'credit']
                    )

                    traffic_history.append({
                        'day': WEEKDAYS[day],
                        'input': input,
                        'output': output,
                        'throughput': input+output,
                        'credit': credit,
                    })
                else:
                    traffic_history.append({
                        'day': WEEKDAYS[day],
                        'input': 0.0,
                        'output': 0.0,
                        'throughput': 0.0,
                        'credit': 0.0,
                    })

            return traffic_history
        else:
            return [{
                'day': WEEKDAYS[day],
                'input': 0.0,
                'output': 0.0,
                'throughput': 0.0,
                'credit': 0.0,
            } for day in range(7)]

    @property
    def credit(self):
        creditData = do_api_call(str(self._id) + '/credit')
        return creditData[0]['credit']/1048576 if creditData else 0

    @active_prop
    def id(self):
        return self._id

    @active_prop
    def login(self):
        return self._login

    @active_prop
    def status(self):
        return self._status

    @active_prop
    def address(self):
        return self._address

{'fraction_non_alphanumeric': 0.11412562665880271, 'fraction_numerical': 0.00874864838297454, 'mean_word_length': 1.8245419211549139, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4076975', 'n_tokens_mistral': 2983, 'n_tokens_neox': 2794, 'n_words': 744}