예제 #1
0
        def backup_next_file():
            try:
                if self.backup_compressing:
                    next_file = self.backup_files.popleft()
                    relpath = os.path.relpath(next_file, self.game_dir)
                    self.next_backup_file = next_file

                    self.compressing_label.setText(
                        _('Compressing {filename}').format(filename=relpath))

                    compress_thread = CompressThread(self.backup_file,
                        next_file, relpath)
                    compress_thread.completed.connect(completed_compress)
                    self.compress_thread = compress_thread

                    compress_thread.start()

            except IndexError:
                self.backup_compressing = False
                self.compress_thread = None

                self.finish_backup_saves()

                main_window = self.get_main_window()
                status_bar = main_window.statusBar()

                if self.after_backup is not None:
                    self.after_update_backups = self.after_backup
                    self.after_backup = None
                else:
                    status_bar.showMessage(_('Saves backup completed'))

                self.update_backups_table()
예제 #2
0
        def extract_next_file():
            try:
                if self.extracting_backup:
                    extracting_element = self.extracting_infolist.popleft()
                    self.extracting_label.setText(_('Extracting {filename}'
                        ).format(filename=extracting_element.filename))
                    self.next_extract_file = extracting_element

                    extracting_thread = ExtractingThread(
                        self.extracting_zipfile, extracting_element,
                        self.extract_dir)
                    extracting_thread.completed.connect(completed_extract)
                    self.extracting_thread = extracting_thread

                    extracting_thread.start()

            except IndexError:
                self.extracting_backup = False
                self.extracting_thread = None

                self.finish_restore_backup()

                main_window = self.get_main_window()
                status_bar = main_window.statusBar()

                status_bar.showMessage(_('{backup_name} backup restored'
                    ).format(backup_name=backup_name))
    def move_new_soundpack(self):
        # Find the soundpack in the self.extract_dir
        # Move the soundpack from that location into self.soundpacks_dir

        self.moving_new_soundpack = True

        main_window = self.get_main_window()
        status_bar = main_window.statusBar()

        status_bar.showMessage(_('Finding the soundpack'))

        next_scans = deque()
        current_scan = scandir(self.extract_dir)

        soundpack_dir = None

        while True:
            try:
                entry = next(current_scan)
                if entry.is_dir():
                    next_scans.append(entry.path)
                elif entry.is_file():
                    dirname, basename = os.path.split(entry.path)
                    if basename == 'soundpack.txt':
                        soundpack_dir = dirname
                        entry = None
                        break
            except StopIteration:
                if len(next_scans) > 0:
                    current_scan = scandir(next_scans.popleft())
                else:
                    break

        for item in current_scan:
            pass

        if soundpack_dir is None:
            status_bar.showMessage(_('Soundpack installation cancelled - There '
                'is no soundpack in the downloaded archive'))
            delete_path(self.extract_dir)
            self.moving_new_soundpack = False

            self.finish_install_new_soundpack()
        else:
            soundpack_dir_name = os.path.basename(soundpack_dir)
            target_dir = os.path.join(self.soundpacks_dir, soundpack_dir_name)
            if os.path.exists(target_dir):
                status_bar.showMessage(_('Soundpack installation cancelled - '
                    'There is already a {basename} directory in '
                    '{soundpacks_dir}').format(basename=soundpack_dir_name,
                        soundpacks_dir=self.soundpacks_dir))
            else:
                shutil.move(soundpack_dir, self.soundpacks_dir)
                status_bar.showMessage(_('Soundpack installation completed'))

            delete_path(self.extract_dir)
            self.moving_new_soundpack = False

            self.game_dir_changed(self.game_dir)
            self.finish_install_new_soundpack()
