Пример #1
0
    def validateTask(self, task, *, interactive=False):
        """Check if task is properly defined.

        Parameters
        ----------
        task: SyncTask
            Task to validate.
        interactive: bool, optional
            For interactive synchronization `out` will not be vaildated.

        Raises
        ------
        Error
            Invalid task.
        KeyError or Exception
            Invalid `task`.out.path pattern.
        """
        sub, ref, out = task.sub, task.ref, task.out
        if sub is None or not sub.path or sub.no is None:
            raise Error('subtitles not set', task=task)
        if ref is None or not ref.path or ref.no is None:
            raise Error('reference file not set', task=task)
        if not interactive and (out is None or not out.path):
            raise Error('output path not set', task=task)
        if not interactive:
            out.validateOutputPattern()
Пример #2
0
def validateAssets(parent, tasks, updateAssets=True, askForLang=True):
    for task in tasks:
        sub = task.sub
        ref = task.ref

        if sub == None or sub.path == None or sub.no == None:
            raise raiseTaskError(task, _('Subtitles not set'))
        if ref == None or ref.path == None or ref.no == None:
            raise raiseTaskError(task, _('Reference file not set'))
        if sub.path == ref.path and sub.no == ref.no:
            raise raiseTaskError(
                task, _('Subtitles can\'t be the same as reference'))
        if ref.type == 'audio' and not ref.lang:
            raise raiseTaskError(task, _('Select reference language first'))
        if task.out and task.out.path:
            task.out.validateOutputPattern()

    if askForLang and settings().showLanguageNotSelectedPopup:
        if not askForLangSelection(parent, tasks):
            return False

    assetListNotReady = assetListUpdater.isRunning()

    needed = set()
    for task in tasks:
        needed |= assetManager.getAssetsForTask(task)
    missing = [asset for asset in needed if asset.isMissing()]

    if assetListNotReady and missing:
        with BusyDlg(self, _('Downloading assets list...')) as dlg:
            dlg.ShowModalWhile(assetListUpdater.isRunning)
        missing = [asset for asset in needed if asset.isMissing()]

    if missing:
        msg = [_('Following assets are missing on server:'), '']
        msg += [' - ' + asset.getPrettyName() for asset in missing]
        raise Error('\n'.join(msg))

    nonLocal = [asset for asset in needed if not asset.isLocal()]
    if nonLocal:
        if not askForDownloadAssets(parent, nonLocal):
            return False

    if updateAssets:
        update = [asset for asset in needed if asset.isUpgradable()]
        if update:
            askForUpdateAssets(parent, update)

    missing = [asset for asset in needed if not asset.isLocal()]
    if missing:
        msg = [_('Following assets are missing:')]
        msg += [' - ' + asset.getPrettyName() for asset in missing]
        raise Error('\n'.join(msg))

    return True
Пример #3
0
 def validateSelection(self):
     subs = self.m_panelSub.stream
     refs = self.m_panelRef.stream
     if subs.path == None or subs.no == None:
         raise Error(_('Subtitles not set'))
     if refs.path == None or refs.no == None:
         raise Error(_('Reference file not set'))
     if subs.path == refs.path and subs.no == refs.no:
         raise Error(_('Subtitles can\'t be the same as reference'))
     if refs.type == 'audio' and not refs.lang:
         raise Error(_('Select reference language first'))
Пример #4
0
def formatPattern(pattern, formatter):
    try:
        return pattern.format(
            **formatter, **{
                'if': ConditionalFormatter(formatter),
                'if_not': ConditionalFormatter(formatter, inverted=True)
            })

    except KeyError as e:
        raise Error(_('Invalid output pattern, invalid keyword: {}').format(e),
                    pattern=pattern)

    except Exception as e:
        raise Error(_('Invalid output pattern, {}').format(e), pattern=pattern)
Пример #5
0
def loadDictionary(langKey, langVal, minLen=0):
    langKeyInfo = languages.get(code3=langKey)
    langValInfo = languages.get(code3=langVal)

    minKeyLen = langKeyInfo.ngrams or minLen
    minValLen = langValInfo.ngrams or minLen

    dictionary = gizmo.Dictionary()

    def addEntry(key, val):
        if len(key) >= minKeyLen and len(val) >= minValLen:
            if langKeyInfo.rightToLeft: key = key[::-1]
            if langValInfo.rightToLeft: val = val[::-1]
            for k in splitNgrams(key, langKeyInfo.ngrams):
                for v in splitNgrams(val, langValInfo.ngrams):
                    dictionary.add(k.lower(), v)

    asset = assets.getAsset('dict', (langKey, langVal))
    if asset.localVersion():
        for key, val in asset.readDictionary():
            addEntry(key, val)
    else:
        asset = assets.getAsset('dict', (langVal, langKey))
        if asset.localVersion():
            for key, val in asset.readDictionary():
                addEntry(val, key)

    if not asset.localVersion():
        raise Error(_('There is no dictionary for transaltion from {} to {}') \
                .format(langKey, langVal)) \
                .add('language1', langKey) \
                .add('language2', langVal)

    logger.info('dictionary ready with %u entries', dictionary.size())
    return dictionary
