<commit_before>from hashlib import md5
from datetime import datetime
from werkzeug import generate_password_hash, check_password_hash

from annotateit import db
from annotateit.model import Consumer
from annotateit.model.timestamps import Timestamps

__all__ = ['User']

class User(db.Model, Timestamps):
    _id = db.Column('id', db.Integer, primary_key=True)
    username = db.Column(db.String(128), unique=True)
    email = db.Column(db.String(128), unique=True)
    password_hash = db.Column(db.String(128))
    is_admin = db.Column(db.Boolean, default=False)

    # NB: there is a *big* difference between `consumer` and `consumers`
    #
    # `consumer`  - the consumer to which this user belongs (namely AnnotateIt), used by
    #               auth/authz etc.
    #
    # `consumers` - the list of consumers created for this user
    #
    consumers = db.relationship('Consumer', backref='user', lazy='dynamic')

    @classmethod
    def fetch(cls, username):
        return cls.query.filter_by(username=username).first()

    def __init__(self, username, email, password=None):
        self.username = username
        self.email = email
        if password:
            self.password = password

    def __repr__(self):
        return '<User %r>' % self.username

    def _password_set(self, v):
        self.password_hash = generate_password_hash(v)

    password = property(None, _password_set)

    def check_password(self, password):
        if not self.password_hash:
            return False
        return check_password_hash(self.password_hash, password)

    # Alias username to id for the purposes of authentication
    @property
    def id(self):
        return self.username

    @property
    def consumer(self):
        if not hasattr(self, '_consumer'):
            self._consumer = Consumer.fetch('annotateit')
        return self._consumer

    @property
    def gravatar_url(self):
        hsh = md5(self.email.strip().lower()).hexdigest()
        url = 'http://www.gravatar.com/avatar/{hash}?d=mm'.format(hash=hsh)
        return url<commit_msg>UTF-8 encode email address before calculating Gravatar hash.<commit_after>from hashlib import md5
from datetime import datetime
from werkzeug import generate_password_hash, check_password_hash

from annotateit import db
from annotateit.model import Consumer
from annotateit.model.timestamps import Timestamps

__all__ = ['User']

class User(db.Model, Timestamps):
    _id = db.Column('id', db.Integer, primary_key=True)
    username = db.Column(db.String(128), unique=True)
    email = db.Column(db.String(128), unique=True)
    password_hash = db.Column(db.String(128))
    is_admin = db.Column(db.Boolean, default=False)

    # NB: there is a *big* difference between `consumer` and `consumers`
    #
    # `consumer`  - the consumer to which this user belongs (namely AnnotateIt), used by
    #               auth/authz etc.
    #
    # `consumers` - the list of consumers created for this user
    #
    consumers = db.relationship('Consumer', backref='user', lazy='dynamic')

    @classmethod
    def fetch(cls, username):
        return cls.query.filter_by(username=username).first()

    def __init__(self, username, email, password=None):
        self.username = username
        self.email = email
        if password:
            self.password = password

    def __repr__(self):
        return '<User %r>' % self.username

    def _password_set(self, v):
        self.password_hash = generate_password_hash(v)

    password = property(None, _password_set)

    def check_password(self, password):
        if not self.password_hash:
            return False
        return check_password_hash(self.password_hash, password)

    # Alias username to id for the purposes of authentication
    @property
    def id(self):
        return self.username

    @property
    def consumer(self):
        if not hasattr(self, '_consumer'):
            self._consumer = Consumer.fetch('annotateit')
        return self._consumer

    @property
    def gravatar_url(self):
        hsh = md5(self.email.strip().lower().encode('utf-8')).hexdigest()
        url = 'http://www.gravatar.com/avatar/{hash}?d=mm'.format(hash=hsh)
        return url
{'fraction_non_alphanumeric': 0.10443864229765012, 'fraction_numerical': 0.005696653216235461, 'mean_word_length': 3.0597302504816954, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1039281', 'n_tokens_mistral': 1275, 'n_tokens_neox': 1217, 'n_words': 326}