예제 #4
0
    def create_menu(self):
        file_menu = QMenu(_('&File'))
        self.menuBar().addMenu(file_menu)
        self.file_menu = file_menu

        exit_action = QAction(_('E&xit'), self, triggered=self.close)
        file_menu.addAction(exit_action)
        self.exit_action = exit_action

        help_menu = QMenu(_('&Help'))
        self.menuBar().addMenu(help_menu)
        self.help_menu = help_menu

        if getattr(sys, 'frozen', False):
            update_action = QAction(_('&Check for update'),
                                    self,
                                    triggered=self.manual_update_check)
            self.update_action = update_action
            self.help_menu.addAction(update_action)
            self.help_menu.addSeparator()

        about_action = QAction(_('&About CDDA Game Launcher'),
                               self,
                               triggered=self.show_about_dialog)
        self.about_action = about_action
        self.help_menu.addAction(about_action)
    def installed_clicked(self):
        selection_model = self.installed_lv.selectionModel()
        if selection_model is not None and selection_model.hasSelection():
            selected = selection_model.currentIndex()
            selected_info = self.soundpacks[selected.row()]

            self.viewname_le.setText(selected_info['VIEW'])
            self.name_le.setText(selected_info['NAME'])
            self.path_label.setText(_('Path:'))
            self.path_le.setText(selected_info['path'])
            self.size_le.setText(sizeof_fmt(selected_info['size']))
            self.homepage_tb.setText('')

            if selected_info['enabled']:
                self.disable_existing_button.setText(_('Disable'))
            else:
                self.disable_existing_button.setText(_('Enable'))

        if not self.tab_disabled:
            self.disable_existing_button.setEnabled(True)
            self.delete_existing_button.setEnabled(True)

        self.install_new_button.setEnabled(False)

        repository_selection = self.repository_lv.selectionModel()
        if repository_selection is not None:
            repository_selection.clearSelection()
예제 #6
0
 def set_download_path(self):
     options = QFileDialog.DontResolveSymlinks
     selected_file, selected_filter = QFileDialog.getOpenFileName(self,
         _('Downloaded archive'), self.download_path_le.text(),
         _('Archive files {formats}').format(formats='(*.zip *.rar *.7z)'),
         options=options)
     if selected_file:
         self.download_path_le.setText(clean_qt_path(selected_file))
예제 #7
0
    def repository_clicked(self):
        selection_model = self.repository_lv.selectionModel()
        if selection_model is not None and selection_model.hasSelection():
            selected = selection_model.currentIndex()
            selected_info = self.repo_soundpacks[selected.row()]

            self.viewname_le.setText(selected_info['viewname'])
            self.name_le.setText(selected_info['name'])

            if selected_info['type'] == 'direct_download':
                self.path_label.setText(_('Url:'))
                self.path_le.setText(selected_info['url'])
                self.homepage_tb.setText('<a href="{url}">{url}</a>'.format(
                    url=html.escape(selected_info['homepage'])))
                if 'size' not in selected_info:
                    if not (self.current_repo_info is not None
                            and self.http_reply is not None
                            and self.http_reply.isRunning()
                            and self.current_repo_info is selected_info):
                        if (self.http_reply is not None
                                and self.http_reply.isRunning()):
                            self.http_reply_aborted = True
                            self.http_reply.abort()

                        self.http_reply_aborted = False
                        self.size_le.setText(_('Getting remote size'))
                        self.current_repo_info = selected_info

                        request = QNetworkRequest(QUrl(selected_info['url']))
                        request.setRawHeader(b'User-Agent',
                                             cons.FAKE_USER_AGENT)

                        self.http_reply = self.qnam.head(request)
                        self.http_reply.finished.connect(
                            self.size_query_finished)
                else:
                    self.size_le.setText(sizeof_fmt(selected_info['size']))
            elif selected_info['type'] == 'browser_download':
                self.path_label.setText(_('Url:'))
                self.path_le.setText(selected_info['url'])
                self.homepage_tb.setText('<a href="{url}">{url}</a>'.format(
                    url=html.escape(selected_info['homepage'])))
                if 'size' in selected_info:
                    self.size_le.setText(sizeof_fmt(selected_info['size']))
                else:
                    self.size_le.setText(_('Unknown'))

        if (self.soundpacks_dir is not None
                and os.path.isdir(self.soundpacks_dir)
                and not self.tab_disabled):
            self.install_new_button.setEnabled(True)
        self.disable_existing_button.setEnabled(False)
        self.delete_existing_button.setEnabled(False)

        installed_selection = self.installed_lv.selectionModel()
        if installed_selection is not None:
            installed_selection.clearSelection()
예제 #8
0
    def set_text(self):
        self.file_menu.setTitle(_('&File'))
        self.exit_action.setText(_('E&xit'))
        self.help_menu.setTitle(_('&Help'))
        if getattr(sys, 'frozen', False):
            self.update_action.setText(_('&Check for update'))
        self.about_action.setText(_('&About CDDA Game Launcher'))

        if self.about_dialog is not None:
            self.about_dialog.set_text()
        self.central_widget.set_text()
