Improve metadata display

This commit is contained in:
Ellwood Zwovic
2017-07-22 18:44:44 -07:00
parent c2f17de704
commit 6752108930
2 changed files with 193 additions and 104 deletions

View File

@@ -14,12 +14,13 @@ bl_info = {
}
import logging
log = logging.getLogger(__name__)
if 'bpy' in locals():
import importlib
log.debug("Reloading")
subproc = importlib.reload(subproc)
bpkg = importlib.reload(bpkg)
Package = bpkg.Package
else:
@@ -30,6 +31,32 @@ else:
import bpy
from collections import OrderedDict
class ConsolidatedPackage:
"""
Stores a grouping of different versions of the same package
"""
log = logging.getLogger(__name__ + ".ConsolidatedPackage")
def __init__(self, pkg=None):
self.versions = []
self.expanded = False
self.installed = False
if pkg is not None:
self.add_version(pkg)
def get_latest_version(self) -> bpkg.Package:
"""Get package with highest version number"""
return self.versions[0] # this is always sorted with the highest on top
def add_version(self, pkg: Package):
self.versions.append(pkg)
self.versions.sort(key=lambda v: v.version, reverse=True)
def __iter__(self):
return (pkg for pkg in self.versions)
class SubprocMixin:
"""Mix-in class for things that need to be run in a subprocess."""
@@ -565,97 +592,72 @@ class USERPREF_PT_packages(bpy.types.Panel):
return startswith + contains
def draw_package(pkg: ConsolidatedPackage, layout: bpy.types.UILayout):# {{{
def draw_package(metapkg: ConsolidatedPackage, layout: bpy.types.UILayout):# {{{
"""Draws the given package"""
pkgbox = layout.box()
spl = pkgbox.split(.8)
left = spl.row(align=True)
blinfo = pkg.versions[0].bl_info
# for install/uninstall buttons
right = spl.row()
right.alignment = 'RIGHT'
right.scale_y = 1.5
# for collapse/expand button
left.operator(
WM_OT_package_toggle_expand.bl_idname,
icon='TRIA_DOWN' if pkg.expanded else 'TRIA_RIGHT',
emboss=False,
).package_name=blinfo['name']
# for metadata
leftcol = left.column(align=True)
def collapsed():
"""Draw collapsed version of package layout"""
lr1 = leftcol.row()
lr2 = leftcol.row()
lr1.label(text=blinfo.get('name', ""))
lr2.label(text=blinfo.get('description', ""))
lr2.enabled = False #Give name more visual weight
if pkg.name:
lr1.label(text=pkg.name)
if pkg.description:
lr2.label(text=pkg.description)
lr2.enabled = False #Give name more visual weight
latest_pkg = pkg.get_latest_version()
if latest_pkg.installed:
if latest_pkg.url:
right.operator(PACKAGE_OT_uninstall.bl_idname,
text="Uninstall").package_name=latest_pkg.name
else:
right.label("Installed")
else:
if latest_pkg.url:
right.operator(PACKAGE_OT_install.bl_idname,
text="Install").package_url=pkg.versions[0].url
else:
right.label("Not installed, but no URL?")
def expanded():
row1 = leftcol.row()
row1.label(blinfo.get('name'), "")
def string_version(version_number) -> str:
"""Take version number as an iterable and format it as a string"""
"""Draw expanded version of package layout"""
def fmt_version(version_number: tuple) -> str:
"""Take version number as a tuple and format it as a string"""
vstr = str(version_number[0])
for component in version_number[1:]:
vstr += "." + str(component)
return vstr
if blinfo.get('description'):
row1 = leftcol.row()
row1.label(pkg.name)
if pkg.description:
row2 = leftcol.row()
row2.label(blinfo['description'])
row2.label(pkg.description)
# row2.scale_y = 1.2
if blinfo.get('version'):
spl = leftcol.row().split(.15)
spl.label("Version:")
spl.label(string_version(blinfo['version']))
def draw_metadatum(key: str, value: str, layout: bpy.types.UILayout):
def draw_metadatum(label: str, value: str, layout: bpy.types.UILayout):
"""Draw the given key value pair in a new row in given layout container"""
row = layout.row()
row.scale_y = .8
spl = row.split(.15)
spl.label("{}:".format(key))
spl.label("{}:".format(label))
spl.label(value)
for prop in (
# "description",
"author",
"category",
# "version",
# "blender",
"location",
"warning",
"support",
# "wiki_url",
# "tracker_url",
):
if blinfo.get(prop):
row = leftcol.row()
row.scale_y = .8
spl = row.split(.15)
spl.label("{}:".format(prop.title()))
spl.label(str(blinfo[prop]))
# don't compare against None here; we don't want to display empty arrays/strings either
if pkg.location:
draw_metadatum("Location", pkg.location, leftcol)
if pkg.version:
draw_metadatum("Version", fmt_version(pkg.version), leftcol)
# if pkg.blender:
# draw_metadatum("Compatible blender version", fmt_version(pkg.blender), leftcol)
if pkg.category:
draw_metadatum("Category", pkg.category, leftcol)
if pkg.author:
draw_metadatum("Author", pkg.author, leftcol)
if pkg.support:
draw_metadatum("Support level", pkg.support.title(), leftcol)
if pkg.warning:
draw_metadatum("Warning", pkg.warning, leftcol)
if pkg.wiki_url or pkg.tracker_url:
padrow = leftcol.row()
padrow.label()
padrow.scale_y = .5
urlrow = leftcol.row()
urlrow.alignment = 'LEFT'
if pkg.wiki_url:
urlrow.operator("wm.url_open", text="Documentation", icon='HELP').url=pkg.wiki_url
if pkg.tracker_url:
urlrow.operator("wm.url_open", text="Report a Bug", icon='URL').url=pkg.tracker_url
def draw_version(layout: bpy.types.UILayout, pkg: Package):
"""Draw version of package"""
@@ -664,7 +666,7 @@ class USERPREF_PT_packages(bpy.types.Panel):
right = spl.column()
right.alignment = 'RIGHT'
left.label(text=string_version(pkg.version))
left.label(text=fmt_version(pkg.version))
if pkg.repository is not None:
draw_metadatum("Repository", pkg.repository, left)
@@ -674,16 +676,49 @@ class USERPREF_PT_packages(bpy.types.Panel):
draw_metadatum("Installed to", str(pkg.installed_location), left)
if len(pkg.versions) > 1:
if len(metapkg.versions) > 1:
row = pkgbox.row()
row.label(text="There are multiple providers of this package:")
for version in pkg.versions:
for version in metapkg.versions:
# row = pkgbox.row()
subvbox = pkgbox.box()
draw_version(subvbox, version)
pkg = metapkg.get_latest_version()
if pkg.expanded:
pkgbox = layout.box()
spl = pkgbox.split(.8)
left = spl.row(align=True)
# for install/uninstall buttons
right = spl.row()
right.alignment = 'RIGHT'
right.scale_y = 1.5
# for collapse/expand button
left.operator(
WM_OT_package_toggle_expand.bl_idname,
icon='TRIA_DOWN' if metapkg.expanded else 'TRIA_RIGHT',
emboss=False,
).package_name=pkg.name
# for metadata
leftcol = left.column(align=True)
if pkg.installed:
if pkg.url:
right.operator(PACKAGE_OT_uninstall.bl_idname,
text="Uninstall").package_name=pkg.name
else:
right.label("Installed")
else:
if pkg.url:
right.operator(PACKAGE_OT_install.bl_idname,
text="Install").package_url=pkg.url
else:
right.label("Not installed, but no URL?")
if metapkg.expanded:
expanded()
else:
collapsed()# }}}
@@ -725,29 +760,6 @@ class USERPREF_PT_packages(bpy.types.Panel):
row = pkgzone.row()
draw_package(USERPREF_PT_packages.all_packages[pkgname], row)
class ConsolidatedPackage:
"""
Stores a grouping of different versions of the same packages,
and view-specific data used for drawing
"""
def __init__(self, pkg=None):
self.versions = []
self.expanded = False
self.installed = False
if pkg is not None:
self.add_version(pkg)
def get_latest_version(self) -> Package:
"""Get package with highest version number"""
return self.versions[0] # this is always sorted with the highest on top
def add_version(self, pkg: Package):
self.versions.append(pkg)
self.versions.sort(key=lambda v: v.version, reverse=True)
def __iter__(self):
return (pkg for pkg in self.versions)
class WM_OT_package_toggle_expand(bpy.types.Operator):
bl_idname = "wm.package_toggle_expand"

