Beispiel #1
0
    def test_make_spec(self):
        t_config = TConfig()
        t_config.DATA_DIR = os.getcwd()
        pyu = PyUpdater(t_config)
        pyu.setup()

        spec_cmd = [
            'make-spec', 'app.py', '-F', '--app-name', 'MyApp',
            '--app-version', '0.1.0'
        ]
        spec_file_name = get_system() + '.spec'
        build_cmd = [
            'build', '--app-name', 'MyApp', '--app-version', '0.1.0',
            spec_file_name
        ]

        build_cmd = [str(b) for b in build_cmd]
        parser = get_parser()
        with open('app.py', 'w') as f:
            f.write('print "Hello, World!"')
        args, pyu_args = parser.parse_known_args(spec_cmd)
        b = Builder(args, pyu_args)
        b.make_spec()
        assert os.path.exists(spec_file_name)
        args, pyu_args = parser.parse_known_args(build_cmd)
        b = Builder(args, pyu_args)
        b.build()
        with ChDir(new_folder):
            assert len(os.listdir(os.getcwd())) == 1
    def _overwrite_app(self):
        # Unix: Overwrites the running applications binary,
        #       then starts the updated binary in the currently
        #       running applications process memory.
        if get_system() == u'mac':
            if self.current_app_dir.endswith('MacOS') is True:
                log.debug('Looks like we\'re dealing with a Mac Gui')
                temp_dir = self._get_mac_dot_app_dir(self.current_app_dir)
                self.current_app_dir = temp_dir

        app_update = os.path.join(self.update_folder, self.name)
        if not os.path.exists(app_update):
            app_update += u'.app'
        log.debug(u'Update Location'
                  ':\n{}'.format(os.path.dirname(app_update)))
        log.debug(u'Update Name: {}'.format(os.path.basename(app_update)))

        current_app = os.path.join(self.current_app_dir, self.name)
        if not os.path.exists(current_app):
            current_app += u'.app'
        log.debug(u'Current App location:\n\n{}'.format(current_app))
        if os.path.exists(current_app):
            if os.path.isfile(current_app):
                os.remove(current_app)
            else:
                shutil.rmtree(current_app, ignore_errors=True)

        log.debug(u'Moving app to new location')
        shutil.move(app_update, os.path.dirname(current_app))
Beispiel #3
0
    def test_make_spec(self):
        t_config = TConfig()
        t_config.DATA_DIR = os.getcwd()
        pyu = PyUpdater(t_config)
        pyu.setup()

        spec_cmd = ['make-spec', 'app.py', '-F', '--app-name', 'MyApp',
                    '--app-version', '0.1.0']
        spec_file_name = get_system() + '.spec'
        build_cmd = ['build', '--app-name', 'MyApp',
                     '--app-version', '0.1.0', spec_file_name]

        build_cmd = [str(b) for b in build_cmd]
        parser = get_parser()
        with open('app.py', 'w') as f:
            f.write('print "Hello, World!"')
        args, pyu_args = parser.parse_known_args(spec_cmd)
        b = Builder(args, pyu_args)
        b.make_spec()
        assert os.path.exists(spec_file_name)
        args, pyu_args = parser.parse_known_args(build_cmd)
        b = Builder(args, pyu_args)
        b.build()
        with ChDir(new_folder):
            assert len(os.listdir(os.getcwd())) == 1
Beispiel #4
0
    def test_execution(self, pyu, db):
        archive_name = 'myapp-{}-0.1.0{}'.format(get_system(), ext)
        parser = get_parser()
        data_dir = pyu.config['DATA_DIR']
        pyu_data_dir = os.path.join(data_dir, 'pyu-data')
        pyu.setup()
        pyu.make_keys(3)
        with ChDir(data_dir):
            loader = Loader(db)
            loader.save_config(pyu.config.copy())
            with open('app.py', 'w') as f:
                f.write('print "Hello World"')
            args, pyu_args = parser.parse_known_args(create_build_cmd(0))
            b = Builder(args, pyu_args)
            b.build()

        assert os.path.exists(os.path.join(pyu_data_dir, 'new',
                              archive_name))
        pyu.process_packages()
        assert os.path.exists(os.path.join(pyu_data_dir, 'deploy',
                              archive_name))
        assert os.path.exists(os.path.join(pyu_data_dir, 'files',
                              archive_name))
        pyu.sign_update()
        assert os.path.exists(os.path.join(pyu_data_dir, 'deploy',
                              'versions.gz'))
Beispiel #5
0
    def _overwrite_app(self):
        # Unix: Overwrites the running applications binary,
        #       then starts the updated binary in the currently
        #       running applications process memory.
        if get_system() == u'mac':
            if self.current_app_dir.endswith('MacOS') is True:
                log.debug('Looks like we\'re dealing with a Mac Gui')
                temp_dir = self._get_mac_dot_app_dir(self.current_app_dir)
                self.current_app_dir = temp_dir

        app_update = os.path.join(self.update_folder, self.name)
        if not os.path.exists(app_update):
            app_update += u'.app'
        log.debug(u'Update Location'
                  ':\n{}'.format(os.path.dirname(app_update)))
        log.debug(u'Update Name: {}'.format(os.path.basename(app_update)))

        current_app = os.path.join(self.current_app_dir, self.name)
        if not os.path.exists(current_app):
            current_app += u'.app'
        log.debug(u'Current App location:\n\n{}'.format(current_app))
        if os.path.exists(current_app):
            if os.path.isfile(current_app):
                os.remove(current_app)
            else:
                shutil.rmtree(current_app, ignore_errors=True)

        log.debug(u'Moving app to new location')
        shutil.move(app_update, os.path.dirname(current_app))
Beispiel #6
0
 def test_extract_no_file(self, client):
     update = client.update_check(client.app_name, '0.0.1')
     assert update is not None
     assert update.download() is True
     with ChDir(update.update_folder):
         files = os.listdir(os.getcwd())
         for f in files:
             remove_any(f)
     if get_system() != 'win':
         assert update.extract() is False
Beispiel #7
0
 def test_extract_no_file(self, client):
     update = client.update_check(client.app_name, '0.0.1')
     assert update is not None
     assert update.download() is True
     with ChDir(update.update_folder):
         files = os.listdir(os.getcwd())
         for f in files:
             remove_any(f)
     if get_system() != 'win':
         assert update.extract() is False
Beispiel #8
0
    def _archive_installed_binary(self):
        # Archives current app and places in cache for future patch updates

        current_archive_filename = self._get_filename(self.name, self.version)

        current_archvie_path = os.path.join(self.update_folder,
                                            current_archive_filename)

        if not os.path.exists(current_archvie_path):
            log.debug(u'Adding base binary v{} to updates '
                      u'folder'.format(self.version))
            # Changing in to directory of currently running exe
            with ChDir(os.path.dirname(sys.argv[0])):
                name = self.name
                if get_system() == u'win':
                    name += u'.exe'
                if get_system() == u'mac':
                    # If not found must be a mac gui app
                    if not os.path.exists(name):
                        name += u'.app'

                archive_ext = os.path.splitext(current_archive_filename)[1]
                if u'gz' in archive_ext:
                    archive_format = u'gztar'
                else:
                    archive_format = u'zip'

                try:
                    plat = get_system()
                    filename = make_archive(self.name,
                                            self.version,
                                            name,
                                            archive_format,
                                            platfrom=plat)
                except Exception as err:
                    filename = None
                    log.error(str(err), exc_info=True)

                if filename is not None:
                    shutil.move(filename, self.update_folder)
Beispiel #9
0
 def test_extract_no_file(self, client):
     update = client.update_check('jms', '0.0.1')
     assert update is not None
     assert update.download() is True
     with ChDir(update.update_folder):
         files = os.listdir(os.getcwd())
         for f in files:
             if os.path.isfile(f):
                 os.remove(f)
             else:
                 shutil.rmtree(f, ignore_errors=True)
     if get_system() != 'win':
         assert update.extract() is False
Beispiel #10
0
 def test_https(self, client):
     update = client.update_check(client.app_name, '0.0.1')
     assert update is not None
     assert update.app_name == 'jms'
     temp_name = update.name
     update.name = None
     assert update.is_downloaded() is False
     update.name = temp_name
     assert update.is_downloaded() is False
     assert update.download() is True
     assert update.is_downloaded() is True
     if get_system() != 'win':
         assert update.extract() is True
Beispiel #11
0
    def restart(self):
        """Will overwrite old binary with updated binary and
        restart using the updated binary.

        Proxy method for :meth:`_overwrite_app` & :meth:`_restart`.
        """
        if get_system() == u'win':
            log.debug(u'Only supported on Unix like systems')
            return
        try:
            self._overwrite_app()
            self._restart()
        except ClientError as err:
            log.error(str(err), exc_info=True)
Beispiel #12
0
    def restart(self):
        """Will overwrite old binary with updated binary and
        restart using the updated binary.

        Proxy method for :meth:`_overwrite_app` & :meth:`_restart`.
        """
        if get_system() == u'win':
            log.debug(u'Only supported on Unix like systems')
            return
        try:
            self._overwrite_app()
            self._restart()
        except ClientError as err:
            log.error(str(err), exc_info=True)
Beispiel #13
0
    def _archive_installed_binary(self):
        # Archives current app and places in cache for future patch updates

        current_archive_filename = self._get_filename(self.name, self.version)

        current_archvie_path = os.path.join(self.update_folder,
                                            current_archive_filename)

        if not os.path.exists(current_archvie_path):
            log.debug(u'Adding base binary v{} to updates '
                      u'folder'.format(self.version))
            # Changing in to directory of currently running exe
            with ChDir(os.path.dirname(sys.argv[0])):
                name = self.name
                if get_system() == u'win':
                    name += u'.exe'
                if get_system() == u'mac':
                    # If not found must be a mac gui app
                    if not os.path.exists(name):
                        name += u'.app'

                archive_ext = os.path.splitext(current_archive_filename)[1]
                if u'gz' in archive_ext:
                    archive_format = u'gztar'
                else:
                    archive_format = u'zip'

                try:
                    plat = get_system()
                    filename = make_archive(self.name, self.version, name,
                                            archive_format, platfrom=plat)
                except Exception as err:
                    filename = None
                    log.error(str(err), exc_info=True)

                if filename is not None:
                    shutil.move(filename, self.update_folder)
Beispiel #14
0
    def init_app(self, obj, test=False):
        """Sets up client with config values from obj

        Args:
            obj (instance): config object

        """
        # ToDo: Remove once code is v1.0
        #       Updated how client is initialized.  Can still be
        #       used the old way but the new way is way more efficient
        #       Just pass in the config object and the client takes care
        #       of the rest.  No need to initialize NotSoTuf object first!
        if hasattr(obj, 'config'):
            config = obj.config.copy()
        else:
            config = Config()
            config.from_object(obj)

        # Grabbing config information
        update_url = config.get(u'UPDATE_URL', None)
        update_urls = config.get(u'UPDATE_URLS', None)

        self.update_urls = self._sanatize_update_url(update_url, update_urls)
        self.app_name = config.get(u'APP_NAME', u'PyiUpdater')
        self.company_name = config.get(u'COMPANY_NAME', u'Digital Sapphire')
        if test:
            self.data_dir = 'cache'
            self.platform = 'mac'
        else:
            self.data_dir = user_cache_dir(self.app_name, self.company_name)
            self.platform = get_system()
        self.update_folder = os.path.join(self.data_dir, u'update')
        self.public_key = config.get(u'PUBLIC_KEY', None)
        self.debug = config.get(u'DEBUG', False)
        self.verify = config.get(u'VERIFY_SERVER_CERT', True)
        if self.verify is True:
            self.http_pool = urllib3.PoolManager(cert_reqs='CERT_REQUIRED',
                                                 ca_certs=certifi.where())
        else:
            self.http_pool = urllib3.PoolManager()
        self.version_file = u'version.json'

        self.current_app_dir = os.path.dirname(sys.argv[0])

        self._setup()
        self.refresh()
Beispiel #15
0
    def init_app(self, obj, test=False):
        """Sets up client with config values from obj

        Args:
            obj (instance): config object

        """
        # ToDo: Remove once code is v1.0
        #       Updated how client is initialized.  Can still be
        #       used the old way but the new way is way more efficient
        #       Just pass in the config object and the client takes care
        #       of the rest.  No need to initialize NotSoTuf object first!
        if hasattr(obj, 'config'):
            config = obj.config.copy()
        else:
            config = Config()
            config.from_object(obj)

        # Grabbing config information
        update_url = config.get(u'UPDATE_URL', None)
        update_urls = config.get(u'UPDATE_URLS', None)

        self.update_urls = self._sanatize_update_url(update_url, update_urls)
        self.app_name = config.get(u'APP_NAME', u'PyiUpdater')
        self.company_name = config.get(u'COMPANY_NAME', u'Digital Sapphire')
        if test:
            self.data_dir = 'cache'
            self.platform = 'mac'
        else:
            self.data_dir = user_cache_dir(self.app_name, self.company_name)
            self.platform = get_system()
        self.update_folder = os.path.join(self.data_dir, u'update')
        self.public_key = config.get(u'PUBLIC_KEY', None)
        self.debug = config.get(u'DEBUG', False)
        self.verify = config.get(u'VERIFY_SERVER_CERT', True)
        if self.verify is True:
            self.http_pool = urllib3.PoolManager(cert_reqs='CERT_REQUIRED',
                                                 ca_certs=certifi.where())
        else:
            self.http_pool = urllib3.PoolManager()
        self.version_file = u'version.json'

        self.current_app_dir = os.path.dirname(sys.argv[0])

        self._setup()
        self.refresh()
Beispiel #16
0
    def _restart(self):
        # Oh yes i did just pull that new binary into
        # the currently running process and kept it pushing
        # like nobody's business. Windows what???
        log.debug(u'Restarting')
        current_app = os.path.join(self.current_app_dir, self.name)
        if get_system() == u'mac':
            if not os.path.exists(current_app):
                current_app += u'.app'
                mac_app_binary_dir = os.path.join(current_app, u'Contents',
                                                  u'MacOS')
                file_ = os.listdir(mac_app_binary_dir)
                # We are making an assumption here that only 1
                # executable will be in the MacOS folder.
                current_app = os.path.join(mac_app_binary_dir, file_[0])
                log.debug('Mac .app exe path: {}'.format(current_app))

        os.execv(current_app, [self.name])
Beispiel #17
0
    def _restart(self):
        # Oh yes i did just pull that new binary into
        # the currently running process and kept it pushing
        # like nobody's business. Windows what???
        log.debug(u'Restarting')
        current_app = os.path.join(self.current_app_dir, self.name)
        if get_system() == u'mac':
            if not os.path.exists(current_app):
                current_app += u'.app'
                mac_app_binary_dir = os.path.join(current_app, u'Contents',
                                                  u'MacOS')
                file_ = os.listdir(mac_app_binary_dir)
                # We are making an assumption here that only 1
                # executable will be in the MacOS folder.
                current_app = os.path.join(mac_app_binary_dir, file_[0])
                log.debug('Mac .app exe path: {}'.format(current_app))

        os.execv(current_app, [self.name])
Beispiel #18
0
    def install_restart(self):
        """ Will install (unzip) the update, overwrite the current app,
        then restart the app using the updated binary.

        On windows Proxy method for :meth:`_extract_update` &
        :meth:`_win_overwrite_app_restart`

        On unix Proxy method for :meth:`_extract_update`,
        :meth:`_overwrite_app` & :meth:`_restart`
        """
        try:
            self._extract_update()

            if get_system() == u'win':
                self._win_overwrite_app_restart()
            else:
                self._overwrite_app()
                self._restart()
        except ClientError as err:
            log.error(str(err), exc_info=True)
Beispiel #19
0
    def install_restart(self):
        """ Will install (unzip) the update, overwrite the current app,
        then restart the app using the updated binary.

        On windows Proxy method for :meth:`_extract_update` &
        :meth:`_win_overwrite_app_restart`

        On unix Proxy method for :meth:`_extract_update`,
        :meth:`_overwrite_app` & :meth:`_restart`
        """
        try:
            self._extract_update()

            if get_system() == u'win':
                self._win_overwrite_app_restart()
            else:
                self._overwrite_app()
                self._restart()
        except ClientError as err:
            log.error(str(err), exc_info=True)
Beispiel #20
0
    def test_async_https(self, client):
        update = client.update_check(client.app_name, '0.0.1')
        assert update is not None
        assert update.app_name == 'jms'
        temp_name = update.name
        update.name = None
        assert update.is_downloaded() is False
        update.name = temp_name
        assert update.is_downloaded() is False
        update.download(async=True)
        count = 0
        while count < 61:
            if update.is_downloaded() is True:
                break
            time.sleep(1)
            count += 1
        assert update.is_downloaded() is True

        if get_system() != 'win':
            assert update.extract() is True
Beispiel #21
0
    def test_build_fail_script_syntax_error(self):
        with pytest.raises(SystemExit):
            t_config = TConfig()
            t_config.DATA_DIR = os.getcwd()
            pyu = PyUpdater(t_config)
            pyu.setup()
            spec_cmd = ['make-spec', 'app.py', '-F']
            spec_file_name = get_system() + '.spec'
            build_cmd = ['build', '--app-name', 'MyApp', '--clean'
                         '--app-version', '0.1.0', spec_file_name]

            parser = get_parser()
            with open('app.py', 'w') as f:
                # Missing closing quote
                f.write('print "Hello, World!')
            args, pyu_args = parser.parse_known_args(spec_cmd)
            b = Builder(args, pyu_args)
            b.make_spec()
            assert os.path.exists(spec_file_name)
            args, pyu_args = parser.parse_known_args(build_cmd)
            b = Builder(args, pyu_args)
Beispiel #22
0
    def test_build_fail_script_syntax_error(self):
        with pytest.raises(SystemExit):
            t_config = TConfig()
            t_config.DATA_DIR = os.getcwd()
            pyu = PyUpdater(t_config)
            pyu.setup()
            spec_cmd = ['make-spec', 'app.py', '-F']
            spec_file_name = get_system() + '.spec'
            build_cmd = [
                'build', '--app-name', 'MyApp', '--clean'
                '--app-version', '0.1.0', spec_file_name
            ]

            parser = get_parser()
            with open('app.py', 'w') as f:
                # Missing closing quote
                f.write('print "Hello, World!')
            args, pyu_args = parser.parse_known_args(spec_cmd)
            b = Builder(args, pyu_args)
            b.make_spec()
            assert os.path.exists(spec_file_name)
            args, pyu_args = parser.parse_known_args(build_cmd)
            b = Builder(args, pyu_args)
Beispiel #23
0
    def install(self):
        """Will extract archived update and leave in update folder.
        If updating a lib you can take over from there. If updating
        an app this call should be followed by :meth:`restart` to
        complete update.

        Proxy method for :meth:`_extract_update`.

        Returns:
            (bool) Meanings::

                True - Install successful

                False - Install failed
        """
        if get_system() == u'win':
            log.debug('Only supported on Unix like systems')
            return False
        try:
            self._extract_update()
        except ClientError as err:
            log.error(str(err), exc_info=True)
            return False
        return True
Beispiel #24
0
    def install(self):
        """Will extract archived update and leave in update folder.
        If updating a lib you can take over from there. If updating
        an app this call should be followed by :meth:`restart` to
        complete update.

        Proxy method for :meth:`_extract_update`.

        Returns:
            (bool) Meanings::

                True - Install successful

                False - Install failed
        """
        if get_system() == u'win':
            log.debug('Only supported on Unix like systems')
            return False
        try:
            self._extract_update()
        except ClientError as err:
            log.error(str(err), exc_info=True)
            return False
        return True
