예제 #1
0
 def fullname(self):
     """Return the path for package."""
     if self.filename:
         return files_path_join(self.type.directory, self.filename)
     if self.directory:
         return files_path_join(self.directory)
     return ''
예제 #2
0
def documentation(request, version='stable'):
    """Page with docs for stable or devel version."""
    if version == 'old':
        doc_list = None
        try:
            doc_list = sorted(listdir(files_path_join('doc', 'old')),
                              reverse=True)
        except:  # noqa: E722
            pass
        return render(
            request,
            'doc/doc.html',
            {
                'version': version,
                'doc_list': doc_list,
            },
        )
    languages = Language.objects.all().order_by('priority')
    bestlang = get_bestlang(request, languages)
    versions = Version.objects.all().order_by('priority')
    docs = Doc.objects.all().order_by('version__priority', 'priority')
    doc_list = []
    doc_list2 = []
    for doc in docs:
        if doc.version.version != '-':
            docv = Release.objects.get(version=doc.version.version).description
        else:
            docv = doc.version.version
        stable_devel = 'devel' if docv.find('-') > 0 else 'stable'
        if stable_devel == version or docv == '-':
            files = []
            for lang in languages:
                name = '%s/weechat_%s.%s.html' % (doc.version.directory,
                                                  doc.name, lang.lang)
                full_name = files_path_join('doc', name)
                if path.exists(full_name):
                    files.append([
                        path.normpath(name),
                        datetime.fromtimestamp(path.getmtime(full_name)),
                        lang.lang
                    ])
                else:
                    files.append(['', '', lang.lang])
            if docv == '-':
                doc_list.append([doc, files])
            else:
                doc_list2.append([doc, files])
    return render(
        request,
        'doc/doc.html',
        {
            'version': version,
            'languages': languages,
            'bestlang': bestlang,
            'versions': versions,
            'doc_list': doc_list + doc_list2,
            'i18n': get_i18n_stats(),
            'doc_version': Release.objects.get(version=version).description,
        },
    )
예제 #3
0
def get_info(name, version):
    """Get an info."""
    # pylint: disable=too-many-branches,too-many-return-statements
    if name == 'stable':
        return version['stable'].description
    if name == 'stable_number':
        return version_as_int(version['stable'].description)
    if name == 'stable_date':
        return str(version['stable'].date)
    if name == 'devel':
        return version['devel'].description
    if name == 'git':
        git = ''
        try:
            with open(files_path_join('git_sources_head.txt'), 'r') as _file:
                git = _file.read().strip()
        except:  # noqa: E722  pylint: disable=bare-except
            pass
        return git
    if name == 'git_scripts':
        git = ''
        try:
            with open(files_path_join('git_scripts_head.txt'), 'r') as _file:
                git = _file.read().strip()
        except:  # noqa: E722  pylint: disable=bare-except
            pass
        return git
    if name == 'next_stable':
        return re.sub('-.*', '', version['devel'].description)
    if name == 'next_stable_number':
        return version_as_int(version['devel'].description)
    if name == 'next_stable_date':
        return str(version['devel'].date)
    if name == 'release_signing_fingerprint':
        return PGP_KEYS['release_signing']
    if name == 'debian_repository_signing_fingerprint':
        return PGP_KEYS['debian_repository_signing']
    if name == 'release_signing_key':
        fingerprint = PGP_KEYS['release_signing']
        with open(media_path_join('pgp', fingerprint), 'rb') as _file:
            return _file.read()
    if name == 'debian_repository_signing_key':
        fingerprint = PGP_KEYS['debian_repository_signing']
        with open(media_path_join('pgp', fingerprint), 'rb') as _file:
            return _file.read()
    if name == 'all':
        infos = []
        for key in INFO_KEYS:
            if key[0] != name and key[0] not in BINARY_INFO_KEYS:
                infos.append(f'{key[0]}:{get_info(key[0], version)}')
        return '\n'.join(infos)
    return ''
예제 #4
0
def script_source(request, api='stable', scriptid='', scriptname=''):
    """Page with source of a script."""
    script = None
    if scriptid:
        script = get_object_or_404(Script, id=scriptid)
        try:
            with open(
                    files_path_join(script.path(),
                                    script.name_with_extension()),
                    'rb') as _file:
                htmlsource = get_highlighted_source(_file.read(),
                                                    script.language)
        except:  # noqa: E722
            raise Http404
    else:
        sname = scriptname
        sext = ''
        pos = sname.rfind('.')
        if pos > 0:
            sext = sname[pos + 1:]
            sname = sname[0:pos]
        if api == 'legacy':
            script = get_object_or_404(
                Script,
                name=sname,
                language=get_language_from_extension(sext),
                max_weechat=API_OLD,
            )
        else:
            script = get_object_or_404(
                Script,
                name=sname,
                language=get_language_from_extension(sext),
                min_weechat__gte=API_STABLE,
            )
        try:
            with open(
                    files_path_join(script.path(),
                                    script.name_with_extension()),
                    'rb') as _file:
                htmlsource = get_highlighted_source(_file.read(),
                                                    PYGMENTS_LEXER[sext])
        except:  # noqa: E722
            raise Http404
    return render(
        request,
        'scripts/source.html',
        {
            'script': script,
            'htmlsource': htmlsource,
        },
    )
예제 #5
0
def get_info(name, version):
    """Get an info."""
    if name == 'stable':
        return version['stable'].description
    elif name == 'stable_number':
        return version_as_int(version['stable'].description)
    elif name == 'stable_date':
        return str(version['stable'].date)
    elif name == 'devel':
        return version['devel'].description
    elif name == 'git':
        git = ''
        try:
            with open(files_path_join('git_sources_head.txt'), 'r') as _file:
                git = _file.read().strip()
        except:  # noqa: E722
            pass
        return git
    elif name == 'git_scripts':
        git = ''
        try:
            with open(files_path_join('git_scripts_head.txt'), 'r') as _file:
                git = _file.read().strip()
        except:  # noqa: E722
            pass
        return git
    elif name == 'next_stable':
        return re.sub('-.*', '', version['devel'].description)
    elif name == 'next_stable_number':
        return version_as_int(version['devel'].description)
    elif name == 'next_stable_date':
        return str(version['devel'].date)
    elif name == 'release_signing_fingerprint':
        return PGP_KEYS['release_signing']
    elif name == 'debian_repository_signing_fingerprint':
        return PGP_KEYS['debian_repository_signing']
    elif name == 'release_signing_key':
        fingerprint = PGP_KEYS['release_signing']
        with open(media_path_join('pgp', fingerprint), 'rb') as _file:
            return _file.read()
    elif name == 'debian_repository_signing_key':
        fingerprint = PGP_KEYS['debian_repository_signing']
        with open(media_path_join('pgp', fingerprint), 'rb') as _file:
            return _file.read()
    elif name == 'all':
        infos = []
        for key in INFO_KEYS:
            if key[0] != name and key[0] not in BINARY_INFO_KEYS:
                infos.append('%s:%s' % (key[0], get_info(key[0], version)))
        return '\n'.join(infos)
    return ''
예제 #6
0
def script_source(request, api='stable', scriptid='', scriptname=''):
    """Page with source of a script."""
    plugin = ''
    if scriptid:
        try:
            plugin = Plugin.objects.get(id=scriptid)
            with open(
                    files_path_join(plugin.path(),
                                    plugin.name_with_extension()),
                    'rb') as _file:
                htmlsource = get_highlighted_source(_file.read(),
                                                    plugin.language)
        except:
            htmlsource = ''
    else:
        sname = scriptname
        sext = ''
        pos = sname.rfind('.')
        if pos > 0:
            sext = sname[pos + 1:]
            sname = sname[0:pos]
        try:
            if api == 'legacy':
                plugin = Plugin.objects.get(
                    name=sname,
                    language=get_language_from_extension(sext),
                    max_weechat=API_OLD)
            else:
                plugin = Plugin.objects.get(
                    name=sname,
                    language=get_language_from_extension(sext),
                    min_weechat__gte=API_STABLE)
            with open(
                    files_path_join(plugin.path(),
                                    plugin.name_with_extension()),
                    'rb') as _file:
                htmlsource = get_highlighted_source(_file.read(),
                                                    PYGMENTS_LEXER[sext])
        except:
            htmlsource = ''
    return render(
        request,
        'plugins/source.html',
        {
            'plugin': plugin,
            'htmlsource': htmlsource,
        },
    )
예제 #7
0
def get_i18n_stats():
    """Return i18n stats, as a dictionary.

    The returned dictionary has following keys:
    - date: date/time of last translations update
    - langs: a dictionary with info about status of this language.
    """
    # pylint: disable=too-many-locals
    try:
        timezone = pytz.timezone(settings.TIME_ZONE)
        filename = files_path_join('stats', 'i18n.txt')
        date = datetime.fromtimestamp(os.path.getmtime(filename), tz=timezone)
        with open(filename, 'r') as _file:
            langs = []
            for line in _file:
                items = line.split(':')
                if len(items) == 2:
                    lang = items[0]
                    count = items[1].split(',')
                    translated = float(count[0])
                    fuzzy = float(count[1])
                    untranslated = float(count[2])
                    total = translated + fuzzy + untranslated
                    if total != 0:
                        pct_fuzzy = int(ceil((fuzzy * 100) / total))
                        pct_untranslated = int(
                            ceil((untranslated * 100) / total))
                        pct_translated = 100 - pct_fuzzy - pct_untranslated
                        if pct_translated < 0:
                            pct_translated = 0
                        nick, name = I18N_MAINTAINER.get(lang, ('-', ''))
                        langs.append({
                            'lang':
                            lang,
                            'lang_i18n':
                            (ugettext(Language.LANG_I18N[lang])
                             if lang in Language.LANG_I18N else lang),
                            'nick':
                            nick,
                            'name':
                            name,
                            'translated':
                            int(translated),
                            'pct_translated':
                            pct_translated,
                            'fuzzy':
                            int(fuzzy),
                            'pct_fuzzy':
                            pct_fuzzy,
                            'untranslated':
                            int(untranslated),
                            'pct_untranslated':
                            pct_untranslated,
                            'total':
                            int(total),
                        })
        return {'date': date, 'langs': langs}
    except:  # noqa: E722  pylint: disable=bare-except
        return None
예제 #8
0
 def html_preview(self):
     """Return HTML with theme preview."""
     filename = files_path_join('themes', 'html',
                                path.basename('%s.html' % self.name))
     if path.isfile(filename):
         with open(filename, 'rb') as _file:
             content = _file.read()
         return content
     return ''
예제 #9
0
 def html_preview(self):
     """Return HTML with theme preview."""
     filename = files_path_join('themes', 'html',
                                os.path.basename(f'{self.name}.html'))
     if os.path.isfile(filename):
         with open(filename, 'r', encoding='utf-8') as _file:
             content = _file.read()
         return content
     return ''
예제 #10
0
def script_source(request, scriptid='', scriptname=''):
    """Page with source of a script."""
    script = None
    if scriptid:
        script = get_object_or_404(Script, id=scriptid)
        try:
            with open(
                    files_path_join(script.path(),
                                    script.name_with_extension()),
                    'rb') as _file:
                htmlsource = get_highlighted_source(_file.read(),
                                                    script.language)
        except:  # noqa: E722  pylint: disable=bare-except
            raise Http404
    else:
        sname = scriptname
        sext = ''
        pos = sname.rfind('.')
        if pos > 0:
            sext = sname[pos + 1:]
            sname = sname[0:pos]
        script = get_object_or_404(
            Script,
            name=sname,
            language=get_language_from_extension(sext),
        )
        try:
            with open(
                    files_path_join(script.path(),
                                    script.name_with_extension()),
                    'rb') as _file:
                htmlsource = get_highlighted_source(_file.read(),
                                                    PYGMENTS_LEXER[sext])
        except:  # noqa: E722  pylint: disable=bare-except
            raise Http404
    return render(
        request,
        'scripts/source.html',
        {
            'script': script,
            'htmlsource': htmlsource,
        },
    )
예제 #11
0
def get_info(name, version):
    """Get an info."""
    if name == 'stable':
        return version['stable'].description
    elif name == 'stable_number':
        return version_as_int(version['stable'].description)
    elif name == 'stable_date':
        return str(version['stable'].date)
    elif name == 'devel':
        return version['devel'].description
    elif name == 'git':
        git = ''
        try:
            with open(files_path_join('git_sources_head.txt'), 'r') as _file:
                git = _file.read().strip()
        except:  # noqa: E722
            pass
        return git
    elif name == 'git_scripts':
        git = ''
        try:
            with open(files_path_join('git_scripts_head.txt'), 'r') as _file:
                git = _file.read().strip()
        except:  # noqa: E722
            pass
        return git
    elif name == 'next_stable':
        return re.sub('-.*', '', version['devel'].description)
    elif name == 'next_stable_number':
        return version_as_int(version['devel'].description)
    elif name == 'next_stable_date':
        return str(version['devel'].date)
    elif name == 'all':
        infos = []
        for key in INFO_KEYS:
            if key[0] != name:
                infos.append('%s:%s' % (key[0], get_info(key[0], version)))
        return '\n'.join(infos)
    return ''
예제 #12
0
def documentation_link(request, version='stable', name=None, lang='en'):
    """
    Shortcuts to docs, with English and stable version as default.

    For example:
      /doc/api          => /files/doc/stable/weechat_plugin_api.en.html
      /doc/api/fr       => /files/doc/stable/weechat_plugin_api.fr.html
      /doc/devel/api/fr => /files/doc/devel/weechat_plugin_api.fr.html
      /doc/user         => /files/doc/stable/weechat_user.en.html
    """
    if version and name and lang:
        doc_name = DOC_SHORTCUT_ALIAS.get(name, name)
        filename = f'weechat_{doc_name}.{lang}.html'
        full_name = files_path_join('doc', version, filename)
        if os.path.exists(full_name):
            return redirect(f'/files/doc/{version}/{filename}')
    return redirect('doc')
예제 #13
0
def documentation_link(request, version='devel', name=None, lang='en'):
    """
    Shortcuts to docs, with English and devel version as default.

    For example:
      /doc/api           => /files/doc/devel/weechat_plugin_api.en.html
      /doc/api/fr        => /files/doc/devel/weechat_plugin_api.fr.html
      /doc/stable/api/fr => /files/doc/stable/weechat_plugin_api.fr.html
      /doc/user          => /files/doc/devel/weechat_user.en.html
    """
    if version and name and lang:
        doc_name = DOC_SHORTCUT_ALIAS.get(name, name)
        filename = 'weechat_%s.%s.html' % (doc_name, lang)
        full_name = files_path_join('doc', version, filename)
        if path.exists(full_name):
            return redirect('/files/doc/%s/%s' % (version, filename))
    return redirect('doc')
예제 #14
0
def theme_source(request, themeid=None, themename=None):
    """Page with source of a theme."""
    if themeid:
        theme = get_object_or_404(Theme, id=themeid)
    else:
        theme = get_object_or_404(Theme, name=themename)
    try:
        with open(files_path_join(theme.path(), theme.name), 'rb') as _file:
            htmlsource = highlight(
                _file.read(),
                get_lexer_by_name('ini', stripnl=True, encoding='utf-8'),
                HtmlFormatter(cssclass='pygments', linenos='table'))
    except:  # noqa: E722
        raise Http404
    return render(
        request,
        'themes/source.html',
        {
            'theme': theme,
            'htmlsource': htmlsource,
        },
    )