예제 #9
0
    def no_launcher_update_found(self):
        if self.in_manual_update_check:
            up_to_date_msgbox = QMessageBox()
            up_to_date_msgbox.setWindowTitle(_('Up to date'))
            up_to_date_msgbox.setText(
                _('The CDDA Game Launcher is up to date.'))
            up_to_date_msgbox.setIcon(QMessageBox.Information)

            up_to_date_msgbox.exec()

            self.in_manual_update_check = False
예제 #10
0
 def set_text(self):
     self.setWindowTitle(_('About CDDA Game Launcher'))
     self.ok_button.setText(_('OK'))
     m = _('<p>CDDA Game Launcher version {version}</p>').format(version=version)
     m += _('<p>Get the latest release'
            ' <a href="https://github.com/remyroy/CDDA-Game-Launcher/releases">on GitHub</a>.'
            '</p>')
     m += _('<p>Please report any issue'
            ' <a href="https://github.com/remyroy/CDDA-Game-Launcher/issues/new">on GitHub</a>.'
            '</p>')
     bitcoin_text = r'3N2BRM61bZLuFRHjSj2Lhtw6DrwPUGeTvV'
     bitcoin_link = r'bitcoin:3N2BRM61bZLuFRHjSj2Lhtw6DrwPUGeTvV'
     ether_link = r'https://etherscan.io/address/0xdb731476e913d75061a78105c3d1b5a7a03aa21b'
     ether_text = r'0xdb731476e913d75061a78105c3d1b5a7a03aa21b'
     m += _('<p>If you like the CDDA Game Launcher, you can buy me a beer by:</p>'
            '<p>donating bitcoins to <a href="{bitcoin_link}">{bitcoin_text}</a></p>'
            '<p><img src="btc-qr.png" /></p>'
            '<p>or by donating ethers to <a href="{ether_link}">{ether_text}</a></p>'
            '<p><img src="eth-qr.png" /></p>').format(bitcoin_text=bitcoin_text,
                                                      bitcoin_link=bitcoin_link,
                                                      ether_link=ether_link,
                                                      ether_text=ether_text)
     m += _('<p>Thanks to the following people for their efforts in'
            ' translating the CDDA Game Launcher</p>'
            '<ul>'
            '<li>Russian: Daniel from <a href="http://cataclysmdda.ru/">cataclysmdda.ru</a>'
            ' and Night_Pryanik'
            '</li>'
            '<li>Italian: Rettiliano Verace from'
            ' <a href="http://emigrantebestemmiante.blogspot.com">Emigrante Bestemmiante</a>'
            '</li>'
            '<li>French: Rémy Roy</li>'
            '<li>Spanish: KurzedMetal</li>'
            '</ul>')
     m += _('<p>Thanks to <a href="http://mattahan.deviantart.com/">Paul Davey aka Mattahan</a>'
            ' for the permission to use his artwork for the launcher icon.</p>')
     m += _('<p>This software is distributed under the MIT License. That means this is'
            ' 100&#37; free software, completely free to use, modify and/or distribute.'
            ' If you like more details check the following boring legal stuff...</p>')
     m += '<p>Copyright (c) 2015-2020 Rémy Roy</p>'
     m += ('<p>Permission is hereby granted, free of charge, to any person obtaining a copy'
           ' of this software and associated documentation files (the "Software"), to deal'
           ' in the Software without restriction, including without limitation the rights'
           ' to use, copy, modify, merge, publish, distribute, sublicense, and/or sell'
           ' copies of the Software, and to permit persons to whom the Software is'
           ' furnished to do so, subject to the following conditions:</p>'
           '<p>The above copyright notice and this permission notice shall be included in'
           ' all copies or substantial portions of the Software.</p>'
           '<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR'
           ' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,'
           ' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE'
           ' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER'
           ' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,'
           ' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE'
           ' SOFTWARE.</p>')
     self.text_content.setHtml(m)