View File

@@ -17,6 +17,7 @@ class Package:
self.installed = False
self.repository = None
self.installed_location = None
def to_dict(self) -> dict:
"""
@@ -39,21 +40,96 @@ class Package:
if package_dict.get(attr) is not None:
setattr(self, attr, package_dict[attr])
#bl_info convenience getters
# bl_info convenience getters
# required fields
@property
def name(self) -> str:
"""Get name from bl_info"""
return self.bl_info['name']
@property
def description(self) -> str:
"""Get description from bl_info"""
return self.bl_info['description']
try:
return self.bl_info['name']
except KeyError:
return None
@property
def version(self) -> tuple:
"""Get version from bl_info"""
return tuple(self.bl_info['version'])
try:
return tuple(self.bl_info['version'])
except KeyError:
return None
@property
def blender(self) -> tuple:
"""Get blender from bl_info"""
try:
return self.bl_info['blender']
except KeyError:
return None
# optional fields
@property
def description(self) -> str:
"""Get description from bl_info"""
try:
return self.bl_info['description']
except KeyError:
return None
@property
def author(self) -> str:
"""Get author from bl_info"""
try:
return self.bl_info['author']
except KeyError:
return None
@property
def category(self) -> str:
"""Get category from bl_info"""
try:
return self.bl_info['category']
except KeyError:
return None
@property
def location(self) -> str:
"""Get location from bl_info"""
try:
return self.bl_info['location']
except KeyError:
return None
@property
def support(self) -> str:
"""Get support from bl_info"""
try:
return self.bl_info['support']
except KeyError:
return None
@property
def warning(self) -> str:
"""Get warning from bl_info"""
try:
return self.bl_info['warning']
except KeyError:
return None
@property
def wiki_url(self) -> str:
"""Get wiki_url from bl_info"""
try:
return self.bl_info['wiki_url']
except KeyError:
return None
@property
def tracker_url(self) -> str:
"""Get tracker_url from bl_info"""
try:
return self.bl_info['tracker_url']
except KeyError:
return None
# @classmethod
# def from_dict(cls, package_dict: dict):
@@ -83,6 +159,7 @@ class Package:
pkg = cls()
pkg.files = [filepath.name]
pkg.installed_location = str(filepath)
try:
pkg.bl_info = module.bl_info
except AttributeError as err: