99 lines
4.4 KiB
Python
99 lines
4.4 KiB
Python
"""Stable scoring weights and derived lifetime rank/badge rules."""
|
|
|
|
POINTS = {
|
|
"attendance": 30,
|
|
"post": 20,
|
|
"comment": 5,
|
|
"like": 1,
|
|
"save": 1,
|
|
}
|
|
|
|
LEVELS = (
|
|
{"id": "companion", "label": "همراه", "minimum_points": 0},
|
|
{"id": "contributor", "label": "مشارکتگر", "minimum_points": 30},
|
|
{"id": "ally", "label": "همیار", "minimum_points": 150},
|
|
{"id": "influencer", "label": "اثرگذار", "minimum_points": 750},
|
|
{"id": "pioneer", "label": "پیشرو", "minimum_points": 1500},
|
|
)
|
|
|
|
ACTIVITY_BADGES = {
|
|
"attendance": (
|
|
{"threshold": 1, "label": "حضور اول", "description": "حضور تأییدشده در یک رویداد"},
|
|
{"threshold": 5, "label": "همراه رویدادها", "description": "حضور تأییدشده در پنج رویداد"},
|
|
{"threshold": 10, "label": "همیار رویدادها", "description": "حضور تأییدشده در ده رویداد"},
|
|
{"threshold": 25, "label": "چهره آشنای رویدادها", "description": "حضور تأییدشده در بیستوپنج رویداد"},
|
|
),
|
|
"posts": (
|
|
{"threshold": 1, "label": "نویسنده انجمن", "description": "انتشار یا همنویسندگی یک نوشته"},
|
|
{"threshold": 5, "label": "نویسنده فعال", "description": "انتشار یا همنویسندگی پنج نوشته"},
|
|
{"threshold": 10, "label": "نویسنده برجسته", "description": "انتشار یا همنویسندگی ده نوشته"},
|
|
),
|
|
"comments": (
|
|
{"threshold": 5, "label": "اهل گفتوگو", "description": "پنج دیدگاه یا پاسخ تأییدشده"},
|
|
{"threshold": 20, "label": "همراه گفتوگو", "description": "بیست دیدگاه یا پاسخ تأییدشده"},
|
|
{"threshold": 50, "label": "صدای اثرگذار", "description": "پنجاه دیدگاه یا پاسخ تأییدشده"},
|
|
),
|
|
"likes": (
|
|
{"threshold": 10, "label": "دستگرم", "description": "ده پسند دادهشده یا دریافتشده"},
|
|
{"threshold": 50, "label": "محبوب انجمن", "description": "پنجاه پسند دادهشده یا دریافتشده"},
|
|
{"threshold": 100, "label": "الهامبخش", "description": "صد پسند دادهشده یا دریافتشده"},
|
|
),
|
|
}
|
|
|
|
|
|
def level_for_points(points: int) -> dict:
|
|
points = max(0, int(points))
|
|
return next(level for level in reversed(LEVELS) if points >= level["minimum_points"])
|
|
|
|
|
|
def level_progress(points: int) -> dict:
|
|
points = max(0, int(points))
|
|
current_index = max(
|
|
index for index, level in enumerate(LEVELS) if points >= level["minimum_points"]
|
|
)
|
|
current = LEVELS[current_index]
|
|
next_level = LEVELS[current_index + 1] if current_index + 1 < len(LEVELS) else None
|
|
|
|
if next_level is None:
|
|
return {
|
|
"current_level": current,
|
|
"next_level": None,
|
|
"points_to_next": 0,
|
|
"progress_percent": 100,
|
|
}
|
|
|
|
span = next_level["minimum_points"] - current["minimum_points"]
|
|
progress_points = points - current["minimum_points"]
|
|
return {
|
|
"current_level": current,
|
|
"next_level": next_level,
|
|
"points_to_next": next_level["minimum_points"] - points,
|
|
"progress_percent": min(100, int(progress_points * 100 / span)),
|
|
}
|
|
|
|
|
|
def earned_badges(total_points: int, activity_counts: dict[str, int]) -> list[dict]:
|
|
badges = []
|
|
for level in LEVELS:
|
|
if total_points >= level["minimum_points"]:
|
|
badges.append({
|
|
"id": f"level-{level['id']}",
|
|
"category": "level",
|
|
"label": level["label"],
|
|
"description": f"سطح کلی با {level['minimum_points']} امتیاز",
|
|
"threshold": level["minimum_points"],
|
|
})
|
|
|
|
for category, levels in ACTIVITY_BADGES.items():
|
|
count = max(0, int(activity_counts.get(category, 0)))
|
|
badge_prefix = "post" if category == "posts" else category
|
|
for badge_level in levels:
|
|
threshold = badge_level["threshold"]
|
|
if count >= threshold:
|
|
badges.append({
|
|
"id": f"{badge_prefix}-{threshold}",
|
|
"category": category,
|
|
**badge_level,
|
|
})
|
|
return badges
|