예제 #11
0
    def prune_auto_backups(self):
        max_auto_backups = max(int(get_config_value('max_auto_backups', '6')),
                               1)

        search_start = (_('auto') + '_').lower()

        backup_dir = os.path.join(self.game_dir, 'save_backups')
        if not os.path.isdir(backup_dir):
            return

        auto_backups = []

        for entry in scandir(backup_dir):
            filename, ext = os.path.splitext(entry.name)
            if entry.is_file() and ext.lower() == '.zip':
                filename_lower = filename.lower()

                if filename_lower.startswith(search_start):
                    auto_backups.append({
                        'path':
                        entry.path,
                        'modified':
                        datetime.fromtimestamp(entry.stat().st_mtime)
                    })

        if len(auto_backups) >= max_auto_backups:
            # Remove backups to have a total of max_auto_backups - 1
            auto_backups.sort(key=lambda x: x['modified'])
            remove_count = len(auto_backups) - max_auto_backups + 1

            to_remove = auto_backups[:remove_count]

            for backup in to_remove:
                delete_path(backup['path'])
예제 #12
0
    def finish_backup_saves(self):
        if self.backup_file is not None:
            self.backup_file.close()

        main_window = self.get_main_window()
        status_bar = main_window.statusBar()

        status_bar.removeWidget(self.compressing_label)
        if self.compressing_progress_bar is not None:
            status_bar.removeWidget(self.compressing_progress_bar)
        if self.compressing_speed_label is not None:
            status_bar.removeWidget(self.compressing_speed_label)
        if self.compressing_size_label is not None:
            status_bar.removeWidget(self.compressing_size_label)

        status_bar.busy -= 1

        self.enable_tab()
        self.get_main_tab().enable_tab()
        self.get_soundpacks_tab().enable_tab()
        self.get_settings_tab().enable_tab()
        self.get_mods_tab().enable_tab()
        self.get_backups_tab().enable_tab()

        if self.manual_backup:
            self.manual_backup = False
            self.backup_current_button.setText(_('Backup current saves'))
예제 #13
0
    def finish_restore_backup(self):
        main_window = self.get_main_window()
        status_bar = main_window.statusBar()

        status_bar.removeWidget(self.extracting_label)
        status_bar.removeWidget(self.extracting_speed_label)
        status_bar.removeWidget(self.extracting_size_label)
        status_bar.removeWidget(self.extracting_progress_bar)

        status_bar.busy -= 1

        self.extracting_backup = False

        if self.extracting_zipfile is not None:
            self.extracting_zipfile.close()

        if self.temp_save_dir is not None:
            delete_path(self.temp_save_dir)

        self.enable_tab()
        self.get_main_tab().enable_tab()
        self.get_soundpacks_tab().enable_tab()
        self.get_settings_tab().enable_tab()
        self.get_mods_tab().enable_tab()
        self.get_backups_tab().enable_tab()

        self.restore_button.setText(_('Restore backup'))

        self.get_main_tab().game_dir_group_box.update_saves()
예제 #14
0
    def set_text(self):
        self.setTabText(self.indexOf(self.main_tab), _('Main'))
        self.setTabText(self.indexOf(self.backups_tab), _('Backups'))
        self.setTabText(self.indexOf(self.mods_tab), _('Mods'))
        #self.setTabText(self.indexOf(self.tilesets_tab), _('Tilesets'))
        self.setTabText(self.indexOf(self.soundpacks_tab), _('Soundpacks'))
        #self.setTabText(self.indexOf(self.fonts_tab), _('Fonts'))
        self.setTabText(self.indexOf(self.settings_tab), _('Settings'))

        self.main_tab.set_text()
        self.backups_tab.set_text()
        self.mods_tab.set_text()
        #self.tilesets_tab.set_text()
        self.soundpacks_tab.set_text()
        #self.fonts_tab.set_text()
        self.settings_tab.set_text()
예제 #15
0
def init_logging():
    logger = logging.getLogger('cddagl')
    logger.setLevel(logging.INFO)

    local_app_data = os.environ.get('LOCALAPPDATA', os.environ.get('APPDATA'))
    if local_app_data is None or not os.path.isdir(local_app_data):
        local_app_data = ''

    logging_dir = os.path.join(local_app_data, 'CDDA Game Launcher')
    if not os.path.isdir(logging_dir):
        os.makedirs(logging_dir)

    logging_file = os.path.join(logging_dir, 'app.log')

    handler = RotatingFileHandler(logging_file,
                                  encoding='utf8',
                                  maxBytes=cons.MAX_LOG_SIZE,
                                  backupCount=cons.MAX_LOG_FILES)
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)

    logger.addHandler(handler)

    handler = logging.StreamHandler()
    logger.addHandler(handler)

    logger.info(
        _('CDDA Game Launcher started: {version}').format(version=version))
 def add_soundpack(self, soundpack_info):
     index = self.soundpacks_model.rowCount()
     self.soundpacks_model.insertRows(self.soundpacks_model.rowCount(), 1)
     disabled_text = ''
     if not soundpack_info['enabled']:
         disabled_text = _(' (Disabled)')
     self.soundpacks_model.setData(self.soundpacks_model.index(index),
         soundpack_info['VIEW'] + disabled_text)
