Skip to content

Commit

Permalink
- Add error handling for when a channel in the EPG exists that does …
Browse files Browse the repository at this point in the history
…not exist in the channel list
  • Loading branch information
tgorgdotcom committed Dec 8, 2020
1 parent 86ac35c commit 5b5d5b7
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 79 deletions.
9 changes: 6 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@
- Start using pip for third-party plugins
- Rename `plex_accessible_ip`/`plex_accessible_port` to `advertise_ip`/`advertise_port`. Add `bind_ip`/`bind_port` options (https://github.com/tgorgdotcom/locast2plex/pull/98)
- Hopefully phase out FCC channel checking (when locast reports proper channel numbers)
- Some kind of web based UI to modify config
- A way to daemonize the script for those running outside of docker
- Install script for those not using docker
- Enable multiplatform Docker image
- Implement proper logging
- Wrap HTTP requests around error handling that existed in do_tuner() previously
- Documentation added for Kodi, Emby/Jellyfin
- Implement proper logging
- Some kind of web based UI to modify config
- Look into pull requests suggestions for ip addressing
- A way to daemonize the script for those running outside of docker

## 1.0.0 (unreleased)
- Most bugs squashed

## 0.6.3
- Add error handling for when a channel in the EPG exists that does not exist in the channel list

## 0.6.2
- Fix an issue where logins fail when passwords with a '%' are used

Expand Down
154 changes: 78 additions & 76 deletions lib/epg2xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,32 @@ def generate_epg_file(config, location):
done_channels = True
for channel_item in channel_info:
sid = str(channel_item['id'])
if sid in dma_channels.keys():
channel_number = str(dma_channels[sid]['channel'])
channel_realname = str(dma_channels[sid]['friendlyName'])
channel_callsign = str(dma_channels[sid]['callSign'])

if 'logo226Url' in channel_item.keys():
channel_logo = channel_item['logo226Url']

elif 'logoUrl' in channel_item.keys():
channel_logo = channel_item['logoUrl']

c_out = sub_el(out, 'channel', id=sid)
sub_el(c_out, 'display-name', text='%s %s' % (channel_number, channel_callsign))
sub_el(c_out, 'display-name', text='%s %s %s' % (channel_number, channel_callsign, sid))
sub_el(c_out, 'display-name', text=channel_number)
sub_el(c_out, 'display-name', text='%s %s fcc' % (channel_number, channel_callsign))
sub_el(c_out, 'display-name', text=channel_callsign)
sub_el(c_out, 'display-name', text=channel_realname)

if channel_logo != None:
sub_el(c_out, 'icon', src=channel_logo)

# Now list Program informations
for channel_item in channel_info:
sid = str(channel_item['id'])
if sid in dma_channels.keys():
channel_number = str(dma_channels[sid]['channel'])
channel_realname = str(dma_channels[sid]['friendlyName'])
channel_callsign = str(dma_channels[sid]['callSign'])
Expand All @@ -103,84 +129,60 @@ def generate_epg_file(config, location):
elif 'logoUrl' in channel_item.keys():
channel_logo = channel_item['logoUrl']

c_out = sub_el(out, 'channel', id=sid)
sub_el(c_out, 'display-name', text='%s %s' % (channel_number, channel_callsign))
sub_el(c_out, 'display-name', text='%s %s %s' % (channel_number, channel_callsign, sid))
sub_el(c_out, 'display-name', text=channel_number)
sub_el(c_out, 'display-name', text='%s %s fcc' % (channel_number, channel_callsign))
sub_el(c_out, 'display-name', text=channel_callsign)
sub_el(c_out, 'display-name', text=channel_realname)
for event in channel_item['listings']:

if channel_logo != None:
sub_el(c_out, 'icon', src=channel_logo)
tm_start = tm_parse(event['startTime']) # this is returned from locast in UTC
tm_duration = event['duration'] * 1000
tm_end = tm_parse(event['startTime'] + tm_duration)

# Now list Program informations
for channel_item in channel_info:
sid = str(channel_item['id'])
channel_number = str(dma_channels[sid]['channel'])
channel_realname = str(dma_channels[sid]['friendlyName'])
channel_callsign = str(dma_channels[sid]['callSign'])

if 'logo226Url' in channel_item.keys():
channel_logo = channel_item['logo226Url']

elif 'logoUrl' in channel_item.keys():
channel_logo = channel_item['logoUrl']

for event in channel_item['listings']:

tm_start = tm_parse(event['startTime']) # this is returned from locast in UTC
tm_duration = event['duration'] * 1000
tm_end = tm_parse(event['startTime'] + tm_duration)

event_genres = []
if 'genres' in event.keys():
event_genres = event['genres'].split(",")

# note we're returning everything as UTC, as the clients handle converting to correct timezone
prog_out = sub_el(out, 'programme', start=tm_start, stop=tm_end, channel=sid)

if event['title']:
sub_el(prog_out, 'title', lang='en', text=event['title'])

if 'movie' in event_genres and event['releaseYear']:
sub_el(prog_out, 'sub-title', lang='en', text='Movie: ' + event['releaseYear'])
elif 'episodeTitle' in event.keys():
sub_el(prog_out, 'sub-title', lang='en', text=event['episodeTitle'])

if 'description' not in event.keys():
event['description'] = "Unavailable"
elif event['description'] is None:
event['description'] = "Unavailable"
sub_el(prog_out, 'desc', lang='en', text=event['description'])

sub_el(prog_out, 'length', units='minutes', text=str(event['duration']))

for f in event_genres:
sub_el(prog_out, 'category', lang='en', text=f.strip())
sub_el(prog_out, 'genre', lang='en', text=f.strip())

if event["preferredImage"] is not None:
sub_el(prog_out, 'icon', src=event["preferredImage"])

if 'rating' not in event.keys():
event['rating'] = "N/A"
r = ET.SubElement(prog_out, 'rating')
sub_el(r, 'value', text=event['rating'])

if 'seasonNumber' in event.keys() and 'episodeNumber' in event.keys():
s_ = int(str(event['seasonNumber']), 10)
e_ = int(str(event['episodeNumber']), 10)
sub_el(prog_out, 'episode-num', system='common',
text='S%02dE%02d' % (s_, e_))
sub_el(prog_out, 'episode-num', system='xmltv_ns',
text='%d.%d.0' % (int(s_)-1, int(e_)-1))
sub_el(prog_out, 'episode-num', system='SxxExx',
text='S%02dE%02d' % (s_, e_))

if 'isNew' in event.keys():
if event['isNew']:
sub_el(prog_out, 'new')
event_genres = []
if 'genres' in event.keys():
event_genres = event['genres'].split(",")

# note we're returning everything as UTC, as the clients handle converting to correct timezone
prog_out = sub_el(out, 'programme', start=tm_start, stop=tm_end, channel=sid)

if event['title']:
sub_el(prog_out, 'title', lang='en', text=event['title'])

if 'movie' in event_genres and event['releaseYear']:
sub_el(prog_out, 'sub-title', lang='en', text='Movie: ' + event['releaseYear'])
elif 'episodeTitle' in event.keys():
sub_el(prog_out, 'sub-title', lang='en', text=event['episodeTitle'])

if 'description' not in event.keys():
event['description'] = "Unavailable"
elif event['description'] is None:
event['description'] = "Unavailable"
sub_el(prog_out, 'desc', lang='en', text=event['description'])

sub_el(prog_out, 'length', units='minutes', text=str(event['duration']))

for f in event_genres:
sub_el(prog_out, 'category', lang='en', text=f.strip())
sub_el(prog_out, 'genre', lang='en', text=f.strip())

if event["preferredImage"] is not None:
sub_el(prog_out, 'icon', src=event["preferredImage"])

if 'rating' not in event.keys():
event['rating'] = "N/A"
r = ET.SubElement(prog_out, 'rating')
sub_el(r, 'value', text=event['rating'])

if 'seasonNumber' in event.keys() and 'episodeNumber' in event.keys():
s_ = int(str(event['seasonNumber']), 10)
e_ = int(str(event['episodeNumber']), 10)
sub_el(prog_out, 'episode-num', system='common',
text='S%02dE%02d' % (s_, e_))
sub_el(prog_out, 'episode-num', system='xmltv_ns',
text='%d.%d.0' % (int(s_)-1, int(e_)-1))
sub_el(prog_out, 'episode-num', system='SxxExx',
text='S%02dE%02d' % (s_, e_))

if 'isNew' in event.keys():
if event['isNew']:
sub_el(prog_out, 'new')

xml_lock = FileLock(out_lock_path)
with xml_lock:
Expand Down
1 change: 1 addition & 0 deletions lib/tuner_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class PlexHttpHandler(BaseHTTPRequestHandler):


def do_GET(self):

base_url = self.config['main']['plex_accessible_ip'] + ':' + self.config['main']['plex_accessible_port']

contentPath = self.path
Expand Down

0 comments on commit 5b5d5b7

Please sign in to comment.