예제 #15
0
def form_add(request):
    """Page with form to add a script."""
    if request.method == 'POST':
        form = ScriptFormAdd(request.POST, request.FILES)
        if form.is_valid():
            scriptfile = request.FILES['file']

            # add script in database
            now = datetime.now()
            script = Script(approved=False,
                            popularity=0,
                            name=form.cleaned_data['name'],
                            version=form.cleaned_data['version'],
                            url='',
                            language=form.cleaned_data['language'],
                            license=form.cleaned_data['license'],
                            desc_en=form.cleaned_data['description'],
                            requirements=form.cleaned_data['requirements'],
                            min_weechat=form.cleaned_data['min_weechat'],
                            author=form.cleaned_data['author'],
                            mail=form.cleaned_data['mail'],
                            added=now,
                            updated=now)

            # write script in pending directory
            filename = files_path_join('scripts', 'pending1',
                                       script.name_with_extension())
            with open(filename, 'w') as _file:
                _file.write(get_script_content(scriptfile))

            # send e-mail
            try:
                subject = f'WeeChat: new script {script.name_with_extension()}'
                sender = (f'{form.cleaned_data["author"]} '
                          f'<{form.cleaned_data["mail"]}>')
                body = (f'Script      : {form.cleaned_data["name"]}\n'
                        f'Version     : {form.cleaned_data["version"]}\n'
                        f'Language    : {form.cleaned_data["language"]}\n'
                        f'License     : {form.cleaned_data["license"]}\n'
                        f'Description : {form.cleaned_data["description"]}\n'
                        f'Requirements: {form.cleaned_data["requirements"]}\n'
                        f'Min WeeChat : {form.cleaned_data["min_weechat"]}\n'
                        f'Author      : {sender}>\n'
                        f'\n'
                        f'Comment:\n{form.cleaned_data["comment"]}\n')
                email = EmailMessage(subject, body, sender,
                                     settings.SCRIPTS_MAILTO)
                email.attach_file(filename)
                email.send()
            except:  # noqa: E722  pylint: disable=bare-except
                return HttpResponseRedirect('/scripts/adderror/')

            # save script in database
            script.save()

            return HttpResponseRedirect('/scripts/addok/')
    else:
        form = ScriptFormAdd()
    return render(
        request,
        'scripts/add.html',
        {
            'form': form,
        },
    )
예제 #16
0
def handler_themes_changed(sender, **kwargs):
    """Build files themes.{xml,json}(.gz) after update/delete of a theme."""
    # pylint: disable=unused-argument,too-many-locals
    theme_list = Theme.objects.filter(visible=1).order_by('id')
    xml = '<?xml version="1.0" encoding="utf-8"?>\n'
    xml += '<themes>\n'
    json_data = []
    for theme in theme_list:
        if not theme.visible:
            continue
        xml += f'  <theme id="{theme.id}">\n'
        json_theme = OrderedDict([
            ('id', f'{theme.id}'),
        ])
        for key, value in theme.__dict__.items():
            if key in ('_state', 'id', 'visible', 'comment'):
                continue
            if value is None:
                value = ''
            else:
                if key == 'mail':
                    value = value.replace('@', ' [at] ')
                    value = value.replace('.', ' [dot] ')
                elif key == 'md5sum':
                    value = theme.get_md5sum()
                elif key == 'sha512sum':
                    value = theme.get_sha512sum()
            value = f'{value}'
            xml += f'    <{key}>{escape(value)}</{key}>\n'
            json_theme[key] = value
        # FIXME: use the "Host" from request, but…
        # request is not available in this handler!
        url = f'https://weechat.org/{theme.build_url()[1:]}'
        xml += f'    <url>{url}</url>\n'
        json_theme['url'] = url
        xml += '  </theme>\n'
        json_data.append(json_theme)
    xml += '</themes>\n'

    # create themes.xml
    filename = files_path_join('themes.xml')
    with open(filename, 'w', encoding='utf-8') as _file:
        _file.write(xml)

    # create themes.xml.gz
    with open(filename, 'rb') as _f_in:
        _f_out = gzip.open(filename + '.gz', 'wb')
        _f_out.writelines(_f_in)
        _f_out.close()

    # create themes.json
    filename = files_path_join('themes.json')
    with open(filename, 'w', encoding='utf-8') as _file:
        _file.write(json.dumps(json_data, indent=2, ensure_ascii=False,
                               separators=(',', ': ')))

    # create themes.json.gz
    with open(filename, 'rb') as _f_in:
        _f_out = gzip.open(filename + '.gz', 'wb')
        _f_out.writelines(_f_in)
        _f_out.close()

    # create themes.tar.bz2 (with theme.xml + 'themes' directory)
    os.chdir(settings.FILES_ROOT)
    tar = tarfile.open(files_path_join('themes.tar.bz2'), 'w:bz2')
    tar.add('themes.xml')
    for name in os.listdir(files_path_join('themes')):
        if name.endswith('.theme'):
            tar.add(f'themes/{name}')
    tar.close()
예제 #17
0
 def filename(self):
     """Return theme filename (on disk)."""
     return files_path_join(self.path(),
                            os.path.basename(self.name))
