コード例 #1
0
    def download_link(self, formatter, ns, target, label):
        if ns == 'download':
            if 'FILES_DOWNLOADS_VIEW' not in formatter.req.perm:
                return html.a(label,
                              href='#',
                              title=_('Missing %(permission)s permission',
                                      permission='FILES_DOWNLOADS_VIEW'),
                              class_='missing')
            files_core = FilesCoreComponent(self.env)
            wiki = ProjectDownloadsWiki(self.env)
            node_factory, download_config = files_core.files_node_factory_and_config(
                formatter.req)
            id_, filename = self._get_id_filename(target)
            if id_ and filename:
                primary_path = get_download_path(id_, filename)
                node = MappedFileNode.from_download_path(
                    primary_path, node_factory, True)
                if node.exists() and node.is_download():
                    return wiki.file_link(formatter, 'filesdownload',
                                          node.download().download_path, label)

                node = MappedFileNode.from_download_path(
                    filename, node_factory, True)
                if node.exists() and node.is_download():
                    return wiki.file_link(formatter, 'filesdownload',
                                          node.download().download_path, label)
            return wiki.file_link(formatter, 'filesdownload', target, label)
コード例 #2
0
    def process_request(self, req):
        req.perm.require('FILES_DOWNLOADS_VIEW')
        file_identifier = req.path_info[11:]  # 11 == len('/downloads/')
        id_, filename = self._get_id_filename(file_identifier)
        if not id_ or not filename:
            add_warning(
                req,
                _("The download for url url %(url)s was not found.",
                  url='/downloads/{0}'.format(file_identifier)))
        else:
            files_core = FilesCoreComponent(self.env)
            node_factory, download_config = files_core.files_node_factory_and_config(
                req)
            primary_path = get_download_path(id_, filename)
            node = MappedFileNode.from_download_path(primary_path,
                                                     node_factory, True)
            if node.exists() and node.is_download():
                req.redirect(req.href.files(node.relative_path))

            node = MappedFileNode.from_download_path(filename, node_factory,
                                                     True)
            if node.exists() and node.is_download():
                req.redirect(req.href.files(node.relative_path))

            add_warning(
                req,
                _(
                    "The old-style download link seems to be broken. "
                    "Checked from %(primary_path)s and %(filename)s",
                    primary_path=primary_path,
                    filename=filename))
        req.redirect(req.href.files({'redirect': 'downloads'}))
コード例 #3
0
    def target_node(self):
        if self._target_node is not None:
            return self._target_node
        env_name = self.environment_identifier()
        if not env_name:
            conf.log.warning("Failed reading identifier")
            raise NodeError('Target node was invalid: env_name not found')
        project = Project.get(env_name=env_name)
        # env_name might be different from project.env_name!
        base_url = project.get_dav_url(relative=True)
        path_info = normalized_base_url(self.req.uri)
        project_id = project.id
        download_config = FilesDownloadConfig(project.env_name, base_url=base_url)
        if not path_info.startswith(download_config.base_url):
            raise NodeError('Target node was invalid: uri %s does not start with %s',
                path_info, base_url)
        self._download_config = download_config
        try:
            node_factory = MappedFileNode(project_id,
                download_config.base_path, download_config.base_url, download_config.downloads_dir)
            self._target_node = MappedFileNode.from_request_path_info(path_info, node_factory)
        except Exception as e:
            conf.log.warning("Not node %s", str(e))
            raise NodeError('Target node was invalid: %s', str(e))

        return self._target_node
コード例 #4
0
    def file_link(self, formatter, ns, target, label):
        req = formatter.req

        if ns != 'file' and ns != 'download' and ns != 'filesdownload':
            return

        files_core = FilesCoreComponent(self.env)
        node_factory, download_config = files_core.files_node_factory_and_config(req)
        try:
            if ns == 'file':
                node = MappedFileNode.from_path(target, node_factory, True)
            else:
                node = MappedFileNode.from_download_path(target, node_factory, True)
            missing_perm = None
            if node.is_download():
                if 'FILES_DOWNLOADS_VIEW' not in req.perm:
                    missing_perm = 'FILES_DOWNLOADS_VIEW'
            elif 'FILES_VIEW' not in req.perm:
                missing_perm = 'FILES_VIEW'
            if missing_perm:
                return html.a(label, href='#',
                    title = _('Missing %(permission)s permission', permission=missing_perm),
                        class_ = 'missing')
            if node.exists():
                if node.is_file():
                    if node.is_download():
                        if not node.download().is_available():
                            return html.a(label, href='#',
                                title = _('Download information not available for %(path)s',
                                    path=node.relative_path),
                                class_ = 'missing')
                        else:
                            return html.a(label, href=node.get_url(req),
                                title = _('Download %(name)s (%(size)s)',name=node.filename,
                                    size= pretty_size(node.size)))
                    else:
                        return html.a(label, href=node.get_url(req),
                            title = _('File %(name)s',name=node.filename))
                elif node.is_dir():
                    return html.a(label, href=node.get_url(req),
                        title = _('Folder %(name)s',name=node.filename))
            else:
                return html.a(label, href='#',
                    title = _('Not existing file: %(path)s', path=node.relative_path),
                    class_ = 'missing')
        except TracError:
            # File doesn't exist
            return html.a(label, href='#',
                title=_('Invalid target for %(ns)s: %(path)s',ns=ns, path=target),
                class_='missing')
