def __init__(self, control, host=None, port=None, max_workers=None):
        if host is None:
            host = config.get_string('koapy.backend.kiwoom_open_api_plus.grpc.host', 'localhost')
        if port is None:
            port = config.get('koapy.backend.kiwoom_open_api_plus.grpc.port')
        if port == 0:
            port = get_free_localhost_port()
        if max_workers is None:
            max_workers = config.get_int('koapy.backend.kiwoom_open_api_plus.grpc.server.max_workers', 8)

        self._control = control
        self._host = host
        self._port = port
        self._max_workers = max_workers

        self._address = self._host + ':' + str(self._port)
        self._servicer = KiwoomOpenApiPlusServiceServicer(self._control)
        self._executor = futures.ThreadPoolExecutor(max_workers=self._max_workers)

        self._server = None
        self._server_started = False
        self._server_stopped = False

        self.reinitialize_server()

        atexit.register(self._executor.shutdown, False)
示例#2
0
 def main(cls, args):
     import argparse
     parser = argparse.ArgumentParser()
     command_choices = [
         'update_version_if_necessary',
         'disable_autologin',
         'open_login_window',
         'show_account_window',
     ]
     default_command = 'update_version_if_necessary'
     parser.add_argument('command',
                         nargs='?',
                         choices=command_choices,
                         default=default_command)
     args = parser.parse_args(args)
     if args.command == 'update_version_if_necessary':
         from koapy.config import config
         credential = config.get(
             'koapy.backend.kiwoom_open_api_plus.credential')
         updater = cls(credential)
         updater.update_version_if_necessary()
     elif args.command == 'disable_autologin':
         cls.__disable_autologin()
     elif args.command == 'open_login_window':
         cls.__open_login_window()
     elif args.command == 'show_account_window':
         cls.__show_account_window()
     return 0
示例#3
0
def version(verbose):
    set_verbosity(verbose)
    from koapy import KiwoomOpenApiPlusVersionUpdater
    from koapy.config import config
    credential = config.get('koapy.backend.kiwoom_open_api_plus.credential')
    updater = KiwoomOpenApiPlusVersionUpdater(credential)
    updater.update_version_if_necessary()
    def __init__(self, host=None, port=None):
        self._host = host or config.get_string('koapy.backend.kiwoom_open_api_plus.grpc.host', 'localhost')
        self._port = port or config.get('koapy.backend.kiwoom_open_api_plus.grpc.port')

        if self._port is None:
            raise ValueError('Port is None')

        self._target = self._host + ':' + str(self._port)
        self._channel = grpc.insecure_channel(self._target)
        self._stub = KiwoomOpenApiPlusService_pb2_grpc.KiwoomOpenApiPlusServiceStub(self._channel)
        self._stub_wrapped = KiwoomOpenApiPlusServiceClientStubWrapper(self._stub)
def enable_autologin_with_control(control):
    logging.info('start enabling autologin')
    executor = futures.ThreadPoolExecutor()
    logging.info('showing account window')
    _future = executor.submit(control.ShowAccountWindow)

    desktop = pywinauto.Desktop(allow_magic_lookup=False)
    account_window = desktop.window(title_re=r'계좌비밀번호 입력 \(버전: [0-9].+[0-9]+\)')

    try:
        logging.info('waiting for account window to show up')
        timeout_account_window_ready = 5
        account_window.wait('ready', timeout_account_window_ready)
    except pywinauto.timings.TimeoutError:
        logging.info('cannot find account window')
        raise
    else:
        logging.info('account window found')
        if is_in_development:
            account_window.logging.info_control_identifiers()

        logging.info('enabling auto login')
        account_window['AUTO'].check()

        account_passwords = config.get('koapy.backend.kiwoom.login.account_passwords')

        account_combo = account_window['ComboBox']
        account_cnt = account_combo.item_count()

        logging.info('putting account passwords')
        for i in range(account_cnt):
            account_combo.select(i)
            account_no = account_combo.selected_text().split()[0]
            if account_no in account_passwords:
                account_window['Edit'].set_text(account_passwords[account_no])
            elif '0000000000' in account_passwords:
                account_window['Edit'].set_text(account_passwords['0000000000'])
            account_window['등록'].click()

        logging.info('closing account window')
        account_window['닫기'].click()

        try:
            logging.info('wating account window to be closed')
            timeout_account_window_done = 5
            account_window.wait_not('visible', timeout_account_window_done)
        except pywinauto.timings.TimeoutError:
            logging.info('cannot sure account window is closed')
            raise
        else:
            logging.info('account window closed')

    executor.shutdown()
    def get_or_create_context(self):
        with contextlib.ExitStack() as stack:
            if self._context is None:
                default_context = config.get(
                    'koapy.data.updater.default_context')
                if default_context == 'koapy.backend.cybos.CybosPlusComObject.CybosPlusComObject':
                    logging.debug('Using CybosPlus backend')
                    default_context = CybosPlusComObject()
                else:
                    if default_context != 'koapy.context.KiwoomOpenApiContext.KiwoomOpenApiContext':
                        logging.warning(
                            'Unexpected default context %s, defaults to KiwoomOpenApiContext.',
                            default_context)
                    logging.debug('Using Kiwoom OpenAPI backend')
                    default_context = KiwoomOpenApiContext()
                self._context = stack.enter_context(default_context)

                def unset_context():
                    self._context = None

                stack.callback(unset_context)
            else:
                logging.debug('Using existing given context of type %s',
                              type(self._context))
            if isinstance(self._context, KiwoomOpenApiContext):
                if self._chart_type == ChartType.DAY:
                    self._date_column_name = '일자'
                    self._date_format = '%Y%m%d'
                elif self._chart_type == ChartType.MINUTE:
                    self._date_column_name = '체결시간'
                    self._date_format = '%Y%m%d%H%M%S'
                else:
                    raise ValueError
            elif isinstance(self._context, CybosPlusComObject):
                if self._chart_type == ChartType.DAY:
                    self._date_column_name = '날짜'
                    self._date_format = '%Y%m%d'
                elif self._chart_type == ChartType.MINUTE:
                    self._date_column_name = '날짜'
                    self._date_format = '%Y%m%d'
                    self._time_column_name = '시간'
                    self._time_format = '%H%M'
                else:
                    raise ValueError
            else:
                raise TypeError
            self._context.EnsureConnected()
            yield self._context
