예제 #1
0
def widgets(request, project):
    obj = get_project(request, project)

    # Parse possible language selection
    form = EngageForm(obj, request.GET)
    lang = None
    component = None
    if form.is_valid():
        if form.cleaned_data['lang']:
            lang = Language.objects.get(code=form.cleaned_data['lang']).code
        if form.cleaned_data['component']:
            component = SubProject.objects.get(
                slug=form.cleaned_data['component'], project=obj).slug

    kwargs = {'project': obj.slug}
    if lang is not None:
        kwargs['lang'] = lang
    engage_url = get_site_url(reverse('engage', kwargs=kwargs))
    engage_url_track = '{0}?utm_source=widget'.format(engage_url)
    widget_base_url = get_site_url(
        reverse('widgets', kwargs={'project': obj.slug}))
    widget_list = []
    for widget_name in sorted(WIDGETS, key=widgets_sorter):
        widget_class = WIDGETS[widget_name]
        if not widget_class.show:
            continue
        color_list = []
        for color in widget_class.colors:
            kwargs = {
                'project': obj.slug,
                'widget': widget_name,
                'color': color,
                'extension': widget_class.extension,
            }
            if lang is not None:
                kwargs['lang'] = lang
            if component is not None:
                kwargs['subproject'] = component
            color_url = reverse('widget-image', kwargs=kwargs)
            color_list.append({
                'name': color,
                'url': get_site_url(color_url),
            })
        widget_list.append({
            'name': widget_name,
            'colors': color_list,
        })

    return render(
        request, 'widgets.html', {
            'engage_url': engage_url,
            'engage_url_track': engage_url_track,
            'widget_list': widget_list,
            'widget_base_url': widget_base_url,
            'object': obj,
            'project': obj,
            'image_src': widget_list[0]['colors'][0]['url'],
            'form': form,
        })
예제 #2
0
 def get_widgets_url(self):
     """Return absolute URL for widgets."""
     return get_site_url('{0}?lang={1}'.format(
         reverse('widgets',
                 kwargs={
                     'project': self.subproject.project.slug,
                 }), self.language.code))
예제 #3
0
def download_dictionary(request, project, lang):
    """Export dictionary into various formats."""
    prj = get_project(request, project)
    lang = get_object_or_404(Language, code=lang)

    # Parse parameters
    export_format = None
    if 'format' in request.GET:
        export_format = request.GET['format']
    if export_format not in ('csv', 'po', 'tbx', 'xliff'):
        export_format = 'csv'

    # Grab all words
    words = Dictionary.objects.filter(project=prj,
                                      language=lang).order_by('source')

    # Translate toolkit based export
    exporter = get_exporter(export_format)(
        prj,
        lang,
        get_site_url(
            reverse('show_dictionary',
                    kwargs={
                        'project': prj.slug,
                        'lang': lang.code
                    })),
        fieldnames=('source', 'target'),
    )

    # Add words
    for word in words.iterator():
        exporter.add_dictionary(word)

    # Save to response
    return exporter.get_response('glossary-{project}-{language}.{extension}')
예제 #4
0
파일: project.py 프로젝트: quinox/weblate
 def get_widgets_url(self):
     """
     Returns absolute URL for widgets.
     """
     return get_site_url(
         reverse('widgets', kwargs={'project': self.slug})
     )
예제 #5
0
    def get_commit_message(self):
        """Format commit message based on project configuration."""
        template = self.subproject.commit_message
        if self.commit_message == '__add__':
            template = self.subproject.add_message
            self.commit_message = ''
            self.save()
        elif self.commit_message == '__delete__':
            template = self.subproject.delete_message
            self.commit_message = ''
            self.save()

        msg = template % {
            'language': self.language_code,
            'language_name': self.language.name,
            'subproject': self.subproject.name,
            'resource': self.subproject.name,
            'component': self.subproject.name,
            'project': self.subproject.project.name,
            'url': get_site_url(self.get_absolute_url()),
            'total': self.total,
            'fuzzy': self.fuzzy,
            'fuzzy_percent': self.get_fuzzy_percent(),
            'translated': self.translated,
            'translated_percent': self.get_translated_percent(),
        }
        if self.commit_message:
            msg = '{0}\n\n{1}'.format(msg, self.commit_message)
            self.commit_message = ''
            self.save()

        return msg
