e7e4f5be2307863f1b6d1069b8e6847dc65552fe
[plugin.video.netflix.git] / resources / lib / Library.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 # Module: LibraryExporter
4 # Created on: 13.01.2017
5
6 import os
7 import pickle
8 from utils import noop
9
10 class Library:
11     """Exports Netflix shows & movies to a local library folder (Not yet ready)"""
12
13     series_label = 'shows'
14     movies_label = 'movies'
15     db_filename = 'lib.ndb'
16
17
18     def __init__ (self, base_url, root_folder, library_settings, log_fn=noop):
19         """Takes the instances & configuration options needed to drive the plugin
20
21         Parameters
22         ----------
23         base_url : :obj:`str`
24             Plugin base url
25
26         root_folder : :obj:`str`
27             Cookie location
28
29         library_settings : :obj:`str`
30             User data cache location
31
32         library_db_path : :obj:`str`
33             User data cache location
34
35         log_fn : :obj:`fn`
36              optional log function
37         """
38         self.base_url = base_url
39         self.base_data_path = root_folder
40         self.enable_custom_library_folder = library_settings['enablelibraryfolder']
41         self.custom_library_folder = library_settings['customlibraryfolder']
42         self.log = log_fn
43         self.db_filepath = os.path.join(self.base_data_path, self.db_filename)
44
45         # check for local library folder & set up the paths
46         if self.enable_custom_library_folder != 'true':
47             self.movie_path = os.path.join(self.base_data_path, self.series_label)
48             self.tvshow_path = os.path.join(self.base_data_path, self.movies_label)
49         else:
50             self.movie_path = os.path.join(self.custom_library_folder, self.movies_label)
51             self.tvshow_path = os.path.join(self.custom_library_folder, self.series_label)
52
53         self.setup_local_netflix_library(source={
54             self.movies_label: self.movie_path,
55             self.series_label: self.tvshow_path
56         })
57
58         self.db = self._load_local_db(filename=self.db_filepath)
59
60     def setup_local_netflix_library (self, source):
61         for label in source:
62             if not os.path.exists(source[label]):
63                 os.makedirs(source[label])
64
65     def write_strm_file(self, path, url):
66         with open(path, 'w+') as f:
67             f.write(url)
68             f.close()
69
70     def _load_local_db (self, filename):
71         # if the db doesn't exist, create it
72         if not os.path.isfile(filename):
73             data = {self.movies_label: {}, self.series_label: {}}
74             self.log('Setup local library DB')
75             self._update_local_db(filename=filename, data=data)
76             return data
77
78         with open(filename) as f:
79             data = pickle.load(f)
80             if data:
81                 return data
82             else:
83                 return {}
84
85     def _update_local_db (self, filename, data):
86         if not os.path.isdir(os.path.dirname(filename)):
87             return False
88         with open(filename, 'w') as f:
89             f.truncate()
90             pickle.dump(data, f)
91         return True
92
93     def movie_exists (self, title, year):
94         movie_meta = '%s (%d)' % (title, year)
95         return movie_meta in self.db[self.movies_label]
96
97     def show_exists (self, title, year):
98         show_meta = '%s (%d)' % (title, year)
99         return show_meta in self.db[self.series_label]
100
101     def season_exists (self, title, year, season):
102         if self.show_exists() == False:
103             return False
104         show_meta = '%s (%d)' % (title, year)
105         show_entry = self.db[self.series_label][show_meta]
106         return season in show_entry['seasons']
107
108     def episode_exists (self, title, year, season, episode):
109         if self.show_exists() == False:
110             return False
111         show_meta = '%s (%d)' % (title, year)
112         show_entry = self.db[self.series_label][show_meta]
113         episode_entry = 'S%02dE%02d' % (season, episode)
114         return episode_entry in show_entry['episodes']
115
116     def add_movie(self, title, year, video_id, pin, build_url):
117         movie_meta = '%s (%d)' % (title, year)
118         dirname = os.path.join(self.movie_path, movie_meta)
119         filename = os.path.join(dirname, movie_meta + '.strm')
120         if os.path.exists(filename):
121             return
122         if not os.path.exists(dirname):
123             os.makedirs(dirname)
124         if self.movie_exists(title=title, year=year) == False:
125             self.db[self.movies_label][movie_meta] = True
126             self._update_local_db(filename=self.db_filepath, db=self.db)
127         self.write_strm_file(path=filename, url=build_url({'action': 'play_video', 'video_id': video_id, 'pin': pin}))
128
129     def add_show(self, title, year, episodes, build_url):
130         show_meta = '%s (%d)' % (title, year)
131         show_dir = os.path.join(self.tvshow_path, show_meta)
132         if not os.path.exists(show_dir):
133             os.makedirs(show_dir)
134         if self.show_exists(title, year) == False:
135             self.db[self.series_label][show_meta] = {'seasons': [], 'episodes': []}
136         for episode_id in episodes:
137             episode = episodes[episode_id]
138             self._add_episode(show_dir=show_dir, show_meta=show_meta, title=title, year=year, season=episode['season'], episode=episode['idx'], video_id=episode['id'], pin=episode['pin'], build_url=build_url)
139         self._update_local_db(filename=self.db_filepath, db=self.db)
140         return show_dir
141
142     def _add_episode(self, title, year, show_dir, show_meta, season, episode, video_id, pin, build_url):
143         season = int(season)
144         episode = int(episode)
145
146         # add season
147         if self.season_exists(title=title, year=year, season=season) == False:
148             self.db[self.series_label][show_meta]['seasons'].append(season)
149
150         # add episode
151         episode_meta = 'S%02dE%02d' % (season, episode)
152         if self.episode_exists(title=title, year=year, season=season, episode=episode) == False:
153             self.db[self.series_label][show_meta]['episodes'].append(episode_meta)
154
155         # create strm file
156         filename = episode_meta + '.strm'
157         filepath = os.path.join(show_dir, filename)
158         if os.path.exists(filepath):
159             return
160         self.write_strm_file(path=filepath, url=build_url({'action': 'play_video', 'video_id': video_id, 'pin': pin}))
161
162     def remove_movie(self, title, year):
163         movie_meta = '%s (%d)' % (title, year)
164         del self.db[self.movies_label][movie_meta]
165         self._update_local_db(filename=self.db_filepath, db=self.db)
166         dirname = os.path.join(self.movie_path, movie_meta)
167         if os.path.exists(dirname):
168             os.rmtree(dirname)
169             return True
170         return False
171
172     def remove_show(self, title, year):
173         show_meta = '%s (%d)' % (title, year)
174         del self.db[self.series_label][show_meta]
175         self._update_local_db(filename=self.db_filepath, db=self.db)
176         show_dir = os.path.join(self.tvshow_path, show_meta)
177         if os.path.exists(show_dir):
178             os.rmtree(show_dir)
179             return True
180         return False
181
182     def remove_season(self, title, year, season):
183         season = int(season)
184         season_list = []
185         episodes_list = []
186         show_meta = '%s (%d)' % (title, year)
187         for season_entry in self.db[self.series_label][show_meta]['seasons']:
188             if season_entry != season:
189                 season_list.append(season_entry)
190         self.db[self.series_label][show_meta]['seasons'] = season_list
191         show_dir = os.path.join(self.tvshow_path, show_meta)
192         if os.path.exists(show_dir):
193             show_files = [f for f in os.listdir(show_dir) if os.path.isfile(os.path.join(show_dir, f))]
194             for filename in show_files:
195                 if 'S%02dE' % (season) in filename:
196                     os.remove(os.path.join(show_dir, filename))
197                 else:
198                     episodes_list.append(filename.replace('.strm', ''))
199             self.db[self.series_label][show_meta]['episodes'] = episodes_list
200         self._update_local_db(filename=self.db_filepath, db=self.db)
201         return True
202
203     def remove_episode(self, title, year, season, episode):
204         episodes_list = []
205         show_meta = '%s (%d)' % (title, year)
206         episode_meta = 'S%02dE%02d' % (season, episode)
207         show_dir = os.path.join(self.tvshow_path, show_meta)
208         if os.path.exists(os.path.join(show_dir, episode_meta + '.strm')):
209             os.remove(os.path.join(show_dir, episode_meta + '.strm'))
210         for episode_entry in self.db[self.series_label][show_meta]['episodes']:
211             if episode_meta != episode_entry:
212                 episodes_list.append(episode_entry)
213         self.db[self.series_label][show_meta]['episodes'] = episodes_list
214         self._update_local_db(filename=self.db_filepath, db=self.db)
215         return True