def notify(self, subject=None, message=None): hosts = [x.strip() for x in self.hosts.split(",")] header = subject message = message time = "3000" # in ms for host in hosts: logger.info("Sending notification command to XMBC @ " + host) try: version = self._sendjson(host, "Application.GetProperties", {"properties": ["version"]})["version"][ "major" ] if version < 12: # Eden notification = header + "," + message + "," + time notifycommand = {"command": "ExecBuiltIn", "parameter": "Notification(" + notification + ")"} request = self._sendhttp(host, notifycommand) else: # Frodo params = {"title": header, "message": message, "displaytime": int(time)} request = self._sendjson(host, "GUI.ShowNotification", params) if not request: raise Exception except Exception: logger.error("Error sending notification request to XBMC")
def _sendhttp(self, host, command): username = self.username password = self.password url_command = urllib.urlencode(command) url = host + '/xbmcCmds/xbmcHttp/?' + url_command req = urllib2.Request(url) if password: base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') req.add_header("Authorization", "Basic %s" % base64string) logger.info('Plex url: %s' % url) try: handle = urllib2.urlopen(req) except Exception as e: logger.warn('Error opening Plex url: %s' % e) return response = handle.read().decode(plexpy.SYS_ENCODING) return response
def delete(self, user_id=None): monitor_db = database.MonitorDatabase() try: if str(user_id).isdigit(): self.delete_all_history(user_id) logger.info( u"Tautulli Users :: Deleting user with id %s from database." % user_id) monitor_db.action( 'UPDATE users SET deleted_user = 1 WHERE user_id = ?', [user_id]) monitor_db.action( 'UPDATE users SET keep_history = 0 WHERE user_id = ?', [user_id]) monitor_db.action( 'UPDATE users SET do_notify = 0 WHERE user_id = ?', [user_id]) return 'Deleted user with id %s.' % user_id else: return 'Unable to delete user, user_id not valid.' except Exception as e: logger.warn( u"Tautulli Users :: Unable to execute database query for delete: %s." % e)
def upsert(self, table_name, value_dict, key_dict): trans_type = 'update' changes_before = self.connection.total_changes gen_params = lambda my_dict: [x + " = ?" for x in my_dict.keys()] update_query = "UPDATE " + table_name + " SET " + ", ".join(gen_params(value_dict)) + \ " WHERE " + " AND ".join(gen_params(key_dict)) self.action(update_query, value_dict.values() + key_dict.values()) if self.connection.total_changes == changes_before: trans_type = 'insert' insert_query = ( "INSERT INTO " + table_name + " (" + ", ".join(value_dict.keys() + key_dict.keys()) + ")" + " VALUES (" + ", ".join(["?"] * len(value_dict.keys() + key_dict.keys())) + ")") try: self.action(insert_query, value_dict.values() + key_dict.values()) except sqlite3.IntegrityError: logger.info('Queries failed: %s and %s', update_query, insert_query) # We want to know if it was an update or insert return trans_type
def import_session_history_media_info(import_db, tautulli_db, old_server_id, new_server_id, session_history_lookup): logger.info( u"Tautulli Importer :: Importing session_history_media_info table for ServerID: %s" % old_server_id) try: query = 'SELECT * FROM session_history_media_info WHERE server_id = %s' % old_server_id session_history_media_info_result = import_db.execute(query).fetchall() for session_history_media_info in session_history_media_info_result: if session_history_media_info['id'] in session_history_lookup: session_history_media_info['id'] = session_history_lookup[ session_history_media_info['id']] session_history_media_info['server_id'] = new_server_id query = ("INSERT INTO session_history_media_info (" + ", ".join(session_history_media_info.keys()) + ")" + " VALUES (" + ", ".join( ["?"] * len(session_history_media_info.keys())) + ")") tautulli_db.action(query, list(session_history_media_info.values())) logger.info( u"Tautulli Importer :: session_history_media_info imported.") except sqlite3.IntegrityError: logger.error(u"Tautulli Import_Tautulli :: Queries failed: %s", query) except Exception as e: raise Exception('Session History Media Info Import failed: %s' % e)
def import_notify_log(import_db, monitor_db, old_notifier_id, new_notifier_id): logger.info( u"Tautulli Importer :: Importing Notifier_log table entries for notifier ID %s" % old_notifier_id) try: query = 'SELECT * FROM notify_log WHERE notifier_id = %s' % old_notifier_id notify_log_result = import_db.execute(query).fetchall() for notify_log in notify_log_result: old_notify_log_id = notify_log.pop('id') notify_log['notifier_id'] = new_notifier_id query = ("INSERT INTO notify_log (" + ", ".join(notify_log.keys()) + ")" + " VALUES (" + ", ".join(["?"] * len(notify_log.keys())) + ")") monitor_db.action(query, list(notify_log.values())) logger.info( u"Tautulli Importer :: Notify_log imported for notifier ID %s." % old_notifier_id) except sqlite3.IntegrityError: logger.error(u"Tautulli Import_Tautulli :: Queries failed: %s", query) except Exception as e: raise Exception('Notify Log Import failed: %s' % e)
def wait(): logger.info("Tautulli is ready!") # Wait endlessly for a signal to happen while True: if not plexpy.SIGNAL: try: time.sleep(1) except KeyboardInterrupt: plexpy.SIGNAL = 'shutdown' else: logger.info('Received signal: %s', plexpy.SIGNAL) if plexpy.SIGNAL == 'shutdown': plexpy.shutdown() elif plexpy.SIGNAL == 'restart': plexpy.shutdown(restart=True) elif plexpy.SIGNAL == 'checkout': plexpy.shutdown(restart=True, checkout=True) elif plexpy.SIGNAL == 'reset': plexpy.shutdown(restart=True, reset=True) elif plexpy.SIGNAL == 'update': plexpy.shutdown(restart=True, update=True) else: logger.error('Unknown signal. Shutting down...') plexpy.shutdown() plexpy.SIGNAL = None
def import_recently_added(import_db, monitor_db, old_server_id, new_server_id): logger.info( u"Tautulli Importer :: Importing recently_added table for ServerID: %s" % old_server_id) try: query = 'SELECT * FROM recently_added WHERE server_id = %s' % old_server_id recently_added_result = import_db.execute(query).fetchall() for recently_added in recently_added_result: old_recently_added_id = recently_added.pop('id') recently_added['server_id'] = new_server_id key_dict = {} key_dict['server_id'] = recently_added.pop('server_id') key_dict['rating_key'] = recently_added.pop('rating_key') key_dict['added_at'] = recently_added.pop('added_at') result = monitor_db.upsert('recently_added', key_dict=key_dict, value_dict=recently_added) logger.info(u"Tautulli Importer :: recently_added imported.") except sqlite3.IntegrityError: logger.error(u"Tautulli Import_Tautulli :: Queries failed: %s", query) except Exception as e: raise Exception('Recently Added Import failed: %s' % e)
def import_tvmaze_lookup(import_db, monitor_db, old_server_id, new_server_id): logger.info( u"Tautulli Importer :: Importing tvmaze_lookup table for ServerID: %s" % old_server_id) try: query = 'SELECT * FROM tvmaze_lookup WHERE server_id = %s' % old_server_id tvmaze_lookup_result = import_db.execute(query).fetchall() for tvmaze_lookup in tvmaze_lookup_result: old_tvmaze_lookup_id = tvmaze_lookup.pop('id') tvmaze_lookup['server_id'] = new_server_id key_dict = {} key_dict['server_id'] = tvmaze_lookup.pop('server_id') key_dict['rating_key'] = tvmaze_lookup.pop('rating_key') result = monitor_db.upsert('tvmaze_lookup', key_dict=key_dict, value_dict=tvmaze_lookup) logger.info(u"Tautulli Importer :: tvmaze_lookup imported.") except sqlite3.IntegrityError: logger.error(u"Tautulli Import_Tautulli :: Queries failed: %s", query) except Exception as e: raise Exception('TVMaze Lookup Import failed: %s' % e)
def shutdown(restart=False, update=False): cherrypy.engine.exit() SCHED.shutdown(wait=False) # Clear any sessions in the db - Not sure yet if we should do this. More testing required # logger.debug(u'Clearing Plex sessions.') # monitor.drop_session_db() CONFIG.write() if not restart and not update: logger.info('PlexPy is shutting down...') if update: logger.info('PlexPy is updating...') try: versioncheck.update() except Exception as e: logger.warn('PlexPy failed to update: %s. Restarting.', e) if CREATEPID: logger.info('Removing pidfile %s', PIDFILE) os.remove(PIDFILE) if restart: logger.info('PlexPy is restarting...') popen_list = [sys.executable, FULL_PATH] popen_list += ARGS if '--nolaunch' not in popen_list: popen_list += ['--nolaunch'] logger.info('Restarting PlexPy with %s', popen_list) subprocess.Popen(popen_list, cwd=os.getcwd()) os._exit(0)
def initialize_scheduler(): """ Start the scheduled background tasks. Re-schedule if interval settings changed. """ with SCHED_LOCK: # Check if scheduler should be started start_jobs = not len(SCHED.get_jobs()) # Update check if CONFIG.CHECK_GITHUB_INTERVAL: minutes = CONFIG.CHECK_GITHUB_INTERVAL else: minutes = 0 schedule_job(versioncheck.checkGithub, 'Check GitHub for updates', hours=0, minutes=minutes) # Start checking for new sessions every minute if CONFIG.PMS_IP: schedule_job(monitor.check_active_sessions, 'Check for active sessions', hours=0, minutes=0, seconds=60) # Refresh the users list every 12 hours (we will make this configurable later) if CONFIG.PMS_TOKEN: schedule_job(plextv.refresh_users, 'Refresh users list', hours=12, minutes=0, seconds=0) # Start scheduler if start_jobs and len(SCHED.get_jobs()): try: SCHED.start() except Exception as e: logger.info(e)
def delete(self, keep_history=False): logger.info(u"Tautulli Servers :: %s: Deleting server from database." % self.CONFIG.PMS_NAME) self.CONFIG.PMS_IS_ENABLED = False self.CONFIG.PMS_IS_DELETED = True if self.WS_CONNECTED: self.shutdown() if not keep_history: try: delete_history = self.delete_all_history() delete_libraries = self.delete_all_libraries() delete_users = self.delete_all_users() monitor_db = database.MonitorDatabase() logger.info( u"Tautulli Servers :: %s: Deleting server from database." % self.CONFIG.PMS_NAME) server_del = monitor_db.action( 'DELETE FROM servers ' 'WHERE id = ?', [self.CONFIG.ID]) return True except Exception as e: logger.warn( "Tautulli Servers :: %s: Unable to execute database query for delete_all_history: %s." % (self.CONFIG.PMS_NAME, e)) return False return True
def notify(self, subject=None, message=None): hosts = [x.strip() for x in self.client_hosts.split(',')] header = subject message = message time = "3000" # in ms for host in hosts: logger.info( 'Sending notification command to Plex Media Server @ ' + host) try: notification = header + "," + message + "," + time notifycommand = { 'command': 'ExecBuiltIn', 'parameter': 'Notification(' + notification + ')' } request = self._sendhttp(host, notifycommand) if not request: raise Exception except: logger.warn( 'Error sending notification request to Plex Media Server')
def delete_all_history(self, user_id=None): monitor_db = database.MonitorDatabase() try: if str(user_id).isdigit(): logger.info( u"Tautulli Users :: Deleting all history for user id %s from database." % user_id) session_history_media_info_del = \ monitor_db.action('DELETE FROM ' 'session_history_media_info ' 'WHERE session_history_media_info.id IN (SELECT session_history_media_info.id ' 'FROM session_history_media_info ' 'JOIN session_history ON session_history_media_info.id = session_history.id ' 'WHERE session_history.user_id = ?)', [user_id]) session_history_metadata_del = \ monitor_db.action('DELETE FROM ' 'session_history_metadata ' 'WHERE session_history_metadata.id IN (SELECT session_history_metadata.id ' 'FROM session_history_metadata ' 'JOIN session_history ON session_history_metadata.id = session_history.id ' 'WHERE session_history.user_id = ?)', [user_id]) session_history_del = \ monitor_db.action('DELETE FROM ' 'session_history ' 'WHERE session_history.user_id = ?', [user_id]) return 'Deleted all items for user_id %s.' % user_id else: return 'Unable to delete items. Input user_id not valid.' except Exception as e: logger.warn( u"Tautulli Users :: Unable to execute database query for delete_all_history: %s." % e)
def shutdown(self): logger.info(u"Tautulli Servers :: %s: Stopping Server Monitoring." % self.CONFIG.PMS_NAME) self.server_shutdown = True self.WS.shutdown() self.initialize_scheduler() self.PLEX_SERVER_UP = None
def delete_all_history(self, section_id=None): monitor_db = database.MonitorDatabase() try: if section_id.isdigit(): logger.info( u"PlexPy Libraries :: Deleting all history for library id %s from database." % section_id) session_history_media_info_del = \ monitor_db.action('DELETE FROM ' 'session_history_media_info ' 'WHERE session_history_media_info.id IN (SELECT session_history_media_info.id ' 'FROM session_history_media_info ' 'JOIN session_history_metadata ON session_history_media_info.id = session_history_metadata.id ' 'WHERE session_history_metadata.section_id = ?)', [section_id]) session_history_del = \ monitor_db.action('DELETE FROM ' 'session_history ' 'WHERE session_history.id IN (SELECT session_history.id ' 'FROM session_history ' 'JOIN session_history_metadata ON session_history.id = session_history_metadata.id ' 'WHERE session_history_metadata.section_id = ?)', [section_id]) session_history_metadata_del = \ monitor_db.action('DELETE FROM ' 'session_history_metadata ' 'WHERE session_history_metadata.section_id = ?', [section_id]) return 'Deleted all items for section_id %s.' % section_id else: return 'Unable to delete items, section_id not valid.' except Exception as e: logger.warn( u"PlexPy Libraries :: Unable to execute database query for delete_all_history: %s." % e)
def shutdown(restart=False, update=False): cherrypy.engine.exit() SCHED.shutdown(wait=False) CONFIG.write() if not restart and not update: logger.info('PlexPy is shutting down...') if update: logger.info('PlexPy is updating...') try: versioncheck.update() except Exception as e: logger.warn('PlexPy failed to update: %s. Restarting.', e) if CREATEPID: logger.info('Removing pidfile %s', PIDFILE) os.remove(PIDFILE) if restart: logger.info('PlexPy is restarting...') exe = sys.executable args = [exe, FULL_PATH] args += ARGS if '--nolaunch' not in args: args += ['--nolaunch'] logger.info('Restarting PlexPy with %s', args) os.execv(exe, args) os._exit(0)
def get_plexpy_pms_token(self, force=False): if force: logger.debug( u"Tautulli PlexTV :: Forcing refresh of Plex.tv token.") devices_list = self.get_devices_list() device_id = next( (d for d in devices_list if d['device_identifier'] == plexpy.CONFIG.PMS_UUID), {}).get('device_id', None) if device_id: logger.debug( u"Tautulli PlexTV :: Removing Tautulli from Plex.tv devices." ) try: self.delete_plextv_device(device_id=device_id) except: logger.error( u"Tautulli PlexTV :: Failed to remove Tautulli from Plex.tv devices." ) return None else: logger.warn( u"Tautulli PlexTV :: No existing Tautulli device found.") logger.info( u"Tautulli PlexTV :: Fetching a new Plex.tv token for Tautulli.") user = self.get_token() if user: token = user['auth_token'] plexpy.CONFIG.__setattr__('PMS_TOKEN', token) plexpy.CONFIG.write() logger.info( u"Tautulli PlexTV :: Updated Plex.tv token for Tautulli.") return token
def delete_all_libraries(self): logger.info( u"Tautulli Servers :: %s: Deleting all libraries from database." % self.CONFIG.PMS_NAME) monitor_db = database.MonitorDatabase() query = 'SELECT id FROM library_sections ' \ 'WHERE server_id = ?' result = monitor_db.select(query, [self.CONFIG.ID]) if result: home_library_cards = plexpy.CONFIG.HOME_LIBRARY_CARDS for library_id in result: libID = str(library_id['id']).encode("utf-8").decode("utf-8") if libID in home_library_cards: home_library_cards.remove(libID) plexpy.CONFIG.__setattr__('HOME_LIBRARY_CARDS', home_library_cards) plexpy.CONFIG.write() try: monitor_db.action( 'DELETE FROM ' 'library_sections ' 'WHERE server_id = ?', [self.CONFIG.ID]) return True except Exception as e: logger.warn( u"Tautulli Servers :: %s: Unable to execute database query for delete_all_libraries: %s." % (self.CONFIG.PMS_NAME, e)) return False
def _sendhttp(self, host, command): username = self.username password = self.password url_command = urllib.urlencode(command) url = host + '/xbmcCmds/xbmcHttp/?' + url_command req = urllib2.Request(url) if password: base64string = base64.encodestring( '%s:%s' % (username, password)).replace('\n', '') req.add_header("Authorization", "Basic %s" % base64string) logger.info('Plex url: %s' % url) try: handle = urllib2.urlopen(req) except Exception as e: logger.warn('Error opening Plex url: %s' % e) return response = handle.read().decode(plexpy.SYS_ENCODING) return response
def import_session_history_metadata(import_db, monitor_db, old_server_id, new_server_id, session_history_lookup): logger.info( u"Tautulli Importer :: Importing session_history_metadata table for ServerID: %s" % old_server_id) try: query = 'SELECT * FROM session_history_metadata WHERE server_id = %s' % old_server_id session_history_metadata_result = import_db.execute(query).fetchall() for session_history_metadata in session_history_metadata_result: if session_history_metadata['id'] in session_history_lookup: session_history_metadata['id'] = session_history_lookup[ session_history_metadata['id']] session_history_metadata['server_id'] = new_server_id session_history_metadata[ 'library_id'] = plexpy.libraries.get_section_index( new_server_id, session_history_metadata['section_id']) query = ("INSERT INTO session_history_metadata (" + ", ".join(session_history_metadata.keys()) + ")" + " VALUES (" + ", ".join( ["?"] * len(session_history_metadata.keys())) + ")") monitor_db.action(query, list(session_history_metadata.values())) logger.info(u"Tautulli Importer :: session_history_metadata imported.") except sqlite3.IntegrityError: logger.error(u"Tautulli Import_Tautulli :: Queries failed: %s", query) except Exception as e: raise Exception('Session History Metadata Import failed: %s' % e)
def delete_all_user_history(self, user_id=None): monitor_db = database.MonitorDatabase() if user_id.isdigit(): logger.info(u"PlexPy DataFactory :: Deleting all history for user id %s from database." % user_id) session_history_media_info_del = monitor_db.action( "DELETE FROM " "session_history_media_info " "WHERE session_history_media_info.id IN (SELECT session_history_media_info.id " "FROM session_history_media_info " "JOIN session_history ON session_history_media_info.id = session_history.id " "WHERE session_history.user_id = ?)", [user_id], ) session_history_metadata_del = monitor_db.action( "DELETE FROM " "session_history_metadata " "WHERE session_history_metadata.id IN (SELECT session_history_metadata.id " "FROM session_history_metadata " "JOIN session_history ON session_history_metadata.id = session_history.id " "WHERE session_history.user_id = ?)", [user_id], ) session_history_del = monitor_db.action( "DELETE FROM " "session_history " "WHERE session_history.user_id = ?", [user_id] ) return "Deleted all items for user_id %s." % user_id else: return "Unable to delete items. Input user_id not valid."
def import_library_sections(import_db, monitor_db, old_server_id, new_server_id): logger.info( u"Tautulli Importer :: Importing library_sections table for ServerID: %s" % old_server_id) try: query = 'SELECT * FROM library_sections WHERE server_id = %s' % old_server_id library_sections = import_db.execute(query).fetchall() for library_section in library_sections: old_library_section_id = library_section.pop('id') library_section['server_id'] = new_server_id key_dict = {} key_dict['server_id'] = library_section.pop('server_id') key_dict['section_id'] = library_section.pop('section_id') result = monitor_db.upsert('library_sections', key_dict=key_dict, value_dict=library_section) logger.info(u"Tautulli Importer :: library_sections imported.") except sqlite3.IntegrityError: logger.error(u"Tautulli Import_Tautulli :: Queries failed: %s", query) except Exception as e: raise Exception('Library Sections Import failed: %s' % e)
def notify(self, message, event): if not message or not event: return # Split host and port if self.host == "": host, port = "localhost", 23053 if ":" in self.host: host, port = self.host.split(':', 1) port = int(port) else: host, port = self.host, 23053 # If password is empty, assume none if self.password == "": password = None else: password = self.password # Register notification growl = gntp.notifier.GrowlNotifier( applicationName='PlexPy', notifications=['New Event'], defaultNotifications=['New Event'], hostname=host, port=port, password=password ) try: growl.register() except gntp.notifier.errors.NetworkError: logger.warning(u'Growl notification failed: network error') return except gntp.notifier.errors.AuthError: logger.warning(u'Growl notification failed: authentication error') return # Fix message message = message.encode(plexpy.SYS_ENCODING, "replace") # Send it, including an image image_file = os.path.join(str(plexpy.PROG_DIR), "data/images/plexpylogo.png") with open(image_file, 'rb') as f: image = f.read() try: growl.notify( noteType='New Event', title=event, description=message, icon=image ) except gntp.notifier.errors.NetworkError: logger.warning(u'Growl notification failed: network error') return logger.info(u"Growl notifications sent.")
def refresh_users(): logger.info("Requesting users list refresh...") result = PlexTV().get_full_users_list() monitor_db = database.MonitorDatabase() if len(result) > 0: for item in result: control_value_dict = {"username": item['username']} new_value_dict = { "user_id": item['user_id'], "username": item['username'], "thumb": item['thumb'], "email": item['email'], "is_home_user": item['is_home_user'], "is_allow_sync": item['is_allow_sync'], "is_restricted": item['is_restricted'] } # Check if we've set a custom avatar if so don't overwrite it. if item['user_id']: avatar_urls = monitor_db.select( 'SELECT thumb, custom_avatar_url ' 'FROM users WHERE user_id = ?', [item['user_id']]) if avatar_urls: if not avatar_urls[0]['custom_avatar_url'] or \ avatar_urls[0]['custom_avatar_url'] == avatar_urls[0]['thumb']: new_value_dict['custom_avatar_url'] = item['thumb'] else: new_value_dict['custom_avatar_url'] = item['thumb'] monitor_db.upsert('users', new_value_dict, control_value_dict) logger.info("Users list refreshed.") else: logger.warn("Unable to refresh users list.")
def shutdown(restart=False, update=False): cherrypy.engine.exit() SCHED.shutdown(wait=False) CONFIG.write() if not restart and not update: logger.info('PlexPy is shutting down...') if update: logger.info('PlexPy is updating...') try: versioncheck.update() except Exception as e: logger.warn('PlexPy failed to update: %s. Restarting.', e) if CREATEPID: logger.info('Removing pidfile %s', PIDFILE) os.remove(PIDFILE) if restart: logger.info('PlexPy is restarting...') popen_list = [sys.executable, FULL_PATH] popen_list += ARGS if '--nolaunch' not in popen_list: popen_list += ['--nolaunch'] logger.info('Restarting PlexPy with %s', popen_list) subprocess.Popen(popen_list, cwd=os.getcwd()) os._exit(0)
def notify(self, subject=None, message=None): hosts = [x.strip() for x in self.hosts.split(',')] header = subject message = message time = "3000" # in ms for host in hosts: logger.info('Sending notification command to XMBC @ ' + host) try: version = self._sendjson(host, 'Application.GetProperties', {'properties': ['version']})['version']['major'] if version < 12: #Eden notification = header + "," + message + "," + time notifycommand = {'command': 'ExecBuiltIn', 'parameter': 'Notification(' + notification + ')'} request = self._sendhttp(host, notifycommand) else: #Frodo params = {'title': header, 'message': message, 'displaytime': int(time)} request = self._sendjson(host, 'GUI.ShowNotification', params) if not request: raise Exception except Exception: logger.error('Error sending notification request to XBMC')
def pms_image_proxy(self, img='', width='0', height='0', fallback=None, **kwargs): if img != '': try: pms_connect = pmsconnect.PmsConnect() result = pms_connect.get_image(img, width, height) cherrypy.response.headers['Content-type'] = result[1] return result[0] except: logger.warn('Image proxy queried but errors occured.') if fallback == 'poster': logger.info('Trying fallback image...') try: fallback_image = open( self.interface_dir + common.DEFAULT_POSTER_THUMB, 'rb') cherrypy.response.headers['Content-type'] = 'image/png' return fallback_image except IOError, e: logger.error('Unable to read fallback image. %s' % e) return None
def write(self): """ Make a copy of the stored config and write it to the configured file """ new_config = ConfigObj(encoding="UTF-8") new_config.filename = self._config_file # first copy over everything from the old config, even if it is not # correctly defined to keep from losing data for key, subkeys in self._config.items(): if key not in new_config: new_config[key] = {} for subkey, value in subkeys.items(): new_config[key][subkey] = value # next make sure that everything we expect to have defined is so for key in self._CONFIG_DEFINITIONS.keys(): key, definition_type, section, ini_key, default = self._define(key) self.check_setting(key) if section not in new_config: new_config[section] = {} new_config[section][ini_key] = self._config[section][ini_key] # Write it to file logger.info(u"Tautulli Config :: Writing configuration to file") try: new_config.write() except IOError as e: logger.error( u"Tautulli Config :: Error writing configuration file: %s", e) self._blacklist()
def add_mobile_device(device_id=None, device_name=None, device_token=None, friendly_name=None): db = database.MonitorDatabase() keys = {'device_id': device_id} values = {'device_name': device_name, 'device_token': device_token} if friendly_name: values['friendly_name'] = friendly_name try: result = db.upsert(table_name='mobile_devices', key_dict=keys, value_dict=values) except Exception as e: logger.warn( u"Tautulli MobileApp :: Failed to register mobile device in the database: %s." % e) return if result == 'insert': logger.info( u"Tautulli MobileApp :: Registered mobile device '%s' in the database." % device_name) else: logger.debug( u"Tautulli MobileApp :: Re-registered mobile device '%s' in the database." % device_name) return True
def upsert(self, table_name, value_dict, key_dict): trans_type = 'update' changes_before = self.connection.total_changes gen_params = lambda my_dict: [x + " = ?" for x in my_dict.keys()] update_query = "UPDATE " + table_name + " SET " + ", ".join(gen_params(value_dict)) + \ " WHERE " + " AND ".join(gen_params(key_dict)) self.action(update_query, value_dict.values() + key_dict.values()) if self.connection.total_changes == changes_before: trans_type = 'insert' insert_query = ( "INSERT INTO " + table_name + " (" + ", ".join(value_dict.keys() + key_dict.keys()) + ")" + " VALUES (" + ", ".join(["?"] * len(value_dict.keys() + key_dict.keys())) + ")" ) try: self.action(insert_query, value_dict.values() + key_dict.values()) except sqlite3.IntegrityError: logger.info('Queries failed: %s and %s', update_query, insert_query) # We want to know if it was an update or insert return trans_type
def write(self): if self.ID: key_dict = {'id': self.ID} elif self.PMS_IDENTIFIER: key_dict = {'PMS_IDENTIFIER': self.PMS_IDENTIFIER} else: return values_dict = {} for key in self._CONFIG_DEFINITIONS.keys(): values_dict[key.lower()] = super(ServerConfig, self).__getattr__(key) if 'id' in values_dict: values_dict.pop('id') try: logger.info( "Tautulli ServerConfig :: %s: Writing configuration to database" % self.PMS_NAME) monitor_db = database.MonitorDatabase() result = monitor_db.upsert('servers', key_dict=key_dict, value_dict=values_dict) if result == 'insert': super(ServerConfig, self).__setattr__('ID', monitor_db.last_insert_id()) except Exception as e: logger.error( "Tautulli ServerConfig :: %s: Error writing configuration: %s" % (self.PMS_NAME, e))
def update(self): # From what I read you can't update the music library on a per directory or per path basis # so need to update the whole thing hosts = [x.strip() for x in self.server_hosts.split(',')] for host in hosts: logger.info('Sending library update command to Plex Media Server@ ' + host) url = "%s/library/sections" % host try: xml_sections = minidom.parse(urllib.urlopen(url)) except IOError, e: logger.warn("Error while trying to contact Plex Media Server: %s" % e) return False sections = xml_sections.getElementsByTagName('Directory') if not sections: logger.info(u"Plex Media Server not running on: " + host) return False for s in sections: if s.getAttribute('type') == "artist": url = "%s/library/sections/%s/refresh" % (host, s.getAttribute('key')) try: urllib.urlopen(url) except Exception as e: logger.warn("Error updating library section for Plex Media Server: %s" % e) return False
def delete_all_user_history(self, user_id=None): monitor_db = database.MonitorDatabase() if user_id.isdigit(): logger.info( u"PlexPy DataFactory :: Deleting all history for user id %s from database." % user_id) session_history_media_info_del = \ monitor_db.action('DELETE FROM ' 'session_history_media_info ' 'WHERE session_history_media_info.id IN (SELECT session_history_media_info.id ' 'FROM session_history_media_info ' 'JOIN session_history ON session_history_media_info.id = session_history.id ' 'WHERE session_history.user_id = ?)', [user_id]) session_history_metadata_del = \ monitor_db.action('DELETE FROM ' 'session_history_metadata ' 'WHERE session_history_metadata.id IN (SELECT session_history_metadata.id ' 'FROM session_history_metadata ' 'JOIN session_history ON session_history_metadata.id = session_history.id ' 'WHERE session_history.user_id = ?)', [user_id]) session_history_del = \ monitor_db.action('DELETE FROM ' 'session_history ' 'WHERE session_history.user_id = ?', [user_id]) return 'Deleted all items for user_id %s.' % user_id else: return 'Unable to delete items. Input user_id not valid.'
def notify(self, artist, album, albumartpath): hosts = [x.strip() for x in self.hosts.split(',')] header = "PlexPy" message = "%s - %s added to your library" % (artist, album) time = "3000" # in ms for host in hosts: logger.info('Sending notification command to XMBC @ ' + host) try: version = self._sendjson(host, 'Application.GetProperties', {'properties': ['version']})['version']['major'] if version < 12: #Eden notification = header + "," + message + "," + time + "," + albumartpath notifycommand = {'command': 'ExecBuiltIn', 'parameter': 'Notification(' + notification + ')'} request = self._sendhttp(host, notifycommand) else: #Frodo params = {'title': header, 'message': message, 'displaytime': int(time), 'image': albumartpath} request = self._sendjson(host, 'GUI.ShowNotification', params) if not request: raise Exception except Exception: logger.error('Error sending notification request to XBMC')
def run(): from websocket import create_connection if plexpy.CONFIG.PMS_SSL and plexpy.CONFIG.PMS_URL[:5] == 'https': uri = plexpy.CONFIG.PMS_URL.replace('https://', 'wss://') + '/:/websockets/notifications' secure = ' secure' else: uri = 'ws://%s:%s/:/websockets/notifications' % ( plexpy.CONFIG.PMS_IP, plexpy.CONFIG.PMS_PORT ) secure = '' # Set authentication token (if one is available) if plexpy.CONFIG.PMS_TOKEN: uri += '?X-Plex-Token=' + plexpy.CONFIG.PMS_TOKEN ws_connected = False reconnects = 0 # Try an open the websocket connection - if it fails after 15 retries fallback to polling while not ws_connected and reconnects <= 15: try: logger.info(u'PlexPy WebSocket :: Opening%s websocket, connection attempt %s.' % (secure, str(reconnects + 1))) ws = create_connection(uri) reconnects = 0 ws_connected = True logger.info(u'PlexPy WebSocket :: Ready') except IOError, e: logger.error(u'PlexPy WebSocket :: %s.' % e) reconnects += 1 time.sleep(5)
def import_from_tautulli(import_database=None, import_ignore_interval=0): logger.info(u"Tautulli Importer :: Data import from %s in progress..." % import_database) try: import_db = sqlite3.connect(import_database, timeout=20) import_db.row_factory = database.dict_factory tautulli_db = database.MonitorDatabase() account_list = import_users(import_db, tautulli_db) import_servers(import_db, tautulli_db, import_ignore_interval) notifier_lookup = import_notifiers(import_db, tautulli_db) import_newsletters(import_db, tautulli_db, notifier_lookup) logger.info( u"Tautulli Importer :: Tautulli data import complete successfully." ) import_db.close() for user_id in account_list: account = plexpy.PLEXTV_ACCOUNTS.reinit_account(user_id=user_id) account.refresh_servers() account.refresh_users() plexpy.PMS_SERVERS.update_unowned_servers() except Exception as e: logger.error( u"Tautulli Importer :: Failed to import tautulli database: %s" % e)
def refresh_users(): logger.info(u"PlexPy PlexTV :: Requesting users list refresh...") result = PlexTV().get_full_users_list() monitor_db = database.MonitorDatabase() if len(result) > 0: for item in result: control_value_dict = {"user_id": item['user_id']} new_value_dict = {"username": item['username'], "thumb": item['thumb'], "email": item['email'], "is_home_user": item['is_home_user'], "is_allow_sync": item['is_allow_sync'], "is_restricted": item['is_restricted'] } # Check if we've set a custom avatar if so don't overwrite it. if item['user_id']: avatar_urls = monitor_db.select('SELECT thumb, custom_avatar_url ' 'FROM users WHERE user_id = ?', [item['user_id']]) if avatar_urls: if not avatar_urls[0]['custom_avatar_url'] or \ avatar_urls[0]['custom_avatar_url'] == avatar_urls[0]['thumb']: new_value_dict['custom_avatar_url'] = item['thumb'] else: new_value_dict['custom_avatar_url'] = item['thumb'] monitor_db.upsert('users', new_value_dict, control_value_dict) logger.info(u"PlexPy PlexTV :: Users list refreshed.") else: logger.warn(u"PlexPy PlexTV :: Unable to refresh users list.")
def delete_all_user_history(self, user_id=None): monitor_db = database.MonitorDatabase() if user_id.isdigit(): logger.info(u"PlexPy DataFactory :: Deleting all history for user id %s from database." % user_id) session_history_media_info_del = \ monitor_db.action('DELETE FROM ' 'session_history_media_info ' 'WHERE session_history_media_info.id IN (SELECT session_history_media_info.id ' 'FROM session_history_media_info ' 'JOIN session_history ON session_history_media_info.id = session_history.id ' 'WHERE session_history.user_id = ?)', [user_id]) session_history_metadata_del = \ monitor_db.action('DELETE FROM ' 'session_history_metadata ' 'WHERE session_history_metadata.id IN (SELECT session_history_metadata.id ' 'FROM session_history_metadata ' 'JOIN session_history ON session_history_metadata.id = session_history.id ' 'WHERE session_history.user_id = ?)', [user_id]) session_history_del = \ monitor_db.action('DELETE FROM ' 'session_history ' 'WHERE session_history.user_id = ?', [user_id]) return 'Deleted all items for user_id %s.' % user_id else: return 'Unable to delete items. Input user_id not valid.'
def set_mobile_device_config(mobile_device_id=None, **kwargs): if str(mobile_device_id).isdigit(): mobile_device_id = int(mobile_device_id) else: logger.error( u"Tautulli MobileApp :: Unable to set exisiting mobile device: invalid mobile_device_id %s." % mobile_device_id) return False keys = {'id': mobile_device_id} values = {} if kwargs.get('friendly_name'): values['friendly_name'] = kwargs['friendly_name'] db = database.MonitorDatabase() try: db.upsert(table_name='mobile_devices', key_dict=keys, value_dict=values) logger.info( u"Tautulli MobileApp :: Updated mobile device agent: mobile_device_id %s." % mobile_device_id) return True except Exception as e: logger.warn( u"Tautulli MobileApp :: Unable to update mobile device: %s." % e) return False
def delete_all_history(self, section_id=None): monitor_db = database.MonitorDatabase() try: if section_id.isdigit(): logger.info(u"PlexPy Libraries :: Deleting all history for library id %s from database." % section_id) session_history_media_info_del = \ monitor_db.action('DELETE FROM ' 'session_history_media_info ' 'WHERE session_history_media_info.id IN (SELECT session_history_media_info.id ' 'FROM session_history_media_info ' 'JOIN session_history_metadata ON session_history_media_info.id = session_history_metadata.id ' 'WHERE session_history_metadata.section_id = ?)', [section_id]) session_history_del = \ monitor_db.action('DELETE FROM ' 'session_history ' 'WHERE session_history.id IN (SELECT session_history.id ' 'FROM session_history ' 'JOIN session_history_metadata ON session_history.id = session_history_metadata.id ' 'WHERE session_history_metadata.section_id = ?)', [section_id]) session_history_metadata_del = \ monitor_db.action('DELETE FROM ' 'session_history_metadata ' 'WHERE session_history_metadata.section_id = ?', [section_id]) return 'Deleted all items for section_id %s.' % section_id else: return 'Unable to delete items, section_id not valid.' except Exception as e: logger.warn(u"PlexPy Libraries :: Unable to execute database query for delete_all_history: %s." % e)
def toggleVerbose(self): plexpy.VERBOSE = not plexpy.VERBOSE logger.initLogger(console=not plexpy.QUIET, log_dir=plexpy.CONFIG.LOG_DIR, verbose=plexpy.VERBOSE) logger.info("Verbose toggled, set to %s", plexpy.VERBOSE) logger.debug("If you read this message, debug logging is available") raise cherrypy.HTTPRedirect("logs")
def initialize_scheduler(): """ Start the scheduled background tasks. Re-schedule if interval settings changed. """ with SCHED_LOCK: # Check if scheduler should be started start_jobs = not len(SCHED.get_jobs()) #Update check if CONFIG.CHECK_GITHUB_INTERVAL: minutes = CONFIG.CHECK_GITHUB_INTERVAL else: minutes = 0 schedule_job(versioncheck.checkGithub, 'Check GitHub for updates', hours=0, minutes=minutes) # Start scheduler if start_jobs and len(SCHED.get_jobs()): try: SCHED.start() except Exception as e: logger.info(e)
def get_server_urls(self, include_https=True): if plexpy.CONFIG.PMS_IDENTIFIER: server_id = plexpy.CONFIG.PMS_IDENTIFIER else: logger.error(u"PlexPy PlexTV :: Unable to retrieve server identity.") return [] plextv_resources = self.get_plextv_resources(include_https=include_https) server_urls = [] try: xml_parse = minidom.parseString(plextv_resources) except Exception as e: logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_server_urls: %s" % e) return [] except: logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_server_urls.") return [] try: xml_head = xml_parse.getElementsByTagName('Device') except Exception as e: logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_server_urls: %s." % e) return [] for a in xml_head: if helpers.get_xml_attr(a, 'clientIdentifier') == server_id: connections = a.getElementsByTagName('Connection') for connection in connections: server_details = {"protocol": helpers.get_xml_attr(connection, 'protocol'), "address": helpers.get_xml_attr(connection, 'address'), "port": helpers.get_xml_attr(connection, 'port'), "uri": helpers.get_xml_attr(connection, 'uri'), "local": helpers.get_xml_attr(connection, 'local') } server_urls.append(server_details) # Else try to match the PMS_IP and PMS_PORT else: connections = a.getElementsByTagName('Connection') for connection in connections: if helpers.get_xml_attr(connection, 'address') == plexpy.CONFIG.PMS_IP and \ int(helpers.get_xml_attr(connection, 'port')) == plexpy.CONFIG.PMS_PORT: plexpy.CONFIG.PMS_IDENTIFIER = helpers.get_xml_attr(a, 'clientIdentifier') logger.info(u"PlexPy PlexTV :: PMS identifier changed from %s to %s." % \ (server_id, plexpy.CONFIG.PMS_IDENTIFIER)) server_details = {"protocol": helpers.get_xml_attr(connection, 'protocol'), "address": helpers.get_xml_attr(connection, 'address'), "port": helpers.get_xml_attr(connection, 'port'), "uri": helpers.get_xml_attr(connection, 'uri'), "local": helpers.get_xml_attr(connection, 'local') } break return server_urls
def initialize_scheduler(): """ Start the scheduled background tasks. Re-schedule if interval settings changed. """ with SCHED_LOCK: # Check if scheduler should be started start_jobs = not len(SCHED.get_jobs()) # Update check if CONFIG.CHECK_GITHUB_INTERVAL and CONFIG.CHECK_GITHUB: minutes = CONFIG.CHECK_GITHUB_INTERVAL else: minutes = 0 schedule_job(versioncheck.checkGithub, 'Check GitHub for updates', hours=0, minutes=minutes) # Start checking for new sessions at set interval if CONFIG.MONITORING_INTERVAL: # Our interval should never be less than 30 seconds if CONFIG.MONITORING_INTERVAL > 30: seconds = CONFIG.MONITORING_INTERVAL else: seconds = 30 else: seconds = 0 if CONFIG.PMS_IP and CONFIG.PMS_TOKEN: schedule_job(plextv.get_real_pms_url, 'Refresh Plex Server URLs', hours=12, minutes=0, seconds=0) schedule_job(pmsconnect.get_server_friendly_name, 'Refresh Plex Server Name', hours=12, minutes=0, seconds=0) schedule_job(activity_pinger.check_recently_added, 'Check for recently added items', hours=0, minutes=0, seconds=seconds) schedule_job(activity_pinger.check_server_response, 'Check for server response', hours=0, minutes=0, seconds=seconds) # If we're not using websockets then fall back to polling if not CONFIG.MONITORING_USE_WEBSOCKET or POLLING_FAILOVER: schedule_job(activity_pinger.check_active_sessions, 'Check for active sessions', hours=0, minutes=0, seconds=seconds) # Refresh the users list if CONFIG.REFRESH_USERS_INTERVAL: hours = CONFIG.REFRESH_USERS_INTERVAL else: hours = 0 if CONFIG.PMS_TOKEN: schedule_job(plextv.refresh_users, 'Refresh users list', hours=hours, minutes=0, seconds=0) # Start scheduler if start_jobs and len(SCHED.get_jobs()): try: SCHED.start() except Exception as e: logger.info(e)
def twitterStep2(self, key): cherrypy.response.headers["Cache-Control"] = "max-age=0,no-cache,no-store" tweet = notifiers.TwitterNotifier() result = tweet._get_credentials(key) logger.info(u"result: " + str(result)) if result: return "Key verification successful" else: return "Unable to verify key"
def update(self): hosts = [x.strip() for x in self.hosts.split(',')] for host in hosts: logger.info('Sending library rescan command to LMS @ ' + host) request = self._sendjson(host) if request: logger.warn('Error sending rescan request to LMS')
def configUpdate(self, **kwargs): # Handle the variable config options. Note - keys with False values aren't getting passed checked_configs = [ "launch_browser", "enable_https", "api_enabled", "freeze_db", "growl_enabled", "prowl_enabled", "xbmc_enabled", "lms_enabled", "plex_enabled", "nma_enabled", "pushalot_enabled", "synoindex_enabled", "pushover_enabled", "pushbullet_enabled", "subsonic_enabled", "twitter_enabled", "osx_notify_enabled", "boxcar_enabled", "mpc_enabled", "email_enabled", "email_tls", "grouping_global_history", "grouping_user_history", "grouping_charts" ] for checked_config in checked_configs: if checked_config not in kwargs: # checked items should be zero or one. if they were not sent then the item was not checked kwargs[checked_config] = 0 # Write Plex token to the config if (not plexpy.CONFIG.PMS_TOKEN or plexpy.CONFIG.PMS_TOKEN == '' \ or kwargs['pms_username'] != plexpy.CONFIG.PMS_USERNAME) \ and (kwargs['pms_username'] != '' or kwargs['pms_password'] != ''): plex_tv = plextv.PlexTV(kwargs['pms_username'], kwargs['pms_password']) token = plex_tv.get_token() if token: kwargs['pms_token'] = token logger.info('Plex.tv token sucessfully written to config.') else: logger.warn('Unable to write Plex.tv token to config.') # Clear Plex token if username or password set to blank if kwargs['pms_username'] == '' or kwargs['pms_password'] == '': kwargs['pms_token'] = '' # If passwords exists in config, do not overwrite when blank value received if kwargs['http_password'] == ' ' and plexpy.CONFIG.HTTP_PASSWORD != '': kwargs['http_password'] = plexpy.CONFIG.HTTP_PASSWORD if kwargs['pms_password'] == ' ' and plexpy.CONFIG.PMS_PASSWORD != '': kwargs['pms_password'] = plexpy.CONFIG.PMS_PASSWORD for plain_config, use_config in [(x[4:], x) for x in kwargs if x.startswith('use_')]: # the use prefix is fairly nice in the html, but does not match the actual config kwargs[plain_config] = kwargs[use_config] del kwargs[use_config] plexpy.CONFIG.process_kwargs(kwargs) # Write the config plexpy.CONFIG.write() # Reconfigure scheduler plexpy.initialize_scheduler() raise cherrypy.HTTPRedirect("config")
def update(self): # From what I read you can't update the music library on a per directory or per path basis # so need to update the whole thing hosts = [x.strip() for x in self.hosts.split(',')] for host in hosts: logger.info('Sending library update command to XBMC @ ' + host) request = self._sendjson(host, 'AudioLibrary.Scan') if not request: logger.warn('Error sending update request to XBMC')
def osxnotifyregister(self, app): cherrypy.response.headers["Cache-Control"] = "max-age=0,no-cache,no-store" from osxnotify import registerapp as osxnotify result, msg = osxnotify.registerapp(app) if result: osx_notify = notifiers.OSX_NOTIFY() osx_notify.notify("Registered", result, "Success :-)") logger.info("Registered %s, to re-register a different app, delete this app first" % result) else: logger.warn(msg) return msg
def check_server_updates(): with monitor_lock: logger.info(u"PlexPy Monitor :: Checking for PMS updates...") pms_connect = pmsconnect.PmsConnect() server_identity = pms_connect.get_server_identity() update_status = pms_connect.get_update_staus() if server_identity and update_status: version = server_identity['version'] logger.info(u"PlexPy Monitor :: Current PMS version: %s", version) if update_status['state'] == 'available': update_version = update_status['version'] logger.info(u"PlexPy Monitor :: PMS update available version: %s", update_version) # Check if any notification agents have notifications enabled if any(d['on_pmsupdate'] for d in notifiers.available_notification_agents()): # Fire off notifications threading.Thread(target=notification_handler.notify_timeline, kwargs=dict(notify_action='pmsupdate')).start() else: logger.info(u"PlexPy Monitor :: No PMS update available.")
def delete_session_history_rows(self, row_id=None): monitor_db = database.MonitorDatabase() if row_id.isdigit(): logger.info(u"PlexPy DataFactory :: Deleting row id %s from the session history database." % row_id) session_history_del = \ monitor_db.action('DELETE FROM session_history WHERE id = ?', [row_id]) session_history_media_info_del = \ monitor_db.action('DELETE FROM session_history_media_info WHERE id = ?', [row_id]) session_history_metadata_del = \ monitor_db.action('DELETE FROM session_history_metadata WHERE id = ?', [row_id]) return 'Deleted rows %s.' % row_id else: return 'Unable to delete rows. Input row not valid.'
def initialize_scheduler(): """ Start the scheduled background tasks. Re-schedule if interval settings changed. """ with SCHED_LOCK: # Check if scheduler should be started start_jobs = not len(SCHED.get_jobs()) # Update check if CONFIG.CHECK_GITHUB_INTERVAL and CONFIG.CHECK_GITHUB: minutes = CONFIG.CHECK_GITHUB_INTERVAL else: minutes = 0 schedule_job(versioncheck.checkGithub, 'Check GitHub for updates', hours=0, minutes=minutes) # Start checking for new sessions at set interval if CONFIG.MONITORING_INTERVAL: # Our interval should never be less than 30 seconds if CONFIG.MONITORING_INTERVAL > 30: seconds = CONFIG.MONITORING_INTERVAL else: seconds = 30 else: seconds = 0 if CONFIG.PMS_IP and CONFIG.PMS_TOKEN: schedule_job(plextv.get_real_pms_url, 'Refresh Plex Server URLs', hours=12, minutes=0, seconds=0) schedule_job(monitor.check_active_sessions, 'Check for active sessions', hours=0, minutes=0, seconds=seconds) # Refresh the users list if CONFIG.REFRESH_USERS_INTERVAL: hours = CONFIG.REFRESH_USERS_INTERVAL else: hours = 0 if CONFIG.PMS_TOKEN: schedule_job(plextv.refresh_users, 'Refresh users list', hours=hours, minutes=0, seconds=0) # Start scheduler if start_jobs and len(SCHED.get_jobs()): try: SCHED.start() except Exception as e: logger.info(e)
def delete(self, user_id=None): monitor_db = database.MonitorDatabase() try: if str(user_id).isdigit(): self.delete_all_history(user_id) logger.info(u"PlexPy DataFactory :: Deleting user with id %s from database." % user_id) monitor_db.action('UPDATE users SET deleted_user = 1 WHERE user_id = ?', [user_id]) monitor_db.action('UPDATE users SET keep_history = 0 WHERE user_id = ?', [user_id]) monitor_db.action('UPDATE users SET do_notify = 0 WHERE user_id = ?', [user_id]) return 'Deleted user with id %s.' % user_id else: return 'Unable to delete user, user_id not valid.' except Exception as e: logger.warn(u"PlexPy Users :: Unable to execute database query for delete: %s." % e)
def _send_tweet(self, message=None): username = self.consumer_key password = self.consumer_secret access_token_key = plexpy.CONFIG.TWITTER_USERNAME access_token_secret = plexpy.CONFIG.TWITTER_PASSWORD logger.info(u"Sending tweet: " + message) api = twitter.Api(username, password, access_token_key, access_token_secret) try: api.PostUpdate(message) except Exception as e: logger.info(u"Error Sending Tweet: %s" % e) return False return True
def _get_authorization(self): oauth_consumer = oauth.Consumer(key=self.consumer_key, secret=self.consumer_secret) oauth_client = oauth.Client(oauth_consumer) logger.info('Requesting temp token from Twitter') resp, content = oauth_client.request(self.REQUEST_TOKEN_URL, 'GET') if resp['status'] != '200': logger.info('Invalid respond from Twitter requesting temp token: %s' % resp['status']) else: request_token = dict(parse_qsl(content)) plexpy.CONFIG.TWITTER_USERNAME = request_token['oauth_token'] plexpy.CONFIG.TWITTER_PASSWORD = request_token['oauth_token_secret'] return self.AUTHORIZATION_URL + "?oauth_token=" + request_token['oauth_token']