def overwrite_file(request, relative_root_dir, django_file, upload_path): """overwrite with uploaded file""" upload_dir = os.path.dirname(absolute_real_path(upload_path)) # Ensure that there is a directory into which we can dump the # uploaded file. if not os.path.exists(upload_dir): os.makedirs(upload_dir) # Get the file extensions of the uploaded filename and the # current translation project _upload_base, upload_ext = os.path.splitext(django_file.name) _local_base, local_ext = os.path.splitext(upload_path) # If the extension of the uploaded file matches the extension # used in this translation project, then we simply write the # file to the disc. if upload_ext == local_ext: outfile = open(absolute_real_path(upload_path), "wb") try: outfile.write(django_file.read()) finally: outfile.close() try: #FIXME: we need a way to delay reparsing store = Store.objects.get(file=upload_path) store.update( update_structure=True, update_translation=True, conservative=False) except Store.DoesNotExist: # newfile, delay parsing pass else: newstore = factory.getobject(django_file, classes=factory_classes) if not newstore.units: return # If the extension of the uploaded file does not match the # extension of the current translation project, we create # an empty file (with the right extension)... empty_store = factory.getobject( absolute_real_path(upload_path), classes=factory_classes) # And save it... empty_store.save() request.translation_project.scan_files() # Then we open this newly created file and merge the # uploaded file into it. store = Store.objects.get(file=upload_path) #FIXME: maybe there is a faster way to do this? store.update( update_structure=True, update_translation=True, conservative=False, store=newstore) store.sync( update_structure=True, update_translation=True, conservative=False)
def get_translated_name(translation_project, store): name = os.path.splitext(store.name)[0] if store.file: path_parts = store.file.name.split(os.sep) else: path_parts = store.parent.get_real_path().split(os.sep) path_parts.append(store.name) pootle_path_parts = store.pootle_path.split('/') # Replace language code path_parts[1] = translation_project.language.code pootle_path_parts[1] = translation_project.language.code # Replace extension path_parts[-1] = ( "%s.%s" % (name, store.filetype.extension)) pootle_path_parts[-1] = ( "%s.%s" % (name, store.filetype.extension)) return ('/'.join(pootle_path_parts), absolute_real_path(os.sep.join(path_parts)))
def export_as_type(request, store, filetype): """export given file to xliff for offline translation""" from pootle_store.filetypes import factory_classes, is_monolingual klass = factory_classes.get(filetype, None) if not klass or is_monolingual(klass) or store.pootle_path.endswith(filetype): raise ValueError path, ext = os.path.splitext(store.real_path) export_path = os.path.join('POOTLE_EXPORT', path + os.path.extsep + filetype) abs_export_path = absolute_real_path(export_path) key = iri_to_uri("%s:export_as_%s" % (store.pootle_path, filetype)) last_export = cache.get(key) if not (last_export and last_export == store.get_mtime() and os.path.isfile(abs_export_path)): from pootle_app.project_tree import ensure_target_dir_exists import tempfile import shutil ensure_target_dir_exists(abs_export_path) outputstore = store.convert(klass) fd, tempstore = tempfile.mkstemp(prefix=store.name, suffix=os.path.extsep + filetype) os.close(fd) outputstore.savefile(tempstore) shutil.move(tempstore, abs_export_path) cache.set(key, store.get_mtime(), settings.OBJECT_CACHE_TIMEOUT) return redirect('/export/' + export_path)
def export_zip(request, translation_project, file_path): if not check_permission("archive", request): raise PermissionDenied(_('You do not have the right to create ZIP archives.')) translation_project.sync() pootle_path = translation_project.pootle_path + (file_path or '') archivename = '%s-%s' % (translation_project.project.code, translation_project.language.code) if file_path.endswith('/'): file_path = file_path[:-1] if file_path: archivename += '-' + file_path.replace('/', '-') archivename += '.zip' export_path = os.path.join('POOTLE_EXPORT', translation_project.real_path, archivename) abs_export_path = absolute_real_path(export_path) key = "%s:export_zip" % pootle_path last_export = cache.get(key) if not (last_export and last_export == translation_project.get_mtime() and os.path.isfile(abs_export_path)): ensure_target_dir_exists(abs_export_path) stores = Store.objects.filter(pootle_path__startswith=pootle_path).exclude(file='') translation_project.get_archive(stores, abs_export_path) cache.set(key, translation_project.get_mtime(), settings.OBJECT_CACHE_TIMEOUT) return redirect('/export/' + export_path)
def export_zip(request, translation_project, file_path): translation_project.sync() pootle_path = translation_project.pootle_path + (file_path or '') archivename = '%s-%s' % (translation_project.project.code, translation_project.language.code) if file_path.endswith('/'): file_path = file_path[:-1] if file_path: archivename += '-' + file_path.replace('/', '-') archivename += '.zip' export_path = os.path.join('POOTLE_EXPORT', translation_project.real_path, archivename) abs_export_path = absolute_real_path(export_path) key = iri_to_uri("%s:export_zip" % pootle_path) last_export = cache.get(key) if (not (last_export and last_export == translation_project.get_mtime() and os.path.isfile(abs_export_path))): ensure_target_dir_exists(abs_export_path) stores = Store.objects.filter(pootle_path__startswith=pootle_path) \ .exclude(file='') translation_project.get_archive(stores, abs_export_path) cache.set(key, translation_project.get_mtime(), settings.OBJECT_CACHE_TIMEOUT) return redirect('/export/' + export_path)
def export_as_xliff(request, store): """Export given file to xliff for offline translation.""" path = store.real_path if not path: # bug 2106 project = request.translation_project.project if project.get_treestyle() == "gnu": path = "/".join(store.pootle_path.split(os.path.sep)[2:]) else: parts = store.pootle_path.split(os.path.sep)[1:] path = "%s/%s/%s" % (parts[1], parts[0], "/".join(parts[2:])) path, ext = os.path.splitext(path) export_path = "/".join(['POOTLE_EXPORT', path + os.path.extsep + 'xlf']) abs_export_path = absolute_real_path(export_path) key = iri_to_uri("%s:export_as_xliff" % store.pootle_path) last_export = cache.get(key) if not (last_export and last_export == store.get_mtime() and os.path.isfile(abs_export_path)): from pootle_app.project_tree import ensure_target_dir_exists from translate.storage.poxliff import PoXliffFile from pootle_misc import ptempfile as tempfile import shutil ensure_target_dir_exists(abs_export_path) outputstore = store.convert(PoXliffFile) outputstore.switchfile(store.name, createifmissing=True) fd, tempstore = tempfile.mkstemp(prefix=store.name, suffix='.xlf') os.close(fd) outputstore.savefile(tempstore) shutil.move(tempstore, abs_export_path) cache.set(key, store.get_mtime(), settings.OBJECT_CACHE_TIMEOUT) return redirect('/export/' + export_path)
def upload_file(request, directory, django_file, overwrite): translation_project = request.translation_project relative_root_dir = directory.pootle_path[len(translation_project.directory.pootle_path):] # for some reason factory checks explicitly for file existance and # if file is open, which makes it difficult to work with Django's # in memory uploads. # # setting _closed to False should work around this #FIXME: hackish, does this have any undesirable side effect? if getattr(django_file, '_closed', None) is None: try: django_file._closed = False except AttributeError: pass # factory also checks for _mode if getattr(django_file, '_mode', None) is None: try: django_file._mode = 1 except AttributeError: pass # mode is an attribute not a property in Django 1.1 if getattr(django_file, 'mode', None) is None: django_file.mode = 1 local_filename = get_local_filename(translation_project, django_file.name) pootle_path = directory.pootle_path + local_filename # The full filesystem path to 'local_filename' upload_path = get_upload_path(translation_project, relative_root_dir, local_filename) try: store = translation_project.stores.get(pootle_path=pootle_path) except Store.DoesNotExist: store = None file_exists = os.path.exists(absolute_real_path(upload_path)) if store is not None and overwrite == 'overwrite' and not check_permission('overwrite', request): raise PermissionDenied(_("You do not have rights to overwrite files here.")) if store is None and not check_permission('administrate', request): raise PermissionDenied(_("You do not have rights to upload new files here.")) if overwrite == 'merge' and not check_permission('translate', request): raise PermissionDenied(_("You do not have rights to upload files here.")) if overwrite == 'suggest' and not check_permission('suggest', request): raise PermissionDenied(_("You do not have rights to upload files here.")) if store is None or (overwrite == 'overwrite' and store.file != ""): overwrite_file(request, relative_root_dir, django_file, upload_path) return newstore = factory.getobject(django_file, classes=factory_classes) #FIXME: are we sure this is what we want to do? shouldn't we # diffrentiate between structure changing uploads and mere # pretranslate uploads? suggestions = overwrite == 'merge' notranslate = overwrite == 'suggest' #allownewstrings = check_permission('overwrite', request) or check_permission('administrate', request) or check_permission('commit', request) #obsoletemissing = allownewstrings and overwrite == 'merge' store.mergefile(newstore, request.user.username, suggestions=suggestions, notranslate=notranslate, allownewstrings=False, obsoletemissing=False)
def get_translated_name(translation_project, store): name, ext = os.path.splitext(store.name) path_parts = store.file.name.split(os.sep) # replace language code path_parts[1] = translation_project.language.code # replace extension path_parts[-1] = name + '.' + translation_project.project.localfiletype return absolute_real_path(os.sep.join(path_parts))
def is_active(self, request): project = request.translation_project.project.code language = request.translation_project.language.code xpi_file = os.path.join('POOTLE_EXPORT', project, language, '%s-%s.xpi' %(project, language)) abs_xpi_file = absolute_real_path(xpi_file) if not os.path.exists(abs_xpi_file): return False else: return super(MozillaDownloadLangpackAction, self).is_active(request)
def set_download_file(self, path_obj, filepath): """Set file for download """ filename = relative_real_path(filepath) export_path = os.path.join('POOTLE_EXPORT', filename) abs_export_path = absolute_real_path(export_path) try: ensure_target_dir_exists(abs_export_path) shutil.copyfile(filepath, abs_export_path) except (IOError, OSError, shutil.Error), e: msg = (_("Failed to copy download file to export directory %s") % abs_export_path) logger.exception('%s', msg) return ''.join([msg, ": ", str(e)])
def get_translated_name(translation_project, store): name, ext = os.path.splitext(store.name) if store.file: path_parts = store.file.name.split(os.sep) else: path_parts = store.parent.get_real_path().split(os.sep) path_parts.append(store.name) pootle_path_parts = store.pootle_path.split('/') # replace language code path_parts[1] = translation_project.language.code pootle_path_parts[1] = translation_project.language.code # replace extension path_parts[-1] = name + '.' + translation_project.project.localfiletype pootle_path_parts[-1] = name + '.' + translation_project.project.localfiletype return '/'.join(pootle_path_parts), absolute_real_path(os.sep.join(path_parts))
def set_download_file(self, path_obj, filepath): """Set file for download """ filename = relative_real_path(filepath) export_path = os.path.join('POOTLE_EXPORT', filename) abs_export_path = absolute_real_path(export_path) try: ensure_target_dir_exists(abs_export_path) shutil.copyfile(filepath, abs_export_path) except (IOError, OSError, shutil.Error) as e: msg = (_("Failed to copy download file to export directory %s") % abs_export_path) logger.exception('%s', msg) return ''.join([msg, ": ", str(e)]) cache.set(self._cache_key(path_obj), path_obj.get_mtime(), settings.OBJECT_CACHE_TIMEOUT) self._dl_path[path_obj.pootle_path] = export_path return ''
def link_func(_request, path_obj, **_kwargs): """Curried link function with self bound from instance method""" link = {'text': _(self.title), 'icon': getattr(self, 'icon', 'icon-download')} export_path = self.get_download(path_obj) if export_path: abs_export_path = absolute_real_path(export_path) last_export = cache.get(self._cache_key(path_obj)) if last_export and (last_export == path_obj.get_mtime() and os.path.isfile(abs_export_path)): # valid and up-to-date cache file - link to that link['href'] = reverse('pootle-export', args=[export_path]) if 'href' not in link: # no usable cache file, link to action query to generate it link['href'] = self._query_url(path_obj.pootle_path) if type(self).__doc__: # return docstring with normalized whitespace as tooltip link['tooltip'] = ' '.join(type(self).__doc__.split()) return link
def export_zip(request, translation_project, file_path): from django.core.cache import cache from django.utils.encoding import iri_to_uri from django.utils.timezone import utc translation_project.sync() pootle_path = translation_project.pootle_path + (file_path or '') archivename = '%s-%s' % (translation_project.project.code, translation_project.language.code) if file_path.endswith('/'): file_path = file_path[:-1] if file_path: archivename += '-' + file_path.replace('/', '-') archivename += '.zip' export_path = os.path.join('POOTLE_EXPORT', translation_project.real_path, archivename) abs_export_path = absolute_real_path(export_path) key = iri_to_uri("%s:export_zip" % pootle_path) last_export = cache.get(key) tp_time = translation_project.get_mtime().replace(tzinfo=utc) up_to_date = False if last_export: # Make both datetimes tz-aware to avoid a crash here last_export = last_export.replace(tzinfo=utc) up_to_date = last_export == tp_time if not (up_to_date and os.path.isfile(abs_export_path)): ensure_target_dir_exists(abs_export_path) stores = Store.objects.filter(pootle_path__startswith=pootle_path) \ .exclude(file='') translation_project.get_archive(stores, abs_export_path) cache.set(key, tp_time, settings.OBJECT_CACHE_TIMEOUT) return redirect('/export/' + export_path)
def get_translated_name(translation_project, store): name = os.path.splitext(store.name)[0] language_code = translation_project.language.code project = translation_project.project if store.file: path_parts = store.file.name.split(os.sep) else: path_parts = store.parent.get_real_path().split(os.sep) path_parts.append(store.name) # Replace language code path_parts[1] = project.lang_mapper.get_upstream_code(language_code) # Replace extension path_parts[-1] = ( "%s.%s" % (name, store.filetype.extension)) return absolute_real_path(os.sep.join(path_parts))
def export_as_xliff(request, pootle_path): """export given file to xliff for offline translation""" if pootle_path[0] != '/': pootle_path = '/' + pootle_path store = get_object_or_404(Store, pootle_path=pootle_path) path, ext = os.path.splitext(store.real_path) export_path = os.path.join('POOTLE_EXPORT', path + os.path.extsep + 'xlf') abs_export_path = absolute_real_path(export_path) key = "%s:export_as_xliff" last_export = cache.get(key) if not (last_export and last_export == store.get_mtime() and os.path.isfile(abs_export_path)): ensure_target_dir_exists(abs_export_path) outputstore = store.convert(PoXliffFile) outputstore.switchfile(store.name, createifmissing=True) fd, tempstore = tempfile.mkstemp(prefix=store.name, suffix='.xlf') os.close(fd) outputstore.savefile(tempstore) shutil.move(tempstore, abs_export_path) cache.set(key, store.get_mtime(), settings.OBJECT_CACHE_TIMEOUT) return redirect('/export/' + export_path)
def export_as_xliff(request, store): """export given file to xliff for offline translation""" path, ext = os.path.splitext(store.real_path) export_path = os.path.join('POOTLE_EXPORT', path + os.path.extsep + 'xlf') abs_export_path = absolute_real_path(export_path) key = iri_to_uri("%s:export_as_xliff" % store.pootle_path) last_export = cache.get(key) if not (last_export and last_export == store.get_mtime() and os.path.isfile(abs_export_path)): from pootle_app.project_tree import ensure_target_dir_exists from translate.storage.poxliff import PoXliffFile import tempfile import shutil ensure_target_dir_exists(abs_export_path) outputstore = store.convert(PoXliffFile) outputstore.switchfile(store.name, createifmissing=True) fd, tempstore = tempfile.mkstemp(prefix=store.name, suffix='.xlf') os.close(fd) outputstore.savefile(tempstore) shutil.move(tempstore, abs_export_path) cache.set(key, store.get_mtime(), settings.OBJECT_CACHE_TIMEOUT) return redirect('/export/' + export_path)
def abs_real_path(self): return absolute_real_path(self.real_path)
def overview(request, translation_project, dir_path, filename=None, goal=None, in_goal_overview=False): if filename: ctx = { 'store_tags': request.store.tag_like_objects, } template_name = "translation_projects/store_overview.html" else: ctx = { 'tp_tags': translation_project.tag_like_objects, } template_name = "browser/overview.html" if (check_permission('translate', request) or check_permission('suggest', request) or check_permission('overwrite', request)): ctx.update({ 'upload_form': _handle_upload_form(request, translation_project), }) can_edit = check_permission('administrate', request) project = translation_project.project language = translation_project.language resource_obj = request.store or request.directory #TODO enable again some actions when drilling down a goal. if goal is None: actions = action_groups(request, resource_obj) else: actions = [] action_output = '' running = request.GET.get(EXTDIR, '') #TODO enable the following again when drilling down a goal. if running and goal is None: if request.store: act = StoreAction else: act = TranslationProjectAction try: action = act.lookup(running) except KeyError: messages.error(request, _("Unable to find '%(action)s' in '%(extdir)s'") % {'action': act, 'extdir': running}) else: if not getattr(action, 'nosync', False): (request.store or translation_project).sync() if action.is_active(request): vcs_dir = settings.VCS_DIRECTORY po_dir = settings.PODIRECTORY tp_dir = request.directory.get_real_path() store_fn = '*' if request.store: tp_dir_slash = add_trailing_slash(tp_dir) if request.store.file.name.startswith(tp_dir_slash): # Note: store_f used below in reverse() call. store_f = request.store.file.name[len(tp_dir_slash):] store_fn = store_f.replace('/', os.sep) # Clear possibly stale output/error (even from other # resource_obj). action.set_output('') action.set_error('') try: action.run(path=resource_obj, root=po_dir, tpdir=tp_dir, project=project.code, language=language.code, store=store_fn, style=translation_project.file_style, vc_root=vcs_dir) except StandardError: err = (_("Error while running '%s' extension action") % action.title) logging.exception(err) if (action.error): messages.error(request, action.error) else: messages.error(request, err) else: if (action.error): messages.warning(request, action.error) action_output = action.output if getattr(action, 'get_download', None): export_path = action.get_download(resource_obj) if export_path: import mimetypes abs_path = absolute_real_path(export_path) filename = os.path.basename(export_path) mimetype, encoding = mimetypes.guess_type(filename) mimetype = mimetype or 'application/octet-stream' with open(abs_path, 'rb') as f: response = HttpResponse(f.read(), mimetype=mimetype) response['Content-Disposition'] = ( 'attachment; filename="%s"' % filename) return response if not action_output: if not request.store: rev_args = [language.code, project.code, ''] overview_url = reverse('pootle-tp-overview', args=rev_args) else: slash = store_f.rfind('/') store_d = '' if slash > 0: store_d = store_f[:slash] store_f = store_f[slash + 1:] elif slash == 0: store_f = store_f[1:] rev_args = [language.code, project.code, store_d, store_f] overview_url = reverse('pootle-tp-overview', args=rev_args) return HttpResponseRedirect(overview_url) if goal is None: description = translation_project.description else: description = goal.description ctx.update(get_overview_context(request)) ctx.update({ 'resource_obj': request.store or request.directory, # Dirty hack. 'translation_project': translation_project, 'description': description, 'project': project, 'language': language, 'feed_path': request.directory.pootle_path[1:], 'action_groups': actions, 'action_output': action_output, 'can_edit': can_edit, 'browser_extends': 'translation_projects/base.html', 'browser_body_id': 'tpoverview', }) tp_pootle_path = translation_project.pootle_path if request.store is None: resource_obj_goals = Goal.get_goals_for_path(resource_obj.pootle_path) resource_obj_has_goals = len(resource_obj_goals) > 0 if in_goal_overview and resource_obj_has_goals: # Then show the goals tab. table_fields = ['name', 'progress', 'priority', 'total', 'need-translation', 'suggestions'] items = [make_goal_item(resource_obj_goal, resource_obj.pootle_path) for resource_obj_goal in resource_obj_goals] ctx.update({ 'table': { 'id': 'tp-goals', 'fields': table_fields, 'headings': get_table_headings(table_fields), 'parent': get_parent(request.directory), 'items': items, }, 'resource_obj_has_goals': True, }) elif goal in resource_obj_goals: # Then show the drill down view for the specified goal. table_fields = ['name', 'progress', 'total', 'need-translation', 'suggestions', 'critical', 'activity'] ctx.update({ 'table': { 'id': 'tp-goals', 'fields': table_fields, 'headings': get_table_headings(table_fields), 'parent': get_goal_parent(request.directory, goal), 'items': get_goal_children(request.directory, goal), }, 'goal': goal, 'goal_url': goal.get_drill_down_url_for_path(tp_pootle_path), 'resource_obj_has_goals': True, }) else: # Then show the files tab. table_fields = ['name', 'progress', 'total', 'need-translation', 'suggestions', 'critical', 'activity'] ctx.update({ 'table': { 'id': 'tp-files', 'fields': table_fields, 'headings': get_table_headings(table_fields), 'parent': get_parent(request.directory), 'items': get_children(request.directory), }, 'resource_obj_has_goals': resource_obj_has_goals, }) elif goal is not None: ctx.update({ 'goal': goal, 'goal_url': goal.get_drill_down_url_for_path(tp_pootle_path), }) if can_edit: if request.store is None: url_kwargs = { 'language_code': language.code, 'project_code': project.code, } add_tag_action_url = reverse('pootle-xhr-tag-tp', kwargs=url_kwargs) else: add_tag_action_url = reverse('pootle-xhr-tag-store', args=[resource_obj.pk]) if goal is None: edit_form = DescriptionForm(instance=translation_project) edit_form_action = reverse('pootle-tp-admin-settings', args=[language.code, project.code]) else: edit_form = GoalForm(instance=goal) edit_form_action = reverse('pootle-xhr-edit-goal', args=[goal.slug]) ctx.update({ 'form': edit_form, 'form_action': edit_form_action, 'add_tag_form': TagForm(), 'add_tag_action_url': add_tag_action_url, }) return render_to_response(template_name, ctx, context_instance=RequestContext(request))
def abs_real_path(self): if self.real_path is not None: return absolute_real_path(self.real_path)
def overview(request, translation_project, dir_path, filename=None, goal=None): from django.utils import dateformat from staticpages.models import StaticPage from pootle.scripts.actions import EXTDIR, StoreAction, TranslationProjectAction from .actions import action_groups if filename: ctx = { 'store_tags': request.store.tag_like_objects, } template_name = "translation_projects/store_overview.html" else: ctx = { 'tp_tags': translation_project.tag_like_objects, } template_name = "browser/overview.html" if (check_permission('translate', request) or check_permission('suggest', request) or check_permission('overwrite', request)): ctx.update({ 'upload_form': _handle_upload_form(request, translation_project), }) can_edit = check_permission('administrate', request) project = translation_project.project language = translation_project.language resource_obj = request.store or request.directory #TODO enable again some actions when drilling down a goal. if goal is None: actions = action_groups(request, resource_obj) else: actions = [] action_output = '' running = request.GET.get(EXTDIR, '') #TODO enable the following again when drilling down a goal. if running and goal is None: if request.store: act = StoreAction else: act = TranslationProjectAction try: action = act.lookup(running) except KeyError: messages.error(request, _("Unable to find '%(action)s' in '%(extdir)s'") % {'action': act, 'extdir': running}) else: if not getattr(action, 'nosync', False): (request.store or translation_project).sync() if action.is_active(request): vcs_dir = settings.VCS_DIRECTORY po_dir = settings.PODIRECTORY tp_dir = request.directory.get_real_path() store_fn = '*' if request.store: tp_dir_slash = add_trailing_slash(tp_dir) if request.store.file.name.startswith(tp_dir_slash): # Note: store_f used below in reverse() call. store_f = request.store.file.name[len(tp_dir_slash):] store_fn = store_f.replace('/', os.sep) # Clear possibly stale output/error (even from other # resource_obj). action.set_output('') action.set_error('') try: action.run(path=resource_obj, root=po_dir, tpdir=tp_dir, project=project.code, language=language.code, store=store_fn, style=translation_project.file_style, vc_root=vcs_dir) except StandardError: err = (_("Error while running '%s' extension action") % action.title) logging.exception(err) if (action.error): messages.error(request, action.error) else: messages.error(request, err) else: if (action.error): messages.warning(request, action.error) action_output = action.output if getattr(action, 'get_download', None): export_path = action.get_download(resource_obj) if export_path: import mimetypes abs_path = absolute_real_path(export_path) filename = os.path.basename(export_path) mimetype, encoding = mimetypes.guess_type(filename) mimetype = mimetype or 'application/octet-stream' with open(abs_path, 'rb') as f: response = HttpResponse(f.read(), mimetype=mimetype) response['Content-Disposition'] = ( 'attachment; filename="%s"' % filename) return response if not action_output: if not request.store: rev_args = [language.code, project.code, ''] overview_url = reverse('pootle-tp-overview', args=rev_args) else: slash = store_f.rfind('/') store_d = '' if slash > 0: store_d = store_f[:slash] store_f = store_f[slash + 1:] elif slash == 0: store_f = store_f[1:] rev_args = [language.code, project.code, store_d, store_f] overview_url = reverse('pootle-tp-overview', args=rev_args) return redirect(overview_url) # TODO: cleanup and refactor, retrieve from cache try: ann_virtual_path = 'announcements/' + project.code announcement = StaticPage.objects.live(request.user).get( virtual_path=ann_virtual_path, ) except StaticPage.DoesNotExist: announcement = None display_announcement = True stored_mtime = None new_mtime = None cookie_data = {} if ANN_COOKIE_NAME in request.COOKIES: json_str = unquote(request.COOKIES[ANN_COOKIE_NAME]) cookie_data = json.loads(json_str) if 'isOpen' in cookie_data: display_announcement = cookie_data['isOpen'] if project.code in cookie_data: stored_mtime = cookie_data[project.code] if announcement is not None: ann_mtime = dateformat.format(announcement.modified_on, 'U') if ann_mtime != stored_mtime: display_announcement = True new_mtime = ann_mtime tp_goals = translation_project.all_goals ctx.update(get_overview_context(request)) ctx.update({ 'resource_obj': request.store or request.directory, # Dirty hack. 'translation_project': translation_project, 'description': translation_project.description, 'project': project, 'language': language, 'tp_goals': tp_goals, 'goal': goal, 'feed_path': request.directory.pootle_path[1:], 'action_groups': actions, 'action_output': action_output, 'can_edit': can_edit, 'browser_extends': 'translation_projects/base.html', 'announcement': announcement, 'announcement_displayed': display_announcement, }) tp_pootle_path = translation_project.pootle_path if request.store is None: table_fields = ['name', 'progress', 'total', 'need-translation', 'suggestions', 'critical', 'last-updated', 'activity'] if goal is not None: # Then show the drill down view for the specified goal. ctx.update({ 'table': { 'id': 'tp-goals', 'fields': table_fields, 'headings': get_table_headings(table_fields), 'parent': get_goal_parent(request.directory, goal), 'items': get_goal_children(request.directory, goal), }, }) else: # Then show the files tab. ctx.update({ 'table': { 'id': 'tp-files', 'fields': table_fields, 'headings': get_table_headings(table_fields), 'parent': get_parent(request.directory), 'items': get_children(request.directory), }, }) if can_edit: if request.store is None: add_tag_action_url = reverse('pootle-xhr-tag-tp', args=[language.code, project.code]) else: add_tag_action_url = reverse('pootle-xhr-tag-store', args=[resource_obj.pk]) ctx.update({ 'form': DescriptionForm(instance=translation_project), 'form_action': reverse('pootle-tp-admin-settings', args=[language.code, project.code]), 'add_tag_form': TagForm(), 'add_tag_action_url': add_tag_action_url, }) if goal is not None: ctx.update({ 'goal_form': GoalForm(instance=goal), 'goal_form_action': reverse('pootle-xhr-edit-goal', args=[goal.slug]), }) response = render(request, template_name, ctx) if new_mtime is not None: cookie_data[project.code] = new_mtime cookie_data = quote(json.dumps(cookie_data)) response.set_cookie(ANN_COOKIE_NAME, cookie_data) return response
def get_real_path(self): return absolute_real_path(self.code)
def overview(request, translation_project, dir_path, filename=None, goal=None, in_goal_overview=False): if filename: ctx = {"store_tags": request.store.tag_like_objects} template_name = "translation_projects/store_overview.html" else: ctx = {"tp_tags": translation_project.tag_like_objects} template_name = "browser/overview.html" if ( check_permission("translate", request) or check_permission("suggest", request) or check_permission("overwrite", request) ): ctx.update({"upload_form": _handle_upload_form(request, translation_project)}) can_edit = check_permission("administrate", request) project = translation_project.project language = translation_project.language resource_obj = request.store or request.directory # TODO enable again some actions when drilling down a goal. if goal is None: actions = action_groups(request, resource_obj) else: actions = [] action_output = "" running = request.GET.get(EXTDIR, "") # TODO enable the following again when drilling down a goal. if running and goal is None: if request.store: act = StoreAction else: act = TranslationProjectAction try: action = act.lookup(running) except KeyError: messages.error( request, _("Unable to find '%(action)s' in '%(extdir)s'") % {"action": act, "extdir": running} ) else: if not getattr(action, "nosync", False): (request.store or translation_project).sync() if action.is_active(request): vcs_dir = settings.VCS_DIRECTORY po_dir = settings.PODIRECTORY tp_dir = request.directory.get_real_path() store_fn = "*" if request.store: tp_dir_slash = add_trailing_slash(tp_dir) if request.store.file.name.startswith(tp_dir_slash): # Note: store_f used below in reverse() call. store_f = request.store.file.name[len(tp_dir_slash) :] store_fn = store_f.replace("/", os.sep) # Clear possibly stale output/error (even from other # resource_obj). action.set_output("") action.set_error("") try: action.run( path=resource_obj, root=po_dir, tpdir=tp_dir, project=project.code, language=language.code, store=store_fn, style=translation_project.file_style, vc_root=vcs_dir, ) except StandardError: err = _("Error while running '%s' extension action") % action.title logging.exception(err) if action.error: messages.error(request, action.error) else: messages.error(request, err) else: if action.error: messages.warning(request, action.error) action_output = action.output if getattr(action, "get_download", None): export_path = action.get_download(resource_obj) if export_path: import mimetypes abs_path = absolute_real_path(export_path) filename = os.path.basename(export_path) mimetype, encoding = mimetypes.guess_type(filename) mimetype = mimetype or "application/octet-stream" with open(abs_path, "rb") as f: response = HttpResponse(f.read(), mimetype=mimetype) response["Content-Disposition"] = 'attachment; filename="%s"' % filename return response if not action_output: if not request.store: rev_args = [language.code, project.code, ""] overview_url = reverse("pootle-tp-overview", args=rev_args) else: slash = store_f.rfind("/") store_d = "" if slash > 0: store_d = store_f[:slash] store_f = store_f[slash + 1 :] elif slash == 0: store_f = store_f[1:] rev_args = [language.code, project.code, store_d, store_f] overview_url = reverse("pootle-tp-overview", args=rev_args) return HttpResponseRedirect(overview_url) if goal is None: description = translation_project.description else: description = goal.description ctx.update(get_overview_context(request)) ctx.update( { "resource_obj": request.store or request.directory, # Dirty hack. "translation_project": translation_project, "description": description, "project": project, "language": language, "feed_path": request.directory.pootle_path[1:], "action_groups": actions, "action_output": action_output, "can_edit": can_edit, "browser_extends": "translation_projects/base.html", "browser_body_id": "tpoverview", } ) tp_pootle_path = translation_project.pootle_path if request.store is None: resource_obj_goals = Goal.get_goals_for_path(resource_obj.pootle_path) resource_obj_has_goals = len(resource_obj_goals) > 0 if in_goal_overview and resource_obj_has_goals: # Then show the goals tab. table_fields = ["name", "progress", "priority", "total", "need-translation", "suggestions"] items = [ make_goal_item(resource_obj_goal, resource_obj.pootle_path) for resource_obj_goal in resource_obj_goals ] ctx.update( { "table": { "id": "tp-goals", "fields": table_fields, "headings": get_table_headings(table_fields), "parent": get_parent(request.directory), "items": items, }, "resource_obj_has_goals": True, } ) elif goal in resource_obj_goals: # Then show the drill down view for the specified goal. table_fields = ["name", "progress", "total", "need-translation", "suggestions", "critical", "activity"] ctx.update( { "table": { "id": "tp-goals", "fields": table_fields, "headings": get_table_headings(table_fields), "parent": get_goal_parent(request.directory, goal), "items": get_goal_children(request.directory, goal), }, "goal": goal, "goal_url": goal.get_drill_down_url_for_path(tp_pootle_path), "resource_obj_has_goals": True, } ) else: # Then show the files tab. table_fields = ["name", "progress", "total", "need-translation", "suggestions", "critical", "activity"] ctx.update( { "table": { "id": "tp-files", "fields": table_fields, "headings": get_table_headings(table_fields), "parent": get_parent(request.directory), "items": get_children(request.directory), }, "resource_obj_has_goals": resource_obj_has_goals, } ) elif goal is not None: ctx.update({"goal": goal, "goal_url": goal.get_drill_down_url_for_path(tp_pootle_path)}) if can_edit: if request.store is None: url_kwargs = {"language_code": language.code, "project_code": project.code} add_tag_action_url = reverse("pootle-xhr-tag-tp", kwargs=url_kwargs) else: add_tag_action_url = reverse("pootle-xhr-tag-store", args=[resource_obj.pk]) if goal is None: edit_form = DescriptionForm(instance=translation_project) edit_form_action = reverse("pootle-tp-admin-settings", args=[language.code, project.code]) else: edit_form = GoalForm(instance=goal) edit_form_action = reverse("pootle-xhr-edit-goal", args=[goal.slug]) ctx.update( { "form": edit_form, "form_action": edit_form_action, "add_tag_form": TagForm(), "add_tag_action_url": add_tag_action_url, } ) return render_to_response(template_name, ctx, context_instance=RequestContext(request))
def overview(request, translation_project, dir_path, filename=None, goal=None): from django.utils import dateformat from staticpages.models import StaticPage from pootle.scripts.actions import EXTDIR, StoreAction, TranslationProjectAction from .actions import action_groups if filename: ctx = { 'store_tags': request.store.tag_like_objects, } template_name = "translation_projects/store_overview.html" else: ctx = { 'tp_tags': translation_project.tag_like_objects, } template_name = "browser/overview.html" if (check_permission('translate', request) or check_permission('suggest', request) or check_permission('overwrite', request)): ctx.update({ 'upload_form': _handle_upload_form(request, translation_project), }) can_edit = check_permission('administrate', request) project = translation_project.project language = translation_project.language resource_obj = request.store or request.directory #TODO enable again some actions when drilling down a goal. if goal is None: actions = action_groups(request, resource_obj) else: actions = [] action_output = '' running = request.GET.get(EXTDIR, '') #TODO enable the following again when drilling down a goal. if running and goal is None: if request.store: act = StoreAction else: act = TranslationProjectAction try: action = act.lookup(running) except KeyError: messages.error( request, _("Unable to find '%(action)s' in '%(extdir)s'") % { 'action': act, 'extdir': running }) else: if not getattr(action, 'nosync', False): (request.store or translation_project).sync() if action.is_active(request): vcs_dir = settings.VCS_DIRECTORY po_dir = settings.PODIRECTORY tp_dir = request.directory.get_real_path() store_fn = '*' if request.store: tp_dir_slash = add_trailing_slash(tp_dir) if request.store.file.name.startswith(tp_dir_slash): # Note: store_f used below in reverse() call. store_f = request.store.file.name[len(tp_dir_slash):] store_fn = store_f.replace('/', os.sep) # Clear possibly stale output/error (even from other # resource_obj). action.set_output('') action.set_error('') try: action.run(path=resource_obj, root=po_dir, tpdir=tp_dir, project=project.code, language=language.code, store=store_fn, style=translation_project.file_style, vc_root=vcs_dir) except StandardError: err = (_("Error while running '%s' extension action") % action.title) logging.exception(err) if (action.error): messages.error(request, action.error) else: messages.error(request, err) else: if (action.error): messages.warning(request, action.error) action_output = action.output if getattr(action, 'get_download', None): export_path = action.get_download(resource_obj) if export_path: import mimetypes abs_path = absolute_real_path(export_path) filename = os.path.basename(export_path) mimetype, encoding = mimetypes.guess_type(filename) mimetype = mimetype or 'application/octet-stream' with open(abs_path, 'rb') as f: response = HttpResponse(f.read(), mimetype=mimetype) response['Content-Disposition'] = ( 'attachment; filename="%s"' % filename) return response if not action_output: if not request.store: rev_args = [language.code, project.code, ''] overview_url = reverse('pootle-tp-overview', args=rev_args) else: slash = store_f.rfind('/') store_d = '' if slash > 0: store_d = store_f[:slash] store_f = store_f[slash + 1:] elif slash == 0: store_f = store_f[1:] rev_args = [ language.code, project.code, store_d, store_f ] overview_url = reverse('pootle-tp-overview', args=rev_args) return redirect(overview_url) # TODO: cleanup and refactor, retrieve from cache try: ann_virtual_path = 'announcements/' + project.code announcement = StaticPage.objects.live(request.user).get( virtual_path=ann_virtual_path, ) except StaticPage.DoesNotExist: announcement = None display_announcement = True stored_mtime = None new_mtime = None cookie_data = {} if ANN_COOKIE_NAME in request.COOKIES: json_str = unquote(request.COOKIES[ANN_COOKIE_NAME]) cookie_data = json.loads(json_str) if 'isOpen' in cookie_data: display_announcement = cookie_data['isOpen'] if project.code in cookie_data: stored_mtime = cookie_data[project.code] if announcement is not None: ann_mtime = dateformat.format(announcement.modified_on, 'U') if ann_mtime != stored_mtime: display_announcement = True new_mtime = ann_mtime tp_goals = translation_project.all_goals ctx.update(get_overview_context(request)) ctx.update({ 'resource_obj': request.store or request.directory, # Dirty hack. 'translation_project': translation_project, 'description': translation_project.description, 'project': project, 'language': language, 'tp_goals': tp_goals, 'goal': goal, 'feed_path': request.directory.pootle_path[1:], 'action_groups': actions, 'action_output': action_output, 'can_edit': can_edit, 'browser_extends': 'translation_projects/base.html', 'announcement': announcement, 'announcement_displayed': display_announcement, }) tp_pootle_path = translation_project.pootle_path if request.store is None: table_fields = [ 'name', 'progress', 'total', 'need-translation', 'suggestions', 'critical', 'last-updated', 'activity' ] if goal is not None: # Then show the drill down view for the specified goal. ctx.update({ 'table': { 'id': 'tp-goals', 'fields': table_fields, 'headings': get_table_headings(table_fields), 'parent': get_goal_parent(request.directory, goal), 'items': get_goal_children(request.directory, goal), }, }) else: # Then show the files tab. ctx.update({ 'table': { 'id': 'tp-files', 'fields': table_fields, 'headings': get_table_headings(table_fields), 'parent': get_parent(request.directory), 'items': get_children(request.directory), }, }) if can_edit: if request.store is None: add_tag_action_url = reverse('pootle-xhr-tag-tp', args=[language.code, project.code]) else: add_tag_action_url = reverse('pootle-xhr-tag-store', args=[resource_obj.pk]) ctx.update({ 'form': DescriptionForm(instance=translation_project), 'form_action': reverse('pootle-tp-admin-settings', args=[language.code, project.code]), 'add_tag_form': TagForm(), 'add_tag_action_url': add_tag_action_url, }) if goal is not None: ctx.update({ 'goal_form': GoalForm(instance=goal), 'goal_form_action': reverse('pootle-xhr-edit-goal', args=[goal.slug]), }) response = render(request, template_name, ctx) if new_mtime is not None: cookie_data[project.code] = new_mtime cookie_data = quote(json.dumps(cookie_data)) response.set_cookie(ANN_COOKIE_NAME, cookie_data) return response