def main(): client = cgtwq.DesktopClient() client.connect() win_unicode_console.enable() logging.basicConfig( level="INFO", format="%(levelname)-7s:%(name)s: %(message)s", ) print("{:-^50}".format("Link 导入 v{}".format(__version__))) print( """\ 所需表格格式: | 镜头 | 资产1 | 资产2 | | --------------------- | ------ | ------- | | SDKTEST_EP01_01_sc001 | asset1 | asset2 | | SDKTEST_EP01_01_sc002 | asset1 | 必须有命名为镜头(支持别名:shot)的列,所有其他表头不为空的列将视为资产。 镜头的值为 shot.entity 字段 资产的值为 asset.entity 字段 """ ) client = cgtwq.DesktopClient() client.connect() plugin_data = client.plugin.data() # type: ignore db = cgtwq.Database(cast.text(plugin_data.database)) # type: ignore filename = filetools.ask_filename() if not filename: return workbook = openpyxl.load_workbook(filename) for i in xlsxtools.iter_workbook_as_dict(workbook, HEADER_ALIAS): shot = i.get("shot") if shot: _link( db, cast.text(shot), tuple( cast.text(v) for k, v in six.iteritems(i) if (k and v and k != "shot") ), ) else: LOGGER.warning("忽略不支持的数据: %s", cast.binary(i).decode("unicode-escape"))
def test_current_select(): try: select = cgtwq.DesktopClient().current_select() assert isinstance(select, cgtwq.Selection) except ValueError as ex: if ex.args != ("Empty selection.", ): raise
def main(): client = cgtwq.DesktopClient() client.connect() plugin_data = client.plugin.data() select = cgtwq.Selection.from_data(**plugin_data._asdict()) select.flow.submit(plugin_data.file_path_list)
def __init__(self): super(Dialog, self).__init__() QtCompat.loadUi(os.path.join(__file__, '../downloader.ui'), self) self.file_sets = {} self._files = RemoteFiles() self.is_downloading = False # Recover from config. self.dir = CONFIG['OUTPUT_DIR'] # Setup radio buttons. self.radioButtonSubmit.toggled.connect( lambda status: self.on_radio_toggled(SUBMIT_FILE, status)) select = cgtwq.DesktopClient().selection() pipeline = select.module.database.pipeline.filter( cgtwq.Filter('entity', select['pipeline'][0]))[0] for filebox in ( select.module.database.filebox.list_by_pipeline(pipeline)): button = QRadioButton(filebox.title) button.setObjectName(filebox.title) button.toggled.connect(lambda status, target=filebox: self. on_radio_toggled(target, status)) self.groupBox.layout().addWidget(button) # Connect signals. self.toolButton.clicked.connect(self.ask_dir) self.lineEditDir.editingFinished.connect(self.autoset) self.checkBoxSkipSame.toggled.connect(self.update_filelist) self.update_filelist()
def block(select, field): """Block drag in when task already approved. """ assert isinstance(select, cgtwq.Selection), type(select) client = cgtwq.DesktopClient() if any(i == 'Approve' for i in select[field]): client.plugin.send_result(False)
def dialog_login(): """Login teamwork. """ client = cgtwq.DesktopClient() if client.is_logged_in(): client.connect() Tray.message('CGTeamWork', '登录成功') return account = '帐号' password = '******' panel = nuke.Panel(utf8('登录CGTeamWork')) panel.addSingleLineInput(utf8('帐号'), '') panel.addPasswordInput(utf8('密码'), '') while True: confirm = panel.show() if confirm: try: cgtwq.core.CONFIG['DEFAULT_TOKEN'] = cgtwq.login( panel.value(account), panel.value(password)) except ValueError: Tray.message('CGTeamWork', '登录失败') continue Tray.message('CGTeamWork', '登录成功') break
def create_workbook(rows): # type: (typing.List[typing.Dict]) -> openpyxl.Workbook book = openpyxl.Workbook() sheet = book.active sheet.append( ['镜头', '流程', '制作者', '状态', '时间', '顺序(最新为1)', "阶段", '操作用户', '备注']) sheet.freeze_panes = 'A2' server_ip = cgtwq.DesktopClient().server_ip for i in rows: row = [ i['shot'], i['pipeline'], i['artist'], i['status'], i['time'], i['order'], i['step'], i['created_by'], ] note = parse_html_comment(i['html']) if note['text']: row.append(note['text']) for img in note['images']: link = u'=HYPERLINK("http://{}/{}","[{}]")'.format( server_ip, img, os.path.basename(img)) row.append(link) sheet.append(row) return book
def add_panel(): """Add custom pannel. """ LOGGER.info('添加面板') if cgtwq.DesktopClient().executable(): import cgtwq_uploader panels.register(cgtwq_uploader.Dialog, '上传mov', 'com.wlf.uploader')
def main(): cgtwq.DesktopClient().connect() # TODO: refactor this when new version of `wlf` released mp_logging.basic_config() QApplication(sys.argv) frame = Dialog() QtProgressBar.default_parent = frame sys.exit(frame.exec_())
def main(): win_unicode_console.enable() logging.basicConfig(level='INFO', format='%(levelname)-7s:%(name)s: %(message)s') print('更新返修次数 v{}'.format(__version__)) client = cgtwq.DesktopClient() client.connect() select = client.selection() setup_fields(select.module) for i in select.to_entries(): update_entry(i)
def _connect_desktop_client(): account, passwd = ( os.getenv("CGTWQ_TEST_ACCOUNT"), os.getenv("CGTWQ_TEST_PASSWORD"), ) if account and passwd: info = cgtwq.login(account, passwd) cgtwq.core.CONFIG["DEFAULT_TOKEN"] = info.token return client = cgtwq.DesktopClient() if client.is_logged_in(): client.connect()
def _setup_cgtw(): client = cgtwq.DesktopClient() if not client.executable(): return import cgtwn import pyblish_lite_nuke client.start() pyblish_lite_nuke.setup() cgtwn.setup() if client.is_logged_in(): client.connect()
def main(): client = cgtwq.DesktopClient() client.connect() select = client.selection() __main__ = sys.modules['__main__'] for k, v in { 'DATABASE': select.module.database, 'MODULE': select.module, 'SELECT': select }.items(): setattr(__main__, k, v) print(''' 已设置变量: DATABASE: 当前数据库对象 MODULE: 当前模块对象 SELECT: 当前所选对象''')
def main(): logging.basicConfig(level=logging.INFO) win_unicode_console.enable() client = cgtwq.DesktopClient() client.connect() select = client.selection() try: assign_same_to_downstream(select) pause(5) except KeyError: LOGGER.error('当前仅支持流程: %s', ','.join(DOWNSTREAM_DICT.keys())) pause(0) except: import traceback traceback.print_exc() pause(0) raise
def main(): win_unicode_console.enable() logging.basicConfig( level='INFO', format='%(levelname)-7s:%(name)s: %(message)s') logging.getLogger("cgtwq").setLevel(logging.DEBUG) print('{:-^50}'.format('导入XLSX返修表 v{}'.format(__version__))) dummy = application() client = cgtwq.DesktopClient() client.connect() plugin_data = client.plugin.data() filename = ask_filename() if not filename: return try: data = get_data(filename) if not data: LOGGER.error('没能发现任何可用数据') raise ParseException import_data(data, plugin_data.database, plugin_data.module, plugin_data.module_type) pause() except CancelledError: LOGGER.info('用户取消') except ParseException: print('\n分析表格失败, 请检查上方日志\n') pause(0) return except ImportException: print('\n导入数据失败, 请检查上方日志\n') pause(0) return except: import traceback traceback.print_exc() pause(0) raise
def main(): """Get plugin setting from cgtw. """ logging.basicConfig(level=logging.INFO) print('AIA_manage v{}'.format(__version__)) client = cgtwq.DesktopClient() client.connect() metadata = client.plugin.metadata() select = client.selection() func = { 'set_readonly': set_readonly, 'set_writable': set_writable, 'transfer': transfer, 'block': lambda select: block(select, metadata.arguments['field']) }[metadata.arguments['operation']] try: func(select) except: client.plugin.send_result(False) raise
def process(self, instance): assert isinstance(instance, pyblish.api.Instance) client = cgtwq.DesktopClient() if client.is_logged_in(): client.connect() shot = PurePath(instance.name).shot try: task = Task.from_shot(shot) instance.context.data['task'] = task except ValueError: self.log.error('无法在数据库中找到对应任务: %s', shot) raise self.log.info('任务 %s', task) try: instance.context.data['workfileFileboxInfo'] = \ task.filebox.get('workfile') except: self.log.error('找不到标识为workfile的文件框 请联系管理员进行设置') raise
def __init__(self, target=SUBMIT_FILE): select = cgtwq.DesktopClient().selection() files = set() if target == SUBMIT_FILE: # Get from submit files. files.update(select.flow.list_submit_file()) else: # Get from filebox. checked = set() for entry in progress(select.to_entries(), '获取文件框内容'): assert isinstance(entry, cgtwq.Entry) filebox = entry.filebox.from_id(target.id) path = Path(filebox.path) for rule in filebox.rule: key = (path, rule) if key in checked: continue files.update(i for i in path.glob(rule) if i.is_file()) checked.add(key) files = (RemoteFile(i) if not isinstance(i, RemoteFile) else i for i in list(files)) super(RemoteFiles, self).__init__(files)
def main(): print('{:-^50s}'.format('导出历史 v{}'.format(__version__))) wlf.mp_logging.basic_config() dummy_app = QApplication(sys.argv) filename, _ = QFileDialog.getSaveFileName( None, '保存位置', 'E:/任务历史-{}.xlsx'.format(datetime.now().strftime('%Y%m%d-%H%M')), '*.xlsx') if not filename: return client = cgtwq.DesktopClient() client.connect() pipeline = set( client.selection().get_fields("pipeline").column("pipeline")) select = client.selection().module.filter( cgtwq.Field("pipeline").in_(list(pipeline)), ) try: rows = get_rows(select) wb = create_workbook(rows) wb.save(filename) webbrowser.open(os.path.dirname(filename)) except IOError: LOGGER.error('不能写入文件: %s', filename) msgbox('不能写入文件: {}, 请检查文件占用'.format(filename))
def test_plugin_data(self): try: result = cgtwq.DesktopClient().plugin.data() self.assertIsInstance(result, cgtwq.model.PluginData) except cgtwq.IDError: pass
# -*- coding=UTF-8 -*- """Test `cgtwn` module. """ from __future__ import (absolute_import, division, print_function, unicode_literals) from unittest import TestCase, main, skipUnless import cgtwq @skipUnless(cgtwq.DesktopClient().is_logged_in(), 'not logged in') class TaskTestCase(TestCase): def test_init(self): from cgtwn import Task cgtwq.DesktopClient().connect() select = Task.from_shot('MT_EP06_06_sc013') self.assertEqual(len(select), 1) if __name__ == '__main__': main()
def test_init(self): from cgtwn import Task cgtwq.DesktopClient().connect() select = Task.from_shot('MT_EP06_06_sc013') self.assertEqual(len(select), 1)
# -*- coding=UTF-8 -*- """Downloader test. """ from __future__ import absolute_import, print_function, unicode_literals import uuid import pytest from pathlib2 import Path import cgtwq from downloader import RemoteFile, RemoteFiles # pylint: disable = invalid-name cgteamwork_required = pytest.mark.skipif( not cgtwq.DesktopClient().is_logged_in(), reason='Need cgteamwork logged in') pytestmark = [] # pylint: enable = invalid-name @cgteamwork_required def test_update(): for target in ('Final', 'Submit'): print(RemoteFiles(target)) def test_remote_file_download(tmp_path): # type: (pathlib2.Path) -> None context1 = uuid.uuid4().hex
def test_refresh_selected(self): cgtwq.DesktopClient().refresh_selected("proj_sdktest", "shot")
def test_status(self): result = cgtwq.DesktopClient().status self.assertIsInstance(result, cgtwq.client.DesktopClientStatus)
def add_menu(): """Add menu for commands and nodes.""" LOGGER.info('添加菜单') def _(*args, **kwargs): args = (i.encode('utf-8') if isinstance(i, unicode) else i for i in args) kwargs = tuple({ k: v.encode('utf-8') if isinstance(v, unicode) else v for k, v in kwargs.items() }.items()) return (args, kwargs) def _autocomp(): try: comp.Comp().create_nodes() except comp.FootageError: nuke.message(utf8('请先导入素材')) def _open_help(): help_page = os.path.join(RESOURCE_DIR, 'Documentation/build/html/index.html') webbrowser.open(help_page) all_menu = [{ _('编辑'): [ _('同时编辑多个节点', lambda: edit_panels.MultiEdit().show(), 'F2'), _('分离图层', lambda: edit.split_layers(nuke.selectedNode()), 'F3', icon="SplitLayers.png"), _("分离rgba", lambda: edit.shuffle_rgba(nuke.selectedNode()), 'SHIFT+F3'), _("重命名PuzzleMatte", lambda: edit_panels.ChannelsRename().show(), 'F4'), _("标记为稍后启用", lambda: enable_later.mark_enable(nuke.selectedNodes()), 'SHIFT+D'), _('输出当前帧png', lambda: comp.render_png(nuke.selectedNodes(), show=True), 'SHIFT+F7'), _("设置帧范围", edit.dialog_set_framerange), _('转换为相对路径', lambda: edit.use_relative_path(nuke.selectedNodes()), icon="utilitiesfolder.png"), None, _("禁用所有稍后启用节点", lambda: enable_later.marked_nodes().disable(), 'CTRL+SHIFT+D'), _("修正读取错误", asset.fix_read, 'F6'), _("Reload所有", edit.reload_all_read_node), _("检查缺帧", lambda: asset.warn_missing_frames(show_ok=True)), _("检查素材更新", lambda: asset.warn_mtime(show_ok=True)), _("转换单帧为序列", edit.replace_sequence), { _('最佳实践'): [ _("清理无用节点", lambda: edit.delete_unused_nodes(message=True)), _("合并重复读取节点", edit.remove_duplicated_read), _("Glow节点不使用mask", edit.best_practice.glow_no_mask) ] }, { _('整理'): [ _("整理所选节点(竖式摆放)", lambda: orgnize.autoplace(nuke.selectedNodes()), "L", shortcutContext=DAG_CONTEXT), _("所有Gizmo转Group", edit.all_gizmo_to_group), _("根据背板重命名所有节点", orgnize.rename_all_nodes), _("节点添加Dots变成90度", lambda: orgnize.nodes_add_dots(nuke.selectedNodes())), _("所有节点添加Dots变成90度", lambda: orgnize.nodes_add_dots(nuke.allNodes())) ] } ] }, { _('合成'): [ _('自动合成', _autocomp, icon='autocomp.png'), _('自动合成设置', lambda: comp.panels.CompConfigPanel().showModalDialog(), icon='autocomp.png'), _('redshift预合成', lambda: comp.Precomp.redshift(nuke.selectedNodes()), 'F1', shortcutContext=DAG_CONTEXT, icon='autocomp.png') ] }, { _('工具'): [ _('批量自动合成', lambda: comp.panels.BatchCompPanel().showModalDialog(), icon='autocomp.png'), _('扫描空文件夹', scanner.call_from_nuke), _('分离exr', splitexr.Dialog.show), _("分割当前文件(根据背板)", orgnize.split_by_backdrop) ] }, { _('帮助'): [ _('吾立方插件 文档', _open_help), _("吾立方网站", lambda: webbrowser.open('http://www.wlf-studio.com/')) ] }] if cgtwq.DesktopClient().executable(): all_menu.insert( -2, { _('CGTeamWork', icon='cgteamwork.png'): [ _('登录', cgtwn_panels.dialog_login), _('创建项目文件夹', cgtwn_panels.dialog_create_dirs), _( '上传工具', lambda: nukescripts.panels.restorePanel( 'com.wlf.uploader')), ] }) if getattr(nuke, 'startPerformanceTimers'): all_menu.insert( -1, { _('性能监控'): [ _('开始', nuke.startPerformanceTimers), _('结束', nuke.stopPerformanceTimers), _('重置', nuke.resetPerformanceTimers), ], }) # Add all menu. def _add_menu(menu, parent=nuke.menu("Nuke")): assert isinstance(menu, dict) for k, v in menu.items(): m = parent.addMenu(*k[0], **dict(k[1])) for i in v: if i is None: m.addSeparator() elif isinstance(i, dict): _add_menu(i, m) elif isinstance(i, tuple): m.addCommand(*i[0], **dict(i[1])) for menu in all_menu: _add_menu(menu) # Set old autoplace shortcut. try: nuke.menu("Nuke").findItem('Edit').findItem('Node').findItem( 'Autoplace').setShortcut("Ctrl+L") except AttributeError as ex: print(ex) # create_node_menu _plugin_path = '../../../plugins' m = nuke.menu("Nodes") m = m.addMenu('吾立方'.encode('utf-8'), icon='Modify.png') create_menu_by_dir(m, os.path.abspath(os.path.join(__file__, _plugin_path)))