예제 #18
0
def handler_scripts_changed(sender, **kwargs):
    """Build files plugins.{xml,json}(.gz) after update/delete of a script."""
    xml = '<?xml version="1.0" encoding="utf-8"?>\n'
    xml += '<plugins>\n'
    json_data = []
    strings = []
    for script in Script.objects.filter(visible=1).order_by('id'):
        if not script.visible or script.is_legacy():
            continue
        xml += '  <plugin id="%s">\n' % script.id
        json_script = OrderedDict([
            ('id', '%s' % script.id),
        ])
        for key, value in script.__dict__.items():
            value_i18n = {}
            if key in ('_state', 'id', 'visible', 'comment'):
                continue
            if value is None:
                value = ''
            else:
                if key == 'url':
                    # FIXME: use the "Host" from request, but…
                    # request is not available in this handler!
                    value = ('https://weechat.org/%s' % script.build_url()[1:])
                elif key == 'mail':
                    value = value.replace('@', ' [at] ')
                    value = value.replace('.', ' [dot] ')
                elif key == 'md5sum':
                    value = script.get_md5sum()
                elif key == 'sha512sum':
                    value = script.get_sha512sum()
                elif key == 'desc_en':
                    for lang, locale in settings.LANGUAGES_LOCALES.items():
                        if lang[0:2] != 'en':
                            translation.activate(lang)
                            value_i18n['desc_%s' % locale] = ugettext(value)
                            translation.deactivate()
            value = '%s' % value
            xml += '    <%s>%s</%s>\n' % (key, escape(value), key)
            json_script[key] = value
            for field in value_i18n:
                xml += '    <%s>%s</%s>\n' % (field, escape(
                    value_i18n[field]), field)
                json_script[field] = value_i18n[field]
        xml += '  </plugin>\n'
        json_data.append(json_script)
        strings.append((
            script.desc_en,
            'description for script "%s" (%s)' %
            (script.name_with_extension(), script.version_weechat()),
        ))
    xml += '</plugins>\n'

    # create plugins.xml
    filename = files_path_join('plugins.xml')
    with open(filename, 'w', encoding='utf-8') as _file:
        _file.write(xml)

    # create plugins.xml.gz
    with open(filename, 'rb') as _f_in:
        _f_out = gzip.open(filename + '.gz', 'wb')
        _f_out.writelines(_f_in)
        _f_out.close()

    # create plugins.json
    filename = files_path_join('plugins.json')
    with open(filename, 'w', encoding='utf-8') as _file:
        _file.write(
            json.dumps(json_data,
                       indent=2,
                       ensure_ascii=False,
                       separators=(',', ': ')))
        # json.dump(json_data, _file)

    # create plugins.json.gz
    with open(filename, 'rb') as _f_in:
        _f_out = gzip.open(filename + '.gz', 'wb')
        _f_out.writelines(_f_in)
        _f_out.close()

    # create _i18n_scripts.py
    i18n_autogen('scripts', 'scripts', strings)
예제 #19
0
def form_add(request):
    """Page with form to add a theme."""
    if request.method == 'POST':
        form = ThemeFormAdd(request.POST, request.FILES)
        if form.is_valid():
            themefile = request.FILES['themefile']

            # get properties
            content = get_theme_content(themefile)
            props = Theme.get_props(content)

            # add theme in database
            now = datetime.now()
            theme = Theme(visible=False,
                          name=props['name'],
                          version=props['weechat'],
                          desc=form.cleaned_data['description'],
                          author=form.cleaned_data['author'],
                          mail=form.cleaned_data['mail'],
                          added=now,
                          updated=now)

            # write theme in pending directory
            filename = files_path_join('themes', 'pending', theme.name)
            with open(filename, 'w') as _file:
                _file.write(content)

            # send e-mail
            try:
                subject = f'WeeChat: new theme {theme.name}'
                sender = (f'{form.cleaned_data["author"]} '
                          f'<{form.cleaned_data["mail"]}>')
                body = (f'Theme      : {props["name"]}\n'
                        f'Version    : {props["weechat"]}\n'
                        f'Description: {form.cleaned_data["description"]}\n'
                        f'Author     : {sender}\n'
                        f'Comment    :\n{form.cleaned_data["comment"]}\n')
                email = EmailMessage(subject, body, sender,
                                     settings.THEMES_MAILTO)
                email.attach_file(filename)
                email.send()
            except:  # noqa: E722  pylint: disable=bare-except
                return HttpResponseRedirect('/themes/adderror/')

            # save theme in database
            theme.save()

            return HttpResponseRedirect('/themes/addok/')
    else:
        form = ThemeFormAdd()
    try:
        stable_version = Release.objects.get(version='stable').description
        release_stable = Release.objects.get(version=stable_version)
    except ObjectDoesNotExist:
        release_stable = None
    return render(
        request,
        'themes/add.html',
        {
            'release_stable': release_stable,
            'form': form,
        },
    )
예제 #20
0
def handler_script_changed(sender, **kwargs):
    """Build files plugins.{xml,json}(.gz) after update/delete of a script."""
    xml = '<?xml version="1.0" encoding="utf-8"?>\n'
    xml += '<plugins>\n'
    json = '[\n'
    strings = []
    for script in Script.objects.filter(visible=1).order_by('id'):
        if script.visible and not script.is_legacy():
            xml += '  <plugin id="%s">\n' % script.id
            json += '  {\n'
            json += '    "id": "%s",\n' % script.id
            for key, value in script.__dict__.items():
                value_i18n = {}
                if key not in ['_state', 'id', 'visible', 'comment']:
                    if value is None:
                        value = ''
                    else:
                        if key == 'url':
                            # FIXME: use the "Host" from request, but…
                            # request is not available in this handler!
                            value = ('https://weechat.org/%s' %
                                     script.build_url()[1:])
                        elif key == 'mail':
                            value = value.replace('@', ' [at] ')
                            value = value.replace('.', ' [dot] ')
                        elif key == 'md5sum':
                            value = script.md5()
                        elif key.startswith('desc'):
                            if key == 'desc_en':
                                for lang, locale in \
                                        settings.LANGUAGES_LOCALES.items():
                                    if lang[0:2] != 'en':
                                        translation.activate(lang)
                                        value_i18n['desc_%s' % locale] = \
                                            escape(ugettext(value))
                                        translation.deactivate()
                            value = escape(value)
                    xml += getxmlline(key, value)
                    json += getjsonline(key, value)
                    for field in value_i18n:
                        xml += getxmlline(field, value_i18n[field])
                        json += getjsonline(field, value_i18n[field])
            xml += '  </plugin>\n'
            json = json[:-2] + '\n  },\n'
            strings.append((
                script.desc_en,
                'description for script "%s" (%s)' %
                (script.name_with_extension(), script.version_weechat()),
            ))
    xml += '</plugins>\n'
    json = json[:-2] + '\n]\n'

    # create plugins.xml
    filename = files_path_join('plugins.xml')
    with open(filename, 'w', encoding='utf-8') as _file:
        _file.write(xml)

    # create plugins.xml.gz
    with open(filename, 'rb') as _f_in:
        _f_out = gzip.open(filename + '.gz', 'wb')
        _f_out.writelines(_f_in)
        _f_out.close()

    # create plugins.json
    filename = files_path_join('plugins.json')
    with open(filename, 'w', encoding='utf-8') as _file:
        _file.write(json)

    # create plugins.json.gz
    with open(filename, 'rb') as _f_in:
        _f_out = gzip.open(filename + '.gz', 'wb')
        _f_out.writelines(_f_in)
        _f_out.close()

    # create _i18n_scripts.py
    i18n_autogen('scripts', 'scripts', strings)
