Skip to content

Commit c36d292

Browse files
committed
feat: add new method to extract browsers histories using browser-history external module (more browsers supported and all profiles are imported) + old method can still be used with the --legacy flag + fix boolean arguments in commandline (before they requires one positional argument)
Signed-off-by: Stephen L. <LRQ3000@gmail.com>
1 parent bc5ad87 commit c36d292

File tree

2 files changed

+36
-12
lines changed

2 files changed

+36
-12
lines changed

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
77

88
[project] # beware if using setuptools: setup.py still gets executed, and even if pyproject.toml fields take precedence, if there is any code error in setup.py, building will fail!
99
name = "webactogram" # renamed from online-actogram according to PEP 423 https://peps.python.org/pep-0423/#pick-meaningful-names
10-
version = "0.3.5" # see PEP 440 https://peps.python.org/pep-0440/#pre-releases and https://packaging.python.org/en/latest/guides/single-sourcing-package-version/
10+
version = "0.4.0" # see PEP 440 https://peps.python.org/pep-0440/#pre-releases and https://packaging.python.org/en/latest/guides/single-sourcing-package-version/
1111
description = "Actogram from browsers history, may help to screen sleep-wake patterns & disorders!"
1212
authors = [
1313
{name = "Barrett F. Davis", email = "barrettfdavis@gmail.com"},
@@ -49,6 +49,7 @@ dependencies = [
4949
"numpy>=1.21.0",
5050
"pandas>=1.3.4",
5151
"scipy>=1.6.1",
52+
"browser-history",
5253
]
5354

5455
[project.urls]

src/webactogram/webactogram.py

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
from collections.abc import Sequence
5555
# Path
5656
from pathlib import Path
57+
# Browser history
58+
from browser_history import get_history
5759

5860
# Scientific stack
5961
import numpy as np
@@ -77,17 +79,19 @@
7779
## Main class
7880
class Actography:
7981
def __init__(self, args):
80-
self.show = args.show
81-
self.png = args.png
82-
self.save_csv = args.save_csv
82+
self.show = args.show # show the plot
83+
self.png = args.png # save as png
84+
self.save_csv = args.csv # save as csv
8385

8486
self.freq = args.freq
8587
self.norm = args.normalize
8688
self.dblur = args.daily_blur
8789
self.hblur = args.hourly_blur
8890

89-
self.landscape = args.landscape
90-
self.printer_friendly = args.printer_friendly
91+
self.landscape = args.landscape # horizontal or vertical printing mode
92+
self.printer_friendly = args.printer_friendly # printer friendly mode (black and white)
93+
94+
self.legacy = args.legacy # use legacy (internal) browsers histories import method, otherwise if false we will use browser-history external module (more browsers supported and all profiles are imported)
9195

9296
self.zz = None # wakefulness
9397
self.dd = None # day range
@@ -128,12 +132,30 @@ def __call__(self):
128132
def __main__(self):
129133
os.makedirs('actograms/', exist_ok=True)
130134

131-
self.ImportData(self) # import the data
135+
# import the data
136+
if self.legacy:
137+
# Old internal method to import browsers histories
138+
self.ImportData(self)
139+
else:
140+
# New method to import browsers histories using an external module
141+
self.import_data_ext()
132142
self.ProcessData(self) # process the data
133143

134144
plot = self.PlotData(self) # plot the data
135145
self.ExportData(self, plot) # export the data (to png or csv)
136146

147+
def import_data_ext(self):
148+
""" Import histories data using browser-history package """
149+
outputs = get_history()
150+
# his is a list of (datetime.datetime, url) tuples
151+
histories = outputs.histories
152+
# convert to a dataframe with the same structure as before, to stay compatible
153+
df = pd.DataFrame((x[0] for x in histories), columns=['visit_time'])
154+
df['visit_time'] = pd.to_datetime(df['visit_time'].dt.tz_localize(None), errors='coerce').dropna() # drop NaT values (and keep it as a DataFrame, because it will always return a Series since we are manipulating a single column)
155+
# TODO: browser-history.get_history() returns timezone-awake datetime objects, but the rest of the code compares against timezone-naive datetime objects, so for now we strip away the timezone-aware info using df['visit_time'].dt.tz_localize(None)
156+
self.df = df
157+
return df
158+
137159
class ImportData:
138160
def __init__(self, act):
139161
super().__init__()
@@ -783,11 +805,12 @@ def main(argv: Sequence[str] | None = None) -> int:
783805
parser.add_argument('--daily_blur', type=int, action='store', default=False, help='Daily blur of the actogram. Default is 0 (no blur).')
784806
parser.add_argument('--normalize', type=int, action='store', default=True, help='Normalize the actogram. Default is True (normalize).')
785807

786-
parser.add_argument('--png', type=bool, action='store', default=True, help='Save the actogram as a png. Default is True (save).')
787-
parser.add_argument('--show', type=bool, action='store', default=True, help='Show the actogram in a window. Default is True (show).')
788-
parser.add_argument('--printer_friendly', type=bool, action='store', default=False, help='Printer friendly actogram. Default is False (no).')
789-
parser.add_argument('--landscape', type=bool, action='store', default=True, help='Landscape actogram. Default is True (yes).')
790-
parser.add_argument('--save_csv', type=bool, action='store', default=True, help='Save the actogram as a csv. Default is True (save).')
808+
parser.add_argument('--png', action='store_true', default=True, help='Save the actogram as a png. Default is True (save).')
809+
parser.add_argument('--csv', action='store_true', default=True, help='Save the actogram as a csv. Default is True (save).')
810+
parser.add_argument('--show', action='store_true', default=True, help='Show the actogram in a window just after generation. Default is True (show).')
811+
parser.add_argument('--printer_friendly', action='store_true', default=False, help='Printer friendly actogram (black and white). Default is False (no).')
812+
parser.add_argument('--landscape', action='store_true', default=True, help='Orientation of the plot: True is horizontal, False is vertical. Default is True (horizontal).')
813+
parser.add_argument('--legacy', action='store_true', default=False, help='Use old internal method to import browser histories data. If false, will use browser-history external module (more browsers supported and all profiles are imported). Default: False (no).')
791814

792815
ARGS, UNK = parser.parse_known_args(argv)
793816

0 commit comments

Comments
 (0)