예제 #6
0
파일: project.py 프로젝트: quinox/weblate
 def get_share_url(self):
     """
     Returns absolute URL usable for sharing.
     """
     return get_site_url(
         reverse('engage', kwargs={'project': self.slug})
     )
예제 #7
0
 def get_absolute_url(self):
     return get_site_url(
         reverse(
             'show_language',
             kwargs={'lang': self.code}
         )
     )
예제 #8
0
    def json_req(self,
                 url,
                 http_post=False,
                 skip_auth=False,
                 raw=False,
                 **kwargs):
        """Perform JSON request."""
        # Encode params
        if len(kwargs) > 0:
            params = urlencode(
                {key: val.encode('utf-8')
                 for key, val in kwargs.items()})
        else:
            params = ''

        # Store for exception handling
        self.request_url = url
        self.request_params = params

        # Append parameters
        if len(params) > 0 and not http_post:
            url = '?'.join((url, params))

        # Create request object with custom headers
        request = Request(url)
        request.timeout = 0.5
        request.add_header('User-Agent', USER_AGENT)
        request.add_header('Referer', get_site_url())
        # Optional authentication
        if not skip_auth:
            self.authenticate(request)

        # Fire request
        if http_post:
            handle = urlopen(request, params.encode('utf-8'))
        else:
            handle = urlopen(request)

        # Read and possibly convert response
        text = handle.read()
        # Needed for Microsoft
        if text[:3] == b'\xef\xbb\xbf':
            text = text.decode('UTF-8-sig')
        else:
            text = text.decode('utf-8')
        # Replace literal \t
        text = text.strip().replace('\t', '\\t').replace('\r', '\\r')
        # Needed for Google
        while ',,' in text or '[,' in text:
            text = text.replace(',,', ',null,').replace('[,', '[')

        if raw:
            return text

        # Parse JSON
        response = json.loads(text)

        # Return data
        return response
예제 #9
0
 def get_share_url(self):
     """Returns absolute URL usable for sharing."""
     return get_site_url(
         reverse('engage-lang',
                 kwargs={
                     'project': self.subproject.project.slug,
                     'lang': self.language.code
                 }))
예제 #10
0
def download_dictionary_ttkit(export_format, prj, lang, words):
    '''
    Translate-toolkit builder for dictionary downloads.
    '''
    # Use translate-toolkit for other formats
    if export_format == 'po':
        # Construct store
        from translate.storage.po import pofile
        store = pofile()

        # Export parameters
        content_type = 'text/x-po'
        extension = 'po'
        has_lang = False

        # Set po file header
        store.updateheader(add=True,
                           language=lang.code,
                           x_generator='Weblate %s' % weblate.VERSION,
                           project_id_version='%s (%s)' %
                           (lang.name, prj.name),
                           language_team='%s <%s>' % (
                               lang.name,
                               get_site_url(
                                   reverse('show_dictionary',
                                           kwargs={
                                               'project': prj.slug,
                                               'lang': lang.code
                                           })),
                           ))
    else:
        # Construct store
        from translate.storage.tbx import tbxfile
        store = tbxfile()

        # Export parameters
        content_type = 'application/x-tbx'
        extension = 'tbx'
        has_lang = True

    # Setup response and headers
    response = HttpResponse(content_type='%s; charset=utf-8' % content_type)
    filename = 'glossary-%s-%s.%s' % (prj.slug, lang.code, extension)
    response['Content-Disposition'] = 'attachment; filename=%s' % filename

    # Add words
    for word in words.iterator():
        unit = store.UnitClass(word.source)
        if has_lang:
            unit.settarget(word.target, lang.code)
        else:
            unit.target = word.target
        store.addunit(unit)

    # Save to response
    response.write(str(store))

    return response