예제 #17
0
 def set_ka_directory(self):
     options = QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly
     directory = QFileDialog.getExistingDirectory(self,
             _('Archive directory'), self.keep_archive_directory_line.text(),
             options=options)
     if directory:
         self.keep_archive_directory_line.setText(clean_qt_path(directory))
         self.ka_directory_changed()
    def delete_existing(self):
        selection_model = self.installed_lv.selectionModel()
        if selection_model is None or not selection_model.hasSelection():
            return

        selected = selection_model.currentIndex()
        selected_info = self.soundpacks[selected.row()]

        confirm_msgbox = QMessageBox()
        confirm_msgbox.setWindowTitle(_('Delete soundpack'))
        confirm_msgbox.setText(_('This will delete the soundpack directory. It '
            'cannot be undone.'))
        confirm_msgbox.setInformativeText(_('Are you sure you want to '
            'delete the {view} soundpack?').format(view=selected_info['VIEW']))
        confirm_msgbox.addButton(_('Delete the soundpack'),
            QMessageBox.YesRole)
        confirm_msgbox.addButton(_('I want to keep the soundpack'),
            QMessageBox.NoRole)
        confirm_msgbox.setIcon(QMessageBox.Warning)

        if confirm_msgbox.exec() == 0:
            main_window = self.get_main_window()
            status_bar = main_window.statusBar()

            if not delete_path(selected_info['path']):
                status_bar.showMessage(_('Soundpack deletion cancelled'))
            else:
                self.soundpacks_model.removeRows(selected.row(), 1)
                self.soundpacks.remove(selected_info)

                status_bar.showMessage(_('Soundpack deleted'))
예제 #19
0
def log_exception(extype, value, tb):
    tb_io = StringIO()
    traceback.print_tb(tb, file=tb_io)

    logger.critical(
        _('Global error:\nLauncher version: {version}\nType: '
          '{extype}\nValue: {value}\nTraceback:\n{traceback}').format(
              version=cddagl.__version__,
              extype=str(extype),
              value=str(value),
              traceback=tb_io.getvalue()))
예제 #20
0
def sizeof_fmt(num, suffix=None):
    if suffix is None:
        suffix = _('B')
    for unit in [
            '',
            _('Ki'),
            _('Mi'),
            _('Gi'),
            _('Ti'),
            _('Pi'),
            _('Ei'),
            _('Zi')
    ]:
        if abs(num) < 1024.0:
            return "%3.1f %s%s" % (num, unit, suffix)
        num /= 1024.0
    return "%.1f %s%s" % (num, _('Yi'), suffix)
예제 #21
0
    def install_clicked(self):
        choosen_file = self.download_path_le.text()
        if not os.path.isfile(choosen_file):
            filenotfound_msgbox = QMessageBox()
            filenotfound_msgbox.setWindowTitle(_('File not found'))

            text = (_(
                '{filepath} is not an existing file on your system. '
                'Make sure to download the archive with your browser. Make '
                'sure to select the downloaded archive afterwards.')).format(
                    filepath=choosen_file)

            filenotfound_msgbox.setText(text)
            filenotfound_msgbox.addButton(_('I will try again'),
                                          QMessageBox.AcceptRole)
            filenotfound_msgbox.setIcon(QMessageBox.Warning)
            filenotfound_msgbox.exec()

            return

        self.downloaded_path = choosen_file
        self.done(1)
