Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tabler.io upgrade, longest streak feature #95

Merged
merged 4 commits into from
Dec 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"@tabler/core": "^1.0.0-beta19",
"@tabler/core": "^1.0.0-beta20",
"apexcharts": "^3.36.3",
"htmx.org": "^1.9.2"
},
Expand Down
4 changes: 2 additions & 2 deletions spybot/templates/spybot/base/navbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ <h1 class="navbar-brand d-none-navbar-horizontal pe-0 pe-md-3">
{% tabler_icon 'sun' %}
</a>
</div>
{% if user != None %}
{% if logged_in_user != None %}
<div class="nav-item dropdown">
<a href="#" class="nav-link d-flex lh-1 text-reset p-0" data-bs-toggle="dropdown" aria-label="Open user menu">
<!-- <span class="avatar avatar-sm" style="background-image: url(./static/avatars/000m.jpg)"></span>-->
<div class="d-none d-xl-block ps-2">
<div class="mb-1 small text-secondary">Logged in as</div>
<div>{{user.name}}</div>
<div>{{logged_in_user.name}}</div>
</div>
</a>
<div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
Expand Down
2 changes: 1 addition & 1 deletion spybot/templates/spybot/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<div class="col-md-8">
<div class="card">
<div class="card-header row g-0">
<h3 class="card-title">Logged in as {{user.name}}</h3>
<h3 class="card-title">Logged in as {{logged_in_user.name}}</h3>
</div>
</div>
</div>
Expand Down
9 changes: 9 additions & 0 deletions spybot/templates/spybot/user.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ <h3 class="card-title ">{{ user.user_name }}</h3>
<span>{{ user.afk_time|floatformat:0 }}h</span>
</div>
</div>

<div class="datagrid-item">
<div class="datagrid-title">
Longest streak
</div>
<div class="datagrid-content">
<span>{{ streak.length }} days</span>
</div>
</div>
</div>
</div>
</div>
Expand Down
17 changes: 13 additions & 4 deletions spybot/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ def get_user(request):
return request.user if isinstance(request.user, MergedUser) else None


def get_context(request):
return {"logged_in_user": get_user(request)}


def home(request):
context = {}
context = get_context(request)

# logged in user
user = get_user(request)
Expand Down Expand Up @@ -182,6 +186,7 @@ def convert_to_jstime(dt: datetime.datetime):
first_user_object["data"] = new_first_user_series

return render(request, 'spybot/timeline.html', {
**get_context(request),
'activity_by_user': list(users.values()),
'min': convert_to_jstime(cutoff),
'max': convert_to_jstime(now_time),
Expand Down Expand Up @@ -209,7 +214,7 @@ def halloffame(request):
merged_user['num_silver_awards'] = len(awards_silver)
merged_user['num_bronze_awards'] = len(awards_bronze)

context = {'top_users': users}
context = {**get_context(request), 'top_users': users}
return render(request, 'spybot/halloffame.html', context)


Expand All @@ -220,19 +225,23 @@ def user(request, user_id: int):
afk_time = int(u.get('afk_time'))
online_time = int(u.get('online_time'))

streak = visualization.user_longest_streak(user_id)[0]

game_name = ""
game_id = 0

if u.get('online') == 1:
game_id, game_name = get_steam_game(MergedUser.objects.get(id=user_id))

return render(request, 'spybot/user.html', {
**get_context(request),
'user': u,
'total_time': afk_time + online_time,
'data': [afk_time, online_time],
'names': str(u.get('names')).split(","),
'game_id': game_id,
'game_name': game_name
'game_name': game_name,
'streak': streak,
})


Expand Down Expand Up @@ -290,4 +299,4 @@ def recent_events_fragment(request):

def profile(request):
user = get_user(request)
return render(request, 'spybot/profile.html', {'user': user})
return render(request, 'spybot/profile.html', {**get_context(request), 'user': user})
77 changes: 77 additions & 0 deletions spybot/visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,80 @@ def user(user_id: int):
awards;""", [user_id, user_id])

return dictfetchall(cursor)


def user_longest_streak(merged_user_id: int):
with connection.cursor() as cursor:
cursor.execute("""
WITH dates AS (
SELECT DISTINCT
spybot_mergeduser.name,
CAST(TSUserActivity.startTime AS DATE) AS day
FROM TSUserActivity
INNER JOIN TSUser ON tsUserID = TSUser.id
INNER JOIN spybot_mergeduser ON TSUser.merged_user_id = spybot_mergeduser.id
WHERE merged_user_id = %s
),
cte AS (
SELECT
day,
IFNULL(DATE(day) > DATE(LAG(day, 1) OVER (ORDER BY day)) + INTERVAL 1 DAY, 1) AS startsStreak
FROM dates
),
result AS (
SELECT
dates.day AS start_day,
SUM(startsStreak) AS streakGroup,
ROW_NUMBER() OVER (PARTITION BY SUM(startsStreak) ORDER BY dates.day) AS runningStreakLength,
COUNT(*) OVER (PARTITION BY SUM(startsStreak)) AS totalStreakLength
FROM
dates
JOIN cte ON dates.day >= cte.day AND cte.startsStreak = 1
GROUP BY dates.day
ORDER BY dates.day
)
SELECT
start_day,
DATE_ADD(start_day, INTERVAL (totalStreakLength - 1) DAY) AS end_day,
totalStreakLength AS length
FROM result
WHERE runningStreakLength = 1
ORDER BY totalStreakLength DESC, start_day DESC
LIMIT 1;
""", [merged_user_id])
return dictfetchall(cursor)


#
# WITH dates AS (
# SELECT DISTINCT
# CAST(TSUserActivity.startTime AS DATE) AS day
# FROM TSUserActivity
# ORDER BY day DESC
# ),
# cte AS (
# SELECT
# day,
# IFNULL(DATE(day) > DATE(LAG(day, 1) OVER (ORDER BY day)) + INTERVAL 1 DAY, 1) AS startsStreak
# FROM dates
# ),
# result AS (
# SELECT
# dates.day AS start_day,
# SUM(startsStreak) AS streakGroup,
# ROW_NUMBER() OVER (PARTITION BY SUM(startsStreak) ORDER BY dates.day) AS runningStreakLength,
# COUNT(*) OVER (PARTITION BY SUM(startsStreak)) AS totalStreakLength
# FROM
# dates
# JOIN cte ON dates.day >= cte.day AND cte.startsStreak = 1
# GROUP BY dates.day
# ORDER BY dates.day
# )
# SELECT
# start_day,
# DATE_ADD(start_day, INTERVAL (totalStreakLength - 1) DAY) AS end_day,
# totalStreakLength AS streak_length
# FROM result
# WHERE runningStreakLength = 1
# ORDER BY totalStreakLength DESC, start_day DESC
# LIMIT 1;
Loading