예제 #11
0
def weblate_context(request):
    """
    Context processor to inject various useful variables into context.
    """
    if 'next' in request.GET:
        login_redirect_url = request.GET['next']
    else:
        login_redirect_url = request.get_full_path()

    projects = Project.objects.all_acl(request.user)

    # Load user translations if user is authenticated
    subscribed_projects = None
    if request.user.is_authenticated:
        subscribed_projects = request.user.profile.subscriptions.all()

    if settings.OFFER_HOSTING:
        description = _(
            'Hosted Weblate, the place to translate your software project.')
    else:
        description = _(
            'This site runs Weblate for translating various software projects.'
        )

    if (hasattr(settings, 'ROLLBAR') and 'client_token' in settings.ROLLBAR
            and 'environment' in settings.ROLLBAR):
        rollbar_token = settings.ROLLBAR['client_token']
        rollbar_environment = settings.ROLLBAR['environment']
    else:
        rollbar_token = None
        rollbar_environment = None

    return {
        'version': weblate.VERSION,
        'description': description,
        'weblate_url': URL_BASE % weblate.VERSION,
        'donate_url': URL_DONATE % weblate.VERSION,
        'site_title': settings.SITE_TITLE,
        'site_url': get_site_url(),
        'offer_hosting': settings.OFFER_HOSTING,
        'demo_server': settings.DEMO_SERVER,
        'enable_avatars': settings.ENABLE_AVATARS,
        'enable_sharing': settings.ENABLE_SHARING,
        'piwik_site_id': settings.PIWIK_SITE_ID,
        'piwik_url': settings.PIWIK_URL,
        'google_analytics_id': settings.GOOGLE_ANALYTICS_ID,
        'current_date': datetime.utcnow().strftime('%Y-%m-%d'),
        'current_year': datetime.utcnow().strftime('%Y'),
        'current_month': datetime.utcnow().strftime('%m'),
        'login_redirect_url': login_redirect_url,
        'hooks_enabled': settings.ENABLE_HOOKS,
        'has_ocr': weblate.screenshots.views.HAS_OCR,
        'registration_open': settings.REGISTRATION_OPEN,
        'acl_projects': projects,
        'subscribed_projects': subscribed_projects,
        'rollbar_token': rollbar_token,
        'rollbar_environment': rollbar_environment,
    }
예제 #12
0
 def get_widgets_url(self):
     """Returns absolute URL for widgets."""
     return get_site_url('%s?lang=%s' % (
         reverse('widgets',
                 kwargs={
                     'project': self.subproject.project.slug,
                 }),
         self.language.code,
     ))
예제 #13
0
파일: models.py 프로젝트: wrestrtdr/weblate
def get_export_url(component):
    """Return Git export URL for component"""
    return get_site_url(
        reverse('git-export',
                kwargs={
                    'project': component.project.slug,
                    'subproject': component.slug,
                    'path': '',
                }))
예제 #14
0
파일: mixins.py 프로젝트: sc123088/weblate
 def reverse_url(self, name=None):
     """
     Generic reverser for URL.
     """
     if name is None:
         urlname = self._reverse_url_name()
     else:
         urlname = '%s_%s' % (name, self._reverse_url_name())
     return get_site_url(reverse(urlname,
                                 kwargs=self._reverse_url_kwargs()))
예제 #15
0
def export_stats(request, project, subproject):
    '''
    Exports stats in JSON format.
    '''
    subprj = get_subproject(request, project, subproject, True)

    jsonp = None
    if 'jsonp' in request.GET and request.GET['jsonp']:
        jsonp = request.GET['jsonp']

    response = []
    for trans in subprj.translation_set.all():
        response.append({
            'code':
            trans.language.code,
            'name':
            trans.language.name,
            'total':
            trans.total,
            'total_words':
            trans.total_words,
            'last_change':
            trans.last_change,
            'last_author':
            trans.get_last_author(),
            'translated':
            trans.translated,
            'translated_words':
            trans.translated_words,
            'translated_percent':
            trans.get_translated_percent(),
            'fuzzy':
            trans.fuzzy,
            'fuzzy_percent':
            trans.get_fuzzy_percent(),
            'failing':
            trans.failing_checks,
            'failing_percent':
            trans.get_failing_checks_percent(),
            'url':
            trans.get_share_url(),
            'url_translate':
            get_site_url(trans.get_absolute_url()),
        })
    if jsonp:
        return HttpResponse('{0}({1})'.format(
            jsonp, json.dumps(
                response,
                cls=DjangoJSONEncoder,
            )),
                            content_type='application/javascript')
    return JsonResponse(data=response, safe=False)
