__init__.py
DOCSTING COMES HERE
ListView (PaginatedContent)
¶
Content Agnostic Numbered List
This class, using ListViewItems as abstractions you can give it a list of data and which columns to show and it will show it.
Todo
Currently we rely on the commands/play code to send information about which elements are being picked.
Column format: {"name": "idx", "size": 3, "heading": "Num"} name: The method name that will be called from the ListViewItem !!! size "How much size is allocated to the columns," see ListView.content for more information about the dynamic options heading: The text shown in the header
"idx" is generated in the content function, not by the ListViewItem
Source code in mps_youtube/listview/__init__.py
class ListView(content.PaginatedContent):
""" Content Agnostic Numbered List
This class, using ListViewItems as abstractions you can
give it a list of data and which columns to show and it will
show it.
Todo:
Currently we rely on the commands/play code to send information
about which elements are being picked.
Attributes:
func The function that will be run on the selected items
objects List of objects(or a ContentQuery object)
columns A list of Hashes containing information about which
columns to show
page Current Page
Column format:
{"name": "idx", "size": 3, "heading": "Num"}
name: The method name that will be called from the ListViewItem
size: How much size is allocated to the columns,
see ListView.content for more information about
the dynamic options
heading: The text shown in the header
"idx" is generated in the content function, not by the ListViewItem
"""
func = None
objects = None
columns = None
page = 0
def __init__(self, columns, objects, function_call=None):
""" """
self.func = function_call
self.objects = objects
self.columns = columns
self.object_type = None
# Ensure single type of object
types = len(set([obj.__class__ for obj in objects]))
if types == 0:
raise BaseException("No objects in list")
if types > 1:
raise BaseException("More than one kind of objects in list")
self.object_type = [obj.__class__ for obj in objects][0]
def numPages(self):
""" Returns # of pages """
return max(1, math.ceil(len(self.objects) / self.views_per_page()))
def getPage(self, page):
self.page = page
return self.content()
def _page_slice(self):
chgt = self.views_per_page()
return slice(self.page * chgt, (self.page+1) * chgt)
def content(self):
""" Generates content
===============
Dynamic fields
===============
Column.size may instead of an integer be a string
containing either "length" or "remaining".
Length is for time formats like 20:40
Remaining will allocate all remaining space to that
column.
TODO: Make it so set columns can set "remaining" ?
"""
# Sums all ints, deal with strings later
remaining = (util.getxy().width) - sum(1 + (x['size'] if x['size'] and x['size'].__class__ == int else 0) for x in self.columns) - (len(self.columns))
lengthsize = 0
if "length" in [x['size'] for x in self.columns]:
max_l = max((getattr(x, "length")() for x in self.objects))
lengthsize = 8 if max_l > 35999 else 7
lengthsize = 6 if max_l < 6000 else lengthsize
for col in self.columns:
if col['size'] == "remaining":
col['size'] = remaining - lengthsize
if col['size'] == "length":
col['size'] = lengthsize
for num, column in enumerate(self.columns):
column['idx'] = num
column['sign'] = "-" if not column['name'] == "length" else ""
fmt = ["%{}{}s ".format(x['sign'], x['size']) for x in self.columns]
fmtrow = fmt[0:1] + ["%s "] + fmt[2:]
fmt, fmtrow = "".join(fmt).strip(), "".join(fmtrow).strip()
titles = tuple([x['heading'][:x['size']] for x in self.columns])
out = "\n" + (c.ul + fmt % titles + c.w) + "\n"
for num, obj in enumerate(self.objects[self._page_slice()]):
col = (c.r if num % 2 == 0 else c.p)
idx = num + (self.views_per_page() * self.page) + 1
line = ''
for column in self.columns:
fieldsize, field = column['size'], column['name']
direction = "<" if column['sign'] == "-" else ">"
if field == "idx":
field = "%2d" % idx
else:
field = getattr(obj, field)(fieldsize)
field = str(field) if field.__class__ != str else field
line += util.uea_pad(fieldsize, field, direction)
if column != self.columns[-1]:
line += " "
line = col + line + c.w
out += line + "\n"
return out
def _play(self, _, choice, __): # pre, choice, post
""" Handles what happends when a user selects something from the list
Currently this functions hooks into commands/play
"""
uids = []
for splitted_choice in choice.split(","):
cho = splitted_choice.strip()
if cho.isdigit():
uids.append(int(cho) - 1)
else:
cho = cho.split("-")
if cho[0].isdigit() and cho[1].isdigit():
uids += list(range(int(cho[0]) - 1, int(cho[1])))
var = getattr(self.object_type, "return_field")()
self.func([getattr(self.objects[x], var)() for x in uids])
def views_per_page(self):
""" Determines how many views can be per page
"""
return util.getxy().max_results
content(self)
¶
Generates content
=============== Dynamic fields ===============
Column.size may instead of an integer be a string containing either "length" or "remaining".
Length is for time formats like 20:40 Remaining will allocate all remaining space to that column.
TODO: Make it so set columns can set "remaining" ?
Source code in mps_youtube/listview/__init__.py
def content(self):
""" Generates content
===============
Dynamic fields
===============
Column.size may instead of an integer be a string
containing either "length" or "remaining".
Length is for time formats like 20:40
Remaining will allocate all remaining space to that
column.
TODO: Make it so set columns can set "remaining" ?
"""
# Sums all ints, deal with strings later
remaining = (util.getxy().width) - sum(1 + (x['size'] if x['size'] and x['size'].__class__ == int else 0) for x in self.columns) - (len(self.columns))
lengthsize = 0
if "length" in [x['size'] for x in self.columns]:
max_l = max((getattr(x, "length")() for x in self.objects))
lengthsize = 8 if max_l > 35999 else 7
lengthsize = 6 if max_l < 6000 else lengthsize
for col in self.columns:
if col['size'] == "remaining":
col['size'] = remaining - lengthsize
if col['size'] == "length":
col['size'] = lengthsize
for num, column in enumerate(self.columns):
column['idx'] = num
column['sign'] = "-" if not column['name'] == "length" else ""
fmt = ["%{}{}s ".format(x['sign'], x['size']) for x in self.columns]
fmtrow = fmt[0:1] + ["%s "] + fmt[2:]
fmt, fmtrow = "".join(fmt).strip(), "".join(fmtrow).strip()
titles = tuple([x['heading'][:x['size']] for x in self.columns])
out = "\n" + (c.ul + fmt % titles + c.w) + "\n"
for num, obj in enumerate(self.objects[self._page_slice()]):
col = (c.r if num % 2 == 0 else c.p)
idx = num + (self.views_per_page() * self.page) + 1
line = ''
for column in self.columns:
fieldsize, field = column['size'], column['name']
direction = "<" if column['sign'] == "-" else ">"
if field == "idx":
field = "%2d" % idx
else:
field = getattr(obj, field)(fieldsize)
field = str(field) if field.__class__ != str else field
line += util.uea_pad(fieldsize, field, direction)
if column != self.columns[-1]:
line += " "
line = col + line + c.w
out += line + "\n"
return out
numPages(self)
¶
Returns # of pages
Source code in mps_youtube/listview/__init__.py
def numPages(self):
""" Returns # of pages """
return max(1, math.ceil(len(self.objects) / self.views_per_page()))
views_per_page(self)
¶
Determines how many views can be per page
Source code in mps_youtube/listview/__init__.py
def views_per_page(self):
""" Determines how many views can be per page
"""
return util.getxy().max_results