-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtvselect.py
More file actions
186 lines (156 loc) · 7.67 KB
/
tvselect.py
File metadata and controls
186 lines (156 loc) · 7.67 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
import collections
import datetime
import logging
log = logging.getLogger(__name__)
def getChannelsList(sotre, channels=None):
log.debug('getChannelsList()')
channels = channels or store.getChannelList()
return map(lambda channel: channel['name'], channels)
def getGroupsList(store, channels=None):
log.debug('getGroupList()')
def reduceList(array, element):
if element['group'] not in array:
array.append(element['group'])
return array
channels = channels or store.getChannelList()
return reduce(reduceList, channels, [])
def getChannelsMap(store):
log.debug('getChannnelsMap()')
result = collections.OrderedDict()
for channel in store.getChannelList():
result[channel['name']] = channel['label']
return result
def getCategoriesMap(store):
log.debug('getCategoriesMap()')
result = collections.OrderedDict()
for channel in store.getChannelList():
result[channel['group']] = channel['category']
return result
def enlist(item):
if type(item) == str:
return [item]
elif type(item) == list:
return item
def timeCompare(time1, time2):
def swap(v1, v2):
return v2, v1
time1delta = time1.hour - 12
time2delta = time2.hour - 12
if abs(time1delta - time2delta) >= 12:
time1, time2 = swap(time1, time2)
if time1 > time2:
return 1
elif time1 < time2:
return -1
else:
return 0
class ShowSelect:
def __init__(self, store, force=False):
self.store = store
self.force = force
def __listChannelNames(self, channels=None):
return getChannelsList(self.store, channels)
def __listChannelGroups(self, channels=None):
return getGroupsList(self.store, channels)
##
# Format channel names list according provided chName or chGroup
##
def __formatChannelList(self, channelsList, chName=None, chGroup=None):
if chName:
log.debug('__formatChannelList(): single channel filter %s', chName)
channelsAll = self.__listChannelNames(channelsList)
# TODO(edzius): add debug logging for filtered channels
channels = filter(lambda channel: channel in channelsAll, enlist(chName))
elif chGroup:
log.debug('__formatChannelList(): channel group filter %s', chGroup)
groupsAll = self.__listChannelGroups(channelsList)
# TODO(edzius): add debug logging for filtered channels. Otherwise this filter is redundant
groups = filter(lambda group: group in groupsAll, enlist(chGroup))
channels = self.__listChannelNames(filter(lambda channel: channel['group'] in groups, channelsList))
log.debug('__formatChannelList(): channel group found channels %s', channels)
else:
log.debug('__formatChannelList(): all channel filter')
channels = self.__listChannelNames(channelsList)
return channels
##
# Format channels matrix according provided date or dateFrom and dateTo
##
def __formatChannelTimetable(self, channelsList, date=None, dateFrom=None, dateTo=None):
channelsMatrix = {}
# FIXME(edzius): Channel names in list as IS. Fix to convert to std from.
if date != None:
log.debug('__formatChannelTimetable(): single date mapping %s', date)
channelsMatrix[date] = list(channelsList)
elif dateFrom != None and dateTo != None:
log.debug('__formatChannelTimetable(): range dates mapping %s - %s', dateFrom, dateTo)
day = datetime.timedelta(days=1)
while dateFrom <= dateTo:
log.debug('__formatChannelTimetable(): add range date mapping %s', dateFrom)
channelsMatrix[dateFrom] = list(channelsList)
dateFrom += day
else:
log.debug('__formatChannelTimetable(): use cached channel dates')
for channel in channelsList:
log.debug('__formatChannelTimetable(): lookuop channel schedules for %s', channel)
chSchedules = self.store.listChannelSchedules(channel)
for chDate in chSchedules:
log.debug('__formatChannelTimetable(): include channel schedule %s for %s', chDate, channel)
if chDate not in channelsMatrix:
channelsMatrix[chDate] = []
channelsMatrix[chDate].append(channel)
return channelsMatrix
def __formatShowsList(self, channel, showsList, showName=None, time=None, timeFrom=None, timeTo=None):
log.debug('__formatShowsList(): %s showName=%s time=%s timeFrom=%s timeTo=%s', channel, showName, time, timeFrom, timeTo)
nowTime = datetime.datetime.now().time()
timeThis = None
timeNext = None
shows = []
for i in range(len(showsList)):
show = showsList[i]
if showName and show['title'].find(showName) == -1 and show['description'].find(showName) == -1:
log.debug('FILTER: Not satisfied show title/description (%s/%s): %s', show['title'], show['description'], showName)
continue
if i+1 < len(showsList):
showNext = showsList[i+1]
else:
showNext = showsList[0]
# Optimization for date parsing
timeThis = timeNext or datetime.datetime.strptime(show['time'], '%H:%M').time()
timeNext = datetime.datetime.strptime(showNext['time'], "%H:%M").time()
if time != None:
if timeCompare(time, timeThis) < 0 or timeCompare(time, timeNext) >= 0:
log.debug('FILTER: Not satisfied show time (%s-%s): %s', timeThis, timeNext, time)
continue
if timeFrom != None:
if timeCompare(timeFrom, timeNext) > 0:
log.debug('FILTER: Not satisfied show time (%s): more %s', timeNext, timeFrom)
continue
if timeTo != None:
if timeCompare(timeTo, timeThis) < 0:
log.debug('FILTER: Not satisfied show timeTo (%s): less %s', timeThis, timeTo)
continue
show['live'] = (timeCompare(nowTime, timeThis) >= 0 and timeCompare(nowTime, timeNext) < 0)
show['ends'] = showNext['time']
show['channel'] = channel
shows.append(show)
return shows
def select(self, chName=None, chGroup=None, showName=None, date=None, dateFrom=None, dateTo=None, time=None, timeFrom=None, timeTo=None):
log.debug('select(): chName=%s chGroup=%s showName=%s date=%s dateFrom=%s dateTo=%s time=%s timeFrom=%s timeTo=%s',
chName, chGroup, showName, date, dateFrom, dateTo, time, timeFrom, timeTo)
channelsList = self.store.getChannelList()
selectedChannels = self.__formatChannelList(channelsList, chName, chGroup)
selectedTimetable = self.__formatChannelTimetable(selectedChannels, date, dateFrom, dateTo)
selectedResult = []
for date, channels in selectedTimetable.items():
for channel in channels:
channelShows = self.store.getChannelSchedule(channel, date)
if not channelShows:
log.info('No shows for channel %s', channel)
continue
selectedShows = self.__formatShowsList(channel, channelShows, showName, time, timeFrom, timeTo)
if len(selectedShows) == 0:
log.debug('No criteria matchinf shows for channel %s', channel)
continue
selectedResult.extend(selectedShows)
log.debug('Selected shows matching criteria: %s', len(selectedResult))
return selectedResult