예제 #16
0
def weblate_context(request):
    """
    Context processor to inject various useful variables into context.
    """
    if 'next' in request.GET:
        login_redirect_url = request.GET['next']
    else:
        login_redirect_url = request.get_full_path()

    projects = Project.objects.all_acl(request.user)

    # Load user translations if user is authenticated
    usertranslations = None
    if request.user.is_authenticated():
        usertranslations = Translation.objects.filter(
            language__in=request.user.profile.languages.all(),
            subproject__project__in=projects,
        ).order_by(
            'subproject__project__name', 'subproject__name'
        ).select_related()

    return {
        'version': weblate.VERSION,

        'weblate_url': URL_BASE % weblate.VERSION,
        'donate_url': URL_DONATE % weblate.VERSION,

        'site_title': appsettings.SITE_TITLE,
        'site_url': get_site_url(),

        'offer_hosting': appsettings.OFFER_HOSTING,
        'demo_server': appsettings.DEMO_SERVER,
        'enable_avatars': appsettings.ENABLE_AVATARS,
        'enable_sharing': appsettings.ENABLE_SHARING,

        'piwik_site_id': appsettings.PIWIK_SITE_ID,
        'piwik_url': appsettings.PIWIK_URL,
        'google_analytics_id': appsettings.GOOGLE_ANALYTICS_ID,

        'current_date': datetime.utcnow().strftime('%Y-%m-%d'),
        'current_year': datetime.utcnow().strftime('%Y'),
        'current_month': datetime.utcnow().strftime('%m'),

        'login_redirect_url': login_redirect_url,

        'hooks_enabled': appsettings.ENABLE_HOOKS,

        'registration_open': appsettings.REGISTRATION_OPEN,
        'acl_projects': projects,
        'usertranslations': usertranslations,
    }
예제 #17
0
def is_spam(text, request):
    """Generic spam checker interface."""
    if settings.AKISMET_API_KEY:
        from akismet import Akismet
        akismet = Akismet(
            settings.AKISMET_API_KEY,
            get_site_url()
        )
        return akismet.comment_check(
            get_ip_address(request),
            request.META.get('HTTP_USER_AGENT', ''),
            comment_content=text,
            comment_type='comment'
        )
    return False
예제 #18
0
def download_translation_format(request, project, subproject, lang, fmt):
    obj = get_translation(request, project, subproject, lang)

    try:
        exporter = get_exporter(fmt)(obj.subproject.project, obj.language,
                                     get_site_url(obj.get_absolute_url()))
    except KeyError:
        raise Http404('File format not supported')

    for unit in obj.unit_set.iterator():
        exporter.add_unit(unit)

    # Save to response
    return exporter.get_response(
        '{{project}}-{0}-{{language}}.{{extension}}'.format(subproject))
예제 #19
0
    def render(self):
        translations = []
        offset = 30
        color = self.COLOR_MAP[self.color]
        for data in get_per_language_stats(self.obj):
            language, translated, total = data[:3]
            if total == 0:
                percent = 0
            else:
                percent = int(100 * translated / total)
            if self.color == 'auto':
                if percent >= 90:
                    color = '#4c1'
                elif percent >= 75:
                    color = '#dfb317'
                else:
                    color = '#e05d44'
            translations.append((
                # Language name
                language.name,
                # Translation percent
                percent,
                # Text y offset
                offset,
                # Bar y offset
                offset - 10,
                # Bar width
                int(percent * 1.5),
                # Bar color
                color,
                # Row URL
                get_site_url(
                    reverse('project-language',
                            kwargs={
                                'lang': language.code,
                                'project': self.obj.slug
                            })),
                # Bounding box y offset
                offset - 15,
            ))
            offset += 20

        self.image = render_to_string(
            'multi-language-badge.svg', {
                'height': len(translations) * 20 + 20,
                'boxheight': len(translations) * 20 + 10,
                'translations': translations,
            })