コード例 #5
0
    def process_update(self, node, node_factory, req, timeline_notifier, user):
        open_in_mode_mode = ''
        filename = None
        selected_files = self._get_selected_files(req, node, True)

        # Updating the meta-info can currently be done only for one file at a time
        if len(selected_files) == 1:
            filename = selected_files[0]
            relative_path = os.path.join(node.relative_path, filename)

            target_node = MappedFileNode.from_path(relative_path, node_factory,
                assume_relative_path=True)
            from_dir = os.path.dirname(target_node.relative_path)
            moved_node = None

            # If the filename was changed, we have to do the move_by_request
            if req.args.get('to_relative_path', filename) != filename:

                try:
                    moved_node = target_node.move_by_request(req, user.id,
                        timeline_notifier,
                        destination_is_dir=False, update_also=True)
                except TracError as e:
                    add_warning(req, _("Could not move file or folder %(filename)s: ",
                        filename=target_node.filename) + str(e))

                # If the moving was successful, add a proper notice
                if moved_node:
                    target_node = moved_node
                    self.log.debug("update target_node %s", target_node)
                    destination = target_node.get_parent_dir()
                    destination_link = tag.a(target_node.filename,
                        href=destination.get_href(req))
                    sentence = _("Renamed and updated file %(filename)s successfully to ",
                        filename=selected_files[0])
                    add_notice(req, tag(sentence, destination_link))
                    if from_dir == os.path.dirname(target_node.relative_path):
                        open_in_mode_mode = 'show_mode'
                        filename = target_node.filename

            # If the filename was not changed, just updating the file info is enough
            else:
                try:
                    target_node.update_metadata_from_request(req, user.id)
                    open_in_mode_mode = 'show_mode'
                    filename = target_node.filename
                    add_notice(req, _("Updated file %(filename)s download information.",
                        filename=filename))
                except TracError as e:
                    self.log.exception("foobar")
                    add_warning(req, _("Could not save the downloads information for file."))
        return filename, open_in_mode_mode
コード例 #6
0
    def process_request(self, req):
        req.perm.require('FILES_DOWNLOADS_VIEW')
        file_identifier = req.path_info[11:] # 11 == len('/downloads/')
        id_, filename = self._get_id_filename(file_identifier)
        if not id_ or not filename:
            add_warning(req, _("The download for url url %(url)s was not found.",
                url='/downloads/{0}'.format(file_identifier)))
        else:
            files_core = FilesCoreComponent(self.env)
            node_factory, download_config = files_core.files_node_factory_and_config(req)
            primary_path = get_download_path(id_, filename)
            node = MappedFileNode.from_download_path(primary_path, node_factory, True)
            if node.exists() and node.is_download():
                req.redirect(req.href.files(node.relative_path))

            node = MappedFileNode.from_download_path(filename, node_factory, True)
            if node.exists() and node.is_download():
                req.redirect(req.href.files(node.relative_path))

            add_warning(req, _("The old-style download link seems to be broken. "
                               "Checked from %(primary_path)s and %(filename)s",
                                primary_path=primary_path, filename=filename))
        req.redirect(req.href.files({'redirect': 'downloads'}))
コード例 #7
0
    def download_link(self, formatter, ns, target, label):
        if ns == 'download':
            if 'FILES_DOWNLOADS_VIEW' not in formatter.req.perm:
                return html.a(label, href='#',
                    title = _('Missing %(permission)s permission',
                                permission='FILES_DOWNLOADS_VIEW'),
                        class_ = 'missing')
            files_core = FilesCoreComponent(self.env)
            wiki = ProjectDownloadsWiki(self.env)
            node_factory, download_config = files_core.files_node_factory_and_config(formatter.req)
            id_, filename = self._get_id_filename(target)
            if id_ and filename:
                primary_path = get_download_path(id_, filename)
                node = MappedFileNode.from_download_path(primary_path, node_factory, True)
                if node.exists() and node.is_download():
                    return wiki.file_link(formatter, 'filesdownload',
                        node.download().download_path, label)

                node = MappedFileNode.from_download_path(filename, node_factory, True)
                if node.exists() and node.is_download():
                    return wiki.file_link(formatter, 'filesdownload',
                        node.download().download_path, label)
            return wiki.file_link(formatter, 'filesdownload', target, label)