Beispiel #25
0
 def gen_archive_name(version):
     archive_name = 'myapp-{}-0.1.{}{}'.format(get_system(),
                                               version, ext)
     return archive_name
Beispiel #26
0
 def test_archive(self):
     with open('test2', 'w') as f:
         f.write('this is a test')
     ex2 = ExternalLib('test', 'test2', '0.2')
     ex2.archive()
     assert os.path.exists('test-{}-0.2{}'.format(get_system(), EXT))
Beispiel #27
0
 def test_archive(self):
     with io.open('test', 'w', encoding='utf-8') as f:
         f.write('this is a test')
     ex = ExternalLib('test2', 'test', '0.1')
     ex.archive()
     assert os.path.exists('test2-{}-0.1{}'.format(get_system(), EXT))
Beispiel #28
0
 def test_extract(self, client):
     update = client.update_check(client.app_name, '0.0.1')
     assert update is not None
     assert update.download() is True
     if get_system() != 'win':
         assert update.extract() is True
Beispiel #29
0
from jms_utils.paths import ChDir
from jms_utils.system import get_system

from pyupdater import PyUpdater
from pyupdater.utils.config import Loader, TransistionDict
from pyupdater.wrapper.builder import Builder
from pyupdater.wrapper.options import get_parser
from tconfig import TConfig


def create_build_cmd(version):
    cmd = ['build', '--app-name', 'myapp', '--app-version',
           '0.1.{}'.format(version), 'app.py', '-F']
    return cmd

if get_system() == 'win':
    ext = '.zip'
else:
    ext = '.tar.gz'


@pytest.mark.usefixtures('cleandir', 'db', 'pyu')
class TestUtils(object):

    def test_dev_dir_none(self):
        myconfig = TConfig()
        myconfig.APP_NAME = None
        updater = TransistionDict()
        updater.from_object(myconfig)
        assert updater['APP_NAME'] == 'PyUpdater App'
Beispiel #30
0
 def test_extract(self, client):
     update = client.update_check(client.app_name, '0.0.1')
     assert update is not None
     assert update.download() is True
     if get_system() != 'win':
         assert update.extract() is True
from jms_utils.paths import ChDir
from jms_utils.system import get_system

from pyi_updater.downloader import FileDownloader
from pyi_updater.exceptions import PatcherError
from pyi_updater.utils import (get_package_hashes, EasyAccessDict,
                               version_string_to_tuple,
                               version_tuple_to_string)

if bsdiff4 is None:
    from pyi_updater.utils import bsdiff4_py as bsdiff4

log = logging.getLogger(__name__)

platform_ = get_system()

progress_signal = signal(u'progress_info')


class Patcher(object):
    """Downloads, verifies, and patches binaries

    Args:
        name (str): Name of binary to patch

        json_data (dict): Info dict with all package meta data

        current_version (str): Version number of currently installed binary

        highest_version (str): Newest version available
Beispiel #32
0
 def test_archive(self):
     with io.open('test2', 'w', encoding='utf-8') as f:
         f.write('this is a test')
     ex2 = ExternalLib('test', 'test2', '0.2')
     ex2.archive()
     assert os.path.exists('test-{}-0.2{}'.format(get_system(), EXT))
from jms_utils.system import get_system


from pyi_updater.downloader import FileDownloader
from pyi_updater.exceptions import PatcherError
from pyi_updater.utils import (get_package_hashes,
                               EasyAccessDict,
                               version_string_to_tuple,
                               version_tuple_to_string)

if bsdiff4 is None:
    from pyi_updater.utils import bsdiff4_py as bsdiff4

log = logging.getLogger(__name__)

platform_ = get_system()

progress_signal = signal(u'progress_info')


class Patcher(object):
    """Downloads, verifies, and patches binaries

    Args:
        name (str): Name of binary to patch

        json_data (dict): Info dict with all package meta data

        current_version (str): Version number of currently installed binary

        highest_version (str): Newest version available