예제 #20
0
 def __init__(self,
              project=None,
              language=None,
              url=None,
              translation=None):
     if translation is not None:
         self.project = translation.subproject.project
         self.language = translation.language
         self.url = get_site_url(translation.get_absolute_url())
     else:
         self.project = project
         self.language = language
         self.url = url
     self.storage = self.get_storage()
     self.storage.setsourcelanguage(self.project.source_language.code)
     self.storage.settargetlanguage(self.language.code)
예제 #21
0
def download_dictionary_ttkit(export_format, prj, lang, words):
    """Translate-toolkit builder for dictionary downloads."""
    exporter = get_exporter(export_format)(prj, lang,
                                           get_site_url(
                                               reverse('show_dictionary',
                                                       kwargs={
                                                           'project': prj.slug,
                                                           'lang': lang.code
                                                       })))

    # Add words
    for word in words.iterator():
        exporter.add_dictionary(word)

    # Save to response
    return exporter.get_response('glossary-{project}-{language}.{extension}')
예제 #22
0
 def get_stats(self):
     """Return stats dictionary"""
     return {
         'code': self.language.code,
         'name': self.language.name,
         'total': self.total,
         'total_words': self.total_words,
         'last_change': self.last_change,
         'last_author': self.get_last_author(),
         'translated': self.translated,
         'translated_words': self.translated_words,
         'translated_percent': self.get_translated_percent(),
         'fuzzy': self.fuzzy,
         'fuzzy_percent': self.get_fuzzy_percent(),
         'failing': self.failing_checks,
         'failing_percent': self.get_failing_checks_percent(),
         'url': self.get_share_url(),
         'url_translate': get_site_url(self.get_absolute_url()),
     }
예제 #23
0
def get_notification_email(language,
                           email,
                           notification,
                           translation_obj=None,
                           context=None,
                           headers=None,
                           user=None,
                           info=None):
    '''
    Renders notification email.
    '''
    cur_language = django_translation.get_language()
    context = context or {}
    headers = headers or {}
    references = None
    if 'unit' in context:
        unit = context['unit']
        references = '{0}/{1}/{2}/{3}'.format(
            unit.translation.subproject.project.slug,
            unit.translation.subproject.slug, unit.translation.language.code,
            unit.id)
    if references is not None:
        references = '<{0}@{1}>'.format(references, get_site_domain())
        headers['In-Reply-To'] = references
        headers['References'] = references
    try:
        if info is None:
            info = force_text(translation_obj)
        LOGGER.info('sending notification %s on %s to %s', notification, info,
                    email)

        # Load user language
        if language is not None:
            django_translation.activate(language)

        # Template name
        context['subject_template'] = 'mail/{0}_subject.txt'.format(
            notification)

        # Adjust context
        context['current_site_url'] = get_site_url()
        if translation_obj is not None:
            context['translation'] = translation_obj
            context['translation_url'] = get_site_url(
                translation_obj.get_absolute_url())
        context['site_title'] = settings.SITE_TITLE

        # Render subject
        subject = render_to_string(context['subject_template'],
                                   context).strip()

        # Render body
        body = render_to_string('mail/{0}.txt'.format(notification), context)
        html_body = render_to_string('mail/{0}.html'.format(notification),
                                     context)

        # Define headers
        headers['Auto-Submitted'] = 'auto-generated'
        headers['X-AutoGenerated'] = 'yes'
        headers['Precedence'] = 'bulk'
        headers['X-Mailer'] = 'Weblate {0}'.format(VERSION)

        # Reply to header
        if user is not None:
            headers['Reply-To'] = user.email

        # List of recipients
        if email == 'ADMINS':
            emails = [a[1] for a in settings.ADMINS]
        else:
            emails = [email]

        # Create message
        email = EmailMultiAlternatives(
            settings.EMAIL_SUBJECT_PREFIX + subject,
            body,
            to=emails,
            headers=headers,
        )
        email.attach_alternative(html_body, 'text/html')

        # Return the mail
        return email
    finally:
        django_translation.activate(cur_language)