예제 #21
0
 def filename(self):
     """Return script filename (on disk)."""
     return files_path_join(self.path(),
                            os.path.basename(self.name_with_extension()))
예제 #22
0
파일: models.py 프로젝트: andir/weechat.org
def handler_theme_changed(sender, **kwargs):
    """Build files themes.{xml,json}(.gz) after update/delete of a theme."""
    theme_list = Theme.objects.filter(visible=1).order_by('id')
    xml = '<?xml version="1.0" encoding="utf-8"?>\n'
    xml += '<themes>\n'
    json = '[\n'
    for theme in theme_list:
        if theme.visible:
            xml += '  <theme id="%s">\n' % theme.id
            json += '  {\n'
            json += '    "id": "%s",\n' % theme.id
            for key, value in theme.__dict__.items():
                if key not in ['_state', 'id', 'visible', 'comment']:
                    if value is None:
                        value = ''
                    else:
                        if key == 'mail':
                            value = value.replace('@', ' [at] ')
                            value = value.replace('.', ' [dot] ')
                        elif key == 'md5sum':
                            try:
                                with open(
                                        files_path_join(
                                            theme.path(), theme.name),
                                        'rb') as _file:
                                    filemd5 = md5()
                                    filemd5.update(_file.read())
                                    value = filemd5.hexdigest()
                            except:  # noqa: E722
                                value = ''
                        elif key.startswith('desc'):
                            value = escape(value)
                    strvalue = '%s' % value
                    xml += getxmlline(key, strvalue)
                    json += getjsonline(key, strvalue)
            # FIXME: use the "Host" from request, but…
            # request is not available in this handler!
            strvalue = 'https://weechat.org/%s' % theme.build_url()[1:]
            xml += '    %s\n' % xml_value('url', strvalue)
            json += '    %s\n' % json_value('url', strvalue)
            xml += '  </theme>\n'
            json = json[:-2] + '\n  },\n'
    xml += '</themes>\n'
    json = json[:-2] + '\n]\n'

    # create themes.xml
    filename = files_path_join('themes.xml')
    with open(filename, 'w', encoding='utf-8') as _file:
        _file.write(xml)

    # create themes.xml.gz
    with open(filename, 'rb') as _f_in:
        _f_out = gzip.open(filename + '.gz', 'wb')
        _f_out.writelines(_f_in)
        _f_out.close()

    # create themes.json
    filename = files_path_join('themes.json')
    with open(filename, 'w', encoding='utf-8') as _file:
        _file.write(json)

    # create themes.json.gz
    with open(filename, 'rb') as _f_in:
        _f_out = gzip.open(filename + '.gz', 'wb')
        _f_out.writelines(_f_in)
        _f_out.close()

    # create themes.tar.bz2 (with theme.xml + 'themes' directory)
    os.chdir(settings.FILES_ROOT)
    tar = tarfile.open(files_path_join('themes.tar.bz2'), 'w:bz2')
    tar.add('themes.xml')
    for name in os.listdir(files_path_join('themes')):
        if name.endswith('.theme'):
            tar.add('themes/%s' % name)
    tar.close()
예제 #23
0
def stats_repo(request, stats='weechat'):
    """Page with statistics about source code (git repositories)."""
    repository = ''
    sloc = ''
    sloc_lang = ''
    svg_list = [
        'authors', 'tickets_author', 'files_type', 'commits_year',
        'commits_year_month', 'commits_day', 'commits_day_max',
        'commits_day_week', 'commits_hour_day', 'commits_hour_week'
    ]
    git_commits = ['?', '?', '?', '?']
    scripts_downloads = None

    try:
        with open(files_path_join('stats', f'git_{stats}_commits.txt'),
                  'r') as _file:
            git_commits = _file.read().strip().split(',')
    except:  # noqa: E722  pylint: disable=bare-except
        pass

    if stats in ('weechat', 'weechat-relay', 'qweechat'):
        try:
            with open(files_path_join('stats', f'sloc_{stats}.txt'),
                      'r') as _file:
                sloc = _file.read()
        except:  # noqa: E722  pylint: disable=bare-except
            pass

    if stats == 'weechat':
        repository = ('https://github.com/weechat/weechat')
        sloc_lang = 'C'
        svg_list += ['commits_version', 'commits_other_clients']
    elif stats == 'weechat-relay':
        repository = ('https://github.com/weechat/weechat-relay')
        sloc_lang = 'C'
    elif stats == 'scripts':
        repository = ('https://github.com/weechat/scripts')
        svg_list += ['downloads']
        try:
            with open(files_path_join('stats', 'scripts_downloads.txt'),
                      'r') as _file:
                scripts_downloads = _file.read()
        except:  # noqa: E722  pylint: disable=bare-except
            pass
    elif stats == 'qweechat':
        repository = ('https://github.com/weechat/qweechat')
        sloc_lang = 'Python'
    elif stats == 'weechat.org':
        repository = ('https://github.com/weechat/weechat.org')
    return render(
        request,
        'dev/stats.html',
        {
            'stats': stats,
            'repository': repository,
            'sloc': sloc,
            'sloc_lang': sloc_lang,
            'git_commits_last_week': git_commits[0],
            'git_commits_last_month': git_commits[1],
            'git_commits_last_year': git_commits[2],
            'git_commits_total': git_commits[3],
            'scripts_downloads': scripts_downloads,
            'svg_list': svg_list,
        },
    )