コード例 #8
0
ファイル: files.py プロジェクト: nagyistoce/trac-multiproject
    def process_update(self, node, node_factory, req, timeline_notifier, user):
        open_in_mode_mode = ""
        filename = None
        selected_files = self._get_selected_files(req, node, True)

        # Updating the meta-info can currently be done only for one file at a time
        if len(selected_files) == 1:
            filename = selected_files[0]
            relative_path = os.path.join(node.relative_path, filename)

            target_node = MappedFileNode.from_path(relative_path, node_factory, assume_relative_path=True)
            from_dir = os.path.dirname(target_node.relative_path)
            moved_node = None

            # If the filename was changed, we have to do the move_by_request
            if req.args.get("to_relative_path", filename) != filename:

                try:
                    moved_node = target_node.move_by_request(
                        req, user.id, timeline_notifier, destination_is_dir=False, update_also=True
                    )
                except TracError as e:
                    add_warning(
                        req, _("Could not move file or folder %(filename)s: ", filename=target_node.filename) + str(e)
                    )

                # If the moving was successful, add a proper notice
                if moved_node:
                    target_node = moved_node
                    self.log.debug("update target_node %s", target_node)
                    destination = target_node.get_parent_dir()
                    destination_link = tag.a(target_node.filename, href=destination.get_href(req))
                    sentence = _("Renamed and updated file %(filename)s successfully to ", filename=selected_files[0])
                    add_notice(req, tag(sentence, destination_link))
                    if from_dir == os.path.dirname(target_node.relative_path):
                        open_in_mode_mode = "show_mode"
                        filename = target_node.filename

            # If the filename was not changed, just updating the file info is enough
            else:
                try:
                    target_node.update_metadata_from_request(req, user.id)
                    open_in_mode_mode = "show_mode"
                    filename = target_node.filename
                    add_notice(req, _("Updated file %(filename)s download information.", filename=filename))
                except TracError as e:
                    self.log.exception("foobar")
                    add_warning(req, _("Could not save the downloads information for file."))
        return filename, open_in_mode_mode
コード例 #9
0
    def destination_node(self):
        if self._destination_node is not None:
            return self._destination_node

        # If req is a sub-request, req.main is the main request.
        destination = self._get_header('Destination')

        if destination:
            # Parse path from url
            try:
                encoded_destination = normalized_base_url(destination)
                destination = urllib.unquote(encoded_destination).decode('UTF-8')
                self._destination_node = MappedFileNode.from_request_path_info(destination,
                    self.target_node)
            except Exception as e:
                raise NodeError('Destination node was invalid: %s'%str(e))

        return self._destination_node
コード例 #10
0
ファイル: files.py プロジェクト: nagyistoce/trac-multiproject
 def process_delete(self, action, node, node_factory, req, timeline_notifier):
     selected_files = self._get_selected_files(req, node, action == "delete")
     successful_files = 0
     target_node = None
     for filename in selected_files:
         relative_path = os.path.join(node.relative_path, filename)
         removed_node = MappedFileNode.from_path(relative_path, node_factory, assume_relative_path=True)
         try:
             removed_node.remove_by_request(req, timeline_notifier)
             successful_files += 1
         except TracError as e:
             add_warning(req, _("Could not remove file or folder %(filename)s: ", filename=filename) + str(e))
     if len(selected_files) == 1 and successful_files == 1:
         add_notice(req, _("Removed file %(filename)s successfully", filename=selected_files[0]))
     elif successful_files and successful_files == len(selected_files):
         add_notice(req, _("Removed files successfully"))
     elif successful_files:
         add_notice(req, _("Removed other files successfully"))
コード例 #11
0
 def process_move(self, action, node, node_factory, req, timeline_notifier, user):
     is_rename = action == 'rename'
     selected_files = self._get_selected_files(req, node, is_rename)
     successful_files = 0
     target_node = None
     for filename in selected_files:
         relative_path = os.path.join(node.relative_path, filename)
         target_node = MappedFileNode.from_path(relative_path, node_factory,
             assume_relative_path=True)
         try:
             moved_node = target_node.move_by_request(req, user.id,
                 timeline_notifier, destination_is_dir=not is_rename,
                 update_also=is_rename)
             target_node = moved_node
             successful_files += 1
         except TracError as e:
             add_warning(req, _("Could not move file or folder %(filename)s: ",
                 filename=target_node.filename) + str(e))
     destination_link = None
     if target_node:
         destination = target_node.get_parent_dir()
         if is_rename:
             filename = target_node.filename
         else:
             filename = destination.relative_path == '.' and _('Home')\
             or destination.filename
         destination_link = tag.a(filename, href=destination.get_href(req))
     if successful_files and successful_files == len(selected_files):
         if successful_files == 1:
             if is_rename:
                 sentence = _("Renamed file %(filename)s successfully to ",
                     filename=selected_files[0])
             else:
                 sentence = _("Moved file %(filename)s successfully to location ",
                     filename=selected_files[0])
             add_notice(req,
                 tag(sentence, destination_link))
         else:
             # Batch rename not implemented
             add_notice(req,
                 tag(_("Moved files successfully to location "), destination_link))
     elif successful_files:
         add_notice(req, tag(_("Moved other files successfully to location "),
             destination_link))
コード例 #12
0
ファイル: admin.py プロジェクト: nagyistoce/trac-multiproject
    def _handle_change(self, command, downloads_dir_name, can_be_moved):
        try:
            env_name = self.env.project_identifier
        except AttributeError as e:
            # In case of trac admin commands, project_identifier is not found
            env_name = self.env.path.split('/')[-1]
            self.env.project_identifier = env_name

        download_config = FilesDownloadConfig(env_name)
        if downloads_dir_name is None:
            files_core = FilesCoreComponent(self.env)
            downloads_dir_name = files_core.default_downloads_directory
        node_factory = FileSystemNode(download_config.base_path)

        old_node, old_dir_exists = self.get_dir_data(download_config,
                                                     node_factory)

        if command == 'downloads-dir-create':
            if old_dir_exists:
                raise AdminCommandError(
                    _('Project already has existing downloads directory'))
            node = FileSystemNode.from_path(downloads_dir_name, node_factory)
            if node.exists():
                raise AdminCommandError(
                    _('The given downloads directory already exists'))

        msg_handler = lambda msg: printout(msg)

        try:
            self.handle_change(download_config, downloads_dir_name,
                               can_be_moved, node_factory, msg_handler,
                               msg_handler)
        except TracError as e:
            raise AdminCommandError(str(e))
        if command == 'downloads-dir-create':
            files_core = FilesCoreComponent(self.env)
            mapped_node_factory, mapped_download_config = files_core.files_node_factory_and_config(
            )
            created_node = MappedFileNode.from_path(
                download_config.downloads_dir, mapped_node_factory)
            files_notifier = FilesEventNotifier(self.env)
            files_notifier.node_created('trac', created_node)
コード例 #13
0
 def process_delete(self, action, node, node_factory, req, timeline_notifier):
     selected_files = self._get_selected_files(req, node, action == 'delete')
     successful_files = 0
     target_node = None
     for filename in selected_files:
         relative_path = os.path.join(node.relative_path, filename)
         removed_node = MappedFileNode.from_path(relative_path, node_factory,
             assume_relative_path=True)
         try:
             removed_node.remove_by_request(req, timeline_notifier)
             successful_files += 1
         except TracError as e:
             add_warning(req, _("Could not remove file or folder %(filename)s: ",
                 filename=filename) + str(e))
     if len(selected_files) == 1 and successful_files == 1:
         add_notice(req, _("Removed file %(filename)s successfully",
             filename=selected_files[0]))
     elif successful_files and successful_files == len(selected_files):
         add_notice(req, _("Removed files successfully"))
     elif successful_files:
         add_notice(req, _("Removed other files successfully"))
コード例 #14
0
ファイル: core.py プロジェクト: nagyistoce/trac-multiproject
 def files_node_factory_and_config(self, req=None, context_name='files'):
     """
     :param req: Request object
     :param str context_name: either 'files' or 'webdav'
     :return:
     """
     ctx = None
     ctx_key = 'files.node_factory.' + context_name
     if req:
         ctx = get_context(req)
         try:
             return ctx[ctx_key], self.files_download_config(context_name, req=req)
         except KeyError:
             pass
     download_config = self.files_download_config(context_name=context_name, req=req)
     project = Project.get(self.env)
     project_id = project.id
     node_factory = MappedFileNode(project_id,
         download_config.base_path, download_config.base_url, download_config.downloads_dir)
     if ctx:
         ctx[ctx_key] = node_factory
     return node_factory, download_config
コード例 #15
0
ファイル: files.py プロジェクト: nagyistoce/trac-multiproject
 def process_move(self, action, node, node_factory, req, timeline_notifier, user):
     is_rename = action == "rename"
     selected_files = self._get_selected_files(req, node, is_rename)
     successful_files = 0
     target_node = None
     for filename in selected_files:
         relative_path = os.path.join(node.relative_path, filename)
         target_node = MappedFileNode.from_path(relative_path, node_factory, assume_relative_path=True)
         try:
             moved_node = target_node.move_by_request(
                 req, user.id, timeline_notifier, destination_is_dir=not is_rename, update_also=is_rename
             )
             target_node = moved_node
             successful_files += 1
         except TracError as e:
             add_warning(
                 req, _("Could not move file or folder %(filename)s: ", filename=target_node.filename) + str(e)
             )
     destination_link = None
     if target_node:
         destination = target_node.get_parent_dir()
         if is_rename:
             filename = target_node.filename
         else:
             filename = destination.relative_path == "." and _("Home") or destination.filename
         destination_link = tag.a(filename, href=destination.get_href(req))
     if successful_files and successful_files == len(selected_files):
         if successful_files == 1:
             if is_rename:
                 sentence = _("Renamed file %(filename)s successfully to ", filename=selected_files[0])
             else:
                 sentence = _("Moved file %(filename)s successfully to location ", filename=selected_files[0])
             add_notice(req, tag(sentence, destination_link))
         else:
             # Batch rename not implemented
             add_notice(req, tag(_("Moved files successfully to location "), destination_link))
     elif successful_files:
         add_notice(req, tag(_("Moved other files successfully to location "), destination_link))