예제 #22
0
    def set_text(self):
        self.file_menu.setTitle(_('&File'))
        self.exit_action.setText(_('E&xit'))
        self.help_menu.setTitle(_('&Help'))
        self.faq_action.setText(_('&Frequently asked questions (FAQ)'))
        self.game_issue_action.setText(_('&Game issue'))
        self.update_action.setText(_('&Check for update'))
        self.about_action.setText(_('&About CDDA Game Launcher'))

        if self.about_dialog is not None:
            self.about_dialog.set_text()
        self.central_widget.set_text()
    def disable_existing(self):
        selection_model = self.installed_lv.selectionModel()
        if selection_model is None or not selection_model.hasSelection():
            return

        selected = selection_model.currentIndex()
        selected_info = self.soundpacks[selected.row()]

        if selected_info['enabled']:
            config_file = os.path.join(selected_info['path'], 'soundpack.txt')
            new_config_file = os.path.join(selected_info['path'],
                'soundpack.txt.disabled')
            try:
                shutil.move(config_file, new_config_file)
                selected_info['enabled'] = False
                self.soundpacks_model.setData(selected, selected_info['VIEW'] +
                    _(' (Disabled)'))
                self.disable_existing_button.setText(_('Enable'))
            except OSError as e:
                main_window = self.get_main_window()
                status_bar = main_window.statusBar()

                status_bar.showMessage(str(e))
        else:
            config_file = os.path.join(selected_info['path'],
                'soundpack.txt.disabled')
            new_config_file = os.path.join(selected_info['path'],
                'soundpack.txt')
            try:
                shutil.move(config_file, new_config_file)
                selected_info['enabled'] = True
                self.soundpacks_model.setData(selected, selected_info['VIEW'])
                self.disable_existing_button.setText(_('Disable'))
            except OSError as e:
                main_window = self.get_main_window()
                status_bar = main_window.statusBar()

                status_bar.showMessage(str(e))
예제 #24
0
def init_logging():
    logger = logging.getLogger('cddagl')
    logger.setLevel(logging.INFO)

    local_app_data = os.environ.get('LOCALAPPDATA', os.environ.get('APPDATA'))
    if local_app_data is None or not os.path.isdir(local_app_data):
        local_app_data = ''

    logging_dir = os.path.join(local_app_data, 'CDDA Game Launcher')
    if not os.path.isdir(logging_dir):
        os.makedirs(logging_dir)

    logging_file = os.path.join(logging_dir, 'app.log')

    handler = RotatingFileHandler(logging_file,
                                  encoding='utf8',
                                  maxBytes=cons.MAX_LOG_SIZE,
                                  backupCount=cons.MAX_LOG_FILES)
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)

    logger.addHandler(handler)

    if not getattr(sys, 'frozen', False):
        handler = logging.StreamHandler()
        logger.addHandler(handler)
    else:
        '''class LoggerWriter:
            def __init__(self, logger, level, imp=None):
                self.logger = logger
                self.level = level
                self.imp = imp

            def __getattr__(self, attr):
                return getattr(self.imp, attr)

            def write(self, message):
                if message != '\n':
                    self.logger.log(self.level, message)


        sys._stdout = sys.stdout
        sys._stderr = sys.stderr

        sys.stdout = LoggerWriter(logger, logging.INFO, sys._stdout)
        sys.stderr = LoggerWriter(logger, logging.ERROR, sys._stderr)'''

    logger.info(
        _('CDDA Game Launcher started: {version}').format(version=version))
예제 #25
0
        def timeout():
            self.extracting_progress_bar.setValue(self.extracting_index)

            if self.extracting_index == len(self.extracting_infolist):
                self.extracting_timer.stop()

                main_window = self.get_main_window()
                status_bar = main_window.statusBar()

                status_bar.removeWidget(self.extracting_label)
                status_bar.removeWidget(self.extracting_progress_bar)

                status_bar.busy -= 1

                self.extracting_new_soundpack = False

                self.extracting_zipfile.close()
                self.extracting_zipfile = None

                if self.downloaded_file.lower().endswith('.7z'):
                    self.extracting_archive = None

                if self.install_type == 'direct_download':
                    download_dir = os.path.dirname(self.downloaded_file)
                    delete_path(download_dir)

                self.move_new_soundpack()

            else:
                extracting_element = self.extracting_infolist[
                    self.extracting_index]

                self.extracting_label.setText(
                    _('Extracting {0}').format(extracting_element.filename))

                if self.downloaded_file.lower().endswith('.7z'):
                    destination = os.path.join(
                        self.extract_dir,
                        *extracting_element.filename.split('/'))
                    dest_dir = os.path.dirname(destination)
                    if not os.path.isdir(dest_dir):
                        os.makedirs(dest_dir)
                    with open(destination, 'wb') as f:
                        f.write(extracting_element.read())
                else:
                    self.extracting_zipfile.extract(extracting_element,
                                                    self.extract_dir)

                self.extracting_index += 1
