118 lines
4.8 KiB
Ruby
118 lines
4.8 KiB
Ruby
module BadgeRewarder
|
|
YEARS = { 1 => "one", 2 => "two", 3 => "three" }.freeze
|
|
REPOSITORIES = ["thepracticaldev/dev.to", "thepracticaldev/DEV-ios", "thepracticaldev/DEV-Android"].freeze
|
|
|
|
LONGEST_STREAK_WEEKS = 16
|
|
LONGEST_STREAK_MESSAGE = "16 weeks! You've achieved the longest #{ApplicationConfig['COMMUNITY_NAME']} writing " \
|
|
"streak possible. This makes you eligible for special quests in the future. Keep up the amazing contributions to" \
|
|
" our community!".freeze
|
|
|
|
MINIMUM_QUALITY = -25
|
|
|
|
def self.award_yearly_club_badges
|
|
(1..3).each do |i|
|
|
message = "Happy #{ApplicationConfig['COMMUNITY_NAME']} birthday! Can you believe it's been #{i} #{'year'.pluralize(i)} already?!"
|
|
badge = Badge.find_by!(slug: "#{YEARS[i]}-year-club")
|
|
User.where("created_at < ? AND created_at > ?", i.year.ago, i.year.ago - 2.days).find_each do |user|
|
|
achievement = BadgeAchievement.create(
|
|
user_id: user.id,
|
|
badge_id: badge.id,
|
|
rewarding_context_message_markdown: message,
|
|
)
|
|
user.save if achievement.valid?
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.award_beloved_comment_badges(comment_count = 24)
|
|
badge_id = Badge.find_by!(slug: "beloved-comment").id
|
|
Comment.where("public_reactions_count > ?", comment_count).find_each do |comment|
|
|
message = "You're famous! [This is the comment](#{URL.comment(comment)}) for which you are being recognized. 😄"
|
|
achievement = BadgeAchievement.create(
|
|
user_id: comment.user_id,
|
|
badge_id: badge_id,
|
|
rewarding_context_message_markdown: message,
|
|
)
|
|
comment.user.save if achievement.valid?
|
|
end
|
|
end
|
|
|
|
def self.award_top_seven_badges(usernames, message_markdown = "Congrats!!!")
|
|
award_badges(usernames, "top-7", message_markdown)
|
|
end
|
|
|
|
def self.award_fab_five_badges(usernames, message_markdown = "Congrats!!!")
|
|
award_badges(usernames, "fab-5", message_markdown)
|
|
end
|
|
|
|
def self.award_contributor_badges(usernames, message_markdown = "Thank you so much for your contributions!")
|
|
award_badges(usernames, "dev-contributor", message_markdown)
|
|
end
|
|
|
|
def self.award_tag_badges
|
|
Tag.where.not(badge_id: nil).find_each do |tag|
|
|
past_winner_user_ids = BadgeAchievement.where(badge_id: tag.badge_id).pluck(:user_id)
|
|
winning_article = Article.where("score > 100").
|
|
published.
|
|
where.not(user_id: past_winner_user_ids).
|
|
order(score: :desc).
|
|
where("published_at > ?", 7.5.days.ago). # More than seven days, to have some wiggle room.
|
|
cached_tagged_with(tag).first
|
|
if winning_article
|
|
award_badges(
|
|
[winning_article.user.username],
|
|
tag.badge.slug,
|
|
"Congratulations on posting the most beloved [##{tag.name}](#{URL.tag(tag)}) post from the past seven days! Your winning post was [#{winning_article.title}](#{URL.article(winning_article)}). (You can only win once per badge-eligible tag)",
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.award_contributor_badges_from_github(since = 1.day.ago, message_markdown = "Thank you so much for your contributions!")
|
|
badge = Badge.find_by!(slug: "dev-contributor")
|
|
|
|
REPOSITORIES.each do |repo|
|
|
commits = Github::Client.commits(repo, since: since.utc.iso8601)
|
|
|
|
authors_uids = commits.map { |commit| commit.author.id }
|
|
Identity.github.where(uid: authors_uids).find_each do |i|
|
|
BadgeAchievement.where(user_id: i.user_id, badge_id: badge.id).first_or_create(
|
|
rewarding_context_message_markdown: message_markdown,
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.award_streak_badge(num_weeks)
|
|
# No credit for super low quality
|
|
article_user_ids = Article.published.where("published_at > ? AND score > ?", 1.week.ago, MINIMUM_QUALITY).pluck(:user_id)
|
|
message = if num_weeks == LONGEST_STREAK_WEEKS
|
|
LONGEST_STREAK_MESSAGE
|
|
else
|
|
"Congrats on achieving this streak! Consistent writing is hard. The next streak badge you can get is the #{num_weeks * 2} Week Badge. 😉"
|
|
end
|
|
users = User.where(id: article_user_ids).where("articles_count >= ?", num_weeks)
|
|
usernames = []
|
|
users.find_each do |user|
|
|
count = 0
|
|
num_weeks.times do |i|
|
|
num = i + 1
|
|
count += 1 if user.articles.published.where("published_at > ? AND published_at < ?", num.weeks.ago, (num - 1).weeks.ago).any?
|
|
end
|
|
usernames << user.username if count >= num_weeks
|
|
end
|
|
award_badges(usernames, "#{num_weeks}-week-streak", message)
|
|
end
|
|
|
|
def self.award_badges(usernames, slug, message_markdown)
|
|
badge_id = Badge.find_by!(slug: slug).id
|
|
User.where(username: usernames).find_each do |user|
|
|
BadgeAchievement.create(
|
|
user_id: user.id,
|
|
badge_id: badge_id,
|
|
rewarding_context_message_markdown: message_markdown,
|
|
)
|
|
user.save
|
|
end
|
|
end
|
|
end
|