Ejemplo n.º 1
0
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"))
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
    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()
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
def add_panel():
    """Add custom pannel. """

    LOGGER.info('添加面板')
    if cgtwq.DesktopClient().executable():
        import cgtwq_uploader
        panels.register(cgtwq_uploader.Dialog, '上传mov', 'com.wlf.uploader')
Ejemplo n.º 9
0
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_())
Ejemplo n.º 10
0
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)
Ejemplo n.º 11
0
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()
Ejemplo n.º 12
0
    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()
Ejemplo n.º 13
0
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: 当前所选对象''')
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
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
Ejemplo n.º 16
0
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
Ejemplo n.º 17
0
    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
Ejemplo n.º 18
0
    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)
Ejemplo n.º 19
0
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))
Ejemplo n.º 20
0
 def test_plugin_data(self):
     try:
         result = cgtwq.DesktopClient().plugin.data()
         self.assertIsInstance(result, cgtwq.model.PluginData)
     except cgtwq.IDError:
         pass
Ejemplo n.º 21
0
# -*- 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()
Ejemplo n.º 22
0
 def test_init(self):
     from cgtwn import Task
     cgtwq.DesktopClient().connect()
     select = Task.from_shot('MT_EP06_06_sc013')
     self.assertEqual(len(select), 1)
Ejemplo n.º 23
0
# -*- 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
Ejemplo n.º 24
0
 def test_refresh_selected(self):
     cgtwq.DesktopClient().refresh_selected("proj_sdktest", "shot")
Ejemplo n.º 25
0
 def test_status(self):
     result = cgtwq.DesktopClient().status
     self.assertIsInstance(result, cgtwq.client.DesktopClientStatus)
Ejemplo n.º 26
0
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)))