Beispiel #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"))
Beispiel #2
0
def _cast_strings(v):
    # type: (Sequence[Text]) -> Sequence[Text]
    if isinstance(v, six.binary_type):
        return (cast.text(v), )
    if isinstance(v, six.text_type):
        return (v, )
    return v
Beispiel #3
0
def latest() -> Text:
    # Use `requests` if we have more http related feature
    resp = cast.instance(
        urllib.request.urlopen(_VERSION_URL),
        http.client.HTTPResponse,
    )
    return cast.text(resp.read())
Beispiel #4
0
def _upload_image_v5_2(filename, folder, token):
    # type: (Text, Text, Text) -> ImageInfo
    """Upload image to server.

    Args:
        filename (str): Filename.
        folder (str): Server upload folder, usually same with project name.
        token (str): Server session token.

    Returns:
        ImageInfo: Uploaded image information.
    """

    filename = cast.text(filename)
    basename = os.path.basename(filename)
    data = post(
        "web_upload_file",
        {
            "folder": folder,
            "type": "project",
            "method": "convert_image",
            "filename": basename,
        },
        token=token,
        files={
            "file": (basename, open(filename, "rb"), mimetypes.guess_type(basename)[0])
        },
    )
    assert isinstance(data, dict), type(data)
    return ImageInfo(data["max"], data["min"], filename)
Beispiel #5
0
def get_online_account_id(token=None):
    # type: (Text) -> Text
    token = token or cast.text(core.CONFIG["DEFAULT_TOKEN"])
    resp = server.call("c_token",
                       "get_all_online_account_id_with_type",
                       token=token)
    return resp
Beispiel #6
0
def _get_status_v5_2(token):
    # type: (Text) -> Tuple[StatusInfo, ...]
    token = token or cast.text(CONFIG["DEFAULT_TOKEN"])
    resp = http.call("c_status",
                     "get_all",
                     token=token,
                     field_array=StatusInfo._fields)
    return tuple(StatusInfo(*i) for i in resp)
Beispiel #7
0
def get_account_id(token=None):
    # type: (Text) -> Text
    """Get account id from token.

    Args:
        token (str): Server token

    Returns:
        str: Account id.
    """

    token = token or cast.text(core.CONFIG["DEFAULT_TOKEN"])
    return server.call("c_token", "get_account_id", token=token)
Beispiel #8
0
def get_status(token=None):
    # type: (Optional[Text]) -> Tuple[StatusInfo, ...]
    """Get all status on the server.

    Args:
        token (str): User token.

    Returns:
        tuple[StatusInfo]: Status data.
    """
    token = token or cast.text(CONFIG["DEFAULT_TOKEN"])
    if compat.api_level() == compat.API_LEVEL_5_2:
        return _get_status_v5_2(token)
    return _get_status_v6_1(token)
Beispiel #9
0
def get_software_types(token=None):
    # type: (Text) -> List[Text]
    """Get all software types on the server.

    Args:
        token ([type], optional): Defaults to None. [description]

    Returns:
        list[str]
    """

    token = token or cast.text(CONFIG["DEFAULT_TOKEN"])
    resp = http.call("c_status", "get_software_type", token=token)
    return resp
Beispiel #10
0
def _get_shot(path, version_pattern=r"(.+)v(\d+)"):
    # type: (Text, Text) -> Text
    """The related shot for this footage.

    >>> _get_shot('sc_001_v20.nk')
    u'sc_001'
    >>> _get_shot('hello world')
    u'hello world'
    >>> _get_shot('sc_001_v-1.nk')
    u'sc_001_v-1'
    >>> _get_shot('sc001V1.jpg')
    u'sc001'
    >>> _get_shot('sc001V1_no_bg.jpg')
    u'sc001'
    >>> _get_shot('suv2005_v2_m.jpg')
    u'suv2005'
    """

    p = PurePath(cast.text(path))
    match = re.match(version_pattern, cast.text(p.name), flags=re.I)
    if not match:
        return cast.text(p.stem)
    shot = match.group(1)
    return shot.strip("_")
Beispiel #11
0
def _parse_by_indent(lines, indent="    "):
    key = ""  # type: str
    values = []
    for line in lines:
        line = cast.text(line)
        if line.startswith(indent) or line == indent.rstrip(" "):
            values.append(line[len(indent):])
        else:
            if key:
                yield (key, values)
                key = ""
                values = []
            key = line
    if values:
        yield (key, values)
Beispiel #12
0
    def set_fields(self, token=None, **data):
        # type: (Text, *Any) -> None
        r"""Set field data for the plug-in.

        Args:
            token (str, optional): Defaults to None. User token.
            \*\*data: Field name as key, Value as value.
        """

        token = token or cast.text(core.CONFIG["DEFAULT_TOKEN"])

        self.call("set_one_with_id",
                  token=token,
                  id=self.uuid,
                  field_data_array=data)

        self.last_fetch_time = None
Beispiel #13
0
def login(account, password):
    # type: (Text, Text) -> AccountInfo
    """Login on server.

    Args:
        account (str): Account name.
        password (str): Password.

    Raises:
        ValueError: When login fail.

    Returns:
        AccountInfo: Account information.
    """

    try:
        resp = server.call(
            "c_token",
            "login",
            account=account,
            password=password,
            token="",
            client_type="py",
        )
    except ValueError as ex:
        try:
            raise {
                "token::login, get account data error": AuthenticateError,
                "token::login, 密码错误,请检查": AuthenticateError,
                "token::login, 账号或密码错误, 请检查": AuthenticateError,
            }[cast.text(ex.args[0])]
        except (KeyError, IndexError):
            pass
        raise ex
    assert isinstance(resp, dict), type(resp)
    # Correct server-side typo.
    resp["password_complexity"] = (
        # spell-checker: disable
        resp.pop("password_comlexity", None)
        # spell-checker: enable
    )
    _ = [resp.setdefault(i, None) for i in AccountInfo._fields]
    return AccountInfo(**resp)
