def __init__(self, data=None): signalsmixin.SignalsMixin.__init__(self) plexresource.PlexResource.__init__(self, data) self.accessToken = None self.multiuser = False self.isSupported = None self.hasFallback = False self.supportsAudioTranscoding = False self.supportsVideoTranscoding = False self.supportsPhotoTranscoding = False self.supportsVideoRemuxOnly = False self.supportsScrobble = True self.allowsMediaDeletion = False self.allowChannelAccess = False self.activeConnection = None self.serverClass = None self.pendingReachabilityRequests = 0 self.pendingSecureRequests = 0 self.features = {} self.librariesByUuid = {} self.server = self self.session = http.Session() self.owner = None self.owned = False self.synced = False self.sameNetwork = False self.uuid = None self.name = None self.platform = None self.versionNorm = None self.rawVersion = None self.transcodeSupport = False if data is None: return self.owner = data.attrib.get('sourceTitle') self.owned = data.attrib.get('owned') == '1' self.synced = data.attrib.get('synced') == '1' self.sameNetwork = data.attrib.get('publicAddressMatches') == '1' self.uuid = data.attrib.get('clientIdentifier') self.name = data.attrib.get('name') self.platform = data.attrib.get('platform') self.rawVersion = data.attrib.get('productVersion') self.versionNorm = util.normalizedVersion(self.rawVersion) self.transcodeSupport = data.attrib.get('transcodeSupport') == '1'
def identify(config, target, cms, ratio=0.95, diff404=None, summary=False): base_url = target.rstrip('/') if not base_url.startswith('http'): base_url = 'http://{}'.format(base_url) dbh = dbhandler.Handler(db=config.db) sess = http.Session() tags = dbh.tags(cms=cms) total = len(tags) requests = 0 prev_response_tags = [] rand_str = lambda: ''.join([ random.choice(string.letters) for _ in xrange(random.randrange(8, 17)) ]) not_found = sess.get(base_url + '/' + (diff404 or rand_str()), verify=False) not_found_code = not_found.status_code not_found_data = not_found.content not_found_ratio = lambda _: diff.Diff(not_found_data, _).ratio() response_tags = None offset = 0 while True: id = dbh.query_next(cms=cms, tags=tags, offset=offset) logging.debug('requesting {}'.format(id.url)) response = sess.get(base_url + id.url) requests += 1 code = response.status_code data = response.content url = response.url file = id.url whitespace = string.whitespace.replace(' ', '') printable = lambda data: ''.join( [_ for _ in data if _ not in whitespace]) logging.debug('response: {} {}'.format(code, printable(data)[:66])) if code in [500, 502, 503]: logging.critical('server down') break elif code == 404 or (code == not_found_code and not_found_ratio(data) >= ratio): logging.warning('{} not found {}'.format(code, url)) response_tags = dbh.tags_via_url(cms=cms, url=file) tags = list(set(tags).difference(response_tags)) elif code == 200: response_hash = hash.hash(response.content) logging.debug('{} {}'.format(url, response_hash)) response_tags = dbh.tags_via_hash(cms=cms, hash=response_hash) tags = list(set(tags).intersection(response_tags)) elif code == 403: logging.warning('{} access denied {}'.format(code, url)) offset += 1 else: logging.critical('unrecognized http status code {}'.format(code)) break if code != 403: offset = 0 if prev_response_tags == response_tags: logging.info('duplicates detected') for tag in tags: logging.info('{}'.format(tag)) break prev_response_tags = response_tags if len(tags) == 1: logging.info('match {}'.format(tags[0])) break if summary: logging.info('{} cms versions exist'.format(total)) logging.info('{} cms versions detected'.format(len(tags))) logging.info('{} requests sent'.format(requests))