コード例 #16
0
ファイル: admin.py プロジェクト: nagyistoce/trac-multiproject
    def _handle_change(self, command, downloads_dir_name, can_be_moved):
        try:
            env_name = self.env.project_identifier
        except AttributeError as e:
            # In case of trac admin commands, project_identifier is not found
            env_name = self.env.path.split("/")[-1]
            self.env.project_identifier = env_name

        download_config = FilesDownloadConfig(env_name)
        if downloads_dir_name is None:
            files_core = FilesCoreComponent(self.env)
            downloads_dir_name = files_core.default_downloads_directory
        node_factory = FileSystemNode(download_config.base_path)

        old_node, old_dir_exists = self.get_dir_data(download_config, node_factory)

        if command == "downloads-dir-create":
            if old_dir_exists:
                raise AdminCommandError(_("Project already has existing downloads directory"))
            node = FileSystemNode.from_path(downloads_dir_name, node_factory)
            if node.exists():
                raise AdminCommandError(_("The given downloads directory already exists"))

        msg_handler = lambda msg: printout(msg)

        try:
            self.handle_change(
                download_config, downloads_dir_name, can_be_moved, node_factory, msg_handler, msg_handler
            )
        except TracError as e:
            raise AdminCommandError(str(e))
        if command == "downloads-dir-create":
            files_core = FilesCoreComponent(self.env)
            mapped_node_factory, mapped_download_config = files_core.files_node_factory_and_config()
            created_node = MappedFileNode.from_path(download_config.downloads_dir, mapped_node_factory)
            files_notifier = FilesEventNotifier(self.env)
            files_notifier.node_created("trac", created_node)
コード例 #17
0
    def import_files(self, dry_run=False):
        dry_run = True if dry_run in ['-n', '--dry-run'] else False
        try:
            env_name = self.env.project_identifier
        except AttributeError:
            # Since open_environment is not used in trac-admin commands
            # we need to manually set the project_identifier
            env_name = self.env.path.split('/')[-1]
            self.env.project_identifier = env_name
        download_data_list = self.get_download_data()
        path = conf.getEnvironmentDownloadsPath(self.env)
        if download_data_list is None:
            printout("env:%(env_name)s, download table was not found" %
                     {'env_name': self.env.project_identifier})
            return
        files_core = FilesCoreComponent(self.env)
        node_factory, download_config = files_core.files_node_factory_and_config(
        )
        env_name = download_config.env_name

        project_files = {}
        first_file = {}
        for download_data in download_data_list:
            filename = download_data['file']
            id_ = download_data['id']
            if filename not in project_files:
                project_files[filename] = []
                first_file[filename] = id_
            project_files[filename].append(id_)

        for download_data in download_data_list:
            filename = download_data['file']
            id_ = download_data['id']
            if not download_data['author_id']:
                printout(
                    "env:%(env_name)s file:%(download)s id:%(id_)s: "
                    "The author %(author)s of download %(download)s was not found."
                    % {
                        'env_name': env_name,
                        'download': filename,
                        'id_': id_,
                        'author': download_data['author']
                    })
                continue
            base_downloads_path = filesystem.safe_path(path, to_unicode(id_))
            original_node = FileSystemNode(base_downloads_path)
            original_node.populate_file_data(filename)
            from_path = original_node._abs_path_encoded
            existing_node = MappedFileNode.from_download_path(
                filename, node_factory, True)
            download_path = filename
            if len(project_files[filename]) > 1:
                download_path = get_download_path(id_, filename)
                to_node = MappedFileNode.from_download_path(
                    download_path, node_factory, True)
            else:
                # No duplicate downloads, put it into root
                to_node = existing_node
            if not to_node.is_download():
                printout(
                    "env:%(env_name)s file:%(download)s id:%(id_)s: "
                    "With %(rel_path)s: Download information is incorrect" % {
                        'env_name': env_name,
                        'download': filename,
                        'id_': id_,
                        'rel_path': to_node.relative_path
                    })
                continue
            if to_node.download().is_available():
                printout(
                    "env:%(env_name)s file:%(download)s id:%(id_)s: "
                    "With %(rel_path)s: The download information is already available"
                    % {
                        'env_name': env_name,
                        'download': filename,
                        'id_': id_,
                        'rel_path': to_node.relative_path
                    })
                continue
            elif to_node.exists():
                printout(
                    "env:%(env_name)s file:%(download)s id:%(id_)s: "
                    "With %(rel_path)s: The download already exists" % {
                        'env_name': env_name,
                        'download': filename,
                        'id_': id_,
                        'rel_path': to_node.relative_path
                    })
                continue
            can_be_removed = False
            download = self.populate_new_download(to_node.download(),
                                                  original_node, download_data)
            if len(project_files[filename]) > 1:
                # If there were duplicate filenames, special handling for them is needed
                if (existing_node.exists() and existing_node.is_file()
                        and existing_node.is_download()):
                    old_download = existing_node.download()
                    if (old_download.is_available()
                            and old_download.hash == download.hash
                            and old_download.version == 1 and
                            download.uploader_id == old_download.uploader_id
                            and download.created == old_download.created):
                        # Copy all information, which might be changed
                        download.clone_user_values(old_download)
                        download.count = old_download.count
                        can_be_removed = True
                    else:
                        # Else, we just accept that there has been changes
                        # Download count might be duplicated. In that case, manual work
                        # could be done.
                        printout(
                            "env:%(env_name)s file:%(download)s id:%(id_)s: "
                            "Cannot remove download because it is not original or has changed, "
                            "download count was %(count)s" % {
                                'env_name': env_name,
                                'id_': id_,
                                'download': filename,
                                'count': download.count
                            })
            if not dry_run:
                if os.path.sep in download_path:
                    parent_dir = to_node.get_parent_dir()
                    if not parent_dir.exists():
                        data = {'type': 'dir'}
                        FileSystemNode.create_check(parent_dir, data)
                        FileSystemNode.create_do(parent_dir, data)
                        FileSystemNode.create_post_process(parent_dir, data)
                shutil.copy2(from_path, to_node._abs_path_encoded)
                to_node.chmod()
                self.save_new_download(download)
                if can_be_removed:
                    existing_node.download().delete_completely()
                    existing_node.remove_do({})
            else:
                printout(
                    "env:%(env_name)s file:%(download)s id:%(id_)s: "
                    "Would copy file to %(download_path)s%(other)s" % {
                        'env_name':
                        env_name,
                        'id_':
                        id_,
                        'download':
                        filename,
                        'download_path':
                        to_node.download().download_path,
                        'other':
                        can_be_removed and ', and would also remove original'
                        or ''
                    })

        was_enabled = False
        if not self.env.is_component_enabled(DOWNLOADS_GLUE_COMPONENT):
            if not dry_run:
                self.env.config.set('components', DOWNLOADS_GLUE_COMPONENT,
                                    'enabled')
                self.env.config.save()
            was_enabled = True
        if download_data_list:
            if was_enabled:
                printout(
                    "env:%(env_name)s: downloads handled, component %(component)s enabled."
                    % {
                        'env_name': env_name,
                        'component': DOWNLOADS_GLUE_COMPONENT
                    })
            else:
                printout("env:%(env_name)s: downloads handled." %
                         {'env_name': env_name})
        else:
            printout(
                "env:%(env_name)s: no downloads found, component %(component)s enabled."
                % {
                    'env_name': env_name,
                    'component': DOWNLOADS_GLUE_COMPONENT
                })