예제 #26
0
 def set_text(self):
     self.command_line_parameters_label.setText(
         _('Command line parameters:'))
     self.keep_launcher_open_checkbox.setText(
         _('Keep the launcher opened after launching the game'))
     self.locale_label.setText(_('Language:'))
     self.locale_combo.setItemText(0,
         _('System language or best match ({locale})').format(
             locale=get_ui_locale()))
     self.allow_mul_insts_checkbox.setText(_('Allow multiple instances of '
         'the launcher to be started'))
     if getattr(sys, 'frozen', False):
         self.use_launcher_dir_checkbox.setText(_('Use the launcher '
             'directory as the game directory'))
         self.no_launcher_version_check_checkbox.setText(_('Do not check '
             'for new version of the CDDA Game Launcher on launch'))
     self.setTitle(_('Launcher'))
    def finish_install_new_soundpack(self):
        self.installing_new_soundpack = False

        self.installed_lv.setEnabled(True)
        self.repository_lv.setEnabled(True)

        self.install_new_button.setText(_('Install this soundpack'))

        self.get_main_tab().enable_tab()
        self.get_mods_tab().enable_tab()
        self.get_settings_tab().enable_tab()
        self.get_backups_tab().enable_tab()

        if self.close_after_install:
            self.get_main_window().close()
예제 #28
0
def handle_exception(extype, value, tb):
    logger = logging.getLogger('cddagl')

    tb_io = StringIO()
    traceback.print_tb(tb, file=tb_io)

    logger.critical(
        _('Global error:\n'
          'Launcher version: {version}\n'
          'Type: {extype}\n'
          'Value: {value}\n'
          'Traceback:\n{traceback}').format(version=version,
                                            extype=str(extype),
                                            value=str(value),
                                            traceback=tb_io.getvalue()))
    ui_exception(extype, value, tb)
예제 #29
0
 def set_text(self):
     self.prevent_save_move_checkbox.setText(
         _('Do not copy or move the save directory'))
     self.prevent_save_move_checkbox.setToolTip(
         _('If your save directory size is '
           'large, it might take a long time to copy it during the update '
           'process.\nThis option might help you speed the whole thing but '
           'your previous version will lack the save directory.'))
     self.keep_archive_copy_checkbox.setText(
         _('Keep a copy of the downloaded '
           'archive in the following directory:'))
     self.auto_refresh_builds_checkbox.setText(
         _('Automatically refresh builds list every'))
     self.arb_min_label.setText(_('minutes'))
     self.remove_previous_version_checkbox.setText(
         _('Remove previous version after update (not recommended)'))
     self.permanently_delete_files_checkbox.setText(
         _('Permanently delete files instead of moving them in the recycle '
           'bin (not recommended)'))
     self.setTitle(_('Update/Installation'))
예제 #30
0
def retry_rename(src, dst):
    while os.path.exists(src):
        try:
            os.rename(src, dst)
        except OSError as e:
            retry_msgbox = QMessageBox()
            retry_msgbox.setWindowTitle(_('Cannot rename file'))

            process = None
            if e.filename is not None:
                process = find_process_with_file_handle(e.filename)

            text = _('''
<p>The launcher failed to rename the following file: {src} to {dst}</p>
<p>When trying to rename or access {filename}, the launcher raised the
following error: {error}</p>
''').format(
    src=html.escape(src),
    dst=html.escape(dst),
    filename=html.escape(e.filename),
    error=html.escape(e.strerror))

            if process is None:
                text = text + _('''
<p>No process seems to be using that file.</p>
''')
            else:
                text = text + _('''
<p>The process <strong>{image_file_name} ({pid})</strong> is currently using
that file. You might need to end it if you want to retry.</p>
''').format(image_file_name=process['image_file_name'], pid=process['pid'])

            retry_msgbox.setText(text)
            retry_msgbox.setInformativeText(_('Do you want to retry renaming '
                'this file?'))
            retry_msgbox.addButton(_('Retry renaming the file'),
                QMessageBox.YesRole)
            retry_msgbox.addButton(_('Cancel the operation'),
                QMessageBox.NoRole)
            retry_msgbox.setIcon(QMessageBox.Critical)

            if retry_msgbox.exec() == 1:
                return False

    return True