示例#1
0
    def install_update(self):
        if not self._update_ready or self._status == UPDATER_STATUS_INSTALLING:
            return False
        self._status = UPDATER_STATUS_INSTALLING
        self.emit_status()
        logger.info('Installing update')
        try:
            assert self._update_file_path and isfile(self._update_file_path)
            logger.debug("self._update_file_path %s", self._update_file_path)
            path, name = split(self._update_file_path)
            old_cwd = os.getcwd()
            os.chdir(path)
            system = get_platform()
            if system == 'Windows':
                from common.config import load_config

                config = load_config()
                root = config.sync_directory
                log_basename = time.strftime('%Y%m%d_%H%M%S.log')
                log_filename = get_bases_filename(root, log_basename)
                if not self._is_ascii(log_filename):
                    log_filename = log_basename
                args = [name, '/verysilent', '/Log={}'.format(log_filename)]
                if is_portable():
                    args.append('/PATH={}'.format(get_application_path()))
                subprocess.Popen(
                    args,
                    creationflags=0x00000200  # CREATE_NEW_PROCESS_GROUP
                    | 0x00000008,  # DETACHED_PROCESS
                    close_fds=True)
            elif system == 'Darwin':
                bundle_path = normpath(
                    join(get_application_path(), '..', '..', '..', '..'))
                logger.debug("bundle_path: %s", bundle_path)
                subprocess.call(
                    ['ditto', '-xk', self._update_file_path, bundle_path])
                subprocess.call(
                    ['xattr', '-d', '-r', 'com.apple.quarantine', bundle_path])
                logger.debug("Update completed, restart")
                remove_file(get_cfg_filename('lock'))
                if is_portable():
                    launcher_path = normpath(
                        join(bundle_path, "..", "Pvtbox-Mac.command"))
                else:
                    launcher_path = bundle_path
                subprocess.call(['open', launcher_path])
            os.chdir(old_cwd)
            Application.exit()
        except Exception as e:
            logger.warning("Can't install update. Reason: %s", e)
            self._status = UPDATER_STATUS_INSTALL_ERROR
            self.emit_status()
            return False

        self._status = UPDATER_STATUS_INSTALLED
        self.emit_status()
        return True
示例#2
0
 def default_config():
     return dict(
         autologin=not is_portable(),
         upload_limit=0,
         download_limit=0,
         fs_events_processing_delay=1,
         fs_events_processing_period=1,
         fs_folder_timeout=2,
         sync_directory=FilePath(get_data_dir()),
         conflict_file_suffix='Conflicted copy from {}'.format(
             get_device_name()),
         node_hash=sha512(uuid4().bytes).hexdigest(),
         user_hash=None,
         send_statistics=True,
         license_type=UNKNOWN_LICENSE,  # unknown licence by default
         lang=None,  # System language
         user_email=None,
         last_user_email=None,
         user_password_hash=None,
         http_downloader_timeout=3,
         excluded_dirs=(),  # List of directories excluded from sync
         max_log_size=100,  # Max log file size Mb
         download_backups=False,
         remote_events_max_total=5000,
         max_remote_events_per_request=100,
         max_relpath_len=3096,
         sync_dir_size=0,
         copies_logging=True,
         excluded_dirs_applied=(),  # List of excluded dirs, applied in DB
         host=REGULAR_URI,
         tracking_address='https://tracking.pvtbox.net:443/1/',
         smart_sync=True,
     )
示例#3
0
    def start(self, app_start_ts, args):
        '''
        Performs application initialization and launch

        @raise SystemExit
        '''
        logger.debug("Launching application...")
        if is_portable():
            logger.debug("Portable detected")

        # Acquire lock file to prevent multiple app instances launching
        lock_acquired = self.acquire_lock()
        if not lock_acquired or is_already_started():
            if 'wipe_internal' in args and args['wipe_internal']:
                from common.tools import send_wipe_internal
                send_wipe_internal()
            else:
                if 'download_link' in args and args['download_link']:
                    from common.tools import send_download_link
                    send_download_link(args['download_link'])
                elif 'copy' in args and args['copy']:
                    from common.tools import send_copy_to_sync_dir
                    send_copy_to_sync_dir(args['copy'])
                elif 'offline_on' in args and args['offline_on']:
                    from common.tools import send_offline_on
                    send_offline_on(args['offline_on'])

                send_show_command()
            logger.error("Application started already. Exiting")

            raise SystemExit(0)

        register_smart()

        register_smart()

        sync_folder_removed = args.get('sync_folder_removed', False)
        logging_disabled = args.get('logging_disabled', False)
        if not sync_folder_removed and not logging_disabled:
            clear_old_logs(logger)

        self._gui = GUI(parent=self,
                        args=sys.argv[1:],
                        sync_folder_removed=sync_folder_removed,
                        loglevel=args['loglevel'],
                        logging_disabled=logging_disabled)

        self._gui.run_with_splash()

        logger.debug("ApplicationImpl start returning")