예제 #24
0
def documentation(request, version='stable'):
    """Page with docs for stable or devel version."""
    # pylint: disable=too-many-locals
    timezone = pytz.timezone(settings.TIME_ZONE)
    if version == 'old':
        doc_list = None
        try:
            doc_list = sorted(os.listdir(files_path_join('doc', 'old')),
                              reverse=True)
        except:  # noqa: E722  pylint: disable=bare-except
            pass
        return render(
            request,
            'doc/doc_version.html',
            {
                'version': version,
                'doc_list': doc_list,
            },
        )
    languages = Language.objects.all().order_by('priority')
    bestlang = get_bestlang(request, languages)
    versions = Version.objects.all().order_by('priority')
    docs = Doc.objects.all().order_by('version__priority', 'priority')
    doc_list = []
    doc_list2 = []
    for doc in docs:
        if doc.version.version != '-':
            docv = Release.objects.get(version=doc.version.version).description
        else:
            docv = doc.version.version
        stable_devel = 'devel' if docv.find('-') > 0 else 'stable'
        if stable_devel == version or docv == '-':
            files = []
            for lang in languages:
                name = (f'{doc.version.directory}/weechat_{doc.name}.'
                        f'{lang.lang}.html')
                full_name = files_path_join('doc', name)
                if os.path.exists(full_name):
                    files.append((
                        os.path.normpath(name),
                        datetime.fromtimestamp(os.path.getmtime(full_name),
                                               tz=timezone),
                        lang,
                    ))
                else:
                    files.append(['', '', lang.lang])
            if docv == '-':
                doc_list.append([doc, files])
            else:
                doc_list2.append([doc, files])
    try:
        doc_version = Release.objects.get(version=version).description
    except ObjectDoesNotExist:
        doc_version = None
    return render(
        request,
        'doc/doc_version.html',
        {
            'version': version,
            'languages': languages,
            'bestlang': bestlang,
            'versions': versions,
            'doc_list': doc_list + doc_list2,
            'i18n': get_i18n_stats(),
            'doc_version': doc_version,
        },
    )
예제 #25
0
def form_add(request):
    """Page with form to add a script."""
    if request.method == 'POST':
        form = ScriptFormAdd(request.POST, request.FILES)
        if form.is_valid():
            scriptfile = request.FILES['file']
            min_max = form.cleaned_data['min_max'].split(':')
            if min_max[0] == '-':
                min_max[0] = ''
            if min_max[1] == '-':
                min_max[1] = ''

            # add script in database
            now = datetime.now()
            script = Script(visible=False,
                            popularity=0,
                            name=form.cleaned_data['name'],
                            version=form.cleaned_data['version'],
                            url='',
                            language=form.cleaned_data['language'],
                            license=form.cleaned_data['license'],
                            desc_en=form.cleaned_data['description'],
                            requirements=form.cleaned_data['requirements'],
                            min_weechat=min_max[0],
                            max_weechat=min_max[1],
                            author=form.cleaned_data['author'],
                            mail=form.cleaned_data['mail'],
                            added=now,
                            updated=now)

            # write script in pending directory
            filename = files_path_join('scripts', 'pending1',
                                       script.name_with_extension())
            with open(filename, 'w') as _file:
                _file.write(scriptfile.read().replace('\r\n', '\n'))

            # send e-mail
            try:
                subject = ('WeeChat: new script %s' %
                           script.name_with_extension())
                body = (
                    ''
                    'Script      : %s\n'
                    'Version     : %s\n'
                    'Language    : %s\n'
                    'License     : %s\n'
                    'Description : %s\n'
                    'Requirements: %s\n'
                    'Min WeeChat : %s\n'
                    'Max WeeChat : %s\n'
                    'Author      : %s <%s>\n'
                    '\n'
                    'Comment:\n%s\n' %
                    (form.cleaned_data['name'], form.cleaned_data['version'],
                     form.cleaned_data['language'],
                     form.cleaned_data['license'],
                     form.cleaned_data['description'],
                     form.cleaned_data['requirements'], min_max[0], min_max[1],
                     form.cleaned_data['author'], form.cleaned_data['mail'],
                     form.cleaned_data['comment']))
                sender = '%s <%s>' % (form.cleaned_data['author'],
                                      form.cleaned_data['mail'])
                email = EmailMessage(subject, body, sender,
                                     settings.SCRIPTS_MAILTO)
                email.attach_file(filename)
                email.send()
            except:  # noqa: E722
                return HttpResponseRedirect('/scripts/adderror/')

            # save script in database
            script.save()

            return HttpResponseRedirect('/scripts/addok/')
    else:
        form = ScriptFormAdd()
    return render(
        request,
        'scripts/add.html',
        {
            'form': form,
        },
    )
