class Settings(db.Model): __tablename__ = "user_settings" id = db.Column(db.Integer, primary_key=True, autoincrement=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id')) user = db.relationship("User", back_populates="settings") rudeness_min = db.Column(db.Float, db.CheckConstraint('rudeness_min>=0'), default=0) rudeness_max = db.Column(db.Float, db.CheckConstraint('rudeness_max<=1'), default=1) gender_filter_on = db.Column(db.Boolean, default=False) gender_female_per = db.Column(db.Integer, db.CheckConstraint('gender_female_per>=0 AND gender_female_per<=100'), default=50) include_corporate = db.Column(db.Boolean, default=True) virality_min = db.Column(db.Float, db.CheckConstraint('virality_min>=0'), default=0) virality_max = db.Column(db.Float, db.CheckConstraint('virality_max<=1'), default=1) seriousness_min = db.Column(db.Float, db.CheckConstraint('seriousness_min>=0'), default=0) seriousness_max = db.Column(db.Float, db.CheckConstraint('seriousness_max<=1'), default=1) echo_range = db.Column(db.Enum(EchoRangeEnum), default=EchoRangeEnum.narrow) rudeness_ck = db.CheckConstraint('rudeness_max>rudeness_min') virality_ck = db.CheckConstraint('virality_max>virality_min') seriousness_ck = db.CheckConstraint('seriousness_max>seriousness_min') def as_dict(self): d = {c.name: getattr(self, c.name) for c in self.__table__.columns if c.name!='echo_range'} d['echo_range'] = self.echo_range.value return d def update(self, settings_dict): self.rudeness_min = settings_dict['rudeness_min'] self.rudeness_max = settings_dict['rudeness_max'] self.gender_filter_on = settings_dict['gender_filter_on'] self.gender_female_per = settings_dict['gender_female_per'] self.include_corporate = settings_dict['include_corporate'] self.virality_min = settings_dict['virality_min'] self.virality_max = settings_dict['virality_max'] self.seriousness_min = settings_dict['seriousness_min'] self.seriousness_max = settings_dict['seriousness_max'] self.echo_range = EchoRangeEnum(settings_dict['echo_range'])
class Post(db.Model): __tablename__ = "posts" id = db.Column(db.Integer, primary_key=True, autoincrement=True) original_id = db.Column(db.String(40), nullable=False) content = db.Column(db.JSON, nullable=False) source = db.Column(db.String(255), nullable=False) retrieved_at = db.Column(db.DateTime, nullable=False) created_at = db.Column(db.DateTime) # filters is_news = db.Column(db.Boolean) toxicity = db.Column(db.Float) gender = db.Column(db.Enum(GenderEnum)) is_corporate = db.Column(db.Boolean) virality_count = db.Column(db.Integer) has_link = db.Column(db.Boolean) news_score = db.Column(db.Float) political_quintile = db.Column(db.Enum(PoliticsEnum)) db.UniqueConstraint('source_id', 'source', name='post_id') def __init__(self, original_id, source, content, is_news): self.original_id = original_id self.source = source self.content = content self.is_news = is_news self.retrieved_at = datetime.datetime.now() if source=='twitter': self.created_at = datetime.datetime.strptime(content['created_at'], '%a %b %d %H:%M:%S +0000 %Y') self.has_link = len(content['entities']['urls']) > 0 # 'possibly_sensitive' in content else: self.created_at = datetime.datetime.strptime(content['created_time'], '%Y-%m-%dT%H:%M:%S+0000') self.has_link = content['type']=='link' def as_dict(self): d = {c.name: getattr(self, c.name) for c in self.__table__.columns if c.name not in ['gender', 'political_quintile']} d['gender'] = str(self.gender) d['political_quintile'] = self.political_quintile.value if self.political_quintile else None return d def get_text(self): # TODO: logic fore getting text - should we get text from link shared, etc? text = "" if self.source=="twitter": text = self.content['full_text'] if 'full_text' in self.content else self.content['text'] if self.source=="facebook": text = self.content['message'] if 'message' in self.content else "" return text def has_toxicity_rate(self): return self.toxicity is not None def update_content(self, content, is_news=False): self.content.update(content) if is_news: self.is_news = True def update_toxicity(self, score): self.toxicity = score db.session.commit() def update_gender_corporate(self, gender, corporate): self.gender = gender self.is_corporate = corporate db.session.commit() def has_gender_corporate(self): return (self.gender is not None) and (self.is_corporate is not None) def update_replies_count(self, count): new_content = self.content.copy() prev_count = self.content['replies_count'] if 'replies_count' in self.content else 0 new_content['replies_count'] = max(count, prev_count) self.content = new_content def has_virality(self): return self.virality_count is not None def has_news_score(self): return self.news_score is not None def has_already_been_analyzed(self): return self.has_virality() and self.has_news_score() and self.has_gender_corporate() and self.has_toxicity_rate() def get_author_name(self): if self.source=='facebook': return self.content['from']['name'] else: if 'retweeted_status' in self.content: return self.content['retweeted_status']['user']['name'] return self.content['user']['name']
class User(db.Model): __tablename__ = "users" id = db.Column(db.Integer, primary_key=True, autoincrement=True) email = db.Column(db.String(255), unique=True, nullable=False) password = db.Column(db.String(255), nullable=False) registered_on = db.Column(db.DateTime, nullable=False) completed_registration = db.Column(db.Boolean, default=False) facebook_name = db.Column(db.String(255)) facebook_picture_url = db.Column(db.String(255)) facebook_id = db.Column(db.String(255)) facebook_email = db.Column(db.String(255)) twitter_name = db.Column(db.String(255)) twitter_id = db.Column(db.String(255)) facebook_auth = db.relationship("FacebookAuth", uselist=False, back_populates="user", cascade="delete, delete-orphan") twitter_auth = db.relationship("TwitterAuth", uselist=False, back_populates="user", cascade="delete, delete-orphan") twitter_authorized = db.Column(db.Boolean, nullable=False, default=False) facebook_authorized = db.Column(db.Boolean, nullable=False, default=False) twitter_data = db.Column(db.JSON) facebook_data = db.Column(db.JSON) political_affiliation = db.Column(db.Enum(PoliticsEnum), default=PoliticsEnum.center) posts = db.relationship("Post", secondary=post_associations_table, lazy='dynamic') settings = db.relationship("Settings", uselist=False, back_populates="user") def __init__(self, email, password): self.email = email self.password = bcrypt.generate_password_hash(password) self.registered_on = datetime.datetime.now() settings = Settings() self.settings = settings def is_authenticated(self): return True def is_active(self): return True def is_anonymous(self): return False def get_id(self): return self.id def get_names(self): d = {c.name: getattr(self, c.name) for c in self.__table__.columns if c.name not in [ 'password', 'id', 'political_affiliation', 'posts', 'settings', 'facebook_data']} d['political_affiliation'] = self.political_affiliation.value d['avatar'] = self.twitter_data['profile_image_url_https'] if self.twitter_data else self.facebook_picture_url return d def set_facebook_data(self, data): self.facebook_name = data['name'] if 'name' in data else '' self.facebook_email = data['email'] if 'email' in data else '' self.facebook_id = data['id'] if 'picture' in data: if 'data' in data['picture']: if 'url' in data['picture']['data']: self.facebook_picture_url = data['picture']['data']['url'] self.facebook_data = data self.facebook_authorized = True db.session.commit() def set_twitter_data(self, id, name, data): self.twitter_name = name self.twitter_id = id self.twitter_data = data self.twitter_authorized = True db.session.commit() def set_political_affiliation(self, political_affiliation): self.political_affiliation = PoliticsEnum(int(political_affiliation)) db.session.commit() def complete_registration(self): self.completed_registration = True db.session.commit() def __repr__(self): return '<User {0}>'.format(self.email)
class Post(db.Model): __tablename__ = "posts" id = db.Column(db.Integer, primary_key=True, autoincrement=True) original_id = db.Column(db.String(40), nullable=False) content = db.Column(db.JSON, nullable=False) source = db.Column(db.String(255), nullable=False) retrieved_at = db.Column(db.DateTime, nullable=False) created_at = db.Column(db.DateTime) # filters toxicity = db.Column(db.Float) gender = db.Column(db.Enum(GenderEnum)) is_corporate = db.Column(db.Boolean) virality_count = db.Column(db.Integer) has_link = db.Column(db.Boolean) news_score = db.Column(db.Float) db.UniqueConstraint('source_id', 'source', name='post_id') rule_associations = db.relationship("PostAdditiveRule", back_populates="post", cascade="delete, delete-orphan") rules = None __mapper_args__ = { 'polymorphic_on': source, } def __init__(self, original_id, source, content): self.original_id = original_id self.source = source self.content = content self.retrieved_at = datetime.datetime.now() self.rules = None if source == 'twitter': self.created_at = datetime.datetime.strptime( content['created_at'], '%a %b %d %H:%M:%S +0000 %Y') # TODO: fix this eventually # pylint: disable=len-as-condition self.has_link = len(content['entities']['urls'] ) > 0 # 'possibly_sensitive' in content elif source == 'facebook': self.created_at = datetime.datetime.strptime( content['created_time'], '%Y-%m-%dT%H:%M:%S+0000') self.has_link = content['type'] == 'link' elif source == 'mastodon': self.created_at = content['created_at'] if content['card'] and content['card']['type']: self.has_link = content['card']['type'].lower() == 'link' else: self.has_link = False def as_dict(self): d = { c.name: getattr(self, c.name) for c in self.__table__.columns if c.name not in ['gender'] } d['gender'] = str(self.gender) # using the cache saves time over db lookups if self.rules: d['rules'] = self.rules return d def cache_rule(self, rule): """Cache a list of rule dicts that this post has associated with it for serializing later.""" if self.rules is None: self.rules = [] self.rules.append(rule) def get_text(self): raise NotImplementedError def has_toxicity_rate(self): return self.toxicity is not None def update_content(self, content): self.content.update(content) def update_toxicity(self, score): self.toxicity = score db.session.commit() def update_gender_corporate(self, gender, corporate): self.gender = gender self.is_corporate = corporate db.session.commit() def has_gender_corporate(self): return (self.gender is not None) and (self.is_corporate is not None) def get_precomputed_gender(self): return None def has_precomputed_corporate(self): return None def has_virality(self): return self.virality_count is not None def has_news_score(self): return self.news_score is not None def has_already_been_analyzed(self): return self.has_virality() and self.has_news_score() and self.has_gender_corporate()\ and self.has_toxicity_rate() def get_urls(self): raise NotImplementedError def get_author_name(self): raise NotImplementedError def get_likes_count(self): raise NotImplementedError def get_comments_count(self): raise NotImplementedError def get_shares_count(self): raise NotImplementedError