示例#7
0
 def __init__(self,
              port=None,
              client_check_timeout=None,
              verbosity=None,
              log_level=None):
     self._port = port or config.get(
         'koapy.grpc.port') or get_free_localhost_port()
     self._client_check_timeout = client_check_timeout
     self._verbosity = verbosity
     if log_level is None:
         if self._verbosity is not None:
             log_level = verbosity_to_loglevel(self._verbosity)
     self._log_level = log_level
     if self._log_level is not None:
         set_loglevel(self._log_level)
     self._server_proc_args = [
         'python', '-m', 'koapy.pyqt5.tools.start_tray_application',
         '--port',
         str(self._port)
     ]
     if self._verbosity:
         self._server_proc_args.append('-' + 'v' * self._verbosity)
     self._server_proc = None
     self._server_proc_terminate_timeout = config.get_int(
         'koapy.grpc.context.server.terminate.timeout', 10)
     self._client = KiwoomOpenApiServiceClient(port=self._port)
     logging.debug('Testing if client is ready...')
     if not self._client.is_ready(client_check_timeout):
         logging.debug('Client is not ready, creating a new server')
         self._server_proc = subprocess.Popen(self._server_proc_args)
         assert self._client.is_ready()
         self._stub = self._client.get_stub()
     else:
         logging.debug('Client is ready, using existing server')
         self._stub = self._client.get_stub()
     self._lock = threading.RLock()
     self._enter_count = 0
示例#8
0
# check http://marketdata.krx.co.kr/mdi#document=01100305 for more information

import re
import datetime
import logging

import requests

from koapy.config import config

user_agent = config.get('koapy.utils.krx.user_agent')

oldest_year_available = 1975