コード例 #18
0
ファイル: files.py プロジェクト: nagyistoce/trac-multiproject
    def process_request(self, req):
        """ Process request for listing, creating and removing projects
        """

        files_core = FilesCoreComponent(self.env)
        timeline_notifier = FilesEventNotifier(self.env)
        node_factory, download_config = files_core.files_node_factory_and_config(req)
        if req.args.get("redirect") == "downloads":
            req.perm.require("FILES_DOWNLOADS_VIEW")
            if download_config.downloads_dir == "":
                raise HTTPNotFound(_("The project doesn't have downloads directory."))
            req.redirect(req.href.files(download_config.downloads_dir))

        user_store = get_userstore()
        user = user_store.getUser(req.authname)

        env_name = download_config.env_name

        node = MappedFileNode.from_request_path_info(req.path_info, node_factory)
        open_in_mode_mode = ""
        filename = None
        if req.args.get("action") == "open_in_mode":
            open_in_mode_mode = req.args.get("mode")
        if not node.exists():
            if node.is_download() and node.download().is_available():
                node.delete()
            raise HTTPNotFound(_("The file was not found!"))
        if req.method == "POST" and not req.args.get("cancel"):
            # Each X_from_request or X_by_request method does permission check
            action = req.args.get("action")
            # need to delete a file?
            if action == "delete_multiple" or action == "delete":
                self.process_delete(action, node, node_factory, req, timeline_notifier)
            elif action == "add_file":
                filename, open_in_mode_mode = self.process_add_file(node, req, timeline_notifier, user)
            elif action == "move_multiple" or action == "rename":
                self.process_move(action, node, node_factory, req, timeline_notifier, user)
            elif action == "add_folder":
                try:
                    new_dir = node.create_dir_from_request(req, user.id, timeline_notifier)
                    if not new_dir:
                        add_warning(req, _("No folder name was given"))
                    else:
                        filename = new_dir.filename
                        open_in_mode_mode = "show_mode"
                except TracError as e:
                    add_warning(req, _("Error when creating a new directory: ") + str(e))
            elif action == "update":
                filename, open_in_mode_mode = self.process_update(node, node_factory, req, timeline_notifier, user)

        if node.is_dir():
            if open_in_mode_mode:
                if not filename:
                    filename = req.args.get("target")
                return self.show_dir(
                    req,
                    node,
                    node_factory,
                    files_core,
                    user_store,
                    target_filename=filename,
                    current_mode=open_in_mode_mode,
                )
            else:
                return self.show_dir(req, node, node_factory, files_core, user_store)
        elif node.is_file():
            mimeview = Mimeview(self.env)
            try:
                node.show_file(req, mimeview, timeline_notifier)
            except InvalidOperationError as e:
                pass
            else:
                add_warning(req, _("Error was received when displaying the file"))
            parent_node = node.get_parent_dir()
            # Error was obtained
            return self.show_dir(req, parent_node, node_factory, files_core, user_store)
        else:
            raise TracError(_("Invalid filesystem node was requested"))