예제 #26
0
파일: models.py 프로젝트: andir/weechat.org
 def file_exists(self):
     """Checks if the theme exists (on disk)."""
     return os.path.isfile(
         files_path_join(self.path(), os.path.basename(self.name)))
예제 #27
0
def form_add(request):
    """Page with form to add a theme."""
    if request.method == 'POST':
        form = ThemeFormAdd(request.POST, request.FILES)
        if form.is_valid():
            themefile = request.FILES['themefile']

            # get properties
            content = themefile.read().replace('\r\n', '\n')
            props = Theme.get_props(content)

            # add theme in database
            now = datetime.now()
            theme = Theme(visible=False,
                          name=props['name'],
                          version=props['weechat'],
                          desc=form.cleaned_data['description'],
                          author=form.cleaned_data['author'],
                          mail=form.cleaned_data['mail'],
                          added=now,
                          updated=now)

            # write theme in pending directory
            filename = files_path_join('themes', 'pending', theme.name)
            with open(filename, 'w') as _file:
                _file.write(content)

            # send e-mail
            try:
                subject = 'WeeChat: new theme %s' % theme.name
                body = (
                    ''
                    'Theme      : %s\n'
                    'Version    : %s\n'
                    'Description: %s\n'
                    'Author     : %s\n'
                    'Mail       : %s\n'
                    'Comment    :\n%s\n' %
                    (props['name'], props['weechat'],
                     form.cleaned_data['description'],
                     form.cleaned_data['author'], form.cleaned_data['mail'],
                     form.cleaned_data['comment']))
                sender = '%s <%s>' % (form.cleaned_data['author'],
                                      form.cleaned_data['mail'])
                email = EmailMessage(subject, body, sender,
                                     settings.THEMES_MAILTO)
                email.attach_file(filename)
                email.send()
            except:  # noqa: E722
                return HttpResponseRedirect('/themes/adderror/')

            # save theme in database
            theme.save()

            return HttpResponseRedirect('/themes/addok/')
    else:
        form = ThemeFormAdd()
    try:
        stable_version = Release.objects.get(version='stable').description
        release_stable = Release.objects.get(version=stable_version)
    except ObjectDoesNotExist:
        release_stable = None
    return render(
        request,
        'themes/add.html',
        {
            'release_stable': release_stable,
            'form': form,
        },
    )
예제 #28
0
def handler_scripts_changed(sender, **kwargs):
    """Build files scripts.{xml,json}(.gz) after update/delete of a script."""
    # pylint: disable=unused-argument,too-many-locals,too-many-nested-blocks
    # pylint: disable=too-many-branches,too-many-statements
    xml = '<?xml version="1.0" encoding="utf-8"?>\n'
    xml += '<plugins>\n'
    json_data = []
    strings = []

    # add disabled reasons in strings to translate
    reasons = {
        script.disabled
        for script in Script.objects.exclude(disabled='')
    }
    for reason in reasons:
        strings.append((reason, 'reason for a disabled script'))

    # build xml/json content
    script_list = Script.objects.filter(approved=True).order_by('id')
    for script in script_list:
        strings.append((
            script.desc_en,
            (f'description for script "{script.name_with_extension()}" '
             f'({script.version_weechat()})'),
        ))
        if script.disabled:
            continue
        xml += f'  <plugin id="{script.id}">\n'
        json_script = OrderedDict([
            ('id', f'{script.id}'),
        ])
        for key, value in script.__dict__.items():
            value_i18n = {}
            if key in ('_state', 'id', 'approved', 'approval'):
                continue
            if value is None:
                value = ''
            else:
                if key == 'url':
                    # FIXME: use the "Host" from request, but…
                    # request is not available in this handler!
                    value = f'https://weechat.org/{script.build_url()[1:]}'
                elif key == 'mail':
                    value = value.replace('@', ' [at] ')
                    value = value.replace('.', ' [dot] ')
                elif key == 'md5sum':
                    value = script.get_md5sum()
                elif key == 'sha512sum':
                    value = script.get_sha512sum()
                elif key == 'desc_en':
                    for lang, locale in settings.LANGUAGES_LOCALES.items():
                        if lang[0:2] != 'en':
                            translation.activate(lang)
                            value_i18n[f'desc_{locale}'] = ugettext(value)
                            translation.deactivate()
            value = f'{value}'
            xml += f'    <{key}>{escape(value)}</{key}>\n'
            json_script[key] = value
            for field in value_i18n:
                xml += f'    <{field}>{escape(value_i18n[field])}</{field}>\n'
                json_script[field] = value_i18n[field]
        xml += '  </plugin>\n'
        json_data.append(json_script)
    xml += '</plugins>\n'

    # create scripts.xml
    filename = files_path_join('scripts.xml')
    with open(filename, 'w', encoding='utf-8') as _file:
        _file.write(xml)

    # create scripts.xml.gz
    with open(filename, 'rb') as _f_in:
        _f_out = gzip.open(filename + '.gz', 'wb')
        _f_out.writelines(_f_in)
        _f_out.close()

    # create scripts.json
    filename = files_path_join('scripts.json')
    with open(filename, 'w', encoding='utf-8') as _file:
        _file.write(
            json.dumps(json_data,
                       indent=2,
                       ensure_ascii=False,
                       separators=(',', ': ')))
        # json.dump(json_data, _file)

    # create scripts.json.gz
    with open(filename, 'rb') as _f_in:
        _f_out = gzip.open(filename + '.gz', 'wb')
        _f_out.writelines(_f_in)
        _f_out.close()

    # create _i18n_scripts.py
    i18n_autogen('scripts', 'scripts', strings)