예제 #24
0
def export_stats(request, project, subproject):
    '''
    Exports stats in JSON format.
    '''
    subprj = get_subproject(request, project, subproject)

    try:
        indent = int(request.GET['indent'])
    except (ValueError, KeyError):
        indent = None

    jsonp = None
    if 'jsonp' in request.GET and request.GET['jsonp']:
        jsonp = request.GET['jsonp']

    response = []
    for trans in subprj.translation_set.all():
        response.append({
            'code':
            trans.language.code,
            'name':
            trans.language.name,
            'total':
            trans.total,
            'total_words':
            trans.total_words,
            'last_change':
            trans.last_change,
            'last_author':
            trans.get_last_author(),
            'translated':
            trans.translated,
            'translated_words':
            trans.translated_words,
            'translated_percent':
            trans.get_translated_percent(),
            'fuzzy':
            trans.fuzzy,
            'fuzzy_percent':
            trans.get_fuzzy_percent(),
            'failing':
            trans.failing_checks,
            'failing_percent':
            trans.get_failing_checks_percent(),
            'url':
            trans.get_share_url(),
            'url_translate':
            get_site_url(trans.get_absolute_url()),
        })
    json_data = json.dumps(
        response,
        default=json_dt_handler,
        indent=indent,
    )
    if jsonp:
        return HttpResponse('{0}({1})'.format(
            jsonp,
            json_data,
        ),
                            content_type='application/javascript')
    return HttpResponse(json_data, content_type='application/json')
예제 #25
0
 def get_attribute(self, instance):
     value = super(AbsoluteURLField, self).get_attribute(instance)
     if 'http:/' not in value and 'https:/' not in value:
         return get_site_url(value)
     return value
예제 #26
0
    def update_unit(self, unit, request, user=None):
        '''
        Updates backend file and unit.
        '''
        if user is None:
            user = request.user
        # Save with lock acquired
        with self.subproject.repository_lock:

            src = unit.get_source_plurals()[0]
            add = False

            pounit, add = self.store.find_unit(unit.context, src)

            # Bail out if we have not found anything
            if pounit is None or pounit.is_obsolete():
                return False, None

            # Check for changes
            if ((not add or unit.target == '') and
                    unit.target == pounit.get_target() and
                    unit.fuzzy == pounit.is_fuzzy()):
                return False, pounit

            # Store translations
            if unit.is_plural():
                pounit.set_target(unit.get_target_plurals())
            else:
                pounit.set_target(unit.target)

            # Update fuzzy flag
            pounit.mark_fuzzy(unit.fuzzy)

            # Optionally add unit to translation file
            if add:
                self.store.add_unit(pounit)

            # We need to update backend now
            author = get_author_name(user)

            # Update po file header
            now = timezone.now()
            if not timezone.is_aware(now):
                now = timezone.make_aware(now, timezone.utc)

            # Prepare headers to update
            headers = {
                'add': True,
                'last_translator': author,
                'plural_forms': self.language.get_plural_form(),
                'language': self.language_code,
                'PO_Revision_Date': now.strftime('%Y-%m-%d %H:%M%z'),
            }

            # Optionally store language team with link to website
            if self.subproject.project.set_translation_team:
                headers['language_team'] = '%s <%s>' % (
                    self.language.name,
                    get_site_url(self.get_absolute_url()),
                )

            # Optionally store email for reporting bugs in source
            report_source_bugs = self.subproject.report_source_bugs
            if report_source_bugs != '':
                headers['report_msgid_bugs_to'] = report_source_bugs

            # Update genric headers
            self.store.update_header(
                **headers
            )

            # commit possible previous changes (by other author)
            self.commit_pending(request, author)
            # save translation changes
            self.store.save()
            # commit VCS repo if needed
            self.git_commit(request, author, timezone.now(), sync=True)

        return True, pounit
