-
Notifications
You must be signed in to change notification settings - Fork 3
/
database_management.py
106 lines (90 loc) · 4.05 KB
/
database_management.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import json
import os
import constants
import asyncio
import connection_management
# Database is always stored as a dict()
# use this function to read database from json string
def parseDatabaseContent(content):
return json.loads(content)
# use this function to read database from json file
def parseDatabaseFile(filename):
with open(filename, 'r') as filePointer:
return json.load(filePointer)
# use this function to return json representation of database as string
def getDatabaseString(database):
return json.dumps(database, indent=4)
# use this function to write json representation of database to file
def outputDatabaseToFile(database, filename):
with open(filename, 'w') as filePointer:
return json.dump(database, filePointer, indent=4)
# use this function to initialize the database (dict format so it's easy to save as json)
def initiateYouTubeRssDatabase():
database = {}
database['feeds'] = {}
database['id to title'] = {}
database['title to id'] = {}
return database
# use this function to remove a subscription from the database by channel title
def removeSubscriptionFromDatabaseByChannelTitle(database, channelTitle):
if channelTitle not in database['title to id']:
return
channelId = database['title to id'][channelTitle]
removeSubscriptionFromDatabaseByChannelId(database, channelId)
return
# use this function to remove a subscription from the database by channel ID
def removeSubscriptionFromDatabaseByChannelId(database, channelId):
if channelId not in database['id to title']:
return
channelTitle = database['id to title'].pop(channelId)
database['title to id'].pop(channelTitle)
database['feeds'].pop(channelId)
outputDatabaseToFile(database, constants.DATABASE_PATH)
# use this function to retrieve new RSS entries for a subscription and add them to
# a database
async def refreshSubscriptionsByChannelId(channelIdList, useTor=False,
auth=None):
database = parseDatabaseFile(constants.DATABASE_PATH)
localFeeds = database['feeds']
tasks = []
semaphore = asyncio.Semaphore(constants.MAX_CONNECTIONS)
for channelId in channelIdList:
localFeed = localFeeds[channelId]
tasks.append(asyncio.create_task(refreshSubscriptionByChannelId(channelId, localFeed,
semaphore=semaphore, useTor=useTor, auth=auth)))
for task in tasks:
await task
outputDatabaseToFile(database, constants.DATABASE_PATH)
async def refreshSubscriptionByChannelId(channelId, localFeed, semaphore, useTor=False,
auth=None):
task = asyncio.create_task(connection_management.getRssEntriesFromChannelId(channelId,
semaphore=semaphore, useTor=useTor, auth=auth))
remoteFeed = await task
if remoteFeed is not None:
remoteFeed.reverse()
for entry in remoteFeed:
filteredEntry = connection_management.getRelevantDictFromFeedParserDict(entry)
filteredEntryIsNew = True
for i, localEntry in enumerate(localFeed):
if localEntry['id'] == filteredEntry['id']:
filteredEntryIsNew = False
# in case any relevant data about the entry is changed, update it
filteredEntry['seen'] = localEntry['seen']
localFeed[i] = filteredEntry
break
if filteredEntryIsNew:
localFeed.insert(0, filteredEntry)
# use this function to add a subscription to the database
def addSubscriptionToDatabase(channelId, channelTitle, refresh=False,
useTor=False, circuitManager=None):
database = parseDatabaseFile(constants.DATABASE_PATH)
database['feeds'][channelId] = []
database['id to title'][channelId] = channelTitle
database['title to id'][channelTitle] = channelId
outputDatabaseToFile(database, constants.DATABASE_PATH)
auth = None
if circuitManager is not None and useTor:
auth = circuitManager.getAuth()
if refresh:
asyncio.run(refreshSubscriptionsByChannelId( [channelId], useTor=useTor,
auth=auth))