class MoodleCourse(db.Document): serial_id = db.SequenceField() moodle_id = db.IntField(unique=True) short_name = db.StringField(default='') full_name = db.StringField(default='') display_name = db.StringField(default='') summary = db.StringField(default='') enrolled_user_count = db.IntField(default=0) visible = db.BooleanField(default=False) format = db.StringField(default='') grade_max = db.IntField() show_grades = db.BooleanField(default=False) start_date = db.IntField(default=0) cover = db.StringField(default='') forum_list = db.ListField(db.ReferenceField('MoodleForum'), default=[]) forum_count = db.IntField(default=0) def get_info(self): return self.to_json() def update_course(self, course_info): self.short_name = course_info.get('short_name') self.full_name = course_info.get('full_name') self.display_name = course_info.get('display_name') self.summary = course_info.get('summary') self.enrolled_user_count = course_info.get('enrolled_user_count') self.visible = course_info.get('visible') self.format = course_info.get('format') self.show_grades = course_info.get('show_grades') self.start_date = course_info.get('start_date') self.cover = course_info.get('cover') print('Update moodle course #{}: {}'.format(self.serial_id, self.short_name)) return self
class StepicReview(db.Document): serial_id = db.SequenceField() stepic_id = db.IntField(unique=True) user = db.ReferenceField('StepicUser') course = db.ReferenceField('StepicCourse') create_date = db.IntField(default=0) update_date = db.IntField(default=0) text = db.StringField(default='') score = db.IntField(default=0) progress = db.FloatField(required=True) user_reputation = db.IntField(required=True) def get_info(self): return self.to_json() def update_review(self, comment_info): self.stepic_id = comment_info.get('stepic_id') self.create_date = parse(comment_info.get('create_date')).timestamp() self.update_date = parse(comment_info.get('update_date')).timestamp() self.text = comment_info.get('text') self.score = comment_info.get('score') self.progress = 0 self.user_reputation = 0 print('Update stepic review #{}'.format(self.serial_id)) return self def update_review_progress(self): self.progress = round( (self.user.courses[str(self.course.stepic_id)].score / self.course.score * 100), 2) if self.course.score else 0 self.user_reputation = self.user.reputation if self.user.reputation else 0 return self
class MoodleTag(db.Document): serial_id = db.SequenceField() moodle_id = db.IntField(unique=True) tag_id = db.IntField() is_standard = db.BooleanField(default=False) display_name = db.StringField(default='') def get_info(self): return self.to_json()
class AccountMember(db.Document): serial_id = db.SequenceField() account_id = db.IntField(unique=True) joined_at = db.IntField() role = db.StringField() role_i18n = db.StringField() def get_info(self): return self.to_json()
class StepicUser(db.Document): serial_id = db.SequenceField() stepic_id = db.IntField(unique=True) full_name = db.StringField(default='') avatar_url = db.StringField(default='') reputation = db.IntField() courses = db.MapField(db.EmbeddedDocumentField('StepicUserCourse')) def get_info(self): return self.to_json() def update_user(self, user_info): self.full_name = user_info.get('full_name') self.avatar_url = user_info.get('avatar') self.reputation = user_info.get('reputation') # update user course grades self.__update_course_grades() print('Update stepic user #{}'.format(self.serial_id)) return self def add_step(self, comment_info): course_id = comment_info.get('course_id') user_course = self.courses.get(str(course_id)) if user_course: user_course.add_step(comment_info) else: self.courses[str(course_id)] = StepicUserCourse( user=self, course=StepicCourse.objects( stepic_id=course_id).first()).add_step(comment_info) return self def add_course(self, review_info): course_id = review_info.get('course_id') user_course = self.courses.get(str(course_id)) if not user_course: self.courses[str(course_id)] = StepicUserCourse( user=self, course=StepicCourse.objects(stepic_id=course_id).first()) return self def __update_course_grades(self): stepic_api = StepicApi(current_user.token) for course_id in self.courses: course_grades = stepic_api.get_user_course_grades( course_id, self.stepic_id) if course_grades: self.courses[course_id].update_step_grades(course_grades[0]) return self
class BaseTeacher(UserMixin, db.Document): serial_id = db.SequenceField() meta = {'allow_inheritance': True} def get_info(self): return self.to_json() def is_stepic_teacher(self): return True if self._cls == 'BaseTeacher.StepicTeacher' else False def is_moodle_teacher(self): return True if self._cls == 'BaseTeacher.MoodleTeacher' else False
class AccountToken(db.Document): serial_id = db.SequenceField() account_id = db.IntField(unique=True) access_token = db.StringField() expires_at = db.IntField() def get_info(self): return self.to_json() # TODO: продление токена (если не удалось продлить, удаляем AccountToken, AccountPrivate перестает обновляться) def plrolongate_token(): return True
class AccountStatistics(db.Document): serial_id = db.SequenceField() account_id = db.IntField(unique=True) battle_avg_xp = db.IntField() battles = db.IntField() wins = db.IntField() draws = db.IntField() losses = db.IntField() survived_battles = db.IntField() hits_percents = db.IntField() max_damage = db.IntField() max_damage_tank_id = db.IntField() max_frags = db.IntField() max_frags_tank_id = db.IntField() max_xp = db.IntField() max_xp_tank_id = db.IntField() def get_info(self): return self.to_json() def update_account_statistics(self, account_statistics_info): self.battle_avg_xp = account_statistics_info.get( WG_API_CONST().ACCOUNT_STATISTICS_BATTLE_AVG_XP) self.battles = account_statistics_info.get( WG_API_CONST().ACCOUNT_STATISTICS_BATTLES) self.wins = account_statistics_info.get( WG_API_CONST().ACCOUNT_STATISTICS_WINS) self.draws = account_statistics_info.get( WG_API_CONST().ACCOUNT_STATISTICS_DRAWS) self.losses = account_statistics_info.get( WG_API_CONST().ACCOUNT_STATISTICS_LOSSES) self.survived_battles = account_statistics_info.get( WG_API_CONST().ACCOUNT_STATISTICS_SURVIVED_BATTTLES) self.hits_percents = account_statistics_info.get( WG_API_CONST().ACCOUNT_STATISTICS_HITS_PERCENTS) self.max_damage = account_statistics_info.get( WG_API_CONST().ACCOUNT_STATISTICS_MAX_DAMAGE) self.max_damage_tank_id = account_statistics_info.get( WG_API_CONST().ACCOUNT_STATISTICS_MAX_DAMAGE_TANK_ID) self.max_frags = account_statistics_info.get( WG_API_CONST().ACCOUNT_STATISTICS_MAX_FRAGS) self.max_frags_tank_id = account_statistics_info.get( WG_API_CONST().ACCOUNT_STATISTICS_MAX_FRAGS_TANK_ID) self.max_xp = account_statistics_info.get( WG_API_CONST().ACCOUNT_STATISTICS_MAX_XP) self.max_xp_tank_id = account_statistics_info.get( WG_API_CONST().ACCOUNT_STATISTICS_MAX_XP_TANK_ID) return self
class MoodleUser(db.Document): serial_id = db.SequenceField() moodle_id = db.IntField() full_name = db.StringField(default='') user_url = db.StringField(default='') user_picture_url = db.StringField(default='') course_grade_dict= db.DictField(default={}) def get_info(self): return self.to_json() def update_course_grade(self, user_course_grade): self.course_grade_dict.update(user_course_grade) print('Update moodle user course grade #{}'.format(self.serial_id)) return self
class FiltrationSet(db.Document): serial_id = db.SequenceField() # название фильтра title = db.StringField(default='', unique=True) # поле "Дата" date_from = db.IntField(default=0) date_to = db.IntField(default=0) date_order = db.StringField(default='-') # поле "Ответы" replies_from = db.IntField(default=0) replies_to = db.IntField(default=10) replies_order = db.StringField(default='-') # поле "Прогресс" progress_from = db.IntField(default=0) progress_to = db.IntField(default=100) progress_order = db.StringField(default='-') # разрешено наследование meta = {'allow_inheritance': True} def get_info(self): return self.to_json() # url параметры поля "Дата" def get_date_args_url(self): date_args_url = 'date[from]={}&date[to]={}&date[order]={}'.format( date.fromtimestamp(self.date_from).isoformat(), date.fromtimestamp(self.date_to).isoformat(), self.date_order) return date_args_url # url параметры поля "Ответы" def get_replies_args_url(self): replies_args_url = 'replies[from]={}&replies[to]={}&replies[order]={}'.format( self.replies_from, self.replies_to, self.replies_order) return replies_args_url # url параметры поля "Прогресс" def get_progress_args_url(self): progress_args_url = 'progress[from]={}&progress[to]={}&progress[order]={}'.format( self.progress_from, self.progress_to, self.progress_order) return progress_args_url
class MoodleDiscussion(db.Document): serial_id = db.SequenceField() moodle_id = db.IntField(unique=True) discussion_id = db.IntField(unique=True) user = db.ReferenceField('MoodleUser') course = db.ReferenceField('MoodleCourse') forum = db.ReferenceField('MoodleForum') discussion_post = db.ReferenceField('MoodlePost') name = db.StringField(default='') subject = db.StringField(default='') message = db.StringField(default='') time_created = db.IntField(default=0) time_modified = db.IntField(default=0) user_modified = db.IntField(default=0) # ? ReferenceField num_replies = db.IntField(required=True) view_url = db.StringField(default='') tag_list = db.ListField(db.ReferenceField('MoodleTag')) post_list = db.ListField(db.ReferenceField('MoodlePost'), default=[]) status = db.StringField(default='new') progress = db.FloatField(required=True) def get_info(self): return self.to_json() def update_discussion(self, discussion_info): self.user = MoodleUser.objects(moodle_id=discussion_info.get('user_id')).modify( full_name=discussion_info.get('user_full_name'), user_picture_url=discussion_info.get('user_picture_url'), upsert=True, new=True) self.name = discussion_info.get('name') self.subject = discussion_info.get('subject') self.message = discussion_info.get('message') self.time_created = discussion_info.get('time_created') self.time_modified = discussion_info.get('time_modified') self.user_modified = discussion_info.get('user_modified') self.num_replies = discussion_info.get('num_replies') self.progress = self.progress if self.progress else 0 print('Update moodle discussion #{}'.format(self.serial_id)) return self
class Clan(db.Document): serial_id = db.SequenceField() clan_id = db.IntField(unique=True) accepts_join_requests = db.BooleanField() color = db.StringField() created_at = db.IntField() description = db.StringField() description_html = db.StringField() members_count = db.IntField() motto = db.StringField() name = db.StringField() tag = db.StringField() updated_at = db.IntField() # emblem = db.StringField() - много ссылок на эмблемы разных размеров # online_members = db.ListField(db.IntField()) - вообще не приходит это поле # clan_treasury - казна клана (credits, crystal, gold) - приходит только gold, а в crystal - null def get_info(self): return self.to_json()
class MoodleForum(db.Document): serial_id = db.SequenceField() moodle_id = db.IntField(unique=True) course = db.ReferenceField('MoodleCourse') type = db.StringField(default='') name = db.StringField(default='') intro = db.StringField(default='') scale = db.IntField(default=0) discussion_list = db.ListField(db.ReferenceField('MoodleDiscussion'), default=[]) def get_info(self): return self.to_json() def update_forum(self, forum_info): self.type = forum_info.get('type') self.name = forum_info.get('name') self.intro = forum_info.get('intro') self.scale = forum_info.get('scale') print('Update moodle forum #{}'.format(self.serial_id)) return self
class AccountPrivate(db.Document): serial_id = db.SequenceField() account_id = db.IntField(unique=True) ban_info = db.StringField() ban_time = db.IntField() bonds = db.IntField() gold = db.IntField() credits = db.IntField() free_xp = db.IntField() is_premium = db.BooleanField() premium_expires_at = db.IntField() # значение берется из account и показывает последнее обновление "приватных" полей (на случай прекращения действия токена) updated_at = db.IntField() def get_info(self): return self.to_json() def update_account_private(self, account_private_info): self.ban_info = account_private_info.get( WG_API_CONST().ACCOUNT_PRIVATE_BAN_INFO) self.ban_time = account_private_info.get( WG_API_CONST().ACCOUNT_PRIVATE_BAN_TIME) self.bonds = account_private_info.get( WG_API_CONST().ACCOUNT_PRIVATE_BONDS) self.gold = account_private_info.get( WG_API_CONST().ACCOUNT_PRIVATE_GOLD) self.credits = account_private_info.get( WG_API_CONST().ACCOUNT_PRIVATE_CREDITS) self.free_xp = account_private_info.get( WG_API_CONST().ACCOUNT_PRIVATE_FREE_XP) self.is_premium = account_private_info.get( WG_API_CONST().ACCOUNT_PRIVATE_IS_PREMIUM) self.premium_expires_at = account_private_info.get( WG_API_CONST().ACCOUNT_PRIVATE_PREMIUM_EXPIRES_AT) return self
class StepicCourse(db.Document): serial_id = db.SequenceField() stepic_id = db.IntField(unique=True) title = db.StringField(default='') summary = db.StringField(default='') cover = db.StringField(default='/static/images/stepic_course_cover.png') cert_reg_threshold = db.IntField(default=0) cert_dist_threshold = db.IntField(default=0) score = db.IntField(default=0) def get_info(self): return self.to_json() def update_course(self, course_info): self.title = course_info.get('title') self.summary = course_info.get('summary') self.cover = course_info.get('cover') self.cert_reg_threshold = course_info.get('cert_reg_threshold') self.cert_dist_threshold = course_info.get('cert_dist_threshold') self.score = course_info.get('score') print('Update stepic course #{}'.format(self.serial_id)) return self
class Account(UserMixin, db.Document): serial_id = db.SequenceField() clan = db.ReferenceField('Clan') private = db.ReferenceField('AccountPrivate') statistics = db.ReferenceField('AccountStatistics') member = db.ReferenceField('AccountMember') token = db.ReferenceField('AccountToken') account_id = db.IntField(unique=True) created_at = db.IntField() global_rating = db.IntField() last_battle_time = db.IntField() logout_at = db.IntField() nickname = db.StringField() updated_at = db.IntField() # avatar = db.ImageField() - или лучше хранить url ? # name = db.StringField() - настоящее имя игрока def __set_public_info(self, account_info): self.created_at = account_info.get(WG_API_CONST().ACCOUNT_CREATED_AT) self.global_rating = account_info.get( WG_API_CONST().ACCOUNT_GLOBAL_RATING) self.last_battle_time = account_info.get( WG_API_CONST().ACCOUNT_LAST_BATTLE_TIME) self.logout_at = account_info.get(WG_API_CONST().ACCOUNT_LOGOUT_AT) self.nickname = account_info.get(WG_API_CONST().ACCOUNT_NICKNAME) self.updated_at = account_info.get(WG_API_CONST().ACCOUNT_UPDATED_AT) return self # ************************************************************************** # Public methods # ************************************************************************** def get_id(self): return str(self.id) def get_info(self): return self.to_json() def update_account_info(self): account_info = WG_API().get_account_info( self.account_id, self.token.access_token).get( WG_API_CONST().RESPONSE_DATA).get(str(self.account_id)) self.__set_public_info(account_info) # private if (account_info.get(WG_API_CONST().ACCOUNT_PRIVATE)): AccountPrivate.objects(account_id=self.account_id).update_one( account_id=self.account_id, updated_at=self.updated_at, upsert=True) self.private = AccountPrivate.objects( account_id=self.account_id).first().update_account_private( account_info.get(WG_API_CONST().ACCOUNT_PRIVATE)).save() # statistics AccountStatistics.objects(account_id=self.account_id).update_one( account_id=self.account_id, upsert=True) self.statistics = AccountStatistics.objects( account_id=self.account_id).first().update_account_statistics( account_info.get(WG_API_CONST().ACCOUNT_STATISTICS).get( WG_API_CONST().ACCOUNT_STATISTICS_ALL)).save() return self.save()
class MoodlePost(db.Document): serial_id = db.SequenceField() moodle_id = db.IntField(unique=True) user = db.ReferenceField('MoodleUser') course = db.ReferenceField('MoodleCourse') forum = db.ReferenceField('MoodleForum') discussion = db.ReferenceField('MoodleDiscussion') subject = db.StringField(default='') reply_subject = db.StringField(default='') message = db.StringField(default='') has_parent = db.BooleanField(default=False) parent_post = db.ReferenceField('MoodlePost') time_created = db.IntField(default=0) view_url = db.StringField(default='') rating = db.IntField(default=0) rating_count = db.IntField(default=0) rating_label = db.StringField(default='') tag_list = db.ListField(db.ReferenceField('MoodleTag')) post_list = db.ListField(db.ReferenceField('MoodlePost'), default=[]) num_replies = db.IntField(required=True) status = db.StringField(required=True) progress = db.FloatField(required=True) def get_info(self): return self.to_json() def update_post(self, post_info): self.subject = post_info.get('subject') self.reply_subject = post_info.get('reply_subject') self.message = post_info.get('message') self.has_parent = post_info.get('has_parent') self.time_created = post_info.get('time_created') self.view_url = post_info.get('view_url') self.tag_list = [ MoodleTag.objects(moodle_id=tag_info.get('id')).modify( moodle_id=tag_info.get('id'), tag_id=tag_info.get('tagid'), is_standard=tag_info.get('isstandard'), display_name=tag_info.get('displayname'), upsert=True, new=True) for tag_info in post_info.get('tags')] self.status = self.status if self.status else 'new' # Иначе не работает фильтрация по дефолтному значению self.progress = 0 if not self.has_parent: self.discussion.modify( discussion_post=self, view_url=self.view_url, tag_list=self.tag_list, status=self.status, progress=self.progress) else: parent_post = MoodlePost.objects(moodle_id=post_info.get('parent_id')).first() if parent_post: if not self in parent_post.post_list: parent_post.post_list.append(self) else: parent_post = MoodlePost.objects(moodle_id=post_info.get('parent_id')).modify( post_list=[self], status='new', progress=0, upsert=True, new=True) self.parent_post = parent_post parent_post.num_replies = len(parent_post.post_list) parent_post.save() if post_info.get('rating'): self.rating = post_info.get('rating').get('rating') self.rating_count = post_info.get('rating').get('count') self.rating_label = post_info.get('rating').get('aggregatelabel') self.num_replies = self.num_replies if self.num_replies else 0 # Иначе не работает фильтрация по дефолтному значению print('Update moodle post #{}'.format(self.serial_id)) return self def update_post_status(self, status_info): self.status = status_info.get('post_status') if not self.has_parent: self.discussion.modify(status=self.status) return self def update_post_progress(self): self.progress = round((self.user.course_grade_dict[str(self.course.moodle_id)] / self.course.grade_max * 100), 2) if self.course.grade_max else 0 if not self.has_parent: self.discussion.modify(progress=self.progress) return self
class StepicComment(db.Document): serial_id = db.SequenceField() stepic_id = db.IntField(unique=True) parent_id = db.IntField() step_id = db.IntField() user = db.ReferenceField('StepicUser') course = db.ReferenceField('StepicCourse') user_role = db.StringField(default='') time = db.IntField(default=0) last_time = db.IntField(default=0) text = db.StringField(default='') # replies = db.ListField(db.ReferenceField('self')) reply_count = db.IntField(required=True) is_deleted = db.BooleanField(required=True) is_pinned = db.BooleanField(default=False) is_staff_replied = db.BooleanField(default=False) is_reported = db.BooleanField(default=False) # attachments = db.ListField(default=[]) epic_count = db.IntField(default=0) abuse_count = db.IntField(default=0) status = db.StringField(required=True) progress = db.FloatField(required=True) user_reputation = db.IntField(required=True) def get_info(self): return self.to_json() def update_comment(self, comment_info): self.stepic_id = comment_info.get('stepic_id') self.parent_id = comment_info.get('parent_id') self.step_id = comment_info.get('step_id') self.user_role = comment_info.get('user_role') self.time = parse(comment_info.get('time')).timestamp() self.last_time = parse(comment_info.get('last_time')).timestamp() self.text = comment_info.get('text') # self.replies = comment_info.get('replies') self.reply_count = comment_info.get('reply_count') if comment_info.get( 'reply_count' ) else 0 # Иначе не работает фильтрация по дефолтному значению self.is_deleted = comment_info.get('is_deleted') if comment_info.get( 'is_deleted') else False self.is_pinned = comment_info.get('is_pinned') self.is_staff_replied = comment_info.get('is_staff_replied') self.is_reported = comment_info.get('is_reported') self.attachments = comment_info.get('attachments') self.epic_count = comment_info.get('epic_count') self.abuse_count = comment_info.get('abuse_count') self.status = self.status if self.status else 'new' # Иначе не работает фильтрация по дефолтному значению self.progress = 0 self.user_reputation = 0 print('Update stepic comment #{}'.format(self.serial_id)) return self def update_comment_status(self, status_info): self.status = status_info.get('comment_status') return self def update_comment_progress(self): self.progress = round( (self.user.courses[str(self.course.stepic_id)].score / self.course.score * 100), 2) if self.course.score else 0 self.user_reputation = self.user.reputation if self.user.reputation else 0 return self