import json
import codecs
import datetime
import collections
import os
JAN_1_25 = datetime.datetime(2025, 1, 1)
JAN_1_24 = datetime.datetime(2024, 1, 1)
JAN_1_23 = datetime.datetime(2023, 1, 1)
JAN_1_22 = datetime.datetime(2022, 1, 1)
JAN_1_21 = datetime.datetime(2021, 1, 1)
JAN_1_20 = datetime.datetime(2020, 1, 1)
PATH = 'path/to/folder/with/watch-history.json'
TIME_BUCKETS = [
'12AM-4AM',
'4AM-8AM',
'8AM-12PM',
'12PM-4PM',
'4PM-8PM',
'8PM-12AM'
]
def process(start, end):
# For file name compatibility
with codecs.open(os.path.join(PATH, 'watch-history.json'), 'r', encoding='utf-8') as f:
raw_file = f.read()
jsonified = json.loads(raw_file)
channel_to_video_count = collections.defaultdict(int)
channel_to_music_count = collections.defaultdict(int)
day_of_week_buckets = {
'Monday': 0,
'Tuesday': 0,
'Wednesday': 0,
'Thursday': 0,
'Friday': 0,
'Saturday': 0,
'Sunday': 0,
}
hour_of_day_buckets = {bucket: 0 for bucket in TIME_BUCKETS}
for video in jsonified:
watch_time = datetime.datetime.fromisoformat(video['time'][:-1])
if watch_time > end:
continue
if watch_time < start:
# File is ordered DESC
break
if 'subtitles' not in video:
# Privated video
continue
channel_name = video['subtitles'][0]['name']
try:
if video['header'] == 'YouTube Music':
channel_to_music_count[channel_name] += 1
else:
channel_to_video_count[channel_name] += 1
day_of_week_buckets[watch_time.strftime('%A')] += 1
hour_of_day_buckets[TIME_BUCKETS[watch_time.hour // 4]] += 1
except KeyError as e:
print('Missing header: ', e)
metadata_output = {
'Videos Watched By Day of Week (UTC)': day_of_week_buckets,
'Videos Watched By Hour of Day (UTC)': hour_of_day_buckets,
}
sorted_video_list = dict(sorted(channel_to_video_count.items(), key=lambda item: item[1], reverse=True))
sorted_music_list = dict(sorted(channel_to_music_count.items(), key=lambda item: item[1], reverse=True))
stringified_videos = json.dumps(sorted_video_list, indent=2, ensure_ascii=False)
stringified_music = json.dumps(sorted_music_list, indent=2, ensure_ascii=False)
stringified_metadata = json.dumps(metadata_output, indent=2)
with codecs.open(os.path.join(PATH, 'watch-history-videos.out.txt'), 'w+', encoding='utf-8') as f:
f.write(stringified_videos)
with codecs.open(os.path.join(PATH, 'watch-history-music.out.txt'), 'w+', encoding='utf-8') as f:
f.write(stringified_music)
with open(os.path.join(PATH, 'watch-history-metadata.out.txt'), 'w+') as f:
f.write(stringified_metadata)
if __name__ == '__main__':
process(JAN_1_24, JAN_1_25)