コード例 #19
0
    def expand_macro(self, formatter, name, content, args=None):

        # Parse optional arguments
        if args is None:
            args = parse_args(content)
            if len(args) > 1:
                args = args[1]

        files_core = FilesCoreComponent(self.env)
        node_factory, download_config = files_core.files_node_factory_and_config(formatter.req)
        if 'FILES_DOWNLOADS_VIEW' not in formatter.req.perm:
            return ''

        if name == 'FilesDownloadsCount':
            count = ProjectDownloadEntry.total_download_count(node_factory.project_id)
            return html.span(count, class_="files_downloads_count")
        elif name == 'FilesDownloads' or name == 'FilesDownloadsNarrow':
            is_narrow = True
            if name == 'FilesDownloads':
                is_narrow = False

            no_hide = False
            if args.has_key('no_hide') and args['no_hide'].lower() == 'true':
                no_hide = True

            only_featured = False
            if args.has_key('only_featured') and args['only_featured'].lower() == 'true':
                only_featured = True

            title = _('Featured downloads') if only_featured else _('Downloads')
            try:
                title = _(args['title'])
            except KeyError:
                title = _('Featured downloads') if only_featured else _('Downloads')
            except ValueError as e:
                title = _('Invalid title: %(reason)s', reason=str(e))

            download_entries = ProjectDownloadEntry.get_all_download_entries(node_factory.project_id,
                only_featured=only_featured)

            downloads = []
            user_store = None
            user_by_id = {}
            if not is_narrow:
                user_store = get_userstore()

            for download_entry in download_entries:
                if not is_narrow and not user_by_id.has_key(download_entry.uploader_id):
                    user = user_store.getUserWhereId(download_entry.uploader_id)
                    user_by_id[download_entry.uploader_id] = user

                # This doesn't check whether the node really exists
                node = MappedFileNode.from_download_entry(download_entry, node_factory)
                downloads.append(node)

            add_stylesheet(formatter.req, 'multiproject/css/files.css')
            add_script(formatter.req, 'multiproject/js/files.js')

            return Chrome(self.env).render_template(formatter.req,
                'multiproject_files_wiki.html',
                    {'downloads' : downloads,
                     'downloads_dir': download_config.downloads_dir,
                     'is_narrow': is_narrow,
                     'no_hide': no_hide,
                     'only_featured': only_featured,
                     'user_by_id': user_by_id,
                     'title': title,
                     'format_filename': format_filename},
                'text/html', True)
コード例 #20
0
    def import_files(self, dry_run=False):
        dry_run = True if dry_run in ['-n', '--dry-run'] else False
        try:
            env_name = self.env.project_identifier
        except AttributeError:
            # Since open_environment is not used in trac-admin commands
            # we need to manually set the project_identifier
            env_name = self.env.path.split('/')[-1]
            self.env.project_identifier = env_name
        download_data_list = self.get_download_data()
        path = conf.getEnvironmentDownloadsPath(self.env)
        if download_data_list is None:
            printout("env:%(env_name)s, download table was not found" %
                     {'env_name': self.env.project_identifier})
            return
        files_core = FilesCoreComponent(self.env)
        node_factory, download_config = files_core.files_node_factory_and_config()
        env_name = download_config.env_name

        project_files = {}
        first_file = {}
        for download_data in download_data_list:
            filename = download_data['file']
            id_ = download_data['id']
            if filename not in project_files:
                project_files[filename] = []
                first_file[filename] = id_
            project_files[filename].append(id_)

        for download_data in download_data_list:
            filename = download_data['file']
            id_ = download_data['id']
            if not download_data['author_id']:
                printout("env:%(env_name)s file:%(download)s id:%(id_)s: "
                         "The author %(author)s of download %(download)s was not found." %
                         {'env_name':env_name, 'download': filename, 'id_': id_,
                          'author':download_data['author']})
                continue
            base_downloads_path = filesystem.safe_path(path, to_unicode(id_))
            original_node = FileSystemNode(base_downloads_path)
            original_node.populate_file_data(filename)
            from_path = original_node._abs_path_encoded
            existing_node = MappedFileNode.from_download_path(filename, node_factory, True)
            download_path = filename
            if len(project_files[filename]) > 1:
                download_path = get_download_path(id_, filename)
                to_node = MappedFileNode.from_download_path(download_path, node_factory, True)
            else:
                # No duplicate downloads, put it into root
                to_node = existing_node
            if not to_node.is_download():
                printout("env:%(env_name)s file:%(download)s id:%(id_)s: "
                         "With %(rel_path)s: Download information is incorrect" %
                         {'env_name':env_name, 'download': filename, 'id_': id_,
                          'rel_path':to_node.relative_path})
                continue
            if to_node.download().is_available():
                printout("env:%(env_name)s file:%(download)s id:%(id_)s: "
                         "With %(rel_path)s: The download information is already available" %
                         {'env_name':env_name, 'download': filename, 'id_': id_,
                          'rel_path':to_node.relative_path})
                continue
            elif to_node.exists():
                printout("env:%(env_name)s file:%(download)s id:%(id_)s: "
                         "With %(rel_path)s: The download already exists" %
                         {'env_name':env_name, 'download': filename, 'id_': id_,
                          'rel_path':to_node.relative_path})
                continue
            can_be_removed = False
            download = self.populate_new_download(to_node.download(), original_node,
                download_data)
            if len(project_files[filename]) > 1:
                # If there were duplicate filenames, special handling for them is needed
                if (existing_node.exists() and existing_node.is_file()
                        and existing_node.is_download()):
                    old_download = existing_node.download()
                    if (old_download.is_available() and old_download.hash == download.hash
                        and old_download.version == 1
                        and download.uploader_id == old_download.uploader_id
                        and download.created == old_download.created):
                        # Copy all information, which might be changed
                        download.clone_user_values(old_download)
                        download.count = old_download.count
                        can_be_removed = True
                    else:
                        # Else, we just accept that there has been changes
                        # Download count might be duplicated. In that case, manual work
                        # could be done.
                        printout("env:%(env_name)s file:%(download)s id:%(id_)s: "
                             "Cannot remove download because it is not original or has changed, "
                             "download count was %(count)s" %
                             {'env_name':env_name, 'id_': id_, 'download': filename,
                              'count': download.count})
            if not dry_run:
                if os.path.sep in download_path:
                    parent_dir = to_node.get_parent_dir()
                    if not parent_dir.exists():
                        data = {'type': 'dir'}
                        FileSystemNode.create_check(parent_dir, data)
                        FileSystemNode.create_do(parent_dir, data)
                        FileSystemNode.create_post_process(parent_dir, data)
                shutil.copy2(from_path, to_node._abs_path_encoded)
                to_node.chmod()
                self.save_new_download(download)
                if can_be_removed:
                    existing_node.download().delete_completely()
                    existing_node.remove_do({})
            else:
                printout("env:%(env_name)s file:%(download)s id:%(id_)s: "
                         "Would copy file to %(download_path)s%(other)s" %
                         {'env_name':env_name, 'id_': id_, 'download': filename,
                          'download_path': to_node.download().download_path,
                          'other': can_be_removed and ', and would also remove original' or ''})

        was_enabled = False
        if not self.env.is_component_enabled(DOWNLOADS_GLUE_COMPONENT):
            if not dry_run:
                self.env.config.set('components', DOWNLOADS_GLUE_COMPONENT, 'enabled')
                self.env.config.save()
            was_enabled = True
        if download_data_list:
            if was_enabled:
                printout("env:%(env_name)s: downloads handled, component %(component)s enabled."
                         %{'env_name': env_name, 'component': DOWNLOADS_GLUE_COMPONENT})
            else:
                printout("env:%(env_name)s: downloads handled." % {'env_name': env_name})
        else:
            printout("env:%(env_name)s: no downloads found, component %(component)s enabled."
                    %{'env_name': env_name, 'component': DOWNLOADS_GLUE_COMPONENT})