示例#4
0
 def default_config():
     return dict(
         autologin=not is_portable(),
         license_type=UNKNOWN_LICENSE,  # unknown licence by default
         node_hash=sha512(str(uuid4()).encode()).hexdigest(),
         user_hash=None,
         user_email=None,
         user_password_hash=None,
         devices=dict(),
         autoupdate=True,
         next_update_check=0,
         logging_disabled=False,
         download_backups=False,
         host=REGULAR_URI,
         old_host=REGULAR_URI,
         smart_sync=True,
     )
示例#5
0
 def _get_update_file_uri(self):
     os = get_platform()
     if os == 'Windows':
         machine = 'x64' if is_os_64bit() else 'x86'
         return '{}/{}/win/PvtboxSetup-offline_{}.exe'.format(
             self._updates_server_addr,
             self._update_branch,
             machine,
         )
     elif os == 'Darwin':
         if is_portable():
             return '{}/{}/osx/Pvtbox-portable.app.zip'.format(
                 self._updates_server_addr,
                 self._update_branch,
             )
         else:
             return '{}/{}/osx/Pvtbox.app.zip'.format(
                 self._updates_server_addr,
                 self._update_branch,
             )
     else:
         return ''
示例#6
0
 def read_config_file(self):
     need_sync = False
     with open(self.config_file_name, 'rb') as f:
         data = f.read()
     try:
         decrypted_data = xor_with_key(data)
         config = loads(decrypted_data)
         secret = UUID(int=158790876260364472748646807733425668096 +
                       getnode()).bytes
         if is_portable():
             config['user_hash'] = None
             config['user_password_hash'] = None
             config['sync_directory'] = FilePath(get_data_dir())
             config['conflict_file_suffix'] = 'Conflicted copy from {}'\
                 .format(get_device_name())
         else:
             try:
                 if config.get('user_hash', None):
                     config['user_hash'] = xor_with_key(
                         bytes.fromhex(config['user_hash']),
                         secret).decode()
             except Exception as e:
                 logger.debug("Error decoding user hash: %s", e)
                 config["user_hash"] = None
             try:
                 if config.get('user_password_hash', None):
                     config['user_password_hash'] = xor_with_key(
                         bytes.fromhex(config['user_password_hash']),
                         secret).decode()
             except Exception as e:
                 logger.debug("Error decoding user password hash: %s", e)
                 config["user_password_hash"] = None
     except ValueError as e:
         logger.warning("Error: %s", e)
         config = loads(data)
         config["user_hash"] = None
         config["user_password_hash"] = None
         need_sync = True
     return config, need_sync
示例#7
0
    def _setup_to_ui(self):
        ui = self._ui
        cfg = self._cfg

        portable = is_portable()

        if cfg.get_setting('lang', None) is None:
            self._ui.language_comboBox.setCurrentIndex(0)
        else:
            lang = cfg.lang if cfg.lang in get_available_languages() else 'en'
            assert lang in get_available_languages()
            for i in range(1, ui.language_comboBox.count()):
                if ui.language_comboBox.itemText(i) == lang:
                    ui.language_comboBox.setCurrentIndex(i)
                    break

        ui.location_edit.setText(
            FilePath(cfg.sync_directory) if cfg.sync_directory else '')
        ui.location_button.setEnabled(not portable)
        if portable:
            ui.location_button.setToolTip(tr("Disabled in portable version"))
        ui.email_label.setText(cfg.user_email if cfg.user_email else '')

        def set_limit(limit, auto_btn, manual_btn, edit):
            edit.setValidator(QRegExpValidator(QRegExp("\\d{1,9}")))
            if limit:
                manual_btn.setChecked(True)
                edit.setText(str(limit))
            else:
                auto_btn.setChecked(True)
                auto_btn.click()

        set_limit(limit=cfg.download_limit,
                  auto_btn=ui.download_auto_radioButton,
                  manual_btn=ui.download_limit_radioButton,
                  edit=ui.download_limit_edit)
        set_limit(limit=cfg.upload_limit,
                  auto_btn=ui.upload_auto_radioButton,
                  manual_btn=ui.upload_limit_radioButton,
                  edit=ui.upload_limit_edit)

        ui.autologin_checkbox.setChecked(self._main_cfg.autologin)
        ui.autologin_checkbox.setEnabled(not portable)
        if portable:
            ui.autologin_checkbox.setToolTip(
                tr("Disabled in portable version"))
        ui.tracking_checkbox.setChecked(cfg.send_statistics)
        ui.autoupdate_checkbox.setChecked(self._main_cfg.autoupdate)
        ui.download_backups_checkBox.setChecked(cfg.download_backups)
        ui.is_smart_sync_checkBox.setChecked(cfg.smart_sync)
        ui.disable_logging_checkBox.setChecked(self._main_cfg.logging_disabled)

        # Disable smart sync for free license
        if not cfg.license_type or cfg.license_type == FREE_LICENSE:
            ui.is_smart_sync_checkBox.setText(
                tr("SmartSync+ is not available for your license"))
            ui.is_smart_sync_checkBox.setChecked(False)
            ui.is_smart_sync_checkBox.setCheckable(False)
            ui.smart_sync_button.setEnabled(False)

        ui.startup_checkbox.setChecked(is_in_system_startup())
        ui.startup_checkbox.setEnabled(not portable)
        if portable:
            ui.startup_checkbox.setToolTip(tr("Disabled in portable version"))