def download_holidays_as_dict(year=None, page_first_call=False):
    now = datetime.datetime.now()

    def generate_otp():
        headers = {
            'Accept': '*/*',
            'Accept-Encoding': 'gzip, deflate',
            'Host': 'marketdata.krx.co.kr',
            'Referer': 'http://marketdata.krx.co.kr/mdi',
            'User-Agent': user_agent,
            'X-Requested-With': 'XMLHttpRequest',
        }
        params = {
            'bld': 'MKD/01/0110/01100305/mkd01100305_01',
            'name': 'form',
            '_': str(int(now.timestamp() * 1000)),
    def __init__(self, port=None, client_check_timeout=None, verbosity=None, log_level=None):
        if port is None:
            port = config.get('koapy.backend.kiwoom_open_api_plus.grpc.port', 0) or get_free_localhost_port()

        if log_level is None and verbosity is not None:
            log_level = verbosity_to_loglevel(verbosity)
        if verbosity is None and log_level is not None:
            verbosity = loglevel_to_verbosity(log_level)

        self._port = port
        self._client_check_timeout = client_check_timeout
        self._verbosity = verbosity
        self._log_level = log_level

        if self._log_level is not None:
            set_loglevel(self._log_level)

        self._server_executable = config.get('koapy.context.server.executable', None)
        if not isinstance(self._server_executable, str):
            self._server_executable = None
        if self._server_executable is None:
            envpath = config.get('koapy.context.server.executable.conda.envpath', None)
            if envpath is not None and isinstance(envpath, str):
                self._server_executable = subprocess.check_output([ # pylint: disable=unexpected-keyword-arg
                    'conda', 'run', '-p', envpath,
                    'python', '-c', 'import sys; print(sys.executable)',
                ], encoding=sys.stdout.encoding, creationflags=subprocess.CREATE_NO_WINDOW).strip()
        if self._server_executable is None:
            envname = config.get('koapy.context.server.executable.conda.envname', None)
            if envname is not None and isinstance(envname, str):
                self._server_executable = subprocess.check_output([ # pylint: disable=unexpected-keyword-arg
                    'conda', 'run', '-n', envname,
                    'python', '-c', 'import sys; print(sys.executable)',
                ], encoding=sys.stdout.encoding, creationflags=subprocess.CREATE_NO_WINDOW).strip()
        if self._server_executable is None:
            self._server_executable = sys.executable

        self._server_proc_args = [self._server_executable, '-m', 'koapy.cli', 'serve']
        if self._port is not None:
            self._server_proc_args.extend(['-p', str(self._port)])
        if self._verbosity is not None:
            self._server_proc_args.extend(['-' + 'v' * self._verbosity])

        self._server_proc = None
        self._server_proc_terminate_timeout = config.get_int('koapy.context.server.terminate.timeout', 10)

        self._client = KiwoomOpenApiPlusServiceClient(port=self._port)

        self.logger.debug('Testing if client is ready...')
        if not self._client.is_ready(self._client_check_timeout):
            assert platform.architecture()[0] == '32bit', 'Server should run under 32bit environment'
            self.logger.debug('Client is not ready, creating a new server')
            self._server_proc = subprocess.Popen(self._server_proc_args)
            assert self._client.is_ready(), 'Failed to create server'
            self._stub = self._client.get_stub()
        else:
            self.logger.debug('Client is ready, using existing server')
            self._stub = self._client.get_stub()

        self._context_lock = threading.RLock()
        self._enter_count = 0
    def LoginUsingCredential(self, credential=None):
        # https://github.com/pywinauto/pywinauto/issues/472
        import sys
        sys.coinit_flags = 2
        import warnings
        warnings.simplefilter("ignore", UserWarning)
        import pywinauto

        if credential is None:
            from koapy.config import config
            credential = config.get(
                'koapy.backend.kiwoom_open_api_plus.credential')

        is_in_development = False
        use_set_text = False

        userid = credential.get('user_id')
        password = credential.get('user_password')
        cert = credential.get('cert_password')

        is_save_userid = True
        is_simulation = credential.get('is_simulation')

        desktop = pywinauto.Desktop(allow_magic_lookup=False)
        login_window = desktop.window(title='Open API Login')

        try:
            self.logger.info('Waiting for login screen')
            timeout_login_screen_ready = 30
            login_window.wait('ready', timeout_login_screen_ready)
        except pywinauto.timings.TimeoutError:
            self.logger.info('Cannot find login screen')
            raise
        else:
            self.logger.info('Login screen found')
            if is_in_development:
                login_window.print_control_identifiers()

            if userid:
                self.logger.info('Putting userid')
                if use_set_text:
                    login_window['Edit1'].set_text(userid)
                else:
                    login_window['Edit1'].set_focus()
                    pywinauto.keyboard.send_keys(userid)
                    pywinauto.keyboard.send_keys('{TAB}')
            if password:
                self.logger.info('Putting password')
                if use_set_text:
                    login_window['Edit2'].set_text(password)
                else:
                    login_window['Edit2'].set_focus()
                    pywinauto.keyboard.send_keys(password)
                    pywinauto.keyboard.send_keys('{TAB}')
            else:
                raise RuntimeError(
                    'password not set, please check config file')

            # not working properly
            if is_save_userid:
                self.logger.info('Checking to save userid')
                login_window['Button6'].check()
            else:
                self.logger.info('Unchecking to save userid')
                login_window['Button6'].uncheck_by_click()

            if not is_simulation:
                if not login_window['Edit3'].is_enabled():
                    self.logger.info('Unchecking to use simulation server')
                    login_window['Button5'].uncheck_by_click()
                if cert:
                    self.logger.info('Putting cert password')
                    if use_set_text:
                        login_window['Edit3'].set_text(cert)
                    else:
                        login_window['Edit3'].set_focus()
                        pywinauto.keyboard.send_keys(cert)
                        pywinauto.keyboard.send_keys('{TAB}')
                else:
                    raise RuntimeError(
                        'cert passowrd not set, please check config file')
            else:
                if login_window['Edit3'].is_enabled():
                    self.logger.info('Checking to use simulation server')
                    login_window['Button5'].check_by_click()

            self.logger.info('Logging in')
            login_window['Button1'].click()
示例#11
0
文件: __init__.py 项目: LKH-1/koapy
import os

from koapy.config import config

# Set QT_API environment variable for correct Qt backend usage
os.environ["QT_API"] = config.get("koapy.qtpy.qt_api", "pyside2")

# Import proper Qt binding using qtpy
from qtpy import *
from qtpy import PYQT5, PYSIDE2, PythonQtError

# PySide2 patch
if PYSIDE2:
    import PySide2

    if "QT_QPA_PLATFORM_PLUGIN_PATH" not in os.environ and hasattr(
            PySide2, "__file__"):
        QT_QPA_PLATFORM_PLUGIN_PATH = os.path.join(
            os.path.dirname(PySide2.__file__), "plugins", "platforms")
        os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = QT_QPA_PLATFORM_PLUGIN_PATH
示例#12
0
import os

from koapy.utils.logging.Logging import Logging # pylint: disable=import-error
from koapy.config import config # pylint: disable=import-error

# Get logger
logger = Logging.get_logger('koapy.compat.pyside2')

# Set QT_API environment variable for correct Qt backend usage
os.environ['QT_API'] = config.get('koapy.qtpy.qt_api', 'pyside2')

# Import proper Qt binding using qtpy
from qtpy import *
from qtpy import PYQT5, PYSIDE2, PythonQtError

# Test which Qt binding is being used
if PYQT5:
    logger.debug('Using PyQt5 as Qt backend')
elif PYSIDE2:
    logger.debug('Using PySide2 as Qt backend')
else:
    raise PythonQtError('No Qt bindings could be found')

# PySide2 patch
if PYSIDE2:
    import PySide2
    if 'QT_QPA_PLATFORM_PLUGIN_PATH' not in os.environ and hasattr(PySide2, '__file__'):
        QT_QPA_PLATFORM_PLUGIN_PATH = os.path.join(os.path.dirname(PySide2.__file__), 'plugins', 'platforms')
        os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = QT_QPA_PLATFORM_PLUGIN_PATH
示例#13
0
    def CommConnect(self):
        """
        https://github.com/ippoeyeslhw/cppy/blob/master/cp_luncher.py
        """

        login_config = config.get('koapy.backend.cybos.login')

        userid = login_config.get('id')
        password = login_config.get('password')
        cert = login_config.get('cert')

        auto_account_password = login_config.get('auto_account_password')
        auto_cert_password = login_config.get('auto_cert_password')
        price_check_only = login_config.get('price_check_only')

        account_passwords = login_config.get('account_passwords')

        app = pywinauto.Application().start(
            r'C:\DAISHIN\STARTER\ncStarter.exe /prj:cp')
        desktop = pywinauto.Desktop(allow_magic_lookup=False)

        try:
            ask_stop = desktop.window(title='ncStarter')
            ask_stop.wait('ready', timeout=8)
        except pywinauto.timings.TimeoutError:
            pass
        else:
            if is_in_development:
                ask_stop.print_control_identifiers()
            if ask_stop['Static2'].window_text().endswith('종료하시겠습니까?'):
                ask_stop['Button1'].click()
                try:
                    ask_stop = desktop.window(title='ncStarter')
                    ask_stop.wait('ready', timeout=5)
                except pywinauto.timings.TimeoutError:
                    pass
                else:
                    if is_in_development:
                        ask_stop.print_control_identifiers()
                    if ask_stop['Static2'].window_text().endswith(
                            '종료할 수 없습니다.'):
                        ask_stop['Button'].click()
                        raise RuntimeError('cannot stop existing server')

        starter = desktop.window(title='CYBOS Starter')
        starter.wait('ready', timeout=10)
        if is_in_development:
            starter.print_control_identifiers()

        if userid:
            starter['Edit1'].set_text(userid)
        if password:
            starter['Edit2'].set_text(password)
        else:
            raise RuntimeError('no password given')
        if not price_check_only:
            if cert:
                starter['Edit3'].set_text(cert)
            else:
                raise RuntimeError('no cert password given')

        if auto_account_password:
            starter['Button4'].check()
            try:
                confirm = desktop.window(title='대신증권')
                confirm.wait('ready', timeout=1)
            except pywinauto.timings.TimeoutError:
                pass
            else:
                if is_in_development:
                    confirm.print_control_identifiers()
                confirm['Button'].click()
        if auto_cert_password:
            starter['Button5'].check()
            try:
                confirm = desktop.window(title='대신증권')
                confirm.wait('ready', timeout=1)
            except pywinauto.timings.TimeoutError:
                pass
            else:
                if is_in_development:
                    confirm.print_control_identifiers()
                confirm['Button'].click()
        if price_check_only:
            starter['Button6'].check()

        starter['Button1'].click()

        should_stop = False
        while not should_stop:
            try:
                account_password = desktop.window(title='종합계좌 비밀번호 확인 입력')
                account_password.wait('ready', timeout=5)
            except pywinauto.timings.TimeoutError:
                should_stop = True
            else:
                if is_in_development:
                    account_password.print_control_identifiers()
                account_no = account_password['Static'].window_text().split(
                    ':')[-1].strip()
                if account_no in account_passwords:
                    account_password['Edit'].set_text(
                        account_passwords[account_no])
                else:
                    raise RuntimeError(
                        'no account password given for account %s' %
                        account_no)
                account_password['Button1'].click()

        try:
            starter.wait_not('visible', timeout=10)
        except pywinauto.timings.TimeoutError:
            pass
示例#14
0
    def Connect(self, credential=None):
        """
        https://github.com/ippoeyeslhw/cppy/blob/master/cp_luncher.py
        """

        import pywinauto

        assert self.IsAdmin(
        ), 'Connect() method requires to be run as administrator'

        is_in_development = False

        if credential is None:
            from koapy.config import config
            credential = config.get(
                'koapy.backend.daishin_cybos_plus.credential')

        userid = credential.get('user_id')
        password = credential.get('user_password')
        cert = credential.get('cert_password')

        auto_account_password = credential.get('auto_account_password')
        auto_cert_password = credential.get('auto_cert_password')
        price_check_only = credential.get('price_check_only')

        account_passwords = credential.get('account_passwords')

        self.logger.info('Starting CYBOS Starter application')
        app = pywinauto.Application().start(
            r'C:\DAISHIN\STARTER\ncStarter.exe /prj:cp')  # pylint: disable=unused-variable
        desktop = pywinauto.Desktop(allow_magic_lookup=False)

        try:
            self.logger.info(
                'Waiting for possible popup which asks for shutting down existing program'
            )
            ask_stop = desktop.window(title='ncStarter')
            ask_stop.wait('ready', timeout=10)
        except pywinauto.timings.TimeoutError:
            self.logger.info('No existing program found to be shutdown')
        else:
            self.logger.info('Existing program found, shutting down')
            if is_in_development:
                ask_stop.print_control_identifiers()
            if ask_stop['Static2'].window_text().endswith('종료하시겠습니까?'):
                ask_stop['Button1'].click()
                try:
                    self.logger.info(
                        'Wating for possible failure message on shutdown')
                    ask_stop = desktop.window(title='ncStarter')
                    ask_stop.wait('ready', timeout=10)
                except pywinauto.timings.TimeoutError:
                    self.logger.info('Successfully shutdown existing program')
                else:
                    self.logger.error('Failed to shutdown existing program')
                    if is_in_development:
                        ask_stop.print_control_identifiers()
                    if ask_stop['Static2'].window_text().endswith(
                            '종료할 수 없습니다.'):
                        ask_stop['Button'].click()
                        raise RuntimeError('Cannot stop existing program')

        try:
            self.logger.info('Waiting for CYBOS Starter login screen')
            starter = desktop.window(title='CYBOS Starter')
            starter.wait('ready', timeout=30)
        except pywinauto.timings.TimeoutError:
            self.logger.exception('Failed to find login screen')
            raise

        if is_in_development:
            starter.print_control_identifiers()

        if userid:
            self.logger.info('Putting user id')
            starter['Edit1'].set_text(userid)
        if password:
            self.logger.info('Putting user password')
            starter['Edit2'].set_text(password)
        else:
            raise RuntimeError('No user password given')

        if not price_check_only:
            if cert:
                self.logger.info('Putting cert password')
                starter['Edit3'].set_text(cert)
            else:
                raise RuntimeError('No cert password given')

        if price_check_only:
            if starter['Edit3'].is_enabled():
                self.logger.info('Checking price check only option')
                starter['Button6'].check_by_click()
        else:
            if not starter['Edit3'].is_enabled():
                starter['Button6'].uncheck_by_click()

        if auto_account_password:
            self.logger.info('Checking auto account password option')
            starter['Button4'].check()  # check dosen't work
            try:
                confirm = desktop.window(title='대신증권')
                confirm.wait('ready', timeout=5)
            except pywinauto.timings.TimeoutError:
                pass
            else:
                if is_in_development:
                    confirm.print_control_identifiers()
                confirm['Button'].click()
        else:
            starter['Button4'].uncheck()  # uncheck dosen't work

        if auto_cert_password:
            self.logger.info('Checking auto cert password option')
            starter['Button5'].check()  # check dosen't work
            try:
                confirm = desktop.window(title='대신증권')
                confirm.wait('ready', timeout=5)
            except pywinauto.timings.TimeoutError:
                pass
            else:
                if is_in_development:
                    confirm.print_control_identifiers()
                confirm['Button'].click()
        else:
            starter['Button5'].uncheck()  # uncheck dosen't work

        self.logger.info('Clicking login button')
        starter['Button1'].click()

        self.logger.info('Setting account passwords if necessary')
        should_stop = False
        while not should_stop:
            try:
                self.logger.info('Waiting for account password setting screen')
                account_password = desktop.window(title='종합계좌 비밀번호 확인 입력')
                account_password.wait('ready', timeout=5)
            except pywinauto.timings.TimeoutError:
                self.logger.info('Account password setting screen not found')
                should_stop = True
            else:
                self.logger.info('Account password setting screen found')
                if is_in_development:
                    account_password.print_control_identifiers()
                account_no = account_password['Static'].window_text().split(
                    ':')[-1].strip()
                if account_no in account_passwords:
                    account_password['Edit'].set_text(
                        account_passwords[account_no])
                else:
                    raise RuntimeError(
                        'No account password given for account %s' %
                        account_no)
                account_password['Button1'].click()

        try:
            self.logger.info('Waiting for starter screen to be closed')
            starter.wait_not('visible', timeout=60)
        except pywinauto.timings.TimeoutError:
            self.logger.warning(
                'Could not wait for starter screen to be closed')
        else:
            self.logger.info('Starter screen is closed')
            try:
                self.logger.info('Waiting for notice window')
                notice = desktop.window(title='공지사항')
                notice.wait('ready', timeout=60)
            except pywinauto.timings.TimeoutError:
                self.logger.info('No notice window found')
            else:
                self.logger.info('Closing notice window')
                notice.close()
                try:
                    self.logger.info(
                        'Waiting for the notice window to be closed')
                    notice.wait_not('visible', timeout=60)
                except pywinauto.timings.TimeoutError:
                    self.logger.warning(
                        'Could not wait for notice screen to be closed')
                else:
                    self.logger.info('Notice window is closed')

        if self.GetConnectState() == 0:
            self.logger.error('Failed to start and connect to CYBOS Plus')
        else:
            self.logger.info('Succesfully connected to CYBOS Plus')

        return self.GetConnectState()
示例#15
0
    def __init__(self,
                 port=None,
                 client_check_timeout=None,
                 verbosity=None,
                 log_level=None):
        if port is None:
            port = (config.get("koapy.backend.kiwoom_open_api_plus.grpc.port",
                               0) or get_free_localhost_port())

        if log_level is None and verbosity is not None:
            log_level = verbosity_to_loglevel(verbosity)
        if verbosity is None and log_level is not None:
            verbosity = loglevel_to_verbosity(log_level)

        self._port = port
        self._client_check_timeout = client_check_timeout
        self._verbosity = verbosity
        self._log_level = log_level

        if self._log_level is not None:
            set_loglevel(self._log_level)

        self._server_executable = config.get("koapy.context.server.executable",
                                             None)
        if not isinstance(self._server_executable, str):
            self._server_executable = None
        if self._server_executable is None:
            envpath = config.get(
                "koapy.context.server.executable.conda.envpath", None)
            if envpath is not None and isinstance(envpath, str):
                self._server_executable = subprocess.check_output(
                    [  # pylint: disable=unexpected-keyword-arg
                        "conda",
                        "run",
                        "-p",
                        envpath,
                        "python",
                        "-c",
                        "import sys; print(sys.executable)",
                    ],
                    encoding=sys.stdout.encoding,
                    creationflags=subprocess.CREATE_NO_WINDOW,
                ).strip()
        if self._server_executable is None:
            envname = config.get(
                "koapy.context.server.executable.conda.envname", None)
            if envname is not None and isinstance(envname, str):
                self._server_executable = subprocess.check_output(
                    [  # pylint: disable=unexpected-keyword-arg
                        "conda",
                        "run",
                        "-n",
                        envname,
                        "python",
                        "-c",
                        "import sys; print(sys.executable)",
                    ],
                    encoding=sys.stdout.encoding,
                    creationflags=subprocess.CREATE_NO_WINDOW,
                ).strip()
        if self._server_executable is None:
            self._server_executable = sys.executable

        self._server_proc_args = [
            self._server_executable, "-m", "koapy.cli", "serve"
        ]
        if self._port is not None:
            self._server_proc_args.extend(["-p", str(self._port)])
        if self._verbosity is not None:
            self._server_proc_args.extend(["-" + "v" * self._verbosity])

        self._server_proc = None
        self._server_proc_terminate_timeout = config.get_int(
            "koapy.context.server.terminate.timeout", 10)

        self._client = KiwoomOpenApiPlusServiceClient(port=self._port)

        self.logger.debug("Testing if client is ready...")
        if not self._client.is_ready(self._client_check_timeout):
            assert (platform.architecture()[0] == "32bit"
                    ), "Server should run under 32bit environment"
            self.logger.debug("Client is not ready, creating a new server")
            self._server_proc = subprocess.Popen(self._server_proc_args)
            assert self._client.is_ready(), "Failed to create server"
            self._stub = self._client.get_stub()
        else:
            self.logger.debug("Client is ready, using existing server")
            self._stub = self._client.get_stub()

        self._context_lock = threading.RLock()
        self._enter_count = 0
示例#16
0
    def ConnectUsingPywinauto_Impl(cls, credential=None):
        """
        https://github.com/ippoeyeslhw/cppy/blob/master/cp_luncher.py
        """

        import pywinauto

        is_in_development = False

        if credential is None:
            from koapy.config import config

            credential = config.get(
                "koapy.backend.daishin_cybos_plus.credential")

        userid = credential.get("user_id")
        password = credential.get("user_password")
        cert = credential.get("cert_password")

        auto_account_password = credential.get("auto_account_password")
        auto_cert_password = credential.get("auto_cert_password")
        price_check_only = credential.get("price_check_only")

        account_passwords = credential.get("account_passwords")

        cls.logger.info("Starting CYBOS Starter application")
        app = pywinauto.Application().start(
            r"C:\DAISHIN\STARTER\ncStarter.exe /prj:cp")  # pylint: disable=unused-variable
        desktop = pywinauto.Desktop(allow_magic_lookup=False)

        try:
            cls.logger.info(
                "Waiting for possible popup which asks for shutting down existing program"
            )
            ask_stop = desktop.window(title="ncStarter")
            ask_stop.wait("ready", timeout=10)
        except pywinauto.timings.TimeoutError:
            cls.logger.info("No existing program found to be shutdown")
        else:
            cls.logger.info("Existing program found, shutting down")
            if is_in_development:
                ask_stop.print_control_identifiers()
            if ask_stop["Static2"].window_text().endswith("종료하시겠습니까?"):
                ask_stop["Button1"].click()
                try:
                    cls.logger.info(
                        "Wating for possible failure message on shutdown")
                    ask_stop = desktop.window(title="ncStarter")
                    ask_stop.wait("ready", timeout=10)
                except pywinauto.timings.TimeoutError:
                    cls.logger.info("Successfully shutdown existing program")
                else:
                    cls.logger.error("Failed to shutdown existing program")
                    if is_in_development:
                        ask_stop.print_control_identifiers()
                    if ask_stop["Static2"].window_text().endswith(
                            "종료할 수 없습니다."):
                        ask_stop["Button"].click()
                        raise RuntimeError("Cannot stop existing program")

        try:
            cls.logger.info("Waiting for CYBOS Starter login screen")
            starter = desktop.window(title="CYBOS Starter")
            starter.wait("ready", timeout=30)
        except pywinauto.timings.TimeoutError:
            cls.logger.exception("Failed to find login screen")
            raise

        if is_in_development:
            starter.print_control_identifiers()

        if userid:
            cls.logger.info("Putting user id")
            starter["Edit1"].set_text(userid)
        if password:
            cls.logger.info("Putting user password")
            starter["Edit2"].set_text(password)
        else:
            raise RuntimeError("No user password given")

        if not price_check_only:
            if cert:
                cls.logger.info("Putting cert password")
                starter["Edit3"].set_text(cert)
            else:
                raise RuntimeError("No cert password given")

        if price_check_only:
            if starter["Edit3"].is_enabled():
                cls.logger.info("Checking price check only option")
                starter["Button6"].check_by_click()
        else:
            if not starter["Edit3"].is_enabled():
                starter["Button6"].uncheck_by_click()

        if auto_account_password:
            cls.logger.info("Checking auto account password option")
            starter["Button4"].check()  # check dosen't work
            try:
                confirm = desktop.window(title="대신증권")
                confirm.wait("ready", timeout=5)
            except pywinauto.timings.TimeoutError:
                pass
            else:
                if is_in_development:
                    confirm.print_control_identifiers()
                confirm["Button"].click()
        else:
            starter["Button4"].uncheck()  # uncheck dosen't work

        if auto_cert_password:
            cls.logger.info("Checking auto cert password option")
            starter["Button5"].check()  # check dosen't work
            try:
                confirm = desktop.window(title="대신증권")
                confirm.wait("ready", timeout=5)
            except pywinauto.timings.TimeoutError:
                pass
            else:
                if is_in_development:
                    confirm.print_control_identifiers()
                confirm["Button"].click()
        else:
            starter["Button5"].uncheck()  # uncheck dosen't work

        cls.logger.info("Clicking login button")
        starter["Button1"].click()

        cls.logger.info("Setting account passwords if necessary")
        should_stop = False
        while not should_stop:
            try:
                cls.logger.info("Waiting for account password setting screen")
                account_password = desktop.window(title="종합계좌 비밀번호 확인 입력")
                account_password.wait("ready", timeout=5)
            except pywinauto.timings.TimeoutError:
                cls.logger.info("Account password setting screen not found")
                should_stop = True
            else:
                cls.logger.info("Account password setting screen found")
                if is_in_development:
                    account_password.print_control_identifiers()
                account_no = (account_password["Static"].window_text().split(
                    ":")[-1].strip())
                if account_no in account_passwords:
                    account_password["Edit"].set_text(
                        account_passwords[account_no])
                else:
                    raise RuntimeError(
                        "No account password given for account %s" %
                        account_no)
                account_password["Button1"].click()

        try:
            cls.logger.info("Waiting for starter screen to be closed")
            starter.wait_not("visible", timeout=60)
        except pywinauto.timings.TimeoutError:
            cls.logger.warning(
                "Could not wait for starter screen to be closed")
        else:
            cls.logger.info("Starter screen is closed")
            try:
                cls.logger.info("Waiting for notice window")
                notice = desktop.window(title="공지사항")
                notice.wait("ready", timeout=60)
            except pywinauto.timings.TimeoutError:
                cls.logger.info("No notice window found")
            else:
                cls.logger.info("Closing notice window")
                notice.close()
                try:
                    cls.logger.info(
                        "Waiting for the notice window to be closed")
                    notice.wait_not("visible", timeout=60)
                except pywinauto.timings.TimeoutError:
                    cls.logger.warning(
                        "Could not wait for notice screen to be closed")
                else:
                    cls.logger.info("Notice window is closed")
    def LoginUsingPywinauto_Impl(cls, credential=None):
        import pywinauto

        if credential is None:
            from koapy.config import config

            credential = config.get(
                "koapy.backend.kiwoom_open_api_plus.credential")

        is_in_development = False
        use_set_text = False

        userid = credential.get("user_id")
        password = credential.get("user_password")
        cert = credential.get("cert_password")

        is_save_userid = True
        is_simulation = credential.get("is_simulation")

        desktop = pywinauto.Desktop(allow_magic_lookup=False)
        login_window = desktop.window(title="Open API Login")

        try:
            cls.logger.info("Waiting for login screen")
            timeout_login_screen_ready = 30
            login_window.wait("ready", timeout_login_screen_ready)
        except pywinauto.timings.TimeoutError:
            cls.logger.info("Cannot find login screen")
            raise
        else:
            cls.logger.info("Login screen found")
            if is_in_development:
                login_window.print_control_identifiers()

            if userid:
                cls.logger.info("Putting userid")
                if use_set_text:
                    login_window["Edit1"].set_text(userid)
                else:
                    login_window["Edit1"].set_focus()
                    pywinauto.keyboard.send_keys(userid)
                    pywinauto.keyboard.send_keys("{TAB}")
            if password:
                cls.logger.info("Putting password")
                if use_set_text:
                    login_window["Edit2"].set_text(password)
                else:
                    login_window["Edit2"].set_focus()
                    pywinauto.keyboard.send_keys(password)
                    pywinauto.keyboard.send_keys("{TAB}")
            else:
                raise RuntimeError(
                    "'user_password' not set, please check credential")

            if is_save_userid:
                cls.logger.info("Checking to save userid")
                login_window["Button6"].check()  # check doesn't work
            else:
                cls.logger.info("Unchecking to save userid")
                login_window["Button6"].uncheck()  # uncheck doesn't work

            if not is_simulation:
                if not login_window["Edit3"].is_enabled():
                    cls.logger.info("Unchecking to use simulation server")
                    login_window["Button5"].uncheck_by_click()
                if cert:
                    cls.logger.info("Putting cert password")
                    if use_set_text:
                        login_window["Edit3"].set_text(cert)
                    else:
                        login_window["Edit3"].set_focus()
                        pywinauto.keyboard.send_keys(cert)
                        pywinauto.keyboard.send_keys("{TAB}")
                else:
                    raise RuntimeError(
                        "'cert_password' not set, please check credential")
            else:
                if login_window["Edit3"].is_enabled():
                    cls.logger.info("Checking to use simulation server")
                    login_window["Button5"].check_by_click()

            cls.logger.info("Logging in")
            login_window["Button1"].click()
示例#18
0
def login_semiauto(wait_closed=False):
    logging.info('starting to login')
    login_config = config.get('koapy.backend.kiwoom.login')

    userid = login_config.get('id')
    password = login_config.get('password')
    cert = login_config.get('cert')

    is_save_userid = True
    is_simulation = login_config.get('is_simulation')

    desktop = pywinauto.Desktop(allow_magic_lookup=False)
    login_window = desktop.window(title='Open API Login')

    try:
        logging.info('waiting for login screen')
        timeout_login_screen_ready = 30
        login_window.wait('ready', timeout_login_screen_ready)
    except pywinauto.timings.TimeoutError:
        logging.info('cannot find login screen')
        raise
    else:
        logging.info('login screen found')
        if is_in_development:
            login_window.print_control_identifiers()

        if userid:
            logging.info('putting userid')
            if set_text_userid:
                login_window['Edit1'].set_text(userid)
            else:
                login_window['Edit1'].set_focus()
                pywinauto.keyboard.send_keys(userid)
                pywinauto.keyboard.send_keys('{TAB}')
        if password:
            logging.info('putting password')
            if set_text_password:
                login_window['Edit2'].set_text(password)
            else:
                login_window['Edit2'].set_focus()
                pywinauto.keyboard.send_keys(password)
                pywinauto.keyboard.send_keys('{TAB}')
        else:
            raise RuntimeError('password not set, please check config file')

        # not working properly
        if is_save_userid:
            logging.info('checking to save userid')
            login_window['Button6'].check()
        else:
            logging.info('unchecking to save userid')
            login_window['Button6'].uncheck_by_click()

        if not is_simulation:
            if not login_window['Edit3'].is_enabled():
                logging.info('unchecking to use simulation server')
                login_window['Button5'].uncheck_by_click()
            if cert:
                logging.info('putting cert password')
                if set_text_cert:
                    login_window['Edit3'].set_text(cert)
                else:
                    login_window['Edit3'].set_focus()
                    pywinauto.keyboard.send_keys(cert)
                    pywinauto.keyboard.send_keys('{TAB}')
            else:
                raise RuntimeError(
                    'cert passowrd not set, please check config file')
        else:
            if login_window['Edit3'].is_enabled():
                logging.info('checking to use simulation server')
                login_window['Button5'].check_by_click()

        logging.info('logging in')
        login_window['Button1'].click()

    if wait_closed:
        try:
            logging.info('waiting login screen to be closed')
            timeout_login_screen_closed = 30
            login_window.wait_not('visible', timeout_login_screen_closed)
        except pywinauto.timings.TimeoutError:
            logging.info('login screen is not closing')
            raise
        else:
            logging.info('login screen closed')

    return login_window