Beispiel #14
0
    def fetch(self, token=None):
        # type: (Text) -> None
        """Fetch plugin data from server."""

        if self.last_fetch_time and (
                self.last_fetch_time - time.time() >
                core.CONFIG["MIN_FETCH_INTERVAL"]):  # type: ignore
            return

        token = token or cast.text(core.CONFIG["DEFAULT_TOKEN"])
        resp = server.call(
            "c_plugin",
            "get_one_with_id",
            token=token,
            id=self.uuid,
            field_array=PluginInfo.fields,
        )
        self._cached_info = PluginInfo(*resp)

        self.last_fetch_time = time.time()
Beispiel #15
0
def _raise_error(result):
    # type: (Any) -> None
    if not isinstance(result, dict):
        return

    code, type_, data = (
        result.get("code"),
        result.get("type"),
        result.get("data", result),
    )

    if code is None:
        return
    elif code == "1":
        return
    elif (code, type_, data) == ("2", "msg", "please login!!!"):
        raise exceptions.LoginError
    msg = cast.text(data)
    if six.PY2:
        msg = cast.binary(msg)
    raise ValueError(msg)
Beispiel #16
0
def _upload_image_v6_1(filename, folder, token):
    # type: (Text, Text, Text) -> ImageInfo
    """Upload image to server.

    Args:
        filename (str): Filename.
        folder (str): Server upload folder, usually same with project name.
        token (str): Server session token.

    Returns:
        ImageInfo: Uploaded image information.
    """

    filename = cast.text(filename)
    basename = os.path.basename(filename)
    mtime = os.path.getmtime(filename)
    data = post(
        "web_upload_file",
        {
            "method": "attachment_upload",
            "is_web": "Y",
            "db": folder,
            "format": "image",
            "filename": basename,
            "attachment_argv": {
                "type": "main",
                "filename": filename,
                "modify_time": datetime.datetime.fromtimestamp(
                    mtime, ChinaTimezone()
                ).strftime("%Y-%m-%d %H:%M:%S"),
            },
        },
        token=token,
        files={
            "file": (basename, open(filename, "rb"), mimetypes.guess_type(basename)[0])
        },
    )
    assert isinstance(data, dict), type(data)
    return ImageInfo(data["max"], data["min"], filename, data["att_id"])
Beispiel #17
0
def _upload_image(image, folder, token):
    # type: (Any, Text, Text) -> ImageInfo
    if isinstance(image, ImageInfo):
        return image
    if isinstance(image, dict):
        if image.get("max") and image.get("min"):
            return ImageInfo(
                max=image["max"],
                min=image["min"],
                path=image.get("path"),
                attachment_id=image.get("att_id"),
            )
        if image.get("path"):
            image = image["path"]
        else:
            raise TypeError(
                "ImageInfo takes dictionary that has key (max, min, path?).",
                image.keys(),
            )

    if not isinstance(image, (six.text_type, str)):
        raise TypeError("Not support such data type.", type(image))

    return upload_image(cast.text(image), folder, token)
Beispiel #18
0
    def filter(cls, filters=None, token=None):
        # type: (Union[cgtwq.Filter, cgtwq.FilterList], Text) -> List[PluginMeta]
        """Filter plugins from server.

        Args:
            filters (Filter or FilterList, optional): Defaults to None. Plugin filter
            token (str, optional): Defaults to None. User token.

        Returns:
            list[Plugin]: Matched plug-ins.
        """

        filters = filters or Field("#id").has("%")
        token = token or cast.text(core.CONFIG["DEFAULT_TOKEN"])

        filters = FilterList(filters)
        resp = server.call(
            "c_plugin",
            "get_with_filter",
            token=token,
            field_array=PluginInfo.fields,
            filter_array=filters,
        )
        return [cls.from_info(PluginInfo(*i)) for i in resp]
def test_gbk():
    assert cast.text(b'\xb2\xe2\xca\xd4', "gbk") == "测试"
Beispiel #20
0
 def __new__(cls, name, bases, dict_):
     # type: (Text, Tuple[Any, ...], Any) -> type
     dict_[_BYTES_KEY] = lambda self: (cast.text(
         __bytes__) + _as_suffix(self.args)).encode("utf-8")
     dict_[_STR_KEY] = lambda self: __str__ + _as_suffix(self.args)
     return type.__new__(cls, name, bases, dict_)
Beispiel #21
0
 def token(self):
     # type: () -> Text
     """User token."""
     return self._token or cast.text(core.CONFIG["DEFAULT_TOKEN"])
Beispiel #22
0
def _column_by_alias(header, header_alias):
    # type: (Any, Dict[Text, Tuple[Text, ...]]) -> Text
    for k, v in six.iteritems(header_alias):
        if header in v:
            return k
    return cast.text(header)
Beispiel #23
0
def _handle_windows_line_ending(lines):
    for i in lines:
        i = cast.text(i)
        yield i.strip("\r\n")
Beispiel #24
0
def typing_from_help(text):
    return "\n".join(iterate_typing_from_help(cast.text(text).splitlines()))
def test_binary():
    assert cast.text(b"value") == "value"
def test_text():
    assert cast.text("测试") == "测试"
def test_utf8():
    assert cast.text(b'\xe6\xb5\x8b\xe8\xaf\x95') == "测试"
def test_dict():
    assert cast.text(dict(a=1)) == "{'a': 1}"
def test_int():
    assert cast.text(1) == "1"