def auto_translation(request, project, component, lang): translation = get_translation(request, project, component, lang) project = translation.component.project if not request.user.has_perm('translation.auto', project): raise PermissionDenied() autoform = AutoForm(translation, request.user, request.POST) if translation.component.locked or not autoform.is_valid(): messages.error(request, _('Failed to process form!')) show_form_errors(request, autoform) return redirect(translation) auto = AutoTranslate(request.user, translation, autoform.cleaned_data['type'], request=request) if autoform.cleaned_data['auto_source'] == 'mt': auto.process_mt( autoform.cleaned_data['engines'], autoform.cleaned_data['threshold'], ) else: auto.process_others(autoform.cleaned_data['component'], ) import_message( request, auto.updated, _('Automatic translation completed, no strings were updated.'), ungettext('Automatic translation completed, %d string was updated.', 'Automatic translation completed, %d strings were updated.', auto.updated)) return redirect(translation)
def handle_translate(request, translation, this_unit_url, next_unit_url): """Save translation or suggestion to database and backend.""" # Antispam protection antispam = AntispamForm(request.POST) if not antispam.is_valid(): # Silently redirect to next entry return HttpResponseRedirect(next_unit_url) form = TranslationForm(request.user, translation, None, request.POST) if not form.is_valid(): show_form_errors(request, form) return None unit = form.cleaned_data['unit'] go_next = True if 'suggest' in request.POST: go_next = perform_suggestion(unit, form, request) elif not request.user.has_perm('unit.edit', unit): messages.error(request, _('Insufficient privileges for saving translations.')) else: go_next = perform_translation(unit, form, request) # Redirect to next entry if go_next: return HttpResponseRedirect(next_unit_url) return HttpResponseRedirect(this_unit_url)
def search_replace(request, project, component=None, lang=None): obj, unit_set, context = parse_url(request, project, component, lang) form = ReplaceForm(request.POST) if not form.is_valid(): messages.error(request, _('Failed to process form!')) show_form_errors(request, form) return redirect(obj) search_text = form.cleaned_data['search'] replacement = form.cleaned_data['replacement'] matching = unit_set.filter(target__contains=search_text) updated = 0 if matching.exists(): confirm = ReplaceConfirmForm(matching, request.POST) if not confirm.is_valid(): for unit in matching: unit.replacement = unit.target.replace(search_text, replacement) context.update({ 'matching': matching, 'search_query': search_text, 'replacement': replacement, 'form': form, 'confirm': ReplaceConfirmForm(matching), }) return render(request, 'replace.html', context) matching = confirm.cleaned_data['units'] obj.commit_pending(request) with transaction.atomic(): for unit in matching.select_for_update(): if not request.user.has_perm('unit.edit', unit): continue unit.translate(request, unit.target.replace(search_text, replacement), unit.state, change_action=Change.ACTION_REPLACE) updated += 1 import_message( request, updated, _('Search and replace completed, no strings were updated.'), ungettext('Search and replace completed, %d string was updated.', 'Search and replace completed, %d strings were updated.', updated)) return redirect(obj)
def search(translation, request): """Perform search or returns cached search results.""" # Possible new search form = SearchForm(request.GET) # Process form if not form.is_valid(): show_form_errors(request, form) search_result = { 'form': form, 'offset': form.cleaned_data.get('offset', 0), 'checksum': form.cleaned_data.get('checksum'), } search_url = form.urlencode() session_key = 'search_{0}_{1}'.format(translation.pk, search_url) if session_key in request.session and 'offset' in request.GET: search_result.update(request.session[session_key]) return search_result allunits = translation.unit_set.search( form.cleaned_data, translation=translation, ) if form.cleaned_data['type'] == 'random': allunits = allunits[:25] search_query = form.get_search_query() name = form.get_name() # Grab unit IDs unit_ids = list(allunits.values_list('id', flat=True)) # Check empty search results if len(unit_ids) == 0: messages.warning(request, _('No string matched your search!')) return redirect(translation) # Remove old search results cleanup_session(request.session) store_result = { 'query': search_query, 'url': search_url, 'key': session_key, 'name': force_text(name), 'ids': unit_ids, 'ttl': int(time.time()) + 86400, } request.session[session_key] = store_result search_result.update(store_result) return search_result
def search(translation, request): """Perform search or returns cached search results.""" # Possible new search form = SearchForm(request.GET) # Process form if not form.is_valid(): show_form_errors(request, form) search_result = { 'form': form, 'offset': form.cleaned_data.get('offset', 0), 'checksum': form.cleaned_data.get('checksum'), } search_url = form.urlencode() session_key = 'search_{0}_{1}'.format(translation.pk, search_url) if session_key in request.session and 'offset' in request.GET: search_result.update(request.session[session_key]) return search_result allunits = translation.unit_set.search( form.cleaned_data, translation=translation, ) search_query = form.get_search_query() name = form.get_name() # Grab unit IDs unit_ids = list(allunits.values_list('id', flat=True)) # Check empty search results if not unit_ids: messages.warning(request, _('No string matched your search!')) return redirect(translation) # Remove old search results cleanup_session(request.session) store_result = { 'query': search_query, 'url': search_url, 'key': session_key, 'name': force_text(name), 'ids': unit_ids, 'ttl': int(time.time()) + 86400, } request.session[session_key] = store_result search_result.update(store_result) return search_result
def download_translation_format(request, project, component, lang): obj = get_translation(request, project, component, lang) form = DownloadForm(request.GET) if not form.is_valid(): show_form_errors(request, form) return redirect(obj) units = obj.unit_set.search( form.cleaned_data, translation=obj, ) return download_translation_file(obj, form.cleaned_data['format'], units)
def download_translation_format(request, project, component, lang): obj = get_translation(request, project, component, lang) form = DownloadForm(request.GET) if not form.is_valid(): show_form_errors(request, form) return redirect(obj) units = obj.unit_set.search( form.cleaned_data, translation=obj, ) return download_translation_file(obj, form.cleaned_data['format'], units)
def state_change(request, project, component=None, lang=None): obj, unit_set, context = parse_url(request, project, component, lang) if not request.user.has_perm('translation.auto', obj): raise PermissionDenied() form = MassStateForm(request.user, obj, request.POST) if not form.is_valid(): messages.error(request, _('Failed to process form!')) show_form_errors(request, form) return redirect(obj) matching = unit_set.filter_type( form.cleaned_data['type'], context['project'], context['translation'].language if 'translation' in context else None, ).exclude( state=STATE_EMPTY ) obj.commit_pending(request) updated = 0 with transaction.atomic(): for unit in matching.select_for_update(): if not request.user.has_perm('unit.edit', unit): continue unit.translate( request, unit.target, int(form.cleaned_data['state']), change_action=Change.ACTION_MASS_STATE, ) updated += 1 import_message( request, updated, _('Mass state change completed, no strings were updated.'), ungettext( 'Mass state change completed, %d string was updated.', 'Mass state change completed, %d strings were updated.', updated ) ) return redirect(obj)
def handle_translate(translation, request, user_locked, this_unit_url, next_unit_url): """Save translation or suggestion to database and backend.""" # Antispam protection antispam = AntispamForm(request.POST) if not antispam.is_valid(): # Silently redirect to next entry return HttpResponseRedirect(next_unit_url) # Check whether translation is not outdated translation.check_sync() form = TranslationForm( request.user.profile, translation, None, request.POST ) if not form.is_valid(): show_form_errors(request, form) return unit = form.cleaned_data['unit'] go_next = True if 'suggest' in request.POST: go_next = perform_suggestion(unit, form, request) elif not can_translate(request.user, unit.translation): messages.error( request, _('You don\'t have privileges to save translations!') ) elif not user_locked: # Custom commit message message = request.POST.get('commit_message') if message is not None and message != unit.translation.commit_message: # Commit pending changes so that they don't get new message unit.translation.commit_pending(request, request.user) # Store new commit message unit.translation.commit_message = message unit.translation.save() go_next = perform_translation(unit, form, request) # Redirect to next entry if go_next: return HttpResponseRedirect(next_unit_url) else: return HttpResponseRedirect(this_unit_url)
def handle_translate(translation, request, user_locked, this_unit_url, next_unit_url): """Save translation or suggestion to database and backend.""" # Antispam protection antispam = AntispamForm(request.POST) if not antispam.is_valid(): # Silently redirect to next entry return HttpResponseRedirect(next_unit_url) # Check whether translation is not outdated translation.check_sync() form = TranslationForm( request.user.profile, translation, None, request.POST ) if not form.is_valid(): show_form_errors(request, form) return unit = form.cleaned_data['unit'] go_next = True if 'suggest' in request.POST: go_next = perform_suggestion(unit, form, request) elif not can_translate(request.user, unit.translation): messages.error( request, _('You don\'t have privileges to save translations!') ) elif not user_locked: # Custom commit message message = request.POST.get('commit_message') if message is not None and message != unit.translation.commit_message: # Commit pending changes so that they don't get new message unit.translation.commit_pending(request, request.user) # Store new commit message unit.translation.commit_message = message unit.translation.save() go_next = perform_translation(unit, form, request) # Redirect to next entry if go_next: return HttpResponseRedirect(next_unit_url) else: return HttpResponseRedirect(this_unit_url)
def save_zen(request, project, component, lang): """Save handler for zen mode.""" def render_mesage(message): return render_to_string( 'message.html', {'tags': message.tags, 'message': message.message} ) translation = get_translation(request, project, component, lang) form = TranslationForm( request.user, translation, None, request.POST ) translationsum = '' if not form.is_valid(): show_form_errors(request, form) elif not request.user.has_perm('unit.edit', form.cleaned_data['unit']): messages.error( request, _('Insufficient privileges for saving translations.') ) else: unit = form.cleaned_data['unit'] perform_translation(unit, form, request) translationsum = hash_to_checksum(unit.get_target_hash()) response = { 'messages': '', 'state': 'success', 'translationsum': translationsum, } storage = get_messages(request) if storage: response['messages'] = '\n'.join([render_mesage(m) for m in storage]) tags = set([m.tags for m in storage]) if 'error' in tags: response['state'] = 'danger' elif 'warning' in tags: response['state'] = 'warning' elif 'info' in tags: response['state'] = 'info' return JsonResponse(data=response)
def save_zen(request, project, component, lang): """Save handler for zen mode.""" def render_mesage(message): return render_to_string( 'message.html', {'tags': message.tags, 'message': message.message} ) translation = get_translation(request, project, component, lang) form = TranslationForm( request.user, translation, None, request.POST ) translationsum = '' if not form.is_valid(): show_form_errors(request, form) elif not request.user.has_perm('unit.edit', form.cleaned_data['unit']): messages.error( request, _('Insufficient privileges for saving translations.') ) else: unit = form.cleaned_data['unit'] perform_translation(unit, form, request) translationsum = hash_to_checksum(unit.get_target_hash()) response = { 'messages': '', 'state': 'success', 'translationsum': translationsum, } storage = get_messages(request) if storage: response['messages'] = '\n'.join([render_mesage(m) for m in storage]) tags = set([m.tags for m in storage]) if 'error' in tags: response['state'] = 'danger' elif 'warning' in tags: response['state'] = 'warning' elif 'info' in tags: response['state'] = 'info' return JsonResponse(data=response)
def download_translation(request, project, component, lang): obj = get_translation(request, project, component, lang) kwargs = {} if 'format' in request.GET or 'type' in request.GET: form = DownloadForm(request.GET) if not form.is_valid(): show_form_errors(request, form) return redirect(obj) kwargs['units'] = obj.unit_set.search( form.cleaned_data, translation=obj, ) kwargs['fmt'] = form.cleaned_data['format'] return download_translation_file(obj, **kwargs)
def new_unit(request, project, component, lang): translation = get_translation(request, project, component, lang) if not request.user.has_perm('unit.add', translation): raise PermissionDenied() form = NewUnitForm(request.user, request.POST) if not form.is_valid(): show_form_errors(request, form) else: key = form.cleaned_data['key'] value = form.cleaned_data['value'][0] if translation.unit_set.filter(context=key).exists(): messages.error( request, _('Translation with this key seem to already exist!')) else: translation.new_unit(request, key, value) messages.success(request, _('New string has been added.')) return redirect(translation)
def auto_translation(request, project, component, lang): translation = get_translation(request, project, component, lang) project = translation.component.project if not request.user.has_perm('translation.auto', project): raise PermissionDenied() autoform = AutoForm(translation, request.user, request.POST) if translation.component.locked or not autoform.is_valid(): messages.error(request, _('Failed to process form!')) show_form_errors(request, autoform) return redirect(translation) auto = AutoTranslate( request.user, translation, autoform.cleaned_data['type'], request=request ) if autoform.cleaned_data['auto_source'] == 'mt': auto.process_mt( autoform.cleaned_data['engines'], autoform.cleaned_data['threshold'], ) else: auto.process_others( autoform.cleaned_data['component'], ) import_message( request, auto.updated, _('Automatic translation completed, no strings were updated.'), ungettext( 'Automatic translation completed, %d string was updated.', 'Automatic translation completed, %d strings were updated.', auto.updated ) ) return redirect(translation)
def handle_translate(translation, request, this_unit_url, next_unit_url): """Save translation or suggestion to database and backend.""" # Antispam protection antispam = AntispamForm(request.POST) if not antispam.is_valid(): # Silently redirect to next entry return HttpResponseRedirect(next_unit_url) form = TranslationForm( request.user, translation, None, request.POST ) if not form.is_valid(): show_form_errors(request, form) return None unit = form.cleaned_data['unit'] go_next = True if 'suggest' in request.POST: go_next = perform_suggestion(unit, form, request) elif not request.user.has_perm('unit.edit', unit): messages.error( request, _('Insufficient privileges for saving translations.') ) else: # Custom commit message message = request.POST.get('commit_message') if message is not None and message != unit.translation.commit_message: # Commit pending changes so that they don't get new message unit.translation.commit_pending(request) # Store new commit message unit.translation.commit_message = message unit.translation.save() go_next = perform_translation(unit, form, request) # Redirect to next entry if go_next: return HttpResponseRedirect(next_unit_url) return HttpResponseRedirect(this_unit_url)
def handle_translate(translation, request, this_unit_url, next_unit_url): """Save translation or suggestion to database and backend.""" # Antispam protection antispam = AntispamForm(request.POST) if not antispam.is_valid(): # Silently redirect to next entry return HttpResponseRedirect(next_unit_url) form = TranslationForm( request.user, translation, None, request.POST ) if not form.is_valid(): show_form_errors(request, form) return None unit = form.cleaned_data['unit'] go_next = True if 'suggest' in request.POST: go_next = perform_suggestion(unit, form, request) elif not request.user.has_perm('unit.edit', unit): messages.error( request, _('Insufficient privileges for saving translations.') ) else: # Custom commit message message = request.POST.get('commit_message') if message is not None and message != unit.translation.commit_message: # Commit pending changes so that they don't get new message unit.translation.commit_pending('commit message', request) # Store new commit message unit.translation.commit_message = message unit.translation.save() go_next = perform_translation(unit, form, request) # Redirect to next entry if go_next: return HttpResponseRedirect(next_unit_url) return HttpResponseRedirect(this_unit_url)
def new_unit(request, project, component, lang): translation = get_translation(request, project, component, lang) if not request.user.has_perm('unit.add', translation): raise PermissionDenied() form = NewUnitForm(request.user, request.POST) if not form.is_valid(): show_form_errors(request, form) else: key = form.cleaned_data['key'] value = form.cleaned_data['value'][0] if translation.unit_set.filter(context=key).exists(): messages.error( request, _('Translation with this key seem to already exist!') ) else: translation.new_unit(request, key, value) messages.success( request, _('New string has been added.') ) return redirect(translation)
def upload_translation(request, project, subproject, lang): ''' Handling of translation uploads. ''' obj = get_translation(request, project, subproject, lang) if not can_upload_translation(request.user, obj): raise PermissionDenied() # Check method and lock if obj.is_locked(request.user): messages.error(request, _('Access denied.')) return redirect(obj) # Get correct form handler based on permissions form = get_upload_form( request.user, obj, request.POST, request.FILES ) # Check form validity if not form.is_valid(): messages.error(request, _('Please fix errors in the form.')) show_form_errors(request, form) return redirect(obj) # Create author name author = None if (can_author_translation(request.user, obj.subproject.project) and form.cleaned_data['author_name'] != '' and form.cleaned_data['author_email'] != ''): author = '%s <%s>' % ( form.cleaned_data['author_name'], form.cleaned_data['author_email'] ) # Check for overwriting overwrite = False if can_overwrite_translation(request.user, obj.subproject.project): overwrite = form.cleaned_data['overwrite'] # Do actual import try: ret, count = obj.merge_upload( request, request.FILES['file'], overwrite, author, merge_header=form.cleaned_data['merge_header'], merge_comments=form.cleaned_data['merge_comments'], method=form.cleaned_data['method'], fuzzy=form.cleaned_data['fuzzy'], ) import_message( request, count, _('No strings were imported from the uploaded file.'), ungettext( 'Processed %d string from the uploaded files.', 'Processed %d strings from the uploaded files.', count ) ) if not ret: messages.warning( request, _('There were no new strings in uploaded file!') ) except Exception as error: messages.error( request, _('File content merge failed: %s') % force_text(error) ) report_error(error, sys.exc_info(), request) return redirect(obj)
def get_credits(request, project, component): """View for credits""" obj = get_component(request, project, component) if not request.user.has_perm('reports.view', obj): raise PermissionDenied() form = ReportsForm(request.POST) if not form.is_valid(): show_form_errors(request, form) return redirect_param(obj, '#reports') data = generate_credits( obj, form.cleaned_data['start_date'], form.cleaned_data['end_date'], ) if form.cleaned_data['style'] == 'json': return JsonResponse(data=data, safe=False) if form.cleaned_data['style'] == 'html': start = '<table>' row_start = '<tr>' language_format = '<th>{0}</th>' translator_start = '<td><ul>' translator_format = '<li><a href="mailto:{0}">{1}</a></li>' translator_end = '</ul></td>' row_end = '</tr>' mime = 'text/html' end = '</table>' else: start = '' row_start = '' language_format = '* {0}\n' translator_start = '' translator_format = ' * {1} <{0}>' translator_end = '' row_end = '' mime = 'text/plain' end = '' result = [] result.append(start) for language in data: name, translators = language.popitem() result.append(row_start) result.append(language_format.format(name)) result.append( ''.join(( translator_start, '\n'.join( [translator_format.format(*t) for t in translators] ), translator_end, )) ) result.append(row_end) result.append(end) return HttpResponse( '\n'.join(result), content_type='{0}; charset=utf-8'.format(mime), )
def get_counts(request, project, component): """View for work counts""" obj = get_component(request, project, component) if not request.user.has_perm('reports.view', obj): raise PermissionDenied() form = ReportsForm(request.POST) if not form.is_valid(): show_form_errors(request, form) return redirect_param(obj, '#reports') data = generate_counts( obj, form.cleaned_data['start_date'], form.cleaned_data['end_date'], ) if form.cleaned_data['style'] == 'json': return JsonResponse(data=data, safe=False) headers = ( 'Name', 'Email', 'Words total', 'Count total', 'Words edited', 'Count edited', 'Words new', 'Count new', ) if form.cleaned_data['style'] == 'html': start = HTML_HEADING.format( ''.join(['<th>{0}</th>'.format(h) for h in headers]) ) row_start = '<tr>' cell_name = cell_count = '<td>{0}</td>\n' row_end = '</tr>' mime = 'text/html' end = '</table>' else: start = '{0}\n{1} {2}\n{0}'.format( RST_HEADING, ' '.join(['{0:40}'.format(h) for h in headers[:2]]), ' '.join(['{0:12}'.format(h) for h in headers[2:]]), ) row_start = '' cell_name = '{0:40} ' cell_count = '{0:12} ' row_end = '' mime = 'text/plain' end = RST_HEADING result = [] result.append(start) for item in data: if row_start: result.append(row_start) result.append( ''.join(( cell_name.format(item['name']), cell_name.format(item['email']), cell_count.format(item['words']), cell_count.format(item['count']), cell_count.format(item['words_new']), cell_count.format(item['count_new']), cell_count.format(item['words_edit']), cell_count.format(item['count_edit']), )) ) if row_end: result.append(row_end) result.append(end) return HttpResponse( '\n'.join(result), content_type='{0}; charset=utf-8'.format(mime), )
def search(translation, request): """Perform search or returns cached search results.""" # Already performed search if 'sid' in request.GET: # Grab from session storage search_id = 'search_{0}'.format(request.GET['sid']) # Check if we know the search if search_id not in request.session: messages.error(request, _('Invalid search string!')) return redirect(translation) search_result = copy.copy(request.session[search_id]) if 'params' in search_result: search_result['form'] = SearchForm(search_result['params']) else: search_result['form'] = SearchForm() return search_result # Possible new search search_form = SearchForm(request.GET) review_form = ReviewForm(request.GET) search_query = None if 'date' in request.GET: if review_form.is_valid(): # Review allunits = translation.unit_set.review( review_form.cleaned_data['date'], request.user) formatted_date = formats.date_format( review_form.cleaned_data['date'], 'SHORT_DATE_FORMAT') name = _('Review of translations since %s') % formatted_date else: show_form_errors(request, review_form) # Filtering by type allunits = translation.unit_set.all() name = _('All strings') elif search_form.is_valid(): # Apply search conditions allunits = translation.unit_set.search( translation, search_form.cleaned_data, ) search_query = search_form.cleaned_data['q'] name = search_form.get_name() else: # Error reporting show_form_errors(request, search_form) # Filtering by type allunits = translation.unit_set.all() name = _('All strings') # Grab unit IDs unit_ids = list(allunits.values_list('id', flat=True)) # Check empty search results if len(unit_ids) == 0: messages.warning(request, _('No string matched your search!')) return redirect(translation) # Checksum unit access offset = 0 if 'checksum' in request.GET: try: unit = allunits.filter( id_hash=checksum_to_hash(request.GET['checksum']))[0] offset = unit_ids.index(unit.id) except (Unit.DoesNotExist, IndexError, ValueError): messages.warning(request, _('No string matched your search!')) return redirect(translation) # Remove old search results cleanup_session(request.session) # Store in cache and return search_id = str(uuid.uuid1()) search_result = { 'params': request.GET, 'query': search_query, 'name': force_text(name), 'ids': unit_ids, 'search_id': search_id, 'ttl': int(time.time()) + 86400, 'offset': offset, } request.session['search_{0}'.format(search_id)] = search_result search_result = copy.copy(search_result) search_result['form'] = search_form return search_result
def upload_translation(request, project, component, lang): """Handling of translation uploads.""" obj = get_translation(request, project, component, lang) if not can_upload_translation(request.user, obj): raise PermissionDenied() # Check method and lock if obj.component.locked: messages.error(request, _('Access denied.')) return redirect(obj) # Get correct form handler based on permissions form = get_upload_form(request.user, obj, request.POST, request.FILES) # Check form validity if not form.is_valid(): messages.error(request, _('Please fix errors in the form.')) show_form_errors(request, form) return redirect(obj) # Create author name author = None if (can_author_translation(request.user, obj.component.project) and form.cleaned_data['author_name'] != '' and form.cleaned_data['author_email'] != ''): author = '{0} <{1}>'.format(form.cleaned_data['author_name'], form.cleaned_data['author_email']) # Check for overwriting overwrite = False if can_overwrite_translation(request.user, obj.component.project): overwrite = form.cleaned_data['upload_overwrite'] # Do actual import try: not_found, skipped, accepted, total = obj.merge_upload( request, request.FILES['file'], overwrite, author, merge_header=form.cleaned_data['merge_header'], method=form.cleaned_data['method'], fuzzy=form.cleaned_data['fuzzy'], ) if total == 0: message = _('No strings were imported from the uploaded file.') else: message = ungettext( 'Processed {0} string from the uploaded files ' '(skipped: {1}, not found: {2}, updated: {3}).', 'Processed {0} strings from the uploaded files ' '(skipped: {1}, not found: {2}, updated: {3}).', total).format(total, skipped, not_found, accepted) if accepted == 0: messages.warning(request, message) else: messages.success(request, message) except Exception as error: messages.error(request, _('File content merge failed: %s') % force_text(error)) report_error(error, sys.exc_info(), request) return redirect(obj)
def get_credits(request, project, component): """View for credits""" obj = get_component(request, project, component) if not request.user.has_perm('reports.view', obj): raise PermissionDenied() form = ReportsForm(request.POST) if not form.is_valid(): show_form_errors(request, form) return redirect_param(obj, '#reports') data = generate_credits( obj, form.cleaned_data['start_date'], form.cleaned_data['end_date'], ) if form.cleaned_data['style'] == 'json': return JsonResponse(data=data, safe=False) if form.cleaned_data['style'] == 'html': start = '<table>' row_start = '<tr>' language_format = '<th>{0}</th>' translator_start = '<td><ul>' translator_format = '<li><a href="mailto:{0}">{1}</a></li>' translator_end = '</ul></td>' row_end = '</tr>' mime = 'text/html' end = '</table>' else: start = '' row_start = '' language_format = '* {0}\n' translator_start = '' translator_format = ' * {1} <{0}>' translator_end = '' row_end = '' mime = 'text/plain' end = '' result = [] result.append(start) for language in data: name, translators = language.popitem() result.append(row_start) result.append(language_format.format(name)) result.append(''.join(( translator_start, '\n'.join([translator_format.format(*t) for t in translators]), translator_end, ))) result.append(row_end) result.append(end) return HttpResponse( '\n'.join(result), content_type='{0}; charset=utf-8'.format(mime), )
def get_counts(request, project, component): """View for work counts""" obj = get_component(request, project, component) if not request.user.has_perm('reports.view', obj): raise PermissionDenied() form = ReportsForm(request.POST) if not form.is_valid(): show_form_errors(request, form) return redirect_param(obj, '#reports') data = generate_counts( obj, form.cleaned_data['start_date'], form.cleaned_data['end_date'], ) if form.cleaned_data['style'] == 'json': return JsonResponse(data=data, safe=False) headers = ( 'Name', 'Email', 'Words total', 'Count total', 'Words edited', 'Count edited', 'Words new', 'Count new', ) if form.cleaned_data['style'] == 'html': start = HTML_HEADING.format(''.join( ['<th>{0}</th>'.format(h) for h in headers])) row_start = '<tr>' cell_name = cell_count = '<td>{0}</td>\n' row_end = '</tr>' mime = 'text/html' end = '</table>' else: start = '{0}\n{1} {2}\n{0}'.format( RST_HEADING, ' '.join(['{0:40}'.format(h) for h in headers[:2]]), ' '.join(['{0:12}'.format(h) for h in headers[2:]]), ) row_start = '' cell_name = '{0:40} ' cell_count = '{0:12} ' row_end = '' mime = 'text/plain' end = RST_HEADING result = [] result.append(start) for item in data: if row_start: result.append(row_start) result.append(''.join(( cell_name.format(item['name']), cell_name.format(item['email']), cell_count.format(item['words']), cell_count.format(item['count']), cell_count.format(item['words_new']), cell_count.format(item['count_new']), cell_count.format(item['words_edit']), cell_count.format(item['count_edit']), ))) if row_end: result.append(row_end) result.append(end) return HttpResponse( '\n'.join(result), content_type='{0}; charset=utf-8'.format(mime), )
def upload_translation(request, project, component, lang): """Handling of translation uploads.""" obj = get_translation(request, project, component, lang) if not request.user.has_perm('upload.perform', obj): raise PermissionDenied() # Check method and lock if obj.component.locked: messages.error(request, _('Access denied.')) return redirect(obj) # Get correct form handler based on permissions form = get_upload_form( request.user, obj, request.POST, request.FILES ) # Check form validity if not form.is_valid(): messages.error(request, _('Please fix errors in the form.')) show_form_errors(request, form) return redirect(obj) # Create author name author = None if (request.user.has_perm('upload.authorship', obj) and form.cleaned_data['author_name'] != '' and form.cleaned_data['author_email'] != ''): author = '{0} <{1}>'.format( form.cleaned_data['author_name'], form.cleaned_data['author_email'] ) # Check for overwriting overwrite = False if request.user.has_perm('upload.overwrite', obj): overwrite = form.cleaned_data['upload_overwrite'] # Do actual import try: not_found, skipped, accepted, total = obj.merge_upload( request, request.FILES['file'], overwrite, author, merge_header=form.cleaned_data['merge_header'], method=form.cleaned_data['method'], fuzzy=form.cleaned_data['fuzzy'], ) if total == 0: message = _('No strings were imported from the uploaded file.') else: message = ungettext( 'Processed {0} string from the uploaded files ' '(skipped: {1}, not found: {2}, updated: {3}).', 'Processed {0} strings from the uploaded files ' '(skipped: {1}, not found: {2}, updated: {3}).', total ).format(total, skipped, not_found, accepted) if accepted == 0: messages.warning(request, message) else: messages.success(request, message) except Exception as error: messages.error( request, _('File content merge failed: %s') % force_text(error) ) report_error(error, sys.exc_info(), request) return redirect(obj)
def search(translation, request): """Perform search or returns cached search results.""" # Possible new search search_form = SearchForm(request.GET) review_form = ReviewForm(request.GET) # Process form if 'date' in request.GET: if review_form.is_valid(): form = review_form else: show_form_errors(request, review_form) # Use blank form form = SearchForm([]) form.is_valid() elif search_form.is_valid(): form = search_form else: show_form_errors(request, search_form) # Use blank form form = SearchForm([]) form.is_valid() search_result = { 'form': form, 'offset': form.cleaned_data['offset'], 'checksum': form.cleaned_data['checksum'], } search_url = form.urlencode() session_key = 'search_{0}_{1}'.format(translation.pk, search_url) if session_key in request.session: search_result.update(request.session[session_key]) return search_result if form.cleaned_data['type'] == 'review': allunits = translation.unit_set.review( form.cleaned_data['date'], request.user ) else: allunits = translation.unit_set.search( translation, form.cleaned_data, ) if form.cleaned_data['type'] == 'random': allunits = allunits[:25] search_query = form.get_search_query() name = form.get_name() # Grab unit IDs unit_ids = list(allunits.values_list('id', flat=True)) # Check empty search results if len(unit_ids) == 0: messages.warning(request, _('No string matched your search!')) return redirect(translation) # Remove old search results cleanup_session(request.session) store_result = { 'query': search_query, 'url': search_url, 'key': session_key, 'name': force_text(name), 'ids': unit_ids, 'ttl': int(time.time()) + 86400, } request.session[session_key] = store_result search_result.update(store_result) return search_result
def search_replace(request, project, component=None, lang=None): obj, unit_set, context = parse_url(request, project, component, lang) form = ReplaceForm(request.POST) if not form.is_valid(): messages.error(request, _('Failed to process form!')) show_form_errors(request, form) return redirect(obj) search_text = form.cleaned_data['search'] replacement = form.cleaned_data['replacement'] matching = unit_set.filter(target__contains=search_text) updated = 0 if matching.exists(): confirm = ReplaceConfirmForm(matching, request.POST) if not confirm.is_valid(): for unit in matching: unit.replacement = unit.target.replace( search_text, replacement ) context.update({ 'matching': matching, 'search_query': search_text, 'replacement': replacement, 'form': form, 'confirm': ReplaceConfirmForm(matching), }) return render( request, 'replace.html', context ) matching = confirm.cleaned_data['units'] obj.commit_pending(request) with transaction.atomic(): for unit in matching.select_for_update(): if not request.user.has_perm('unit.edit', unit): continue unit.translate( request, unit.target.replace(search_text, replacement), unit.state, change_action=Change.ACTION_REPLACE ) updated += 1 import_message( request, updated, _('Search and replace completed, no strings were updated.'), ungettext( 'Search and replace completed, %d string was updated.', 'Search and replace completed, %d strings were updated.', updated ) ) return redirect(obj)
def search(request, project=None, component=None, lang=None): """Perform site-wide search on units.""" is_ratelimited = not check_rate_limit('search', request) search_form = SiteSearchForm(request.GET) context = { 'search_form': search_form, } search_kwargs = {} if component: obj = get_component(request, project, component) context['component'] = obj context['project'] = obj.project context['back_url'] = obj.get_absolute_url() search_kwargs = {'component': obj} elif project: obj = get_project(request, project) context['project'] = obj context['back_url'] = obj.get_absolute_url() search_kwargs = {'project': obj} else: obj = None context['back_url'] = None if lang: s_language = get_object_or_404(Language, code=lang) context['language'] = s_language search_kwargs = {'language': s_language} if obj: if component: context['back_url'] = obj.translation_set.get( language=s_language).get_absolute_url() else: context['back_url'] = reverse('project-language', kwargs={ 'project': project, 'lang': lang, }) else: context['back_url'] = s_language.get_absolute_url() if not is_ratelimited and request.GET and search_form.is_valid(): # Filter results by ACL if component: units = Unit.objects.filter(translation__component=obj) elif project: units = Unit.objects.filter(translation__component__project=obj) else: allowed_projects = request.user.allowed_projects units = Unit.objects.filter( translation__component__project__in=allowed_projects) units = units.search(search_form.cleaned_data, **search_kwargs) if lang: units = units.filter(translation__language=context['language']) units = get_paginator(request, units) context['show_results'] = True context['page_obj'] = units context['title'] = _('Search for %s') % (search_form.cleaned_data['q']) context['query_string'] = search_form.urlencode() context['search_query'] = search_form.cleaned_data['q'] elif is_ratelimited: messages.error(request, _('Too many search queries, please try again later.')) elif request.GET: messages.error(request, _('Invalid search query!')) show_form_errors(request, search_form) return render(request, 'search.html', context)