Program movies on Freebox

This commit is contained in:
2019-10-10 00:20:30 +02:00
parent 4cb1a26863
commit eb1e3295c0

View File

@ -7,11 +7,13 @@ Todo :
* Scrape beginning and end time * Scrape beginning and end time
* Schedule recordings on Freebox using the FB API * Schedule recordings on Freebox using the FB API
https://dev.freebox.fr/sdk/os/pvr/#pvr-programmed-records https://dev.freebox.fr/sdk/os/pvr/#pvr-programmed-records
* Add a configuration setting for beginning and end margin
* Display conflicts if any * Display conflicts if any
""" """
import datetime import datetime
import json import json
import logging import logging
import re
import requests import requests
import textwrap import textwrap
import tmdbsimple import tmdbsimple
@ -33,10 +35,15 @@ class Movie:
self.tmdb_id = '' self.tmdb_id = ''
self.url = '' self.url = ''
self.user_selected = False self.user_selected = False
self.date = 0
self.start_time = 0
self.end_time = 0
def __str__(self): def __str__(self):
return '{}: {} - {} ({})\n TMDB: {} - {}\n @ {}\n {}'.format( return '{}: {} - {} ({})\n TMDB: {} - {}\n @ {}\n {}'.format(
'Today' if self.day == '' else self.day, 'Today' if self.day == '' else self.day,
self.start_time,
self.end_time,
self.title, self.title,
self.genre, self.genre,
self.channel, self.channel,
@ -65,13 +72,15 @@ class TVGuideScraper:
offset = datetime.datetime.today().weekday() offset = datetime.datetime.today().weekday()
days.rotate(-1-offset) days.rotate(-1-offset)
days.appendleft('') days.appendleft('')
date = datetime.date.today()
for day in days: for day in days:
movies += TVGuideScraper._getMovies(day) movies += TVGuideScraper._getMovies(day, date)
date += datetime.timedelta(days=1)
logging.info('Found the following movies: {}'.format(movies)) logging.info('Found the following movies: {}'.format(movies))
return movies return movies
@staticmethod @staticmethod
def _getMovies(day=''): def _getMovies(day='', date=datetime.date.today()):
logging.info('Connecting to {}'.format(TVGuideScraper.TV_GUIDE_URL)) logging.info('Connecting to {}'.format(TVGuideScraper.TV_GUIDE_URL))
r = requests.get(TVGuideScraper.TV_GUIDE_URL.format(day)) r = requests.get(TVGuideScraper.TV_GUIDE_URL.format(day))
r.raise_for_status() r.raise_for_status()
@ -87,9 +96,21 @@ class TVGuideScraper:
movie.channel = channel.select('em')[0]\ movie.channel = channel.select('em')[0]\
.string.replace('Programme ', '') .string.replace('Programme ', '')
movie.day = day.title() movie.day = day.title()
movie.date = datetime.date.strftime(date, '%Y-%m-%d')
movie.start_time = datetime.datetime.strptime(
'{} {}'.format(
movie.date,
movietag.select('.horaire')[0].string
),
'%Y-%m-%d %H:%M'
)
duration = TVGuideScraper._parse_duration(
movietag.select('.texte_cat')[0]
.contents[1].strip(' \n\t()')
)
movie.end_time = movie.start_time + duration
logging.info('Found movie: {0!r}'.format(movie)) logging.info('Found movie: {0!r}'.format(movie))
movies.append(movie) movies.append(movie)
return movies return movies
@ -105,6 +126,17 @@ class TVGuideScraper:
tag['data-nature'] == 'films-telefilms' tag['data-nature'] == 'films-telefilms'
) )
@staticmethod
def _parse_duration(text):
match = re.match(r"((?P<hours>\d+)h)?(?P<minutes>\d+)mn", text)
if not match:
error = "Could not parse duration '{}'".format(text)
logging.error(error)
raise ValueError(error)
hours = int(match.group('hours')) if match.group('hours') else 0
minutes = int(match.group('minutes'))
return datetime.timedelta(hours=hours, minutes=minutes)
class FreeboxMoviePlanner: class FreeboxMoviePlanner:
def __init__(self, movies): def __init__(self, movies):
@ -124,6 +156,9 @@ class FreeboxMoviePlanner:
self.excludeUnavailableChannels() self.excludeUnavailableChannels()
self.findMoviesOnTMDB() self.findMoviesOnTMDB()
self.excludeBadRatings() self.excludeBadRatings()
self.askForUserSelection()
self.excludeNotSelected()
self.programMovies()
def __repr__(self): def __repr__(self):
result = 'FreeboxMoviePlanner <Movies:\n' result = 'FreeboxMoviePlanner <Movies:\n'
@ -200,6 +235,16 @@ class FreeboxMoviePlanner:
def excludeNotSelected(self): def excludeNotSelected(self):
self.movies = [m for m in self.movies if m.user_selected] self.movies = [m for m in self.movies if m.user_selected]
def programMovies(self):
for movie in self.movies:
data = {
'channel_uuid': self.channels[movie.channel],
'start': int(movie.start_time.timestamp()),
'end': int(movie.end_time.timestamp()),
'name': movie.title
}
self.freebox.Pvr.Create_a_precord(data)
if __name__ == '__main__': if __name__ == '__main__':
logging.basicConfig( logging.basicConfig(
@ -207,7 +252,4 @@ if __name__ == '__main__':
format=' %(asctime)s - %(levelname)s - %(message)s' format=' %(asctime)s - %(levelname)s - %(message)s'
) )
fmp = FreeboxMoviePlanner(TVGuideScraper.findAllMovies()) fmp = FreeboxMoviePlanner(TVGuideScraper.findAllMovies())
fmp.askForUserSelection() # fmp = FreeboxMoviePlanner(TVGuideScraper._getMovies())
fmp.excludeNotSelected()
print('\n====== Selected ======\n')
fmp.printAllMovies()