Пример #6
0
 def hasList(self):
     if self.error:
         e = self.error[1]
         self.error = None
         msg = '{}\n{}'.format(_('Communication with server failed'), str(e))
         raise Error(msg) from e
     return self.isListReady
Пример #7
0
def createProducerPipeline(stream):
    if stream.type == 'subtitle/text':
        return SubtitlePipeline(stream)
    elif stream.type == 'audio':
        return SpeechPipeline(stream)
    else:
        raise Error(_('Not supported stream type'), type=stream.type)
Пример #8
0
    def openStream(self, file=None, path=None):
        if path:
            file = readStream(self, self.file, path)

        self.file = file
        self.m_textPath.SetValue(self.file.path)
        self.m_textPath.SetInsertionPoint(self.m_textPath.GetLastPosition())

        self.m_choiceEncoding.Enable(False)
        self.m_buttonOk.Enable(False)

        lang = validateLang(file.lang)
        enc = file.enc
        channels = file.channels

        self.m_listStreams.setStreams(file.streams, file.types)

        if self.m_listStreams.GetItemCount() == 0:
            raise Error(_('There are no usable streams'),
                        path=file.path,
                        types=self.file.types)

        if file.no is not None:
            self.selectStream(file.stream())

        if not lang:
            lang = self.defaultLang

        file.lang = lang
        self.m_choiceLang.SetValue(lang)
        self.m_choiceEncoding.SetValue(enc)
        if channels:
            self.selectAudioChannels(channels)
Пример #9
0
def detectEncoding(path, lang, probeSize=32 * 1024):
    dlang, denc = locale.getdefaultlocale()
    if not lang:
        lang2 = dlang.split('_', 1)[0]
        lang = languages2to3.get(lang2)

    encs = ['UTF-8'] + languages.get(lang, (None, []))[1]
    if denc not in encs:
        encs.append(denc)

    try:
        for enc in encs:
            with open(path, 'r', encoding=enc) as fp:
                try:
                    fp.read(32 * 1024)
                    logger.info('detected encoding %s for file "%s"', enc,
                                path)
                    return enc
                except UnicodeError:
                    pass
    except FileNotFoundError:
        raise Error('File not found').add('path', path)

    logger.info('couldn\'t detect encoding for file "%s", tried %s', path,
                encs)
Пример #10
0
    def openStream(self, stream=None, path=None):
        if path:
            return readStream(self, path, self.stream.types)

        self.stream = stream
        self.m_textPath.SetValue(self.stream.path)
        self.m_textPath.SetInsertionPoint(self.m_textPath.GetLastPosition())

        self.m_choiceEncoding.Enable(False)
        self.m_buttonOk.Enable(False)

        if not stream.lang and len(stream.streams) == 1:
            stream.lang = validateLang(getLangFromPath(stream.path))

        lang = validateLang(stream.lang)
        enc = stream.enc
        channels = stream.channels

        self.m_listStreams.setStreams(stream.streams, stream.types)

        if self.m_listStreams.GetItemCount() == 0:
            raise Error(_('There are no usable streams'),
                        path=stream.path,
                        types=self.stream.types)

        if stream.no != None:
            self.selectStream(stream.stream())

        stream.lang = lang
        self.m_choiceLang.SetValue(lang)
        self.m_choiceEncoding.SetValue(enc)
        if channels:
            self.selectAudioChannels(channels)
Пример #11
0
def detectEncoding(path, lang, probeSize=32 * 1024):
    try:
        dlang, denc = locale.getdefaultlocale()
    except Exception as e:
        logger.warn('getdefaultlocale failed, %r', e)
        dlang, denc = None, None

    if not lang and dlang:
        lang = dlang.split('_', 1)[0]

    encs = ['UTF-8'] + languages.get(lang).encodings
    if denc and denc not in encs:
        encs.append(denc)

    try:
        for enc in encs:
            with open(path, 'r', encoding=enc) as fp:
                try:
                    fp.read(32 * 1024)
                    logger.info('detected encoding %s for file "%s"', enc,
                                path)
                    return enc
                except UnicodeError:
                    pass
    except FileNotFoundError:
        raise Error('File not found').add('path', path)

    logger.info('couldn\'t detect encoding for file "%s", tried %s', path,
                encs)
Пример #12
0
    def __init__(self, parent):
        title = _('Application upgrade')
        asset = assetManager.getSelfUpdaterAsset()
        updater = asset and asset.getUpdater()
        if not updater:
            raise Error('Application upgrade is not available')

        super().__init__(parent, title, updater)
