Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
Activity tracker
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Saswat
Activity tracker
Commits
4970a206
Commit
4970a206
authored
Nov 20, 2022
by
Saswat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
initial commit for gui
parent
b6abe573
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
185 additions
and
43 deletions
+185
-43
__pycache__/dbhandler.cpython-310.pyc
__pycache__/dbhandler.cpython-310.pyc
+0
-0
__pycache__/eventhandler.cpython-310.pyc
__pycache__/eventhandler.cpython-310.pyc
+0
-0
__pycache__/plotter.cpython-310.pyc
__pycache__/plotter.cpython-310.pyc
+0
-0
config.json
config.json
+1
-1
data/activity_data.db
data/activity_data.db
+0
-0
dbhandler.py
dbhandler.py
+1
-1
eventhandler.py
eventhandler.py
+1
-1
gui.py
gui.py
+92
-24
plotter.py
plotter.py
+35
-16
test.py
test.py
+55
-0
weekly.png
weekly.png
+0
-0
No files found.
__pycache__/dbhandler.cpython-310.pyc
View file @
4970a206
No preview for this file type
__pycache__/eventhandler.cpython-310.pyc
View file @
4970a206
No preview for this file type
__pycache__/plotter.cpython-310.pyc
View file @
4970a206
No preview for this file type
config.json
View file @
4970a206
{
"INTERVAL"
:
6
0
,
"INTERVAL"
:
30
0
,
"DATABASE_FILE"
:
"data/activity_data.db"
,
"LOG_FILE"
:
"log/deamon.log"
}
\ No newline at end of file
data/activity_data.db
View file @
4970a206
No preview for this file type
dbhandler.py
View file @
4970a206
...
...
@@ -35,7 +35,7 @@ class DBHandler:
def
write_interval
(
self
,
interval_start
,
app_name
,
duration
):
query
=
f
"INSERT INTO activity VALUES ({interval_start}, '{app_name}', {duration})"
print
(
query
)
#
print(query)
self
.
conn
.
execute
(
query
)
self
.
conn
.
commit
()
...
...
eventhandler.py
View file @
4970a206
...
...
@@ -66,5 +66,5 @@ class EventHandler:
def
handle_termination
(
self
):
self
.
handle_change
(
""
)
self
.
__interval
.
dump_interval
()
self
.
__interval
.
db
.
print_db
()
#
self.__interval.db.print_db()
return
\ No newline at end of file
gui.py
View file @
4970a206
...
...
@@ -2,42 +2,110 @@ from tkinter import *
import
matplotlib.pyplot
as
plt
from
matplotlib.backends.backend_tkagg
import
FigureCanvasTkAgg
from
plotter
import
ActivityPlotter
from
datetime
import
datetime
from
datetime
import
datetime
,
timedelta
from
tkinter.ttk
import
*
from
tkcalendar
import
DateEntry
today
=
datetime
.
now
()
plotter
=
ActivityPlotter
()
figure1
,
figure2
,
figure3
=
plotter
.
get_figs
(
today
)
class
ActivityTracker
:
def
__init__
(
self
)
->
None
:
self
.
root
=
Tk
()
self
.
plotter
=
ActivityPlotter
()
self
.
root
.
title
(
'Activity Tracker'
)
width
=
self
.
root
.
winfo_screenwidth
()
height
=
self
.
root
.
winfo_screenheight
()
self
.
root
.
geometry
(
"
%
dx
%
d"
%
(
width
,
height
))
self
.
screen_time_text
=
"1 hr 30 min"
root
=
Tk
()
self
.
today
=
datetime
.
now
()
self
.
curr_date
=
datetime
.
now
()
self
.
date_text
=
self
.
curr_date
.
strftime
(
'
%
d,
%
b
%
Y'
)
self
.
__fetch_curr_date_figs
()
self
.
__initialise_struct
()
return
width
=
root
.
winfo_screenwidth
()
height
=
root
.
winfo_screenheight
(
)
root
.
geometry
(
"
%
dx
%
d"
%
(
width
,
height
)
)
def
__initialise_struct
(
self
):
self
.
activity_label
=
Label
(
self
.
root
,
text
=
"Activity tracking for: "
,
font
=
(
'Arial'
,
20
)
)
self
.
activity_label
.
grid
(
row
=
0
,
column
=
0
,
columnspan
=
1
,
sticky
=
'nesw'
,
padx
=
20
,
pady
=
20
)
self
.
date_label
=
Label
(
self
.
root
,
text
=
self
.
date_text
,
font
=
(
'Arial'
,
30
))
self
.
date_label
.
grid
(
row
=
0
,
column
=
1
,
columnspan
=
2
,
sticky
=
'nesw'
,
padx
=
20
,
pady
=
20
)
l1
=
Label
(
root
,
text
=
"Activity tracker for today"
)
l2
=
Label
(
root
,
text
=
"total time spent"
)
# grid method to arrange labels in respective
# rows and columns as specified
l1
.
grid
(
row
=
0
,
column
=
0
,
sticky
=
'W'
,
pady
=
2
)
l2
.
grid
(
row
=
0
,
column
=
1
,
sticky
=
'W'
,
pady
=
2
)
self
.
active_time_label
=
Label
(
self
.
root
,
text
=
"Total screen time:"
,
font
=
(
'Arial'
,
20
))
self
.
active_time_label
.
grid
(
row
=
0
,
column
=
3
,
columnspan
=
1
,
sticky
=
'E'
,
padx
=
20
,
pady
=
20
)
self
.
screen_time
=
Label
(
self
.
root
,
text
=
self
.
screen_time_text
,
font
=
(
'Ariel'
,
30
))
self
.
screen_time
.
grid
(
row
=
0
,
column
=
4
,
sticky
=
'W'
,
columnspan
=
1
,
rowspan
=
1
,
padx
=
20
,
pady
=
20
)
cal
=
DateEntry
(
root
,
year
=
today
.
year
,
month
=
today
.
month
,
day
=
today
.
day
)
cal
.
grid
(
row
=
1
,
column
=
0
,
columnspan
=
2
,
sticky
=
'W
'
)
self
.
prev_day_button
=
Button
(
self
.
root
,
text
=
"<"
,
command
=
self
.
get_prev_date
)
self
.
prev_day_button
.
grid
(
row
=
1
,
column
=
0
,
sticky
=
'E
'
)
self
.
cal
=
DateEntry
(
self
.
root
,
year
=
self
.
curr_date
.
year
,
month
=
self
.
curr_date
.
month
,
day
=
self
.
curr_date
.
day
,
font
=
"Arial 15"
)
self
.
cal
.
grid
(
row
=
1
,
column
=
1
,
sticky
=
'e'
,
padx
=
20
,
pady
=
20
,
)
weekly
=
FigureCanvasTkAgg
(
figure1
,
root
)
weekly
.
get_tk_widget
()
.
grid
(
row
=
2
,
column
=
0
,
columnspan
=
2
,
sticky
=
'N
'
)
self
.
reload_button
=
Button
(
self
.
root
,
text
=
"Reload"
,
command
=
self
.
reload_date
)
self
.
reload_button
.
grid
(
row
=
1
,
column
=
2
,
sticky
=
'W
'
)
daily
=
FigureCanvasTkAgg
(
figure2
,
root
)
daily
.
get_tk_widget
()
.
grid
(
row
=
3
,
column
=
0
,
columnspan
=
2
,
sticky
=
'N'
)
self
.
next_day_button
=
Button
(
self
.
root
,
text
=
">"
,
command
=
self
.
get_next_date
)
self
.
next_day_button
.
grid
(
row
=
1
,
column
=
3
,
sticky
=
'W'
)
self
.
next_day_button
.
config
(
state
=
DISABLED
)
perapp
=
FigureCanvasTkAgg
(
figure3
,
root
)
perapp
.
get_tk_widget
()
.
grid
(
row
=
1
,
column
=
2
,
rowspan
=
3
,
sticky
=
'E'
)
copyright_label
=
Label
(
self
.
root
,
text
=
"Activity tracker by Saswat Meher and Suraj Munjani "
,
font
=
(
'Ariel'
,
15
)
)
copyright_label
.
grid
(
row
=
8
,
column
=
0
,
columnspan
=
5
,
sticky
=
'W'
,
padx
=
40
,
pady
=
20
)
root
.
mainloop
()
\ No newline at end of file
self
.
__refresh_graphs
()
def
__refresh_graphs
(
self
):
self
.
figure1
.
savefig
(
'weekly.png'
)
self
.
weekly
=
FigureCanvasTkAgg
(
self
.
figure1
,
self
.
root
)
self
.
weekly
.
get_tk_widget
()
.
grid
(
row
=
2
,
column
=
0
,
columnspan
=
4
,
rowspan
=
3
,
sticky
=
'N'
,
padx
=
20
,
pady
=
20
)
self
.
daily
=
FigureCanvasTkAgg
(
self
.
figure2
,
self
.
root
)
self
.
daily
.
get_tk_widget
()
.
grid
(
row
=
5
,
column
=
0
,
columnspan
=
4
,
rowspan
=
3
,
sticky
=
'N'
,
padx
=
20
,
pady
=
20
)
perapp
=
FigureCanvasTkAgg
(
self
.
figure3
,
self
.
root
)
perapp
.
get_tk_widget
()
.
grid
(
row
=
2
,
column
=
4
,
rowspan
=
6
,
columnspan
=
2
,
sticky
=
'W'
,
padx
=
20
,
pady
=
20
)
def
__refresh_labels
(
self
):
self
.
date_text
=
self
.
curr_date
.
strftime
(
'
%
d,
%
b
%
Y'
)
self
.
date_label
.
config
(
text
=
self
.
date_text
)
self
.
screen_time
.
config
(
text
=
self
.
screen_time_text
)
self
.
cal
.
set_date
(
self
.
curr_date
)
return
def
__refresh_app
(
self
):
if
self
.
curr_date
>=
self
.
today
:
self
.
next_day_button
.
config
(
state
=
DISABLED
)
else
:
self
.
next_day_button
.
config
(
state
=
NORMAL
)
self
.
__fetch_curr_date_figs
()
self
.
__refresh_labels
()
self
.
__refresh_graphs
()
return
def
__fetch_curr_date_figs
(
self
):
self
.
figure1
,
self
.
figure2
,
self
.
figure3
,
self
.
screen_time_text
=
self
.
plotter
.
get_figs
(
self
.
curr_date
)
return
def
get_prev_date
(
self
):
self
.
curr_date
=
self
.
curr_date
-
timedelta
(
days
=
1
)
self
.
__refresh_app
()
return
def
get_next_date
(
self
):
self
.
curr_date
=
self
.
curr_date
+
timedelta
(
days
=
1
)
self
.
__refresh_app
()
return
def
reload_date
(
self
):
new_date
=
self
.
cal
.
get_date
()
self
.
curr_date
=
datetime
.
combine
(
new_date
,
datetime
.
now
()
.
time
())
self
.
__refresh_app
()
return
if
__name__
==
'__main__'
:
tracker
=
ActivityTracker
()
tracker
.
root
.
mainloop
()
\ No newline at end of file
plotter.py
View file @
4970a206
...
...
@@ -11,6 +11,7 @@ class ActivityPlotter:
plt
.
rcParams
.
update
({
'font.size'
:
16
})
self
.
db
=
DBHandler
(
config
[
'DATABASE_FILE'
])
self
.
week_days
=
[
'Mon'
,
'Tue'
,
'Wed'
,
'Thu'
,
'Fri'
,
'Sat'
,
'Sun'
]
self
.
hours
=
[
'12am'
,
'3am'
,
'6am'
,
'9am'
,
'12pm'
,
'3pm'
,
'6pm'
,
'9pm'
,
'12am'
]
#self.curr_week = datetime.fromtimestamp(0)
def
__init_dataholders
(
self
):
...
...
@@ -38,7 +39,15 @@ class ActivityPlotter:
self
.
perapp
=
dict
(
sorted
(
self
.
perapp
.
items
(),
key
=
lambda
x
:
x
[
1
],
reverse
=
True
))
def
__quantise_time
(
self
,
time_list
):
def
__quantise_time
(
self
,
time_list
,
qtype
):
if
len
(
time_list
)
==
0
:
if
qtype
==
0
:
return
np
.
zeros
(
7
),
"mins"
elif
qtype
==
1
:
return
np
.
zeros
(
24
),
"mins"
else
:
return
np
.
zeros
(
0
),
"mins"
max
=
np
.
max
(
time_list
)
time_format
=
"mins"
if
max
>
2
*
60
*
60
:
...
...
@@ -49,43 +58,53 @@ class ActivityPlotter:
return
time_list
,
time_format
def
__get_week_plot
(
self
):
figure
=
plt
.
Figure
(
figsize
=
(
10
,
5
),
dpi
=
70
)
week_day
=
self
.
curr_date
.
date
()
.
weekday
()
figure
=
plt
.
Figure
(
figsize
=
(
15
,
5
),
dpi
=
70
)
ax
=
figure
.
add_subplot
(
111
)
q_perday
,
time_format
=
self
.
__quantise_time
(
self
.
perday
)
q_perday
,
time_format
=
self
.
__quantise_time
(
self
.
perday
.
copy
(),
0
)
ax
.
bar
(
self
.
week_days
,
q_perday
,
width
=
0.35
)
ax
.
patches
[
self
.
curr_date
.
date
()
.
weekday
()]
.
set_color
(
'r'
)
ax
.
patches
[
week_day
]
.
set_color
(
'r'
)
ax
.
get_xticklabels
()[
week_day
]
.
set_backgroundcolor
(
'r'
)
ax
.
set_xlabel
(
"Week Days"
)
ax
.
set_ylabel
(
f
"Total Screen Time in {time_format}"
)
ax
.
set_title
(
"Total daily screen time in a week"
)
ax
.
grid
()
figure
.
tight_layout
()
return
figure
curr_date_time
=
self
.
perday
[
week_day
]
print
(
self
.
perday
)
screen_time_text
=
str
(
int
(
curr_date_time
/
3600
))
+
" hr "
+
str
(
int
((
curr_date_time
%
3600
)
/
60
))
+
" min"
print
(
screen_time_text
)
return
figure
,
screen_time_text
def
__get_day_plot
(
self
):
figure
=
plt
.
Figure
(
figsize
=
(
1
0
,
5
),
dpi
=
70
)
figure
=
plt
.
Figure
(
figsize
=
(
1
5
,
5
),
dpi
=
70
)
ax
=
figure
.
add_subplot
(
111
)
q_perhour
,
time_format
=
self
.
__quantise_time
(
self
.
perhour
)
q_perhour
,
time_format
=
self
.
__quantise_time
(
self
.
perhour
.
copy
(),
1
)
ax
.
bar
(
np
.
arange
(
24
),
q_perhour
,
width
=
0.35
)
ax
.
set_xticks
(
np
.
arange
(
0
,
25
,
3
),
self
.
hours
)
ax
.
set_xlabel
(
"Hour of the day"
)
ax
.
set_ylabel
(
f
"Total Screen Time in {time_format}"
)
ax
.
set_title
(
"Total hourly screen time in a day"
)
ax
.
grid
()
figure
.
tight_layout
()
return
figure
def
__get_app_plot
(
self
):
figure
=
plt
.
Figure
(
figsize
=
(
6
,
10
),
dpi
=
70
)
figure
=
plt
.
Figure
(
figsize
=
(
10
,
10
),
dpi
=
70
)
ax
=
figure
.
add_subplot
(
111
)
q_perapp
,
time_format
=
self
.
__quantise_time
(
np
.
array
(
list
(
self
.
perapp
.
values
())[::
-
1
],
dtype
=
float
)
)
perapp_list
=
np
.
array
(
list
(
self
.
perapp
.
values
())[::
-
1
],
dtype
=
float
)
q_perapp
,
time_format
=
self
.
__quantise_time
(
perapp_list
.
copy
(),
2
)
ax
.
barh
(
list
(
self
.
perapp
.
keys
())[::
-
1
],
q_perapp
)
#for bar, app, values in zip(ax.patches, list(self.perapp.keys())[::-1], list(self.perapp.values())[::-1]):
# ax.text(bar.get_x()+bar.get_width()+ 3, bar.get_y()+bar.get_height()/2, values, color = 'black', va = 'center')
ax
.
set_xlabel
(
f
"Time spent in {time_format}"
)
ax
.
set_ylabel
(
"Applications"
)
ax
.
set_title
(
"Activity per Application"
)
ax
.
grid
()
figure
.
tight_layout
()
return
figure
...
...
@@ -93,11 +112,11 @@ class ActivityPlotter:
self
.
curr_date
=
timestamp
self
.
__load_weekly_data
()
week_fig
=
self
.
__get_week_plot
()
week_fig
,
screen_time_text
=
self
.
__get_week_plot
()
day_fig
=
self
.
__get_day_plot
()
app_fig
=
self
.
__get_app_plot
()
return
week_fig
,
day_fig
,
app_fig
return
week_fig
,
day_fig
,
app_fig
,
screen_time_text
"""
...
...
test.py
0 → 100644
View file @
4970a206
try
:
import
tkinter
as
tk
from
tkinter
import
ttk
except
ImportError
:
import
Tkinter
as
tk
import
ttk
from
tkcalendar
import
Calendar
,
DateEntry
def
example1
():
def
print_sel
():
print
(
cal
.
selection_get
())
top
=
tk
.
Toplevel
(
root
)
cal
=
Calendar
(
top
,
font
=
"Arial 14"
,
selectmode
=
'day'
,
locale
=
'en_US'
,
cursor
=
"hand1"
,
year
=
2018
,
month
=
2
,
day
=
5
)
cal
.
pack
(
fill
=
"both"
,
expand
=
True
)
ttk
.
Button
(
top
,
text
=
"ok"
,
command
=
print_sel
)
.
pack
()
def
example2
():
top
=
tk
.
Toplevel
(
root
)
cal
=
Calendar
(
top
,
selectmode
=
'none'
)
date
=
cal
.
datetime
.
today
()
+
cal
.
timedelta
(
days
=
2
)
cal
.
calevent_create
(
date
,
'Hello World'
,
'message'
)
cal
.
calevent_create
(
date
,
'Reminder 2'
,
'reminder'
)
cal
.
calevent_create
(
date
+
cal
.
timedelta
(
days
=-
2
),
'Reminder 1'
,
'reminder'
)
cal
.
calevent_create
(
date
+
cal
.
timedelta
(
days
=
3
),
'Message'
,
'message'
)
cal
.
tag_config
(
'reminder'
,
background
=
'red'
,
foreground
=
'yellow'
)
cal
.
pack
(
fill
=
"both"
,
expand
=
True
)
ttk
.
Label
(
top
,
text
=
"Hover over the events."
)
.
pack
()
def
example3
():
top
=
tk
.
Toplevel
(
root
)
ttk
.
Label
(
top
,
text
=
'Choose date'
)
.
pack
(
padx
=
10
,
pady
=
10
)
cal
=
DateEntry
(
top
,
width
=
12
,
background
=
'darkblue'
,
foreground
=
'white'
,
borderwidth
=
2
,
year
=
2010
)
cal
.
pack
(
padx
=
10
,
pady
=
10
)
root
=
tk
.
Tk
()
ttk
.
Button
(
root
,
text
=
'Calendar'
,
command
=
example1
)
.
pack
(
padx
=
10
,
pady
=
10
)
ttk
.
Button
(
root
,
text
=
'Calendar with events'
,
command
=
example2
)
.
pack
(
padx
=
10
,
pady
=
10
)
ttk
.
Button
(
root
,
text
=
'DateEntry'
,
command
=
example3
)
.
pack
(
padx
=
10
,
pady
=
10
)
root
.
mainloop
()
\ No newline at end of file
weekly.png
View replaced file @
b6abe573
View file @
4970a206
19.5 KB
|
W:
|
H:
19.8 KB
|
W:
|
H:
2-up
Swipe
Onion skin
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment