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 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 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 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 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 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 StepicUserCourse(db.EmbeddedDocument): user = db.ReferenceField('StepicUser') course = db.ReferenceField('StepicCourse') score = db.IntField(default=0) steps = db.MapField(db.EmbeddedDocumentField('StepicUserStep')) def get_info(self): return self.to_json() def add_step(self, comment_info): step_id = str(comment_info.get('step_id')) user_step = self.steps.get(step_id) if not user_step: self.steps[step_id] = StepicUserStep() return self def update_step_grades(self, course_grades): self.score = course_grades.get('score') results = course_grades.get('results') for step_grades in results: step_id = str(results.get(step_grades).get('step_id')) if step_id in self.steps: self.steps[step_id].update_user_step(results.get(step_grades)) return self
class StepicUserStep(db.EmbeddedDocument): score = db.IntField(default=0) is_passed = db.BooleanField(default=False) is_passed_on_comment = db.BooleanField(default=False) total_submissions = db.IntField(default=0) submissions_on_comment = db.IntField(default=0) def get_info(self): return self.to_json() def update_user_step(self, step_grades): self.score = step_grades.get('score') self.is_passed = step_grades.get('is_passed') self.total_submissions = step_grades.get('total_submissions') 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 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 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 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 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 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 MoodleTeacher(BaseTeacher): moodle_url = db.StringField(default='') moodle_id = db.IntField() token = db.StringField(default='') username = db.StringField(default='') full_name = db.StringField(default='') user_picture_url = db.StringField(default='') course_list = db.ListField(db.ReferenceField('MoodleCourse'), default=[]) filtration_set = db.ReferenceField('MoodleFiltrationSet') def get_info(self): return self.to_json() def update_teacher(self, teacher_info): self.username = teacher_info.get('username') self.full_name = teacher_info.get('fullname') self.user_picture_url = teacher_info.get('userpictureurl') filtration_set_title = '{} (по умолчанию)'.format(teacher_info.get('username')) self.filtration_set = MoodleFiltrationSet.objects(title=filtration_set_title).modify( title=filtration_set_title, date_from=datetime.fromisoformat((date.today() - timedelta(30)).isoformat()).timestamp(), date_to=datetime.fromisoformat((date.today() + timedelta(1)).isoformat()).timestamp(), upsert=True, new=True) print('Update moodle teacher #{}: {}'.format(self.serial_id, self.full_name)) return self def filter_and_sort_discussions(self): # filter filtration_set = self.filtration_set # 4. Курсы discussion_list = MoodleDiscussion.objects(course__in=filtration_set.course_list) if filtration_set.course_list else MoodleDiscussion.objects() # 1. Дата discussion_list = discussion_list.filter(Q(time_created__gte=filtration_set.date_from) & Q(time_created__lte=filtration_set.date_to)) # 2. Ответы discussion_list = discussion_list.filter(Q(num_replies__gte=filtration_set.replies_from) & Q(num_replies__lte=filtration_set.replies_to)) # 5. Теги discussion_list = discussion_list.filter(tag_list__in=[tag for tag in filtration_set.tag_list]) if filtration_set.tag_list else discussion_list # 6. Автор discussion_list = discussion_list.filter(user=filtration_set.author) if filtration_set.author else discussion_list # 7. Статус discussion_list = discussion_list.filter(status=filtration_set.post_status) if filtration_set.post_status != 'all' else discussion_list # 3. Прогресс for discussion in discussion_list: discussion.discussion_post.update_post_progress().save() discussion_list = discussion_list.filter(Q(progress__gte=filtration_set.progress_from) & Q(progress__lte=filtration_set.progress_to)) # sort discussion_list = discussion_list.order_by(*filtration_set.get_sort_args_list()) return discussion_list def filter_and_sort_posts(self): # filter filtration_set = self.filtration_set # 4. Курсы post_list = MoodlePost.objects(course__in=filtration_set.course_list) if filtration_set.course_list else MoodlePost.objects() # 1. Дата post_list = post_list.filter(Q(time_created__gte=filtration_set.date_from) & Q(time_created__lte=filtration_set.date_to)) # 2. Ответы post_list = post_list.filter(Q(num_replies__gte=filtration_set.replies_from) & Q(num_replies__lte=filtration_set.replies_to)) # 5. Теги post_list = post_list.filter(tag_list__in=[tag for tag in filtration_set.tag_list]) if filtration_set.tag_list else post_list # 6. Автор post_list = post_list.filter(user=filtration_set.author) if filtration_set.author else post_list # 7. Статус post_list = post_list.filter(status=filtration_set.post_status) if filtration_set.post_status != 'all' else post_list # 3. Прогресс for post in post_list: post.update_post_progress().save() post_list = post_list.filter(Q(progress__gte=filtration_set.progress_from) & Q(progress__lte=filtration_set.progress_to)) # sort post_list = post_list.order_by(*filtration_set.get_sort_args_list()) return post_list
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 StepicFiltrationSet(FiltrationSet): course_list = db.ListField(db.ReferenceField('StepicCourse'), default=[]) # поле "Репутация" reputation_from = db.IntField(default=0) reputation_to = db.IntField(default=100000) reputation_order = db.StringField(default='-') # поле "Автор" author = db.ReferenceField('StepicUser') # поле "Статус" комментария comment_status = db.StringField(default='all') def get_info(self): return self.to_json() def parse_url_args(self, args): filtration_set_info = { 'date_from': args.get('date[from]'), 'date_to': args.get('date[to]'), 'date_order': args.get('date[order]'), 'replies_from': args.get('replies[from]'), 'replies_to': args.get('replies[to]'), 'replies_order': args.get('replies[order]'), 'progress_from': args.get('progress[from]'), 'progress_to': args.get('progress[to]'), 'progress_order': args.get('progress[order]'), 'reputation_from': args.get('reputation[from]'), 'reputation_to': args.get('reputation[to]'), 'reputation_order': args.get('reputation[order]'), 'course_id_list': args.getlist('course_ids[]'), 'author_id': args.get('author_id'), 'comment_status': args.get('comment_status') } return filtration_set_info def update_filtration_set(self, filtration_set_info): self.date_from = datetime.fromisoformat( filtration_set_info.get('date_from')).timestamp() self.date_to = datetime.fromisoformat( filtration_set_info.get('date_to')).timestamp() self.date_order = filtration_set_info.get('date_order') self.replies_from = filtration_set_info.get('replies_from') self.replies_to = filtration_set_info.get('replies_to') self.replies_order = filtration_set_info.get('replies_order') self.progress_from = filtration_set_info.get('progress_from') self.progress_to = filtration_set_info.get('progress_to') self.progress_order = filtration_set_info.get('progress_order') self.reputation_from = filtration_set_info.get('reputation_from') self.reputation_to = filtration_set_info.get('reputation_to') self.reputation_order = filtration_set_info.get('reputation_order') self.course_list = [ StepicCourse.objects(stepic_id=int(course_id)).first() for course_id in filtration_set_info.get('course_id_list') ] if filtration_set_info.get('course_id_list') else [] self.author = StepicUser.objects( serial_id=filtration_set_info.get('author_id')).first( ) if filtration_set_info.get('author_id') else None self.comment_status = filtration_set_info.get('comment_status') print('Update stepic filtration set #{}'.format(self.serial_id)) return self # copy filtration_set_2 data to filtration_set_1 def copy_filtration_set(self, filtration_set_1, filtration_set_2): filtration_set_1.date_from = filtration_set_2.date_from filtration_set_1.date_to = filtration_set_2.date_to filtration_set_1.date_order = filtration_set_2.date_order filtration_set_1.replies_from = filtration_set_2.replies_from filtration_set_1.replies_to = filtration_set_2.replies_to filtration_set_1.replies_order = filtration_set_2.replies_order filtration_set_1.progress_from = filtration_set_2.progress_from filtration_set_1.progress_to = filtration_set_2.progress_to filtration_set_1.progress_order = filtration_set_2.progress_order filtration_set_1.reputation_from = filtration_set_2.reputation_from filtration_set_1.reputation_to = filtration_set_2.reputation_to filtration_set_1.reputation_order = filtration_set_2.reputation_order filtration_set_1.course_list = filtration_set_2.course_list filtration_set_1.author = filtration_set_2.author filtration_set_1.comment_status = filtration_set_2.comment_status print('Copy stepic filtration_set #{} <-- #{}'.format( filtration_set_1.serial_id, filtration_set_2.serial_id)) return filtration_set_1 # импорт фильтра для Stepic def import_filtration_set(self, filtration_set_id): old_filtration_set = StepicFiltrationSet.objects( serial_id=filtration_set_id).first() self.copy_filtration_set(self, old_filtration_set).save() print('Import stepic filtration_set #{}'.format( old_filtration_set.serial_id)) return self # экспорт фильтра для Stepic def export_filtration_set(self, title): new_filtration_set = StepicFiltrationSet(title=title).save() self.copy_filtration_set(new_filtration_set, self).save() print('Export stepic filtration_set #{}'.format( new_filtration_set.serial_id)) return self # url параметры def get_url(self): url = '?{}&{}&{}&{}&{}&{}&{}'.format( self.get_date_args_url(), self.get_replies_args_url(), self.get_progress_args_url(), self.get_reputation_args_url(), self.get_courses_args_url(), self.get_author_args_url(), self.get_comment_status_args_url()) return url # url параметры поля "Репутация" def get_reputation_args_url(self): reputation_args_url = 'reputation[from]={}&reputation[to]={}&reputation[order]={}'.format( self.reputation_from, self.reputation_to, self.reputation_order) return reputation_args_url # url параметры поля "Курсы" def get_courses_args_url(self): return '&'.join('course_ids[]={}'.format(course.stepic_id) for course in self.course_list) # url параметры поля "Автор" def get_author_args_url(self): return 'author_id={}'.format( self.author.serial_id if self.author else 0) # url параметры поля "Статус" def get_comment_status_args_url(self): return 'comment_status={}'.format(self.comment_status) # параметры сортировки по полям: "Дата", "Ответы", "Прогресс", "Репутация" def get_sort_args_list(self): sort_args_list = [ '{}{}'.format(self.date_order, 'time_created'), '{}{}'.format(self.date_order, 'create_date'), '{}{}'.format(self.replies_order, 'num_replies'), '{}{}'.format(self.progress_order, 'progress'), '{}{}'.format(self.reputation_order, 'user_reputation') ] return sort_args_list
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
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 StepicTeacher(BaseTeacher): stepic_id = db.IntField() token = db.StringField(default='') full_name = db.StringField(default='') avatar_url = db.StringField(default='') course_list = db.ListField(db.ReferenceField('StepicCourse'), default=[]) filtration_set = db.ReferenceField('StepicFiltrationSet') def get_info(self): return self.to_json() def update_teacher(self, teacher_info): self.full_name = teacher_info.get('full_name') self.avatar_url = teacher_info.get('avatar') filtration_set_title = '{} (по умолчанию)'.format( teacher_info.get('full_name')) self.filtration_set = StepicFiltrationSet.objects( title=filtration_set_title).modify( title=filtration_set_title, date_from=datetime.fromisoformat( (date.today() - timedelta(30)).isoformat()).timestamp(), date_to=datetime.fromisoformat( (date.today() + timedelta(1)).isoformat()).timestamp(), upsert=True, new=True) print('Update stepic teacher #{}: {}'.format(self.serial_id, self.full_name)) return self def filter_and_sort_comments(self): # filter filtration_set = self.filtration_set # 5. Курсы comment_list = StepicComment.objects( course__in=filtration_set.course_list ) if filtration_set.course_list else StepicComment.objects() # 1. Дата comment_list = comment_list.filter( Q(time__gte=filtration_set.date_from) & Q(time__lte=filtration_set.date_to)) # 2. Ответы comment_list = comment_list.filter( Q(reply_count__gte=filtration_set.replies_from) & Q(reply_count__lte=filtration_set.replies_to)) # 4. Репутация comment_list = comment_list.filter( Q(user_reputation__gte=filtration_set.reputation_from) & Q(user_reputation__lte=filtration_set.reputation_to)) # 6. Автор comment_list = comment_list.filter( user=filtration_set.author ) if filtration_set.author else comment_list # 7. Статус comment_list = comment_list.filter( status=filtration_set.comment_status ) if filtration_set.comment_status != 'all' else comment_list # 3. Прогресс for comment in comment_list: comment.update_comment_progress().save() comment_list = comment_list.filter( Q(progress__gte=filtration_set.progress_from) & Q(progress__lte=filtration_set.progress_to)) # sort comment_list = comment_list.order_by( *filtration_set.get_sort_args_list()) return comment_list def filter_and_sort_reviews(self): # filter filtration_set = self.filtration_set # 4. Курсы review_list = StepicReview.objects( course__in=filtration_set.course_list ) if filtration_set.course_list else StepicReview.objects() # 1. Дата review_list = review_list.filter( Q(create_date__gte=filtration_set.date_from) & Q(create_date__lte=filtration_set.date_to)) # 3. Репутация review_list = review_list.filter( Q(user_reputation__gte=filtration_set.reputation_from) & Q(user_reputation__lte=filtration_set.reputation_to)) # 2. Прогресс for review in review_list: review.update_review_progress().save() review_list = review_list.filter( Q(progress__gte=filtration_set.progress_from) & Q(progress__lte=filtration_set.progress_to)) # sort review_list = review_list.order_by( *filtration_set.get_sort_args_list()) return review_list