Merge pull request #1381 from pypeclub/feature/remove_user_module

Remove OpenPype User Module
This commit is contained in:
Milan Kolar 2021-04-22 09:50:37 +02:00 committed by GitHub
commit 0d22942af9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 78 additions and 373 deletions

View file

@ -79,6 +79,16 @@ from .avalon_context import (
change_timer_to_current_context
)
from .local_settings import (
IniSettingRegistry,
JSONSettingRegistry,
OpenPypeSecureRegistry,
OpenPypeSettingsRegistry,
get_local_site_id,
change_openpype_mongo_url,
get_openpype_username
)
from .applications import (
ApplicationLaunchFailed,
ApplictionExecutableNotFound,
@ -112,15 +122,6 @@ from .plugin_tools import (
should_decompress
)
from .local_settings import (
IniSettingRegistry,
JSONSettingRegistry,
OpenPypeSecureRegistry,
OpenPypeSettingsRegistry,
get_local_site_id,
change_openpype_mongo_url
)
from .path_tools import (
version_up,
get_version_from_path,
@ -179,6 +180,14 @@ __all__ = [
"change_timer_to_current_context",
"IniSettingRegistry",
"JSONSettingRegistry",
"OpenPypeSecureRegistry",
"OpenPypeSettingsRegistry",
"get_local_site_id",
"change_openpype_mongo_url",
"get_openpype_username",
"ApplicationLaunchFailed",
"ApplictionExecutableNotFound",
"ApplicationNotFound",
@ -224,13 +233,6 @@ __all__ = [
"validate_mongo_connection",
"OpenPypeMongoConnection",
"IniSettingRegistry",
"JSONSettingRegistry",
"OpenPypeSecureRegistry",
"OpenPypeSettingsRegistry",
"get_local_site_id",
"change_openpype_mongo_url",
"timeit",
"is_overlapping_otio_ranges",

View file

@ -25,6 +25,7 @@ from . import (
PypeLogger,
Anatomy
)
from .local_settings import get_openpype_username
from .avalon_context import (
get_workdir_data,
get_workdir_with_workdir_data
@ -1225,7 +1226,7 @@ def _prepare_last_workfile(data, workdir):
file_template = anatomy.templates["work"]["file"]
workdir_data.update({
"version": 1,
"user": os.environ.get("OPENPYPE_USERNAME") or getpass.getuser(),
"user": get_openpype_username(),
"ext": extensions[0]
})

View file

@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
"""Package to deal with saving and retrieving user specific settings."""
import os
import json
import getpass
import platform
from datetime import datetime
from abc import ABCMeta, abstractmethod
import json
# TODO Use pype igniter logic instead of using duplicated code
# disable lru cache in Python 2
@ -24,11 +26,11 @@ try:
except ImportError:
import ConfigParser as configparser
import platform
import six
import appdirs
from openpype.settings import get_local_settings
from .import validate_mongo_connection
_PLACEHOLDER = object()
@ -538,3 +540,25 @@ def change_openpype_mongo_url(new_mongo_url):
if existing_value is not None:
registry.delete_item(key)
registry.set_item(key, new_mongo_url)
def get_openpype_username():
"""OpenPype username used for templates and publishing.
May be different than machine's username.
Always returns "OPENPYPE_USERNAME" environment if is set then tries local
settings and last option is to use `getpass.getuser()` which returns
machine username.
"""
username = os.environ.get("OPENPYPE_USERNAME")
if not username:
local_settings = get_local_settings()
username = (
local_settings
.get("general", {})
.get("username")
)
if not username:
username = getpass.getuser()
return username

View file

@ -18,10 +18,6 @@ from .webserver import (
WebServerModule,
IWebServerRoutes
)
from .user import (
UserModule,
IUserModule
)
from .idle_manager import (
IdleManager,
IIdleManager
@ -60,9 +56,6 @@ __all__ = (
"WebServerModule",
"IWebServerRoutes",
"UserModule",
"IUserModule",
"IdleManager",
"IIdleManager",

View file

@ -64,7 +64,6 @@ class AfterEffectsSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline
"AVALON_ASSET",
"AVALON_TASK",
"AVALON_APP_NAME",
"OPENPYPE_USERNAME",
"OPENPYPE_DEV",
"OPENPYPE_LOG_NO_COLORS"
]

View file

@ -273,7 +273,6 @@ class HarmonySubmitDeadline(
"AVALON_ASSET",
"AVALON_TASK",
"AVALON_APP_NAME",
"OPENPYPE_USERNAME",
"OPENPYPE_DEV",
"OPENPYPE_LOG_NO_COLORS"
]

View file

@ -441,7 +441,6 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin):
"AVALON_ASSET",
"AVALON_TASK",
"AVALON_APP_NAME",
"OPENPYPE_USERNAME",
"OPENPYPE_DEV",
"OPENPYPE_LOG_NO_COLORS"
]

View file

@ -8,7 +8,6 @@ from openpype.modules import (
ITrayModule,
IPluginPaths,
ITimersManager,
IUserModule,
ILaunchHookPaths,
ISettingsChangeListener
)
@ -32,7 +31,6 @@ class FtrackModule(
ITrayModule,
IPluginPaths,
ITimersManager,
IUserModule,
ILaunchHookPaths,
ISettingsChangeListener
):
@ -123,11 +121,6 @@ class FtrackModule(
if self.tray_module:
self.tray_module.stop_timer_manager()
def on_pype_user_change(self, username):
"""Implementation of IUserModule interface."""
if self.tray_module:
self.tray_module.changed_user()
def on_system_settings_save(self, *_args, **_kwargs):
"""Implementation of ISettingsChangeListener interface."""
# Ignore

View file

@ -1,10 +0,0 @@
from .user_module import (
UserModule,
IUserModule
)
__all__ = (
"UserModule",
"IUserModule"
)

View file

@ -1,35 +0,0 @@
import json
from aiohttp.web_response import Response
class UserModuleRestApi:
def __init__(self, user_module, server_manager):
self.module = user_module
self.server_manager = server_manager
self.prefix = "/user"
self.register()
def register(self):
self.server_manager.add_route(
"GET",
self.prefix + "/username",
self.get_username
)
self.server_manager.add_route(
"GET",
self.prefix + "/show_widget",
self.show_user_widget
)
async def get_username(self, request):
return Response(
status=200,
body=json.dumps(self.module.cred, indent=4),
content_type="application/json"
)
async def show_user_widget(self, request):
self.module.action_show_widget.trigger()
return Response(status=200)

View file

@ -1,169 +0,0 @@
import os
import json
import getpass
from abc import ABCMeta, abstractmethod
import six
import appdirs
from .. import (
PypeModule,
ITrayModule,
IWebServerRoutes
)
@six.add_metaclass(ABCMeta)
class IUserModule:
"""Interface for other modules to use user change callbacks."""
@abstractmethod
def on_pype_user_change(self, username):
"""What should happen on Pype user change."""
pass
class UserModule(PypeModule, ITrayModule, IWebServerRoutes):
cred_folder_path = os.path.normpath(
appdirs.user_data_dir('pype-app', 'pype')
)
cred_filename = 'user_info.json'
env_name = "OPENPYPE_USERNAME"
name = "user"
def initialize(self, modules_settings):
user_settings = modules_settings[self.name]
self.enabled = user_settings["enabled"]
self.callbacks_on_user_change = []
self.cred = {}
self.cred_path = os.path.normpath(os.path.join(
self.cred_folder_path, self.cred_filename
))
# Tray attributes
self.widget_login = None
self.action_show_widget = None
self.rest_api_obj = None
def tray_init(self):
from .widget_user import UserWidget
self.widget_login = UserWidget(self)
self.load_credentials()
def register_callback_on_user_change(self, callback):
self.callbacks_on_user_change.append(callback)
def tray_start(self):
"""Store credentials to env and preset them to widget"""
username = ""
if self.cred:
username = self.cred.get("username") or ""
os.environ[self.env_name] = username
self.widget_login.set_user(username)
def tray_exit(self):
"""Nothing special for User."""
return
def get_user(self):
return self.cred.get("username") or getpass.getuser()
def webserver_initialization(self, server_manager):
"""Implementation of IWebServerRoutes interface."""
from .rest_api import UserModuleRestApi
self.rest_api_obj = UserModuleRestApi(self, server_manager)
def connect_with_modules(self, enabled_modules):
for module in enabled_modules:
if isinstance(module, IUserModule):
self.callbacks_on_user_change.append(
module.on_pype_user_change
)
# Definition of Tray menu
def tray_menu(self, parent_menu):
from Qt import QtWidgets
"""Add menu or action to Tray(or parent)'s menu"""
action = QtWidgets.QAction("Username", parent_menu)
action.triggered.connect(self.show_widget)
parent_menu.addAction(action)
parent_menu.addSeparator()
self.action_show_widget = action
def load_credentials(self):
"""Get credentials from JSON file """
credentials = {}
try:
file = open(self.cred_path, "r")
credentials = json.load(file)
file.close()
self.cred = credentials
username = credentials.get("username")
if username:
self.log.debug("Loaded Username \"{}\"".format(username))
else:
self.log.debug("Pype Username is not set")
return credentials
except FileNotFoundError:
return self.save_credentials(getpass.getuser())
except json.decoder.JSONDecodeError:
self.log.warning((
"File where users credentials should be stored"
" has invalid json format. Loading system username."
))
return self.save_credentials(getpass.getuser())
def change_credentials(self, username):
self.save_credentials(username)
for callback in self.callbacks_on_user_change:
try:
callback(username)
except Exception:
self.log.warning(
"Failed to execute callback \"{}\".".format(
str(callback)
),
exc_info=True
)
def save_credentials(self, username):
"""Save credentials to JSON file, env and widget"""
if username is None:
username = ""
username = str(username).strip()
self.cred = {"username": username}
os.environ[self.env_name] = username
if self.widget_login:
self.widget_login.set_user(username)
try:
file = open(self.cred_path, "w")
file.write(json.dumps(self.cred))
file.close()
self.log.debug("Username \"{}\" stored".format(username))
except Exception:
self.log.error(
"Could not store username to file \"{}\"".format(
self.cred_path
),
exc_info=True
)
return self.cred
def show_widget(self):
"""Show dialog to enter credentials"""
self.widget_login.show()

View file

@ -1,88 +0,0 @@
from Qt import QtCore, QtGui, QtWidgets
from avalon import style
from openpype import resources
class UserWidget(QtWidgets.QWidget):
MIN_WIDTH = 300
def __init__(self, module):
super(UserWidget, self).__init__()
self.module = module
# Style
icon = QtGui.QIcon(resources.pype_icon_filepath())
self.setWindowIcon(icon)
self.setWindowTitle("Username Settings")
self.setMinimumWidth(self.MIN_WIDTH)
self.setStyleSheet(style.load_stylesheet())
self.setWindowFlags(
QtCore.Qt.WindowCloseButtonHint |
QtCore.Qt.WindowMinimizeButtonHint
)
self.setLayout(self._main())
def show(self, *args, **kwargs):
super().show(*args, **kwargs)
# Move widget to center of active screen on show
screen = QtWidgets.QApplication.desktop().screen()
screen_center = lambda self: (
screen.rect().center() - self.rect().center()
)
self.move(screen_center(self))
def _main(self):
main_layout = QtWidgets.QVBoxLayout()
form_layout = QtWidgets.QFormLayout()
form_layout.setContentsMargins(10, 15, 10, 5)
label_username = QtWidgets.QLabel("Username:")
label_username.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
label_username.setTextFormat(QtCore.Qt.RichText)
input_username = QtWidgets.QLineEdit()
input_username.setPlaceholderText(
QtCore.QCoreApplication.translate("main", "e.g. John Smith")
)
form_layout.addRow(label_username, input_username)
btn_save = QtWidgets.QPushButton("Save")
btn_save.clicked.connect(self.click_save)
btn_cancel = QtWidgets.QPushButton("Cancel")
btn_cancel.clicked.connect(self.close)
btn_group = QtWidgets.QHBoxLayout()
btn_group.addStretch(1)
btn_group.addWidget(btn_save)
btn_group.addWidget(btn_cancel)
main_layout.addLayout(form_layout)
main_layout.addLayout(btn_group)
self.input_username = input_username
return main_layout
def set_user(self, username):
self.input_username.setText(username)
def click_save(self):
# all what should happen - validations and saving into appsdir
username = self.input_username.text()
self.module.change_credentials(username)
self._close_widget()
def closeEvent(self, event):
event.ignore()
self._close_widget()
def _close_widget(self):
self.hide()

View file

@ -1,6 +1,7 @@
import os
import getpass
import pyblish.api
from openpype.lib import get_openpype_username
class CollectCurrentUserPype(pyblish.api.ContextPlugin):
@ -11,9 +12,6 @@ class CollectCurrentUserPype(pyblish.api.ContextPlugin):
label = "Collect Pype User"
def process(self, context):
user = os.getenv("OPENPYPE_USERNAME", "").strip()
if not user:
user = context.data.get("user", getpass.getuser())
user = get_openpype_username()
context.data["user"] = user
self.log.debug("Colected user \"{}\"".format(user))

View file

@ -3,7 +3,8 @@ from .lib import (
get_project_settings,
get_current_project_settings,
get_anatomy_settings,
get_environments
get_environments,
get_local_settings
)
from .entities import (
SystemSettings,
@ -17,6 +18,7 @@ __all__ = (
"get_current_project_settings",
"get_anatomy_settings",
"get_environments",
"get_local_settings",
"SystemSettings",
"ProjectSettings"

View file

@ -161,9 +161,6 @@
"log_viewer": {
"enabled": true
},
"user": {
"enabled": true
},
"standalonepublish_tool": {
"enabled": true
}

View file

@ -154,20 +154,6 @@
}
]
},
{
"type": "dict",
"key": "user",
"label": "User setting",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
{
"type": "boolean",
"key": "enabled",
"label": "Enabled"
}
]
},
{
"type": "dict",
"key": "standalonepublish_tool",

View file

@ -1,3 +1,5 @@
import getpass
from Qt import QtWidgets
@ -5,16 +7,29 @@ class LocalGeneralWidgets(QtWidgets.QWidget):
def __init__(self, parent):
super(LocalGeneralWidgets, self).__init__(parent)
username_input = QtWidgets.QLineEdit(self)
username_input.setPlaceholderText(getpass.getuser())
layout = QtWidgets.QFormLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.addRow("OpenPype Username", username_input)
self.username_input = username_input
def update_local_settings(self, value):
return
# RETURNING EARLY TO HIDE WIDGET WITHOUT CONTENT
username = ""
if value:
username = value.get("username", username)
self.username_input.setText(username)
def settings_value(self):
# Add changed
# If these have changed then
output = {}
# TEMPORARILY EMPTY AS THERE IS NOTHING TO PUT HERE
username = self.username_input.text()
if username:
output["username"] = username
# Do not return output yet since we don't have mechanism to save or
# load these data through api calls
return output

View file

@ -80,7 +80,6 @@ class LocalSettingsWidget(QtWidgets.QWidget):
general_widget = LocalGeneralWidgets(general_content)
general_layout.addWidget(general_widget)
general_expand_widget.hide()
self.main_layout.addWidget(general_expand_widget)
@ -127,9 +126,9 @@ class LocalSettingsWidget(QtWidgets.QWidget):
self.system_settings.reset()
self.project_settings.reset()
# self.general_widget.update_local_settings(
# value.get(LOCAL_GENERAL_KEY)
# )
self.general_widget.update_local_settings(
value.get(LOCAL_GENERAL_KEY)
)
self.app_widget.update_local_settings(
value.get(LOCAL_APPS_KEY)
)
@ -139,9 +138,9 @@ class LocalSettingsWidget(QtWidgets.QWidget):
def settings_value(self):
output = {}
# general_value = self.general_widget.settings_value()
# if general_value:
# output[LOCAL_GENERAL_KEY] = general_value
general_value = self.general_widget.settings_value()
if general_value:
output[LOCAL_GENERAL_KEY] = general_value
app_value = self.app_widget.settings_value()
if app_value: