|
30 | 30 | # config_loader = ConfigLoader() |
31 | 31 | # config_loader = None |
32 | 32 |
|
33 | | -_FORUM_OPTIONS = {'forum_type', 'info', 'name', 'url', 'banner', 'nb_subforums', 'nb_orphan_subforums'} |
| 33 | +_FORUM_OPTIONS = {'banner', 'forum_type', 'info', 'name', 'url', 'nb_subforums', 'nb_orphan_subforums', 'svg_icon'} |
34 | 34 | _SUBFORUM_OPTIONS = {'info', 'url', 'nb_subforums', 'nb_threads'} |
35 | 35 | _THREAD_OPTIONS = {'name', 'info', 'url', 'flags', 'nb_posts'} |
36 | 36 | _POST_OPTIONS = {'content', 'images', 'language', 'link', 'reactions', 'state', 'timestamp', 'translation', 'user-account'} |
@@ -365,6 +365,159 @@ def _subforum_threads_meta(subforum): |
365 | 365 | ) |
366 | 366 |
|
367 | 367 |
|
| 368 | +def _get_user_account_posts_sorted(user_account): |
| 369 | + posts = [] |
| 370 | + for pid in user_account.get_posts(): |
| 371 | + _, post_id = pid.split(':', 1) |
| 372 | + post = Posts.Post(post_id) |
| 373 | + timestamp = post.get_timestamp() |
| 374 | + if timestamp and post.exists(): |
| 375 | + posts.append((post, float(timestamp))) |
| 376 | + return sorted(posts, key=lambda post_item: post_item[1], reverse=True) |
| 377 | + |
| 378 | + |
| 379 | +def _paginate_items(items, page=1, nb=50): |
| 380 | + try: |
| 381 | + page = int(page) |
| 382 | + except (TypeError, ValueError): |
| 383 | + page = 1 |
| 384 | + try: |
| 385 | + nb = int(nb) |
| 386 | + except (TypeError, ValueError): |
| 387 | + nb = 50 |
| 388 | + if page < 1: |
| 389 | + page = 1 |
| 390 | + if nb < 1: |
| 391 | + nb = 50 |
| 392 | + total = len(items) |
| 393 | + nb_pages = int(total / nb) |
| 394 | + if total and total % nb: |
| 395 | + nb_pages += 1 |
| 396 | + if not nb_pages: |
| 397 | + nb_pages = 1 |
| 398 | + if page > nb_pages: |
| 399 | + page = nb_pages |
| 400 | + start = (page - 1) * nb |
| 401 | + end = min(start + nb, total) |
| 402 | + return items[start:end], {'nb': nb, 'page': page, 'nb_pages': nb_pages, 'total': total, 'nb_first': start + 1 if total else 0, 'nb_last': end} |
| 403 | + |
| 404 | + |
| 405 | +def _posts_to_date_dict(post_items, translation_target=None): |
| 406 | + posts_by_date = {} |
| 407 | + for post, timestamp in post_items: |
| 408 | + meta = post.get_meta(_POST_OPTIONS, translation_target=translation_target, flask_context=True) |
| 409 | + date_day = Date.get_utc_date_from_timestamp(timestamp, separator='/') |
| 410 | + posts_by_date.setdefault(date_day, []).append(meta) |
| 411 | + return posts_by_date |
| 412 | + |
| 413 | + |
| 414 | +def get_user_account_threads_meta(user_account): |
| 415 | + threads = [] |
| 416 | + for thread_str in user_account.get_forum_threads(): |
| 417 | + thread_subtype, thread_id = thread_str.split(':', 1) |
| 418 | + thread = ForumThreads.ForumThread(thread_id, thread_subtype) |
| 419 | + thread_meta = _thread_meta(thread) if thread.exists() else {'type': 'forum-thread', 'subtype': thread_subtype, 'id': thread_id} |
| 420 | + user_thread_posts = user_account.get_correlation_iter_obj(thread, 'post') |
| 421 | + thread_meta['nb_posts'] = len(user_thread_posts) |
| 422 | + first_post_timestamp = None |
| 423 | + last_post_timestamp = None |
| 424 | + for post_id in user_thread_posts: |
| 425 | + timestamp = Posts.Post(post_id).get_timestamp() |
| 426 | + if not timestamp: |
| 427 | + continue |
| 428 | + timestamp = float(timestamp) |
| 429 | + first_post_timestamp = timestamp if first_post_timestamp is None else min(first_post_timestamp, timestamp) |
| 430 | + last_post_timestamp = timestamp if last_post_timestamp is None else max(last_post_timestamp, timestamp) |
| 431 | + thread_meta['first_post_timestamp'] = first_post_timestamp or 0 |
| 432 | + thread_meta['last_post_timestamp'] = last_post_timestamp or 0 |
| 433 | + if first_post_timestamp: |
| 434 | + thread_meta['first_post_date'] = Date.get_utc_datetime_from_timestamp(first_post_timestamp) |
| 435 | + else: |
| 436 | + thread_meta['first_post_date'] = None |
| 437 | + if last_post_timestamp: |
| 438 | + thread_meta['last_post_date'] = Date.get_utc_datetime_from_timestamp(last_post_timestamp) |
| 439 | + else: |
| 440 | + thread_meta['last_post_date'] = None |
| 441 | + threads.append(thread_meta) |
| 442 | + return sorted(threads, key=lambda thread: thread['last_post_timestamp'], reverse=True) |
| 443 | + |
| 444 | + |
| 445 | +def get_user_account_nb_all_week_posts(user_account): |
| 446 | + week = {day: {hour: 0 for hour in range(24)} for day in ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']} |
| 447 | + for post_gid in user_account.get_posts(): |
| 448 | + _, post_id = post_gid.split(':', 1) |
| 449 | + timestamp = Posts.Post(post_id).get_timestamp() |
| 450 | + if not timestamp: |
| 451 | + continue |
| 452 | + weekday, hour = Date.get_utc_weekday_hour_from_timestamp(timestamp) |
| 453 | + week[weekday][hour] += 1 |
| 454 | + stats = [] |
| 455 | + for nb_day, day in enumerate(week): |
| 456 | + for hour in week[day]: |
| 457 | + stats.append({'date': day, 'day': nb_day, 'hour': hour, 'count': week[day][hour]}) |
| 458 | + return stats |
| 459 | + |
| 460 | + |
| 461 | +def get_user_account_nb_year_posts(user_account, year): |
| 462 | + nb_year = {} |
| 463 | + nb_max = 0 |
| 464 | + start = Date.convert_str_date_to_epoch(f'{year}0101') |
| 465 | + end = Date.convert_str_date_to_epoch_end(f'{year}1231') |
| 466 | + for post_gid in user_account.get_posts(): |
| 467 | + _, post_id = post_gid.split(':', 1) |
| 468 | + timestamp = Posts.Post(post_id).get_timestamp() |
| 469 | + if not timestamp: |
| 470 | + continue |
| 471 | + timestamp = int(float(timestamp)) |
| 472 | + if start <= timestamp <= end: |
| 473 | + date = Date.get_utc_date_from_timestamp(timestamp, separator='-') |
| 474 | + nb_year[date] = nb_year.get(date, 0) + 1 |
| 475 | + nb_max = max(nb_max, nb_year[date]) |
| 476 | + return nb_max, nb_year |
| 477 | + |
| 478 | + |
| 479 | +def api_get_user_account(user_id, forum_id, translation_target=None): |
| 480 | + user_account = UsersAccount.UserAccount(user_id, forum_id) |
| 481 | + if not user_account.exists(): |
| 482 | + return {"status": "error", "reason": "Unknown user-account"}, 404 |
| 483 | + meta = user_account.get_meta({'forums', 'icon', 'info', 'translation', 'username', 'usernames', 'username_meta', 'years', 'nb_posts'}, translation_target=translation_target) |
| 484 | + forum = Forums.Forum(forum_id) |
| 485 | + meta['forum'] = forum.get_meta(_FORUM_OPTIONS, flask_context=True) if forum.exists() else None |
| 486 | + meta['threads'] = get_user_account_threads_meta(user_account) |
| 487 | + return meta, 200 |
| 488 | + |
| 489 | + |
| 490 | +def api_get_user_account_posts(user_id, forum_id, page=1, nb=50, translation_target=None): |
| 491 | + user_account = UsersAccount.UserAccount(user_id, forum_id) |
| 492 | + if not user_account.exists(): |
| 493 | + return {"status": "error", "reason": "Unknown user-account"}, 404 |
| 494 | + post_items, pagination = _paginate_items(_get_user_account_posts_sorted(user_account), page=page, nb=nb) |
| 495 | + meta = user_account.get_meta({'icon', 'info', 'translation', 'username', 'usernames', 'username_meta'}, translation_target=translation_target) |
| 496 | + forum = Forums.Forum(forum_id) |
| 497 | + meta['forum'] = forum.get_meta(_FORUM_OPTIONS, flask_context=True) if forum.exists() else None |
| 498 | + return {'user-account': meta, 'posts': _posts_to_date_dict(post_items, translation_target=translation_target), 'pagination': pagination}, 200 |
| 499 | + |
| 500 | + |
| 501 | +def api_get_user_account_nb_all_week_posts(user_id, forum_id): |
| 502 | + user_account = UsersAccount.UserAccount(user_id, forum_id) |
| 503 | + if not user_account.exists(): |
| 504 | + return {"status": "error", "reason": "Unknown user-account"}, 404 |
| 505 | + return get_user_account_nb_all_week_posts(user_account), 200 |
| 506 | + |
| 507 | + |
| 508 | +def api_get_user_account_nb_year_posts(user_id, forum_id, year): |
| 509 | + user_account = UsersAccount.UserAccount(user_id, forum_id) |
| 510 | + if not user_account.exists(): |
| 511 | + return {"status": "error", "reason": "Unknown user-account"}, 404 |
| 512 | + if not year or year == 'null': |
| 513 | + years = user_account.get_years() |
| 514 | + year = years[-1] if years else int(Date.get_current_year()) |
| 515 | + else: |
| 516 | + year = int(year) |
| 517 | + nb_max, nb = get_user_account_nb_year_posts(user_account, year) |
| 518 | + return {'max': nb_max, 'year': year, 'nb': [[date, nb[date]] for date in nb]}, 200 |
| 519 | + |
| 520 | + |
368 | 521 | def get_forums(): |
369 | 522 | """Return metadata for all imported Forum objects.""" |
370 | 523 | forums = [] |
|
0 commit comments