コード例 #21
0
    def process_request(self, req):
        """ Process request for listing, creating and removing projects
        """

        files_core = FilesCoreComponent(self.env)
        timeline_notifier = FilesEventNotifier(self.env)
        node_factory, download_config = files_core.files_node_factory_and_config(req)
        if req.args.get('redirect') == 'downloads':
            req.perm.require('FILES_DOWNLOADS_VIEW')
            if download_config.downloads_dir == '':
                raise HTTPNotFound(_("The project doesn't have downloads directory."))
            req.redirect(req.href.files(download_config.downloads_dir))

        user_store = get_userstore()
        user = user_store.getUser(req.authname)

        env_name = download_config.env_name

        node = MappedFileNode.from_request_path_info(req.path_info, node_factory)
        open_in_mode_mode = ''
        filename = None
        if req.args.get('action') == 'open_in_mode':
            open_in_mode_mode = req.args.get('mode')
        if not node.exists():
            if node.is_download() and node.download().is_available():
                node.delete()
            raise HTTPNotFound(_("The file was not found!"))
        if req.method == 'POST' and not req.args.get('cancel'):
            # Each X_from_request or X_by_request method does permission check
            action = req.args.get('action')
            # need to delete a file?
            if action == 'delete_multiple' or action == 'delete':
                self.process_delete(action, node, node_factory, req, timeline_notifier)
            elif action == 'add_file':
                filename, open_in_mode_mode = self.process_add_file(node,
                    req, timeline_notifier, user)
            elif action == 'move_multiple' or action == 'rename':
                self.process_move(action, node, node_factory, req,
                    timeline_notifier, user)
            elif action == 'add_folder':
                try:
                    new_dir = node.create_dir_from_request(req, user.id, timeline_notifier)
                    if not new_dir:
                        add_warning(req, _("No folder name was given"))
                    else:
                        filename = new_dir.filename
                        open_in_mode_mode = 'show_mode'
                except TracError as e:
                    add_warning(req, _("Error when creating a new directory: ") + str(e))
            elif action == 'update':
                filename, open_in_mode_mode = self.process_update(node, node_factory, req,
                    timeline_notifier, user)

        if node.is_dir():
            if open_in_mode_mode:
                if not filename:
                    filename = req.args.get('target')
                return self.show_dir(req, node, node_factory, files_core, user_store,
                    target_filename=filename, current_mode=open_in_mode_mode)
            else:
                return self.show_dir(req, node, node_factory, files_core, user_store)
        elif node.is_file():
            mimeview = Mimeview(self.env)
            try:
                node.show_file(req, mimeview, timeline_notifier)
            except InvalidOperationError as e:
                pass
            else:
                add_warning(req, _("Error was received when displaying the file"))
            parent_node = node.get_parent_dir()
            # Error was obtained
            return self.show_dir(req, parent_node, node_factory, files_core, user_store)
        else:
            raise TracError(_('Invalid filesystem node was requested'))