Пример #13
0
def checkResponseCode(url, response):
    if response.status < 200 or response.status >= 300:
        code = response.status
        reason = response.reason
        raise Error(_('Got response {}: {}').format(code, reason),
                    code=code,
                    reason=reason,
                    url=url)
Пример #14
0
    async def verify(self, hash):
        logger.info('downloading signature')
        sig = await async_utils.downloadRaw(self.asset.getRemote('sig'))

        logger.info('verifying signature')
        if not pubkey.getVerifier().verify(hash, sig):
            raise Error(_('Signature verification failed'),
                        url=self.asset.getRemote('url'))

        logger.info('signature is valid')
Пример #15
0
 def load(self):
     try:
         if os.path.isfile(config.configpath):
             with open(config.configpath, encoding='utf8') as fp:
                 cfg = json.load(fp)
                 logger.info('configuration loaded from %s',
                             config.configpath)
                 logger.debug('configuration: %r', cfg)
                 self.set(**cfg)
     except Exception as err:
         raise Error(_('Cannot load settings file, {}').format(err),
                     path=config.configpath)
Пример #16
0
    def installUpdate(self):
        try:
            instPath = os.path.join(self.localDir, self.getLocal('install'))
            logger.info('executing installer %s', instPath)
            mode = os.stat(instPath).st_mode
            if (mode & stat.S_IEXEC) == 0:
                os.chmod(instPath, mode | stat.S_IEXEC)
            subprocess.Popen(instPath, cwd=self.localDir)

        except Exception as e:
            logger.error('cannot install update %s: %r', self.path, e, exc_info=True)
            raise Error(_('Update instalation failed miserably'))
Пример #17
0
    def _run(self, timeout):
        try:
            remote = self._asset._getRemoteData()
            url = remote.get('url')

            for key in ['url', 'sig', 'type']:
                if not isinstance(remote.get(key), str):
                    logger.warning('invalid asset remote data %r', remote)
                    return

            with tempfile.TemporaryFile() as fp:
                hash = self._download(fp, url, remote.get('size'), timeout)

                if not self._terminated:
                    try:
                        self._verify(fp, remote.get('sig'), hash)
                    except:
                        raise Error(_('Signature verification failed'),
                                    asset=self._asset.getId(),
                                    url=url)

                if not self._terminated:
                    try:
                        self._asset._removeLocalData()
                        self._install(fp, remote.get('type'))
                    except Exception:
                        self._asset._removeLocalData()
                        raise Error(_('Asset installation failed'),
                                    asset=self._asset.getId(),
                                    url=url)

        except:
            e = sys.exc_info()
            self._exception = e
            logger.error('updater failed', exc_info=True)

        finally:
            with self._lock:
                for onEnd in self._onEnd:
                    onEnd(self._asset, self._terminated, self._exception)
Пример #18
0
    def __init__(self, parent, asset):
        super().__init__(parent)
        self.m_textName.SetLabel(asset.getPrettyName())

        self.lastPos = 0
        self.startTime = time.monotonic()

        self.downloader = asset.downloader()
        if not self.downloader:
            raise Error(_('Update not available'))

        self.downloader.registerCallbacks(self)
        self.downloader.run(timeout=0.5)
Пример #19
0
def raiseTaskError(task, msg):
    msgs = [msg, '']
    if task.sub and task.sub.path:
        msgs.append(_('subtitles: ') + task.sub.path)
    if task.ref and task.ref.path:
        msgs.append(_('references: ') + task.ref.path)
    if task.out and task.out.path:
        msgs.append(_('output: ') + task.out.path)

    raise Error('\n'.join(msgs)) \
            .addn('sub', task.sub) \
            .addn('ref', task.ref) \
            .addn('out', task.out)
Пример #20
0
    def __init__(self, asset):
        self.asset = asset

        self.lock = threading.Lock()
        self.done = False
        self.progress = 0
        self.error = None

        super().__init__(self.job, name='Download')

        for key in ['type', 'url', 'sig']:
            if key not in asset.getRemote():
                raise Error('Invalid asset data, missing parameter', key=key)
Пример #21
0
    async def install(self, fp):
        assetType = self.asset.getRemote('type')
        if assetType == 'zip':
            dstdir = config.assetdir
            logger.info('extracting zip asset to %s', dstdir)
            os.makedirs(dstdir, exist_ok=True)
            zipf = zipfile.ZipFile(fp)
            zipf.extractall(dstdir)
            logger.info('extraction completed')

        else:
            raise Error('Invalid asset type',
                        type=assetType,
                        url=self.asset.getRemote('url'))
