mirror of
https://github.com/pkkid/python-plexapi
synced 2024-11-22 11:43:13 +00:00
Update fetchItem to search all subitems as well
This commit is contained in:
parent
08e61960e7
commit
ebf18ba020
2 changed files with 73 additions and 44 deletions
|
@ -169,40 +169,58 @@ class PlexObject(object):
|
|||
return self
|
||||
|
||||
def _checkAttrs(self, elem, **kwargs):
|
||||
for kwarg, query in kwargs.items():
|
||||
# strip underscore from special cased attrs
|
||||
if kwarg in ('_key', '_cls', '_tag'):
|
||||
kwarg = kwarg[1:]
|
||||
# extract the kwarg operator if present
|
||||
op, operator = 'exact', OPERATORS['exact']
|
||||
if '__' in kwarg:
|
||||
kwarg, op = kwarg.rsplit('__', 1)
|
||||
if op not in OPERATORS:
|
||||
raise BadRequest('Invalid filter operator: __%s' % op)
|
||||
operator = OPERATORS[op]
|
||||
# get value from elem and check ismissing operator
|
||||
value = elem.attrib.get(kwarg)
|
||||
log.debug("Checking %s.%s__%s=%s (value=%s)", elem.tag, kwarg, op,
|
||||
str(query)[:20], str(value)[:20])
|
||||
logme = elem.attrib.get('ratingKey') == '746'
|
||||
attrsFound = {}
|
||||
for attr, query in kwargs.items():
|
||||
attr, op, operator = self._getAttrOperator(attr)
|
||||
values = self._getAttrValue(elem, attr)
|
||||
if logme: log.debug('Check %s.%s__%s=%s (value=%s)', elem.tag, attr, op, str(query)[:20], str(values)[:20])
|
||||
# special case ismissing operator
|
||||
if op == 'ismissing':
|
||||
if query not in (True, False):
|
||||
raise BadRequest('Value when using __ismissing must be in (True, False).')
|
||||
if (query is True and value) or (query is False and not value):
|
||||
if (query is True and values) or (query is False and not values):
|
||||
return False
|
||||
# special case query=None,0,'' to include missing attr
|
||||
if op == 'exact' and query in (None, 0, '') and value is None:
|
||||
# special case query in (None,0,'') to include missing attr
|
||||
if op == 'exact' and query in (None, 0, '') and not values:
|
||||
return True
|
||||
# return if attr were looking for is missing
|
||||
if not value:
|
||||
return False
|
||||
# cast value to the same type as query
|
||||
if isinstance(query, int): value = int(value)
|
||||
if isinstance(query, float): value = float(value)
|
||||
if isinstance(query, bool): value = bool(int(value))
|
||||
# perform the comparison
|
||||
if not operator(value, query):
|
||||
return False
|
||||
return True
|
||||
attrsFound[attr] = False
|
||||
for value in values:
|
||||
if isinstance(query, int): value = int(value)
|
||||
if isinstance(query, float): value = float(value)
|
||||
if isinstance(query, bool): value = bool(int(value))
|
||||
if logme: log.info('%s %s %s', value, op, query)
|
||||
if operator(value, query):
|
||||
attrsFound[attr] = True
|
||||
break
|
||||
if logme: log.info(attrsFound)
|
||||
return all(attrsFound.values())
|
||||
|
||||
def _getAttrOperator(self, attr):
|
||||
attr = attr.lstrip('_')
|
||||
for op, operator in OPERATORS.items():
|
||||
if attr.endswith('__%s' % op):
|
||||
attr = attr.rsplit('__', 1)[0]
|
||||
return attr, op, operator
|
||||
# default to exact match
|
||||
return attr, 'exact', OPERATORS['exact']
|
||||
|
||||
def _getAttrValue(self, elem, attrstr, results=None):
|
||||
#log.debug('Fetching %s in %s', attrstr, elem.tag)
|
||||
parts = attrstr.split('__', 1)
|
||||
attr = parts[0]
|
||||
attrstr = parts[1] if len(parts) == 2 else None
|
||||
if attrstr:
|
||||
results = [] if results is None else results
|
||||
for child in [c for c in elem if c.tag.lower() == attr.lower()]:
|
||||
results += self._getAttrValue(child, attrstr, results)
|
||||
return [r for r in results if r is not None]
|
||||
# loop through attrs so we can perform case-insensative match
|
||||
for _attr, value in elem.attrib.items():
|
||||
if attr.lower() == _attr.lower():
|
||||
return [value]
|
||||
return []
|
||||
|
||||
def _loadData(self, data):
|
||||
raise NotImplementedError('Abstract method not implemented.')
|
||||
|
|
|
@ -173,7 +173,7 @@ class PlexAttributes():
|
|||
self._load_attrs(playqueue, 'pq')
|
||||
|
||||
def _parse_sync(self):
|
||||
# TODO: Get this working..
|
||||
# TODO: Get plexattrs._parse_sync() working.
|
||||
pass
|
||||
|
||||
def _load_attrs(self, obj, cat=None):
|
||||
|
@ -229,29 +229,39 @@ class PlexAttributes():
|
|||
def print_report(self):
|
||||
total_attrs = 0
|
||||
for clsname in sorted(self.attrs.keys()):
|
||||
meta = self.attrs[clsname]
|
||||
count = meta['total']
|
||||
print(_('\n%s (%s)\n%s' % (clsname, count, '-'*30), 'yellow'))
|
||||
attrs = sorted(set(list(meta['xml'].keys()) + list(meta['obj'].keys())))
|
||||
for attr in attrs:
|
||||
state = self._attr_state(clsname, attr, meta)
|
||||
count = meta['xml'].get(attr, 0)
|
||||
categories = ','.join(meta['categories'].get(attr, ['--']))
|
||||
examples = '; '.join(list(meta['examples'].get(attr, ['--']))[:3])[:80]
|
||||
print('%7s %3s %-30s %-20s %s' % (count, state, attr, categories, examples))
|
||||
total_attrs += count
|
||||
if self._clsname_match(clsname):
|
||||
meta = self.attrs[clsname]
|
||||
count = meta['total']
|
||||
print(_('\n%s (%s)\n%s' % (clsname, count, '-'*30), 'yellow'))
|
||||
attrs = sorted(set(list(meta['xml'].keys()) + list(meta['obj'].keys())))
|
||||
for attr in attrs:
|
||||
state = self._attr_state(clsname, attr, meta)
|
||||
count = meta['xml'].get(attr, 0)
|
||||
categories = ','.join(meta['categories'].get(attr, ['--']))
|
||||
examples = '; '.join(list(meta['examples'].get(attr, ['--']))[:3])[:80]
|
||||
print('%7s %3s %-30s %-20s %s' % (count, state, attr, categories, examples))
|
||||
total_attrs += count
|
||||
print(_('\nSUMMARY\n%s' % ('-'*30), 'yellow'))
|
||||
print('%7s %3s %3s %-20s %s' % ('total', 'new', 'old', 'categories', 'clsname'))
|
||||
for clsname in sorted(self.attrs.keys()):
|
||||
print('%7s %12s %12s %s' % (self.attrs[clsname]['total'],
|
||||
_(self.attrs[clsname]['new'] or '', 'cyan'),
|
||||
_(self.attrs[clsname]['old'] or '', 'red'),
|
||||
clsname))
|
||||
if self._clsname_match(clsname):
|
||||
print('%7s %12s %12s %s' % (self.attrs[clsname]['total'],
|
||||
_(self.attrs[clsname]['new'] or '', 'cyan'),
|
||||
_(self.attrs[clsname]['old'] or '', 'red'),
|
||||
clsname))
|
||||
print('\nPlex Version %s' % self.plex.version)
|
||||
print('PlexAPI Version %s' % plexapi.VERSION)
|
||||
print('Total Objects %s' % sum([x['total'] for x in self.attrs.values()]))
|
||||
print('Runtime %s min\n' % self.runtime)
|
||||
|
||||
def _clsname_match(self, clsname):
|
||||
if not self.clsnames:
|
||||
return True
|
||||
for cname in self.clsnames:
|
||||
if cname.lower() in clsname.lower():
|
||||
return True
|
||||
return False
|
||||
|
||||
def _attr_state(self, clsname, attr, meta):
|
||||
if attr in meta['xml'].keys() and attr not in meta['obj'].keys():
|
||||
self.attrs[clsname]['new'] += 1
|
||||
|
@ -280,6 +290,7 @@ if __name__ == '__main__':
|
|||
if not opts.force and os.path.exists(CACHEPATH):
|
||||
with open(CACHEPATH, 'rb') as handle:
|
||||
plexattrs = pickle.load(handle)
|
||||
plexattrs.clsnames = [c for c in opts.clsnames.split(',') if c]
|
||||
if not plexattrs:
|
||||
plexattrs = PlexAttributes(opts).run()
|
||||
with open(CACHEPATH, 'wb') as handle:
|
||||
|
|
Loading…
Reference in a new issue