Initial multiple repository support
And lots of code reshuffling which likely should've been done in separate commits..
This commit is contained in:
@@ -33,82 +33,27 @@ if 'bpy' in locals():
|
||||
messages = recursive_reload(messages)
|
||||
utils = recursive_reload(utils)
|
||||
bpkg = recursive_reload(bpkg)
|
||||
Package = bpkg.Package
|
||||
Package = bpkg.types.Package
|
||||
|
||||
else:
|
||||
from . import subproc
|
||||
from . import messages
|
||||
from . import bpkg
|
||||
from . import utils
|
||||
from .bpkg import Package
|
||||
from .bpkg.types import (
|
||||
Package,
|
||||
ConsolidatedPackage,
|
||||
)
|
||||
|
||||
import bpy
|
||||
from pathlib import Path
|
||||
from collections import OrderedDict
|
||||
|
||||
# global list of all known packages, indexed by name
|
||||
_packages = 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.updateable = False
|
||||
|
||||
if pkg is not None:
|
||||
self.add_version(pkg)
|
||||
|
||||
@property
|
||||
def installed(self) -> bool:
|
||||
"""Return true if any version of this package is installed"""
|
||||
for pkg in self.versions:
|
||||
if pkg.installed:
|
||||
return True
|
||||
return False
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""
|
||||
Return name of this package. All package versions in a
|
||||
ConsolidatedPackage should have the same name by definition
|
||||
"""
|
||||
return self.versions[0].name
|
||||
|
||||
def get_latest_installed_version(self) -> bpkg.Package:
|
||||
"""
|
||||
Return the installed package with the highest version number.
|
||||
If no packages are installed, return None.
|
||||
"""
|
||||
#self.versions is always sorted newer -> older, so we can just grab the first we find
|
||||
for pkg in self.versions:
|
||||
if pkg.installed:
|
||||
return pkg
|
||||
return None
|
||||
|
||||
def get_latest_version(self) -> bpkg.Package:
|
||||
"""Return package with highest version number"""
|
||||
return self.versions[0] # this is always sorted with the highest on top
|
||||
|
||||
def get_display_version(self) -> bpkg.Package:
|
||||
"""
|
||||
Return installed package with highest version number.
|
||||
If no version is installed, return highest uninstalled version.
|
||||
"""
|
||||
pkg = self.get_latest_installed_version()
|
||||
if pkg is None:
|
||||
pkg = self.get_latest_version()
|
||||
return pkg
|
||||
|
||||
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)
|
||||
# used for lazy loading
|
||||
_main_has_run = False
|
||||
|
||||
class SubprocMixin:
|
||||
"""Mix-in class for things that need to be run in a subprocess."""
|
||||
@@ -306,7 +251,8 @@ class PACKAGE_OT_install(SubprocMixin, bpy.types.Operator):
|
||||
|
||||
def _subproc_success(self, success: messages.Success):
|
||||
self.report({'INFO'}, 'Package installed successfully')
|
||||
bpy.ops.package.refresh_packages()
|
||||
global _packages
|
||||
_packages = build_packagelist()
|
||||
self.quit()
|
||||
|
||||
def _subproc_aborted(self, aborted: messages.Aborted):
|
||||
@@ -379,56 +325,58 @@ class PACKAGE_OT_uninstall(SubprocMixin, bpy.types.Operator):
|
||||
self.report({'WARNING'}, 'Error downloading package, but process finished OK. This is weird.')
|
||||
|
||||
|
||||
|
||||
def get_packages_from_disk(refresh=False) -> list:
|
||||
def get_installed_packages(refresh=False) -> list:
|
||||
"""Get list of packages installed on disk"""
|
||||
import addon_utils
|
||||
return [Package.from_module(mod) for mod in addon_utils.modules(refresh=refresh)]
|
||||
|
||||
def get_packages_from_repo() -> list:
|
||||
"""Get list of packages from cached repository lists (does not refresh them from server)"""
|
||||
import pathlib
|
||||
storage_path = pathlib.Path(bpy.utils.user_resource('CONFIG', 'packages', create=True)) / 'repo.json'
|
||||
try:
|
||||
repo = bpkg.Repository.from_file(storage_path)
|
||||
except FileNotFoundError:
|
||||
return []
|
||||
for pkg in repo.packages:
|
||||
pkg.repository = repo.name
|
||||
return repo.packages
|
||||
def get_repo_storage_path() -> Path:
|
||||
return Path(bpy.utils.user_resource('CONFIG', 'repositories'))
|
||||
|
||||
class PACKAGE_OT_refresh_packages(bpy.types.Operator):
|
||||
bl_idname = "package.refresh_packages"
|
||||
bl_label = "Refresh Packages"
|
||||
bl_description = "Scan for packages on disk"
|
||||
def get_repositories() -> list:
|
||||
"""
|
||||
Get list of downloaded repositories and update wm.package_repositories
|
||||
"""
|
||||
log = logging.getLogger(__name__ + ".get_repositories")
|
||||
storage_path = get_repo_storage_path()
|
||||
repos = bpkg.load_repositories(storage_path)
|
||||
log.debug("repos: %s", repos)
|
||||
|
||||
log = logging.getLogger(__name__ + ".PACKAGE_OT_refresh_packages")
|
||||
return repos
|
||||
|
||||
def execute(self, context):
|
||||
global _packages
|
||||
installed_packages = get_packages_from_disk(refresh=True)
|
||||
available_packages = get_packages_from_repo()
|
||||
_packages = build_composite_packagelist(installed_packages, available_packages)
|
||||
context.area.tag_redraw()
|
||||
# class PACKAGE_OT_refresh_packages(bpy.types.Operator):
|
||||
# bl_idname = "package.refresh_packages"
|
||||
# bl_label = "Refresh Packages"
|
||||
# bl_description = "Scan for packages on disk"
|
||||
#
|
||||
# log = logging.getLogger(__name__ + ".PACKAGE_OT_refresh_packages")
|
||||
#
|
||||
# def execute(self, context):
|
||||
# global _packages
|
||||
# installed_packages = get_packages_from_disk(refresh=True)
|
||||
# available_packages = get_packages_from_repo()
|
||||
# _packages = build_composite_packagelist(installed_packages, available_packages)
|
||||
# context.area.tag_redraw()
|
||||
#
|
||||
# return {'FINISHED'}
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
class PACKAGE_OT_refresh_repositories(SubprocMixin, bpy.types.Operator):
|
||||
bl_idname = "package.refresh_repositories"
|
||||
bl_label = "Refresh Repositories"
|
||||
class PACKAGE_OT_refresh(SubprocMixin, bpy.types.Operator):
|
||||
bl_idname = "package.refresh"
|
||||
bl_label = "Refresh"
|
||||
bl_description = 'Check repositories for new and updated packages'
|
||||
bl_options = {'REGISTER'}
|
||||
|
||||
log = logging.getLogger(__name__ + ".PACKAGE_OT_refresh_repositories")
|
||||
log = logging.getLogger(__name__ + ".PACKAGE_OT_refresh")
|
||||
_running = False
|
||||
|
||||
def invoke(self, context, event):
|
||||
self.repolist = bpy.context.user_preferences.addons[__package__].preferences.repositories
|
||||
if len(self.repolist) == 0:
|
||||
wm = context.window_manager
|
||||
self.repositories = wm.package_repositories
|
||||
if len(self.repositories) == 0:
|
||||
self.report({'ERROR'}, "No repositories to refresh")
|
||||
return {'CANCELLED'}
|
||||
|
||||
PACKAGE_OT_refresh_repositories._running = True
|
||||
PACKAGE_OT_refresh._running = True
|
||||
return super().invoke(context, event)
|
||||
|
||||
@classmethod
|
||||
@@ -436,7 +384,7 @@ class PACKAGE_OT_refresh_repositories(SubprocMixin, bpy.types.Operator):
|
||||
return not cls._running
|
||||
|
||||
def cancel(self, context):
|
||||
PACKAGE_OT_refresh_repositories._running = False
|
||||
PACKAGE_OT_refresh._running = False
|
||||
context.area.tag_redraw()
|
||||
|
||||
def create_subprocess(self):
|
||||
@@ -455,18 +403,19 @@ class PACKAGE_OT_refresh_repositories(SubprocMixin, bpy.types.Operator):
|
||||
messages.SubprocError: self._subproc_error,
|
||||
messages.DownloadError: self._subproc_download_error,
|
||||
messages.Success: self._subproc_success,
|
||||
messages.RepositoryResult: self._subproc_repository_result,
|
||||
# messages.RepositoryResult: self._subproc_repository_result,
|
||||
messages.BadRepositoryError: self._subproc_repository_error,
|
||||
messages.Aborted: self._subproc_aborted,
|
||||
}
|
||||
|
||||
import pathlib
|
||||
|
||||
storage_path = pathlib.Path(bpy.utils.user_resource('CONFIG', 'packages', create=True))
|
||||
repository_url = self.repolist[0].url
|
||||
storage_path = pathlib.Path(bpy.utils.user_resource('CONFIG', 'repositories', create=True))
|
||||
repository_urls = [repo.url for repo in self.repositories]
|
||||
self.log.debug("Repository urls %s", repository_urls)
|
||||
|
||||
proc = multiprocessing.Process(target=subproc.refresh_repository,
|
||||
args=(self.pipe_subproc, storage_path, repository_url))
|
||||
proc = multiprocessing.Process(target=subproc.refresh_repositories,
|
||||
args=(self.pipe_subproc, storage_path, repository_urls))
|
||||
return proc
|
||||
|
||||
def _subproc_progress(self, progress: messages.Progress):
|
||||
@@ -485,19 +434,19 @@ class PACKAGE_OT_refresh_repositories(SubprocMixin, bpy.types.Operator):
|
||||
self.quit()
|
||||
|
||||
def _subproc_success(self, success: messages.Success):
|
||||
self.report({'INFO'}, 'Finished refreshing lists')
|
||||
self.quit()
|
||||
|
||||
def _subproc_repository_result(self, result: messages.RepositoryResult):
|
||||
available_packages = result.repository.packages
|
||||
installed_packages = get_packages_from_disk(refresh=False)
|
||||
|
||||
# TODO: deduplicate creation of view-packages..
|
||||
for pkg in available_packages:
|
||||
pkg.repository = result.repository.name
|
||||
|
||||
global _packages
|
||||
_packages = build_composite_packagelist(installed_packages, available_packages)
|
||||
self.report({'INFO'}, 'Package list retrieved successfully')
|
||||
# def _subproc_repository_result(self, result: messages.RepositoryResult):
|
||||
# available_packages = result.repository.packages
|
||||
# installed_packages = get_packages_from_disk(refresh=False)
|
||||
#
|
||||
# # TODO: deduplicate creation of view-packages..
|
||||
# for pkg in available_packages:
|
||||
# pkg.repository = result.repository.name
|
||||
#
|
||||
# global _packages
|
||||
# _packages = build_composite_packagelist(installed_packages, available_packages)
|
||||
|
||||
def _subproc_aborted(self, aborted: messages.Aborted):
|
||||
self.report({'ERROR'}, 'Package list retrieval aborted per your request')
|
||||
@@ -511,26 +460,15 @@ class PACKAGE_OT_refresh_repositories(SubprocMixin, bpy.types.Operator):
|
||||
self.log.error('Refresh process died without telling us! Exit code was 0 though')
|
||||
self.report({'WARNING'}, 'Error refreshing package lists, but process finished OK. This is weird.')
|
||||
|
||||
#TODO:
|
||||
# monkey patch refresh_repositories and add refresh_packages in the success callback
|
||||
# this way refresh_packages is always called after repositories have been refreshed
|
||||
class PACKAGE_OT_refresh(bpy.types.Operator):
|
||||
bl_idname = "package.refresh"
|
||||
bl_label = "Refresh"
|
||||
bl_description = "Check for new and updated packages"
|
||||
|
||||
def execute(self, context):
|
||||
bpy.ops.package.refresh_repositories()
|
||||
# getattr(bpy.ops, __package__).refresh_packages()
|
||||
return {'FINISHED'}
|
||||
|
||||
class RepositoryProperty(bpy.types.PropertyGroup):
|
||||
name = bpy.props.StringProperty(name="Name")
|
||||
url = bpy.props.StringProperty(name="URL")
|
||||
status = bpy.props.EnumProperty(name="Status", items=[
|
||||
("OK", "Okay", "FILE_TICK"),
|
||||
("NOTFOUND", "Not found", "ERROR"),
|
||||
("NOCONNECT", "Could not connect", "QUESTION"),
|
||||
])
|
||||
enabled = bpy.props.BoolProperty(name="Enabled")
|
||||
|
||||
class PACKAGE_UL_repositories(bpy.types.UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
@@ -551,17 +489,16 @@ class PACKAGE_OT_add_repository(bpy.types.Operator):
|
||||
return wm.invoke_props_dialog(self)
|
||||
|
||||
def execute(self, context):
|
||||
prefs = context.user_preferences.addons[__package__].preferences
|
||||
if len(prefs.repositories) > 0:
|
||||
self.report({'ERROR'}, "Only one repository at a time is currently supported")
|
||||
return {'CANCELLED'}
|
||||
wm = context.window_manager
|
||||
|
||||
if len(self.url) == 0:
|
||||
self.report({'ERROR'}, "Repository URL not specified")
|
||||
return {'CANCELLED'}
|
||||
|
||||
repo = prefs.repositories.add()
|
||||
repo.url = utils.parse_repository_url(self.url)
|
||||
repo = wm.package_repositories.add()
|
||||
repo.url = utils.sanitize_repository_url(self.url)
|
||||
|
||||
bpy.ops.package.refresh()
|
||||
|
||||
context.area.tag_redraw()
|
||||
return {'FINISHED'}
|
||||
@@ -571,8 +508,19 @@ class PACKAGE_OT_remove_repository(bpy.types.Operator):
|
||||
bl_label = "Remove Repository"
|
||||
|
||||
def execute(self, context):
|
||||
prefs = context.user_preferences.addons[__package__].preferences
|
||||
prefs.repositories.remove(prefs.active_repository)
|
||||
wm = context.window_manager
|
||||
try:
|
||||
repo = wm['package_repositories'][wm.package_active_repository]
|
||||
except IndexError:
|
||||
return {'CANCELLED'}
|
||||
|
||||
filename = bpkg.utils.format_filename(repo.name) + ".json"
|
||||
path = (get_repo_storage_path() / filename)
|
||||
if path.exists():
|
||||
path.unlink()
|
||||
|
||||
wm.package_repositories.remove(wm.package_active_repository)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
class USERPREF_PT_packages(bpy.types.Panel):
|
||||
@@ -583,11 +531,11 @@ class USERPREF_PT_packages(bpy.types.Panel):
|
||||
|
||||
log = logging.getLogger(__name__ + '.USERPREF_PT_packages')
|
||||
|
||||
# available_packages = []
|
||||
# installed_packages = []
|
||||
displayed_packages = []
|
||||
expanded_packages = []
|
||||
|
||||
redraw = True
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
userpref = context.user_preferences
|
||||
@@ -598,19 +546,19 @@ class USERPREF_PT_packages(bpy.types.Panel):
|
||||
wm = context.window_manager
|
||||
prefs = context.user_preferences.addons[__package__].preferences
|
||||
|
||||
main = layout.row()
|
||||
spl = main.split(.2)
|
||||
mainrow = layout.row()
|
||||
spl = mainrow.split(.2)
|
||||
sidebar = spl.column(align=True)
|
||||
pkgzone = spl.column()
|
||||
|
||||
sidebar.label("Repositories")
|
||||
row = sidebar.row()
|
||||
row.template_list("PACKAGE_UL_repositories", "", prefs, "repositories", prefs, "active_repository")
|
||||
row.template_list("PACKAGE_UL_repositories", "", wm, "package_repositories", wm, "package_active_repository")
|
||||
col = row.column(align=True)
|
||||
col.operator(PACKAGE_OT_add_repository.bl_idname, text="", icon='ZOOMIN')
|
||||
col.operator(PACKAGE_OT_remove_repository.bl_idname, text="", icon='ZOOMOUT')
|
||||
sidebar.separator()
|
||||
sidebar.operator(PACKAGE_OT_refresh_repositories.bl_idname)
|
||||
sidebar.operator(PACKAGE_OT_refresh.bl_idname, text="Check for updates")
|
||||
|
||||
sidebar.separator()
|
||||
sidebar.label("Category")
|
||||
@@ -865,18 +813,16 @@ class USERPREF_PT_packages(bpy.types.Panel):
|
||||
row.alignment='CENTER'
|
||||
row.scale_y = 10
|
||||
|
||||
global _packages
|
||||
|
||||
if len(_packages) == 0:
|
||||
global _main_has_run
|
||||
if not _main_has_run:
|
||||
# TODO: read repository and installed packages synchronously for now;
|
||||
# can't run an operator from draw code to do async monitoring
|
||||
installed_packages = get_packages_from_disk()
|
||||
available_packages = get_packages_from_repo()
|
||||
main()
|
||||
|
||||
_packages = build_composite_packagelist(installed_packages, available_packages)
|
||||
if len(_packages) == 0:
|
||||
center_message(pkgzone, "No packages found")
|
||||
return
|
||||
global _packages
|
||||
if len(_packages) == 0:
|
||||
center_message(pkgzone, "No packages found")
|
||||
return
|
||||
|
||||
wm = bpy.context.window_manager
|
||||
filters = {
|
||||
@@ -892,7 +838,7 @@ class USERPREF_PT_packages(bpy.types.Panel):
|
||||
draw_package(_packages[pkgname], row)
|
||||
|
||||
|
||||
class WM_OT_package_toggle_expand(bpy.types.Operator):
|
||||
class WM_OT_package_toggle_expand(bpy.types.Operator):# {{{
|
||||
bl_idname = "wm.package_toggle_expand"
|
||||
bl_label = ""
|
||||
bl_description = "Toggle display of extended information for given package (hold shift to collapse all other packages)"
|
||||
@@ -913,9 +859,9 @@ class WM_OT_package_toggle_expand(bpy.types.Operator):
|
||||
else:
|
||||
USERPREF_PT_packages.expanded_packages.append(self.package_name)
|
||||
|
||||
return {'FINISHED'}
|
||||
return {'FINISHED'}# }}}
|
||||
|
||||
class PACKAGE_OT_toggle_enabled(bpy.types.Operator):
|
||||
class PACKAGE_OT_toggle_enabled(bpy.types.Operator):# {{{
|
||||
bl_idname = "package.toggle_enabled"
|
||||
bl_label = ""
|
||||
bl_description = "Enable given package if it's disabled, and vice versa if it's enabled"
|
||||
@@ -954,9 +900,9 @@ class PACKAGE_OT_toggle_enabled(bpy.types.Operator):
|
||||
addon_utils.enable(pkg.module_name, default_set=True)
|
||||
pkg.enabled = True
|
||||
|
||||
return {'FINISHED'}
|
||||
return {'FINISHED'}# }}}
|
||||
|
||||
class PACKAGE_OT_disable(bpy.types.Operator):
|
||||
class PACKAGE_OT_disable(bpy.types.Operator):# {{{
|
||||
bl_idname = "package.disable"
|
||||
bl_label = ""
|
||||
bl_description = "Disable given package"
|
||||
@@ -979,96 +925,69 @@ class PACKAGE_OT_disable(bpy.types.Operator):
|
||||
ret = bpy.ops.wm.addon_disable(package.module_name)
|
||||
if ret == {'FINISHED'}:
|
||||
_packages[self.package_name].enabled = False
|
||||
return ret
|
||||
return ret# }}}
|
||||
|
||||
class PackageManagerPreferences(bpy.types.AddonPreferences):
|
||||
bl_idname = __package__
|
||||
# class PackageManagerPreferences(bpy.types.AddonPreferences):
|
||||
# bl_idname = __package__
|
||||
#
|
||||
# repositories = bpy.props.CollectionProperty(
|
||||
# type=RepositoryProperty,
|
||||
# name="Repositories",
|
||||
# )
|
||||
# active_repository = bpy.props.IntProperty()
|
||||
|
||||
repositories = bpy.props.CollectionProperty(
|
||||
type=RepositoryProperty,
|
||||
name="Repositories",
|
||||
)
|
||||
active_repository = bpy.props.IntProperty()
|
||||
|
||||
def validate_packagelist(pkglist: list) -> list:
|
||||
"""Ensures all packages have required fields; strips out bad packages and returns them in a list"""
|
||||
pass
|
||||
|
||||
def build_composite_packagelist(installed: list, available: list) -> OrderedDict:
|
||||
"""Merge list of installed and available packages into one dict, keyed by package name"""
|
||||
def build_packagelist() -> OrderedDict:# {{{
|
||||
"""Make an OrderedDict of ConsolidatedPackages from known repositories + installed packages, keyed by package name"""
|
||||
|
||||
log = logging.getLogger(__name__ + ".build_composite_packagelist")
|
||||
|
||||
masterlist = {}
|
||||
installed_packages = get_installed_packages()
|
||||
known_repositories = get_repositories()
|
||||
|
||||
def packages_are_equivilent(pkg1: Package, pkg2: Package) -> bool:
|
||||
"""Check that packages are the same version and provide the same files"""
|
||||
return pkg1.version == pkg2.version\
|
||||
and pkg1.files == pkg2.files
|
||||
|
||||
def is_user_package(pkg: Package) -> bool:
|
||||
"""Check if package's install location is in user scripts path or preferences scripts path"""
|
||||
from pathlib import Path
|
||||
|
||||
user_script_path = bpy.utils.script_path_user()
|
||||
prefs_script_path = bpy.utils.script_path_pref()
|
||||
|
||||
if user_script_path is not None:
|
||||
in_user = Path(user_script_path) in Path(pkg.installed_location).parents
|
||||
else:
|
||||
in_user = False
|
||||
|
||||
if prefs_script_path is not None:
|
||||
in_prefs = Path(prefs_script_path) in Path(pkg.installed_location).parents
|
||||
else:
|
||||
in_prefs = False
|
||||
|
||||
return in_user or in_prefs
|
||||
|
||||
def is_enabled(pkg: Package) -> bool:
|
||||
"""Check if package is enabled"""
|
||||
if pkg.module_name is not None:
|
||||
return (pkg.module_name in bpy.context.user_preferences.addons)
|
||||
else:
|
||||
raise ValueError("Can't determine if package is enabled without knowing its module name")
|
||||
|
||||
|
||||
for pkg in available:
|
||||
pkgname = pkg.bl_info['name']
|
||||
if pkgname in masterlist:
|
||||
masterlist[pkgname].add_version(pkg)
|
||||
else:
|
||||
masterlist[pkgname] = ConsolidatedPackage(pkg)
|
||||
|
||||
for pkg in installed:
|
||||
pkg.installed = True
|
||||
pkg.enabled = is_enabled(pkg)
|
||||
pkg.user = is_user_package(pkg)
|
||||
if pkg.name in masterlist:
|
||||
for masterpkg in masterlist[pkg.name]:
|
||||
if packages_are_equivilent(pkg, masterpkg):
|
||||
masterpkg.installed = True
|
||||
masterpkg.installed_location = pkg.installed_location
|
||||
masterpkg.user = pkg.user
|
||||
masterpkg.module_name = pkg.module_name
|
||||
masterpkg.enabled = pkg.enabled
|
||||
break
|
||||
else:
|
||||
if masterpkg.version > pkg.version:
|
||||
masterlist[pkg.name].updateable = True
|
||||
for repo in known_repositories:
|
||||
for pkg in repo.packages:
|
||||
if pkg.name is None:
|
||||
return OrderedDict()
|
||||
if pkg.name in masterlist:
|
||||
masterlist[pkg.name].add_version(pkg)
|
||||
else:
|
||||
masterlist[pkg.name] = ConsolidatedPackage(pkg)
|
||||
|
||||
for pkg in installed_packages:
|
||||
if pkg.name in masterlist:
|
||||
masterlist[pkg.name].add_version(pkg)
|
||||
else:
|
||||
masterlist[pkg.name] = ConsolidatedPackage(pkg)
|
||||
|
||||
return OrderedDict(sorted(masterlist.items()))
|
||||
# log.debug(masterlist[None].__dict__)
|
||||
return OrderedDict(sorted(masterlist.items()))# }}}
|
||||
|
||||
def main():
|
||||
"""Entry point; performs initial loading of repositories and installed packages"""
|
||||
global _packages
|
||||
global _main_has_run
|
||||
|
||||
_packages = build_packagelist()
|
||||
|
||||
repos = get_repositories()
|
||||
wm = bpy.context.window_manager
|
||||
wm.package_repositories.clear()
|
||||
for repo in repos:
|
||||
repo_prop = wm.package_repositories.add()
|
||||
repo_prop.name = repo.name
|
||||
repo_prop.url = repo.url
|
||||
|
||||
# needed for lazy loading
|
||||
_main_has_run = True
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(PACKAGE_OT_install)
|
||||
bpy.utils.register_class(PACKAGE_OT_uninstall)
|
||||
bpy.utils.register_class(PACKAGE_OT_toggle_enabled)
|
||||
# bpy.utils.register_class(PACKAGE_OT_disable)
|
||||
bpy.utils.register_class(PACKAGE_OT_refresh_repositories)
|
||||
bpy.utils.register_class(PACKAGE_OT_refresh_packages)
|
||||
# bpy.utils.register_class(PACKAGE_OT_refresh_repositories)
|
||||
# bpy.utils.register_class(PACKAGE_OT_refresh_packages)
|
||||
bpy.utils.register_class(PACKAGE_OT_refresh)
|
||||
bpy.utils.register_class(USERPREF_PT_packages)
|
||||
bpy.utils.register_class(WM_OT_package_toggle_expand)
|
||||
@@ -1087,11 +1006,16 @@ def register():
|
||||
)
|
||||
|
||||
bpy.utils.register_class(RepositoryProperty)
|
||||
bpy.types.WindowManager.package_repositories = bpy.props.CollectionProperty(
|
||||
type=RepositoryProperty,
|
||||
name="Repositories",
|
||||
)
|
||||
bpy.types.WindowManager.package_active_repository = bpy.props.IntProperty()
|
||||
bpy.utils.register_class(PACKAGE_OT_add_repository)
|
||||
bpy.utils.register_class(PACKAGE_OT_remove_repository)
|
||||
bpy.utils.register_class(PACKAGE_UL_repositories)
|
||||
|
||||
bpy.utils.register_class(PackageManagerPreferences)
|
||||
# bpy.utils.register_class(PackageManagerPreferences)
|
||||
|
||||
|
||||
def unregister():
|
||||
@@ -1099,8 +1023,8 @@ def unregister():
|
||||
bpy.utils.unregister_class(PACKAGE_OT_uninstall)
|
||||
bpy.utils.unregister_class(PACKAGE_OT_toggle_enabled)
|
||||
# bpy.utils.unregister_class(PACKAGE_OT_disable)
|
||||
bpy.utils.unregister_class(PACKAGE_OT_refresh_repositories)
|
||||
bpy.utils.unregister_class(PACKAGE_OT_refresh_packages)
|
||||
# bpy.utils.unregister_class(PACKAGE_OT_refresh_repositories)
|
||||
# bpy.utils.unregister_class(PACKAGE_OT_refresh_packages)
|
||||
bpy.utils.unregister_class(PACKAGE_OT_refresh)
|
||||
bpy.utils.unregister_class(USERPREF_PT_packages)
|
||||
bpy.utils.unregister_class(WM_OT_package_toggle_expand)
|
||||
@@ -1108,8 +1032,10 @@ def unregister():
|
||||
del bpy.types.WindowManager.package_install_filter
|
||||
|
||||
bpy.utils.unregister_class(RepositoryProperty)
|
||||
del bpy.types.WindowManager.package_repositories
|
||||
del bpy.types.WindowManager.package_active_repository
|
||||
bpy.utils.unregister_class(PACKAGE_OT_add_repository)
|
||||
bpy.utils.unregister_class(PACKAGE_OT_remove_repository)
|
||||
bpy.utils.unregister_class(PACKAGE_UL_repositories)
|
||||
|
||||
bpy.utils.unregister_class(PackageManagerPreferences)
|
||||
# bpy.utils.unregister_class(PackageManagerPreferences)
|
||||
|
Reference in New Issue
Block a user