Files
blender-portable-repo/scripts/addons/blender_svn/prefs.py
T
2026-03-17 14:58:51 -06:00

191 lines
6.3 KiB
Python

# SPDX-FileCopyrightText: 2021 Blender Studio Tools Authors
#
# SPDX-License-Identifier: GPL-3.0-or-later
from typing import Optional, Any, Set, Tuple, List
import platform
import bpy
from bpy.props import IntProperty, CollectionProperty, BoolProperty, EnumProperty
from bpy.types import AddonPreferences
from .ui.ui_repo_list import draw_checkout, draw_repo_list
from .repository import SVN_repository
from .svn_info import get_svn_info
import json
from pathlib import Path
from .threaded.background_process import Processes
class SVN_addon_preferences(AddonPreferences):
bl_idname = __package__
is_svn_installed: BoolProperty(
name="Is SVN Installed",
description="Whether the `svn` command works at all in the user's command line. If not, user needs to install SVN",
default=False
)
repositories: CollectionProperty(type=SVN_repository)
def init_repo_list(self):
# If we have any repository entries, make sure at least one is active.
self.sync_repo_info_file()
if self.active_repo_idx == -1 and len(self.repositories) > 0:
self.active_repo_idx = 0
elif self.active_repo_idx > len(self.repositories)-1:
self.active_repo_idx = 0
else:
self.active_repo_idx = self.active_repo_idx
def init_repo(self, context, repo_path: Path or str):
"""Attempt to initialize a repository based on a directory.
This means executing `svn info` in the repo_path to get the URL and root dir.
If we already have an SVN_repository instance with that root dir, just return it.
Otherwise, initialize it by storing its directory, URL, and a display name, and then return it.
"""
root_dir, base_url = get_svn_info(repo_path)
if not root_dir:
return
existing_repo = self.repositories.get(root_dir)
if existing_repo:
if existing_repo.external_files_active_index > len(existing_repo.external_files):
existing_repo.external_files_active_index = 0
existing_repo.log_active_index = len(existing_repo.log)-1
existing_repo.reload_svn_log(context)
return existing_repo
repo = self.repositories.add()
repo.initialize(root_dir, base_url)
self.active_repo_idx = len(self.repositories)-1
return repo
checkout_mode: BoolProperty(
name="Checkout In Progress",
description="Internal flag to indicate that the user is currently trying to create a new checkout",
default=False
)
def update_active_repo_idx(self, context):
if len(self.repositories) == 0:
return
active_repo = self.active_repo
# Authenticate when switching repos.
if (
active_repo and
not active_repo.auth_failed and
active_repo.is_cred_entered
):
Processes.start('Redraw Viewport')
if active_repo.authenticated:
Processes.restart('Status')
else:
active_repo.authenticate()
else:
Processes.kill('Status')
active_repo_idx: IntProperty(
name="SVN Repositories",
options=set(),
update=update_active_repo_idx
)
@property
def active_repo(self) -> Optional[SVN_repository]:
if not self.is_svn_installed:
return
if 0 <= self.active_repo_idx <= len(self.repositories)-1:
return self.repositories[self.active_repo_idx]
debug_mode: BoolProperty(
name="Debug Mode",
description="Enable some debug UI",
default=False
)
@property
def is_busy(self):
return Processes.is_running('Commit', 'Update')
loading: BoolProperty(
name="Loading",
description="Disable the credential update callbacks while loading repo data to avoid infinite loops",
default=False
)
def save_repo_info_to_file(self):
saved_props = {'url', 'directory', 'name',
'username', 'password', 'display_name'}
repo_data = {}
for repo in self.repositories:
directory = repo.get('directory', '')
repo_data[directory] = {
key: value for key, value in repo.items() if key in saved_props}
filepath = Path(bpy.utils.user_resource('CONFIG')) / \
Path("blender_svn.txt")
with open(filepath, "w") as f:
json.dump(repo_data, f, indent=4)
def load_repo_info_from_file(self):
self.loading = True
try:
filepath = Path(bpy.utils.user_resource(
'CONFIG')) / Path("blender_svn.txt")
if not filepath.exists():
return
with open(filepath, "r") as f:
repo_data = json.load(f)
for directory, repo_data in repo_data.items():
repo = self.repositories.get(directory)
if not repo:
repo = self.repositories.add()
repo.directory = directory
for key, value in repo_data.items():
setattr(repo, key, value)
finally:
self.loading = False
def sync_repo_info_file(self):
self.load_repo_info_from_file()
self.save_repo_info_to_file()
def draw(self, context):
if not self.is_svn_installed:
draw_prefs_no_svn(self, context)
return
if self.checkout_mode:
draw_checkout(self, context)
else:
draw_repo_list(self, context)
def draw_prefs_no_svn(self, context):
terminal, url = "terminal", "https://subversion.apache.org/packages.html"
system = platform.system()
if system == "Windows":
terminal = "command line (cmd.exe)"
url = "https://subversion.apache.org/packages.html#windows"
elif system == "Darwin":
terminal = "Mac terminal"
url = "https://subversion.apache.org/packages.html#osx"
layout = self.layout
col = layout.column()
col.alert=True
col.label(text="Please ensure that Subversion (aka. SVN) is installed on your system.")
col.label(text=f"Typing `svn` into the {terminal} should yield a result.")
layout.operator("wm.url_open", icon='URL', text='Open Subversion Distribution Page').url=url
registry = [
SVN_addon_preferences
]