From 02c3393e57e4da39b4283526f7d65ba5d59d00f6 Mon Sep 17 00:00:00 2001 From: wjmcat <1435130236@qq.com> Date: Sat, 29 Feb 2020 20:45:50 +0800 Subject: [PATCH 1/5] add quick test --- src/wechaty/accessory.py | 31 +++++++++++++++++++ src/wechaty/config.py | 7 +++++ src/wechaty/images.py | 67 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 src/wechaty/accessory.py create mode 100644 src/wechaty/config.py create mode 100644 src/wechaty/images.py diff --git a/src/wechaty/accessory.py b/src/wechaty/accessory.py new file mode 100644 index 00000000..e035ed27 --- /dev/null +++ b/src/wechaty/accessory.py @@ -0,0 +1,31 @@ +from abc import ABCMeta,abstractclassmethod +from typing import Any +from enum import Enum + +class Puppet(object): + + def message_image(self,id:int,image_type : Enum): + """ + docstring + :param id: + :param image_type: + :return: + """ + pass + +class Accessory(object): + """ + + """ + __metaclass__ = ABCMeta + + def __init__(self): + self.puppet = Puppet() + + @abstractclassmethod + def __str__(self): + """ + docstring + :return: + """ + raise NotImplementedError diff --git a/src/wechaty/config.py b/src/wechaty/config.py new file mode 100644 index 00000000..0a8c7ade --- /dev/null +++ b/src/wechaty/config.py @@ -0,0 +1,7 @@ +import logging + + +class FileBox: + pass + +log = logging.getLogger(__name__) \ No newline at end of file diff --git a/src/wechaty/images.py b/src/wechaty/images.py new file mode 100644 index 00000000..5016bc92 --- /dev/null +++ b/src/wechaty/images.py @@ -0,0 +1,67 @@ +from src.wechaty.accessory import Accessory +from src.wechaty.config import FileBox,log +from typing import Optional,Type,TypeVar +import asyncio +from enum import IntEnum + +class ImageType(IntEnum): + """ + docstring ... + """ + Thumbnail = 0, + HD = 1, + Artwork = 2 + +class Image(Accessory): + """ + docstring ... + """ + def __init__(self,id:str) -> None: + super(Image,self).__init__() + self.id = id + log.info(f"create image : {self.__name__}") + + if self.puppet is None: + raise NotImplementedError("Image class can not be instanciated without a puppet!") + + + @staticmethod + def create(cls:Image,id:str) -> Image: + """ + docstring + :param cls: + :param id: + :return: + """ + log.info(f"create static image : {id}") + return cls(id) + + async def thumbnail(self) -> FileBox: + """ + docstring + :return: + """ + log.info(f"image thumbnail for {self.id}") + file_box = await self.puppet.message_image(self.id, ImageType.Thumbnail) + return file_box + + async def hd(self) -> FileBox: + """ + docstring + :return: + """ + log.info(f"image hd for {self.id}") + file_box = await self.puppet.message_image(self.id,ImageType.HD) + return file_box + + async def artwork(self) -> FileBox: + """ + docstring + :return: + """ + log.info(f"image artwork for {self.id}") + file_box = await self.puppet.message_image(self.id, ImageType.Artwork) + return file_box + + + From d6e39ffa5ec05f7d8857d3ddf323935ebcca262d Mon Sep 17 00:00:00 2001 From: wjmcat <1435130236@qq.com> Date: Tue, 3 Mar 2020 14:28:07 +0800 Subject: [PATCH 2/5] update base structure --- requirements.txt | 1 + src/wechaty/accessory.py | 72 ++++++++++++++++++++++++++---------- src/wechaty/config.py | 37 ++++++++++-------- src/wechaty/config_test.py | 14 +++---- src/wechaty/images.py | 66 +++++++++++++++++++-------------- src/wechaty/user/__init__.py | 0 src/wechaty/wechaty.py | 43 +++++++++++++++++++++ wechaty_puppet/__init__.py | 0 wechaty_puppet/file_box.py | 22 +++++++++++ wechaty_puppet/puppet.py | 27 ++++++++++++++ 10 files changed, 213 insertions(+), 69 deletions(-) create mode 100644 src/wechaty/user/__init__.py create mode 100644 src/wechaty/wechaty.py create mode 100644 wechaty_puppet/__init__.py create mode 100644 wechaty_puppet/file_box.py create mode 100644 wechaty_puppet/puppet.py diff --git a/requirements.txt b/requirements.txt index be3368ad..fc4f382f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +overrides flake8 mypy mypy_extensions diff --git a/src/wechaty/accessory.py b/src/wechaty/accessory.py index e035ed27..28a8b6cc 100644 --- a/src/wechaty/accessory.py +++ b/src/wechaty/accessory.py @@ -1,31 +1,65 @@ -from abc import ABCMeta,abstractclassmethod -from typing import Any -from enum import Enum +""" +docstring +""" +from abc import ABCMeta +from typing import Optional +from wechaty_puppet.puppet import Puppet +from .config import LOG +from .wechaty import Wechaty -class Puppet(object): - def message_image(self,id:int,image_type : Enum): - """ - docstring - :param id: - :param image_type: - :return: - """ - pass - -class Accessory(object): +class Accessory: """ - + docstring """ __metaclass__ = ABCMeta + _puppet: Puppet = None + # static _wechaty property to doing ... + _wechaty: Wechaty = None - def __init__(self): - self.puppet = Puppet() - - @abstractclassmethod def __str__(self): """ docstring :return: """ raise NotImplementedError + + @classmethod + def puppet(cls, value: Puppet = None) -> Optional[Puppet]: + """ + get/set global single instance of the puppet + :return: + """ + if value is None: + LOG.info("get puppet instance ...") + if cls._puppet is None: + raise AttributeError("static puppet instance not found ...") + return cls._puppet + + LOG.info("set puppet instance ...") + cls._puppet = value + return None + + @classmethod + def wechaty(cls, value: Wechaty = None) -> Optional[Wechaty]: + """ + get/set wechaty instance + + If the param of value is None, then the function will return the + instance of wechaty.Otherwise, the function will check the type + of the value, and set as wechaty instance + :param value: + :return: + """ + if value is None: + LOG.info("get wechaty instance") + if cls._wechaty is None: + raise AttributeError("wechaty instance not found") + return cls._wechaty + if not isinstance(value, Wechaty): + raise NameError( + "expected wechaty instance type is Wechaty, " + "but got %s" % value.__class__ + ) + cls._wechaty = value + return None diff --git a/src/wechaty/config.py b/src/wechaty/config.py index bddaacc3..b90f058e 100644 --- a/src/wechaty/config.py +++ b/src/wechaty/config.py @@ -1,22 +1,27 @@ -''' -config module -''' +""" + * + * Wechaty - https://github.com/wechaty/python-wechaty + * + * @copyright wechaty + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + """ import logging import os - -# dummy class -class FileBox: - '''FileBox''' - - def toJSON(self): - '''doc''' - - def toFile(self): - '''doc''' - - -log = logging.getLogger(__name__) +LOG = logging.getLogger(__name__) # log.debug('test logging debug') # log.info('test logging info') diff --git a/src/wechaty/config_test.py b/src/wechaty/config_test.py index 41be37b0..11f885a1 100644 --- a/src/wechaty/config_test.py +++ b/src/wechaty/config_test.py @@ -1,6 +1,6 @@ -''' +""" config unit test -''' +""" from typing import ( Any, # Dict, @@ -9,7 +9,7 @@ import pytest # type: ignore from .config import ( - log, + LOG, ) # pylint: disable=redefined-outer-name @@ -25,14 +25,14 @@ def fixture_data() -> Iterable[str]: def test_config( data: Any, ) -> None: - ''' + """ Unit Test for config function - ''' + """ print(data) assert data == 'test', 'data should equals test' def test_log(): - '''test''' - assert log, 'log should exist' + """test""" + assert LOG, 'log should exist' diff --git a/src/wechaty/images.py b/src/wechaty/images.py index 5016bc92..dabefac7 100644 --- a/src/wechaty/images.py +++ b/src/wechaty/images.py @@ -1,48 +1,61 @@ -from src.wechaty.accessory import Accessory -from src.wechaty.config import FileBox,log -from typing import Optional,Type,TypeVar -import asyncio +""" +docstring +""" from enum import IntEnum +import overrides +from wechaty_puppet.file_box import FileBox +from .accessory import Accessory +from .config import LOG + class ImageType(IntEnum): """ docstring ... """ - Thumbnail = 0, - HD = 1, + Thumbnail = 0 + HD = 1 Artwork = 2 + class Image(Accessory): """ docstring ... """ - def __init__(self,id:str) -> None: - super(Image,self).__init__() - self.id = id - log.info(f"create image : {self.__name__}") - if self.puppet is None: - raise NotImplementedError("Image class can not be instanciated without a puppet!") + @overrides + def __str__(self): + return "image instance : %d" % self.image_id + def __init__(self, image_id: str) -> None: + """ + :param image_id: + """ + super(Image, self).__init__() + self.image_id = image_id + LOG.info("create image : %d", self.image_id) + if self.puppet is None: + raise NotImplementedError("Image class can not be instanced" + " without a puppet!") - @staticmethod - def create(cls:Image,id:str) -> Image: + @classmethod + def create(cls: "Image", image_id: int) -> "Image": """ - docstring + create image instance by image_id :param cls: - :param id: + :param image_id: :return: """ - log.info(f"create static image : {id}") - return cls(id) + LOG.info("create static image : %d", image_id) + return cls(image_id) async def thumbnail(self) -> FileBox: """ docstring :return: """ - log.info(f"image thumbnail for {self.id}") - file_box = await self.puppet.message_image(self.id, ImageType.Thumbnail) + LOG.info("image thumbnail for %d", self.image_id) + file_box = await self.puppet()\ + .message_image(self.image_id, ImageType.Thumbnail) return file_box async def hd(self) -> FileBox: @@ -50,8 +63,9 @@ async def hd(self) -> FileBox: docstring :return: """ - log.info(f"image hd for {self.id}") - file_box = await self.puppet.message_image(self.id,ImageType.HD) + LOG.info("image hd for %d", self.image_id) + file_box = await self.puppet().\ + message_image(self.image_id, ImageType.HD) return file_box async def artwork(self) -> FileBox: @@ -59,9 +73,7 @@ async def artwork(self) -> FileBox: docstring :return: """ - log.info(f"image artwork for {self.id}") - file_box = await self.puppet.message_image(self.id, ImageType.Artwork) + LOG.info("image artwork for %d", self.image_id) + file_box = await self.puppet().\ + message_image(self.image_id, ImageType.Artwork) return file_box - - - diff --git a/src/wechaty/user/__init__.py b/src/wechaty/user/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/wechaty/wechaty.py b/src/wechaty/wechaty.py new file mode 100644 index 00000000..8e3c5ff1 --- /dev/null +++ b/src/wechaty/wechaty.py @@ -0,0 +1,43 @@ +""" +wechaty instance +""" +from typing import Optional + + +# pylint: disable=R0903 +class WechatyOptions: + """ + WechatyOptions instance + """ + def __init__(self): + """ + WechatyOptions constructor + """ + self.io_token: str = None + self.name: str = None + self.profile: Optional[None or str] = None + + +# pylint: disable=R0903 + +class Wechaty: + """ + docstring + """ + def __init__(self): + """ + docstring + """ + raise NotImplementedError + + _global_instance: "Wechaty" = None + + @classmethod + def instance(cls: "Wechaty") -> "Wechaty": + """ + get or create global wechaty instance + :return: + """ + if cls._global_instance is None: + cls._global_instance = Wechaty() + return cls._global_instance diff --git a/wechaty_puppet/__init__.py b/wechaty_puppet/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/wechaty_puppet/file_box.py b/wechaty_puppet/file_box.py new file mode 100644 index 00000000..007f3bcd --- /dev/null +++ b/wechaty_puppet/file_box.py @@ -0,0 +1,22 @@ +""" +docstring +""" +# dummy class +class FileBox: + """ + maintain the file content, which is sended by wechat + """ + + def to_json(self) -> dict: + """ + dump the file content to json object + :return: + """ + raise NotImplementedError + + def to_file(self, file_path: str) -> None: + """ + save the content to the file + :return: + """ + raise NotImplementedError diff --git a/wechaty_puppet/puppet.py b/wechaty_puppet/puppet.py new file mode 100644 index 00000000..84d3c259 --- /dev/null +++ b/wechaty_puppet/puppet.py @@ -0,0 +1,27 @@ +""" +interface for puppet +""" +from enum import Enum + +class Puppet: + """ + puppet interface class + """ + + # pylint: disable=R0201 + def message_image(self, message_id: int, image_type: Enum) -> None: + """ + docstring + :param message_id: + :param image_type: + :return: + """ + raise NotImplementedError + + def start(self) -> None: + """ + start the puppet + :return: + """ + raise NotImplementedError + From 70745f12fa019b1f4b84555bc37859ce347b6e13 Mon Sep 17 00:00:00 2001 From: wjmcat <1435130236@qq.com> Date: Wed, 4 Mar 2020 14:40:57 +0800 Subject: [PATCH 3/5] complete all test --- src/wechaty/accessory.py | 8 ++++---- src/wechaty/images.py | 27 ++++++++++++++++++--------- src/wechaty/wechaty.py | 19 +++++++++++-------- wechaty_puppet/puppet.py | 4 +++- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/wechaty/accessory.py b/src/wechaty/accessory.py index 28a8b6cc..0602ed55 100644 --- a/src/wechaty/accessory.py +++ b/src/wechaty/accessory.py @@ -13,9 +13,9 @@ class Accessory: docstring """ __metaclass__ = ABCMeta - _puppet: Puppet = None + _puppet: Optional[Puppet] = None # static _wechaty property to doing ... - _wechaty: Wechaty = None + _wechaty: Optional[Wechaty] = None def __str__(self): """ @@ -25,7 +25,7 @@ def __str__(self): raise NotImplementedError @classmethod - def puppet(cls, value: Puppet = None) -> Optional[Puppet]: + def puppet(cls, value: Optional[Puppet] = None) -> Optional[Puppet]: """ get/set global single instance of the puppet :return: @@ -41,7 +41,7 @@ def puppet(cls, value: Puppet = None) -> Optional[Puppet]: return None @classmethod - def wechaty(cls, value: Wechaty = None) -> Optional[Wechaty]: + def wechaty(cls, value: Optional[Wechaty] = None) -> Optional[Wechaty]: """ get/set wechaty instance diff --git a/src/wechaty/images.py b/src/wechaty/images.py index dabefac7..68d81fc6 100644 --- a/src/wechaty/images.py +++ b/src/wechaty/images.py @@ -2,7 +2,7 @@ docstring """ from enum import IntEnum -import overrides +from typing import Type, TypeVar from wechaty_puppet.file_box import FileBox from .accessory import Accessory from .config import LOG @@ -17,12 +17,14 @@ class ImageType(IntEnum): Artwork = 2 +T = TypeVar("T", bound="Image") + + class Image(Accessory): """ docstring ... """ - @overrides def __str__(self): return "image instance : %d" % self.image_id @@ -38,7 +40,7 @@ def __init__(self, image_id: str) -> None: " without a puppet!") @classmethod - def create(cls: "Image", image_id: int) -> "Image": + def create(cls: Type[T], image_id: str) -> T: """ create image instance by image_id :param cls: @@ -54,8 +56,11 @@ async def thumbnail(self) -> FileBox: :return: """ LOG.info("image thumbnail for %d", self.image_id) - file_box = await self.puppet()\ - .message_image(self.image_id, ImageType.Thumbnail) + puppet = self.puppet() + if puppet is None: + raise AttributeError + file_box = await puppet.message_image(self.image_id, + ImageType.Thumbnail) return file_box async def hd(self) -> FileBox: @@ -64,8 +69,10 @@ async def hd(self) -> FileBox: :return: """ LOG.info("image hd for %d", self.image_id) - file_box = await self.puppet().\ - message_image(self.image_id, ImageType.HD) + puppet = self.puppet() + if puppet is None: + raise AttributeError + file_box = await puppet.message_image(self.image_id, ImageType.HD) return file_box async def artwork(self) -> FileBox: @@ -74,6 +81,8 @@ async def artwork(self) -> FileBox: :return: """ LOG.info("image artwork for %d", self.image_id) - file_box = await self.puppet().\ - message_image(self.image_id, ImageType.Artwork) + puppet = self.puppet() + if puppet is None: + raise AttributeError + file_box = await puppet.message_image(self.image_id, ImageType.Artwork) return file_box diff --git a/src/wechaty/wechaty.py b/src/wechaty/wechaty.py index 8e3c5ff1..1988d706 100644 --- a/src/wechaty/wechaty.py +++ b/src/wechaty/wechaty.py @@ -2,6 +2,7 @@ wechaty instance """ from typing import Optional +from .config import LOG # pylint: disable=R0903 @@ -19,7 +20,6 @@ def __init__(self): # pylint: disable=R0903 - class Wechaty: """ docstring @@ -30,14 +30,17 @@ def __init__(self): """ raise NotImplementedError - _global_instance: "Wechaty" = None + _global_instance: Optional["Wechaty"] = None - @classmethod - def instance(cls: "Wechaty") -> "Wechaty": + async def start(self) -> None: """ - get or create global wechaty instance + start the wechaty :return: """ - if cls._global_instance is None: - cls._global_instance = Wechaty() - return cls._global_instance + LOG.info("wechaty is starting ...") + + async def stop(self) -> None: + """ + stop the wechaty + """ + LOG.info("wechaty is stoping ...") diff --git a/wechaty_puppet/puppet.py b/wechaty_puppet/puppet.py index 84d3c259..f8d483c1 100644 --- a/wechaty_puppet/puppet.py +++ b/wechaty_puppet/puppet.py @@ -2,6 +2,8 @@ interface for puppet """ from enum import Enum +# from typing import Awaitable +from .file_box import FileBox class Puppet: """ @@ -9,7 +11,7 @@ class Puppet: """ # pylint: disable=R0201 - def message_image(self, message_id: int, image_type: Enum) -> None: + async def message_image(self, message_id: str, image_type: Enum) -> FileBox: """ docstring :param message_id: From 726b2a77604043d113228742eba6eddb4e2d8f18 Mon Sep 17 00:00:00 2001 From: wjmcat <1435130236@qq.com> Date: Wed, 4 Mar 2020 15:28:36 +0800 Subject: [PATCH 4/5] complete accessory class --- src/wechaty/accessory.py | 30 ++++++++++++++++++++++++------ src/wechaty/user/contact.py | 0 src/wechaty/user/room.py | 5 +++++ src/wechaty/wechaty.py | 4 ++-- wechaty_puppet/puppet.py | 3 +++ 5 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 src/wechaty/user/contact.py create mode 100644 src/wechaty/user/room.py diff --git a/src/wechaty/accessory.py b/src/wechaty/accessory.py index 0602ed55..a9b1ebde 100644 --- a/src/wechaty/accessory.py +++ b/src/wechaty/accessory.py @@ -16,13 +16,22 @@ class Accessory: _puppet: Optional[Puppet] = None # static _wechaty property to doing ... _wechaty: Optional[Wechaty] = None + _counter: int = 0 - def __str__(self): + def __init__(self, name: str = "accessory"): + """ + initialize the accessory instance + """ + self.name: str = name + # increase when Accessory is initialized + self._counter += 1 + + def __str__(self) -> str: """ docstring - :return: + :return: the base accessory class name """ - raise NotImplementedError + return "Accessory instance : %s" % self.name @classmethod def puppet(cls, value: Optional[Puppet] = None) -> Optional[Puppet]: @@ -31,12 +40,17 @@ def puppet(cls, value: Optional[Puppet] = None) -> Optional[Puppet]: :return: """ if value is None: - LOG.info("get puppet instance ...") if cls._puppet is None: raise AttributeError("static puppet instance not found ...") + LOG.info("get puppet instance %s ...", + cls._puppet.name) return cls._puppet - LOG.info("set puppet instance ...") + if cls._puppet is not None: + raise AttributeError("can't set puppet instance %s twice" % + cls._puppet.name) + LOG.info("set puppet instance %s ...", + value.name) cls._puppet = value return None @@ -52,14 +66,18 @@ def wechaty(cls, value: Optional[Wechaty] = None) -> Optional[Wechaty]: :return: """ if value is None: - LOG.info("get wechaty instance") if cls._wechaty is None: raise AttributeError("wechaty instance not found") + LOG.info("get wechaty instance %s", + cls._wechaty.name) return cls._wechaty if not isinstance(value, Wechaty): raise NameError( "expected wechaty instance type is Wechaty, " "but got %s" % value.__class__ ) + if cls._wechaty is not None: + raise AttributeError("can't set wechaty instance %s twice" % + cls._wechaty.name) cls._wechaty = value return None diff --git a/src/wechaty/user/contact.py b/src/wechaty/user/contact.py new file mode 100644 index 00000000..e69de29b diff --git a/src/wechaty/user/room.py b/src/wechaty/user/room.py new file mode 100644 index 00000000..c2dbfacb --- /dev/null +++ b/src/wechaty/user/room.py @@ -0,0 +1,5 @@ +""" +python-implementation for room +""" +from threading import Event, Thread +from src.wechaty.accessory import Accessory diff --git a/src/wechaty/wechaty.py b/src/wechaty/wechaty.py index 1988d706..96fd8a4a 100644 --- a/src/wechaty/wechaty.py +++ b/src/wechaty/wechaty.py @@ -24,11 +24,11 @@ class Wechaty: """ docstring """ - def __init__(self): + def __init__(self, name: str = "wechaty"): """ docstring """ - raise NotImplementedError + self.name = name _global_instance: Optional["Wechaty"] = None diff --git a/wechaty_puppet/puppet.py b/wechaty_puppet/puppet.py index f8d483c1..dfefbec1 100644 --- a/wechaty_puppet/puppet.py +++ b/wechaty_puppet/puppet.py @@ -10,6 +10,9 @@ class Puppet: puppet interface class """ + def __init__(self): + self.name: str = "puppet" + # pylint: disable=R0201 async def message_image(self, message_id: str, image_type: Enum) -> FileBox: """ From e87dd3041793f90e2e7e06a5636b89c0d33ee54f Mon Sep 17 00:00:00 2001 From: wjmcat <1435130236@qq.com> Date: Wed, 4 Mar 2020 16:35:55 +0800 Subject: [PATCH 5/5] complete config class --- src/wechaty/config.py | 91 ++++++++++++++++++++++++++++++++++++++ wechaty_puppet/file_box.py | 14 ++++++ 2 files changed, 105 insertions(+) diff --git a/src/wechaty/config.py b/src/wechaty/config.py index b90f058e..2e489437 100644 --- a/src/wechaty/config.py +++ b/src/wechaty/config.py @@ -20,6 +20,9 @@ """ import logging import os +import re +from typing import Optional +from wechaty_puppet.file_box import FileBox LOG = logging.getLogger(__name__) @@ -33,3 +36,91 @@ '../data', ), ) + + +def global_exception_handler(e: Exception) -> None: + """ + handle the global exception + :param e: exception message + :return: + """ + LOG.error("occur %s %s", e.__class__.__name__, str(e.args)) + print(e) + + +class DefaultSetting(dict): + """ + store global default setting + """ + default_api_host: Optional[str] = None + default_port: Optional[int] = None + default_protocol: Optional[str] = None + + +# pylint: disable=R0903 +def valid_api_host(api_host: str) -> bool: + """ + test the validation of the api_host + :param api_host: + :return: + """ + pattern = re.compile( + r'^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|:?[0-9]*' + r'([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|:?[0-9]*' + r'([a-zA-Z0-9][-_.a-zA-Z0-9]{0,61}[a-zA-Z0-9]))\.:?[0-9]*' + r'([a-zA-Z]{2,13}|[a-zA-Z0-9-]{2,30}.[a-zA-Z]{2,3}):?[0-9]*$' + ) + return bool(pattern.match(api_host)) + + +class Config: + """ + store python-wechaty configuration + """ + def __init__(self, + api_host: Optional[str] = None, + token: Optional[str] = None, + protocol: Optional[str] = None, + http_port: Optional[int] = None, + name: str = "python-wechaty", + debug: bool = True, + docker: bool = False): + """ + initialize the configuration + """ + self.default = DefaultSetting + + self.api_host = api_host if api_host is not None \ + else DefaultSetting.default_api_host + + self.http_port = http_port if http_port is not None \ + else DefaultSetting.default_port + + self.protocol = protocol if protocol is not None \ + else DefaultSetting.default_protocol + + if token is None: + raise AttributeError("token can't be None") + + self.name = name + self.debug = debug + self.docker = docker + + if self.api_host is not None and not valid_api_host(self.api_host): + raise AttributeError("api host %s is not valid" % self.api_host) + + +# export const CHATIE_OFFICIAL_ACCOUNT_ID = 'gh_051c89260e5d' +chatie_official_account_id = "gh_051c89260e5d" + + +def qr_code_for_chatie() -> FileBox: + """ + create QRcode for chatie + :return: + """ + # const CHATIE_OFFICIAL_ACCOUNT_QRCODE = + # 'http://weixin.qq.com/r/qymXj7DEO_1ErfTs93y5' + chatie_official_account_qr_code: str = \ + 'http://weixin.qq.com/r/qymXj7DEO_1ErfTs93y5' + return FileBox.from_qr_code(chatie_official_account_qr_code) diff --git a/wechaty_puppet/file_box.py b/wechaty_puppet/file_box.py index 007f3bcd..ace40c46 100644 --- a/wechaty_puppet/file_box.py +++ b/wechaty_puppet/file_box.py @@ -1,6 +1,11 @@ """ docstring """ +from typing import Type, TypeVar + +T = TypeVar("T") + + # dummy class class FileBox: """ @@ -20,3 +25,12 @@ def to_file(self, file_path: str) -> None: :return: """ raise NotImplementedError + + @classmethod + def from_qr_code(cls: Type[T], code:str) -> "FileBox": + """ + create filebox from qrcode + :param code: + :return: + """ + raise NotImplementedError