Пример #22
0
 def selectBy(self, type=None, lang=None):
     """Select stream by type and language (or only one of them)."""
     for s in self.streams.values():
         if self.types and s.type not in self.types:
             continue
         if type and not s.type.startswith(type):
             continue
         if lang and lang != s.lang.lower():
             continue
         return self.select(s.no)
     raise Error(_('There is no matching stream in {}').format(self.path)) \
             .addn('path', self.path) \
             .addn('type', type) \
             .addn('language', lang)
Пример #23
0
    def _install(self, fp, type):
        with self._asset._lock:
            self._asset._local = None
            if type == 'zip':
                dstdir = config.assetdir
                logger.info('extracting zip asset to %s', dstdir)
                os.makedirs(dstdir, exist_ok=True)
                zipf = zipfile.ZipFile(fp)
                zipf.extractall(dstdir)
                logger.info('extraction completed')

            else:
                raise Error('Invalid asset type',
                            asset=self._asset.getId(),
                            type=type,
                            url=self._asset._getRemoteData().get('url'))
Пример #24
0
    def install(self):
        """Run local installer.

        Application must be terminated immediately to let installer work.
        """
        with self._lock:
            try:
                self.installerVersion()
                instPath = os.path.join(self.localDir, self._getLocalData().get('install'))
                logger.info('executing installer %s', instPath)
                mode = os.stat(instPath).st_mode
                if (mode & stat.S_IEXEC) == 0:
                    os.chmod(instPath, mode | stat.S_IEXEC)
                subprocess.Popen(instPath, cwd=self.localDir)

            except:
                logger.error('cannot install update %s', self.path, exc_info=True)
                self._removeLocalData()
                raise Error(_('Update instalation failed miserably'))
Пример #25
0
 def selectBy(self, type=None, lang=None):
     for s in self.streams.values():
         if self.types and s.type not in self.types:
             continue
         if type and not s.type.startswith(type):
             continue
         if lang and lang != s.lang.lower():
             continue
         return self.select(s.no)
     err = Error(_('There is no matching stream in ') + self.path).add(
         'path', self.path)
     if type: err.add('type', type)
     if lang: err.add('language', lang)
     raise err
Пример #26
0
def raiseNotSupportedAssets(assets):
    msg = []
    speech = [asset for asset in assets if asset.type == 'speech']
    dicts = [asset for asset in assets if asset.type == 'dict']

    if speech:
        langs = ', '.join([languages.getName(a.params[0]) for a in speech])
        msg += [ _('Synchronization with {} audio is currently not supported.') \
                .format(langs) ]

    if dicts:
        langs = [
            ' - '.join([languages.getName(p) for p in a.params]) for a in dicts
        ]
        msg += [ _('Synchronization between languages {} is currently not supported.') \
                .format(', '.join(langs)) ]

    msg += ['', _('missing assets:')]
    msg += [' - ' + asset.getPrettyName() for asset in assets]
    raise Error('\n'.join(msg))
Пример #27
0
def validateTask(task, outputRequired=False):
    sub, ref, out = task.sub, task.ref, task.out
    if sub is None or not sub.path or sub.no is None:
        raise Error(_('Subtitles not set'), task=task)
    if ref is None or not ref.path or ref.no is None:
        raise Error(_('Reference file not set'), task=task)
    if outputRequired and (not out or not out.path):
        raise Error(_('Output file not set'), task=task)
    if sub.path == ref.path and sub.no == ref.no:
        raise Error(_('Subtitles can\'t be the same as reference'), task=task)
    if ref.type == 'audio' and not ref.lang:
        raise Error(_('Select reference language first'), task=task)
    if out and out.path:
        try:
            out.validateOutputPattern()
        except:
            raise Error(_('Invalid output pattern'), task=task)
Пример #28
0
def loadDictionary(lang1, lang2, minLen=0):
    dictionary = gizmo.Dictionary()

    asset = assets.getAsset('dict', (lang1, lang2))
    if asset.isLocal():
        for key, val in loadDictionaryFromFile(asset.path):
            if len(key) >= minLen and len(val) >= minLen:
                dictionary.add(key, val)

    else:
        asset = assets.getAsset('dict', (lang2, lang1))
        if asset.isLocal():
            for key, val in loadDictionaryFromFile(asset.path):
                if len(key) >= minLen and len(val) >= minLen:
                    dictionary.add(val, key)

    if not asset.isLocal():
        raise Error(_('There is no dictionary for transaltion from {} to {}')
                    .format(lang1, lang2)) \
                    .add('language1', lang1) \
                    .add('language2', lang2)

    logger.info('dictionary ready with %u entries', dictionary.size())
    return dictionary
Пример #29
0
def raiseMissingAssets(assets):
    msg = [_('Following assets are missing:')]
    msg += [' - ' + asset.getPrettyName() for asset in assets]
    raise Error('\n'.join(msg))