예제 #27
0
    def update_units(self, author):
        """Update backend file and unit."""
        updated = False
        for unit in self.unit_set.filter(pending=True):

            src = unit.get_source_plurals()[0]
            add = False

            pounit, add = self.store.find_unit(unit.context, src)

            unit.pending = False

            # Bail out if we have not found anything
            if pounit is None or pounit.is_obsolete():
                self.log_error('message %s disappeared!', unit)
                unit.save(backend=True, update_fields=['pending'])
                continue

            # Check for changes
            if ((not add or unit.target == '') and
                    unit.target == pounit.get_target() and
                    unit.fuzzy == pounit.is_fuzzy()):
                unit.save(backend=True, update_fields=['pending'])
                continue

            updated = True

            # Optionally add unit to translation file.
            # This has be done prior setting tatget as some formats
            # generate content based on target language.
            if add:
                self.store.add_unit(pounit)

            # Store translations
            if unit.is_plural():
                pounit.set_target(unit.get_target_plurals())
            else:
                pounit.set_target(unit.target)

            # Update fuzzy flag
            pounit.mark_fuzzy(unit.fuzzy)

            # Update comments as they might have been changed (eg, fuzzy flag
            # removed)
            translated = pounit.is_translated()
            flags = pounit.get_flags()
            if translated != unit.translated or flags != unit.flags:
                unit.translated = translated
                unit.flags = flags
            unit.save(
                backend=True,
                update_fields=['translated', 'flags', 'pending']
            )

        # Did we do any updates?
        if not updated:
            return

        # Update po file header
        now = timezone.now()
        if not timezone.is_aware(now):
            now = timezone.make_aware(now, timezone.utc)

        # Prepare headers to update
        headers = {
            'add': True,
            'last_translator': author,
            'plural_forms': self.language.get_plural_form(),
            'language': self.language_code,
            'PO_Revision_Date': now.strftime('%Y-%m-%d %H:%M%z'),
        }

        # Optionally store language team with link to website
        if self.subproject.project.set_translation_team:
            headers['language_team'] = '{0} <{1}>'.format(
                self.language.name,
                get_site_url(self.get_absolute_url())
            )

        # Optionally store email for reporting bugs in source
        report_source_bugs = self.subproject.report_source_bugs
        if report_source_bugs != '':
            headers['report_msgid_bugs_to'] = report_source_bugs

        # Update genric headers
        self.store.update_header(
            **headers
        )

        # save translation changes
        self.store.save()

        # Update stats (the translated flag might have changed)
        self.update_stats()
예제 #28
0
def widgets(request, project):
    obj = get_project(request, project)

    # Parse possible language selection
    form = EnageLanguageForm(obj, request.GET)
    lang = None
    if form.is_valid() and form.cleaned_data['lang'] != '':
        lang = Language.objects.get(code=form.cleaned_data['lang'])

    if lang is None:
        engage_base = reverse('engage', kwargs={'project': obj.slug})
    else:
        engage_base = reverse(
            'engage-lang',
            kwargs={'project': obj.slug, 'lang': lang.code}
        )
    engage_url = get_site_url(engage_base)
    engage_url_track = '{0}?utm_source=widget'.format(engage_url)
    widget_base_url = get_site_url(
        reverse('widgets', kwargs={'project': obj.slug})
    )
    widget_list = []
    for widget_name in sorted(WIDGETS, key=widgets_sorter):
        widget_class = WIDGETS[widget_name]
        color_list = []
        for color in widget_class.colors:
            if lang is None:
                color_url = reverse(
                    'widget-image',
                    kwargs={
                        'project': obj.slug,
                        'widget': widget_name,
                        'color': color,
                        'extension': widget_class.extension,
                    }
                )
            else:
                color_url = reverse(
                    'widget-image-lang',
                    kwargs={
                        'project': obj.slug,
                        'widget': widget_name,
                        'color': color,
                        'lang': lang.code,
                        'extension': widget_class.extension,
                    }
                )
            color_list.append({
                'name': color,
                'url': get_site_url(color_url),
            })
        widget_list.append({
            'name': widget_name,
            'colors': color_list,
        })

    return render(
        request,
        'widgets.html',
        {
            'engage_url': engage_url,
            'engage_url_track': engage_url_track,
            'widget_list': widget_list,
            'widget_base_url': widget_base_url,
            'object': obj,
            'project': obj,
            'image_src': widget_list[0]['colors'][0]['url'],
            'form': form,
        }
    )