def filter_stream(self, req, method, filename, stream, data): """ Adds project total count information in project summary block:: Downloads: 288 """ # TODO: Make interface for the project summary box and implement it here # Filter only the summary table wiki macro if filename != 'multiproject_summary.html': return stream # Load project and followers info project = Project.get(self.env) count = ProjectDownloadEntry.total_download_count(project.id) if count == 0: return stream # Add following information into project summary block trans = Transformer('//div[@class="summary"]/table').append( tag.tr( tag.th('Downloads:'), tag.td(count) ) ) return stream | trans
def handle_change(self, download_config, new_downloads_dir, can_be_moved, node_factory, warning, notice): """ :param FilesDownloadConfig download_config: download_configuration configuration :returns: True if new """ old_node, old_dir_exists = self.get_dir_data(download_config, node_factory) try: download_config.downloads_dir = new_downloads_dir except DownloadDirValidationException as e: raise TracError(_("New downloads directory is not valid: ") + str(e)) new_node = FileSystemNode.from_path(download_config.downloads_dir, node_factory) if new_node.exists() and not new_node.is_dir(): raise TracError(_("Error: Destination path exists and is a file")) elif new_node.exists() and can_be_moved: raise TracError(_("Error: Destination path already exists")) try: download_config.save() notice(_("Your changes have been saved.")) except Exception as e: self.log.exception("Failed to save downloads directory") raise TracError(_("Saving new value failed")) was_created = False if old_dir_exists and can_be_moved: try: old_node.move(new_node.relative_path) notice(_("Moved old downloads directory to be new one")) was_created = True except Exception as e: self.log.exception("Exception while moving old directory to new one") warning(_("Error while moving the old directory.")) elif not new_node.exists(): try: new_node.get_parent_dir().create_dir(new_node.filename) notice(_("Created new downloads directory")) was_created = True except Exception as e: self.log.exception("Creating new downloads directory failed.") warning(_("Creating new downloads directory failed.")) else: # not can_be_moved if old_dir_exists: try: for entry in ProjectDownloadEntry.get_all_download_entries(node_factory.project_id): entry.delete() except Exception as e: warning(_("Marking files as deleted failed")) notice(_("Set the new downloads directory to be the directory chosen.")) return was_created
def handle_unset(self, warning, notice): 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 try: files_core = FilesCoreComponent(self.env) node_factory, download_config = files_core.files_node_factory_and_config() download_config.delete() notice(_("Your changes have been saved.")) except Exception as e: self.log.exception("Failed to unset downloads directory") raise TracError(_("Unsetting failed")) try: for entry in ProjectDownloadEntry.get_all_download_entries(node_factory.project_id): entry.delete() except Exception as e: warning(_("Marking files as deleted failed"))
def handle_unset(self, warning, notice): 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 try: files_core = FilesCoreComponent(self.env) node_factory, download_config = files_core.files_node_factory_and_config( ) download_config.delete() notice(_('Your changes have been saved.')) except Exception as e: self.log.exception('Failed to unset downloads directory') raise TracError(_('Unsetting failed')) try: for entry in ProjectDownloadEntry.get_all_download_entries( node_factory.project_id): entry.delete() except Exception as e: warning(_("Marking files as deleted failed"))
def filter_stream(self, req, method, filename, stream, data): """ Adds project total count information in project summary block:: Downloads: 288 """ # TODO: Make interface for the project summary box and implement it here # Filter only the summary table wiki macro if filename != "multiproject_summary.html": return stream # Load project and followers info project = Project.get(self.env) count = ProjectDownloadEntry.total_download_count(project.id) if count == 0: return stream # Add following information into project summary block trans = Transformer('//div[@class="summary"]/table').append(tag.tr(tag.th("Downloads:"), tag.td(count))) return stream | trans
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)
def show_dir(self, req, node, node_factory, files_core, user_store, target_filename='', current_mode=''): """ Shows the content of a dir in a browser :param MappedFileNode node: mapped file node """ only_downloads_dir = False try: node.require_read_perm(req.perm) except PermissionError as e: if node.relative_path == '.' and 'FILES_DOWNLOADS_VIEW' in req.perm: add_warning(req, _("You must have FILES_VIEW permission " "to view files in Home folder.")) only_downloads_dir = True else: raise dirs, files = self.get_dirs_and_files(only_downloads_dir, node) # Ajax request case (after permission check) if req.get_header('X-Requested-With') == 'XMLHttpRequest': return 'multiproject_files_tree.html', {'tree_dirs': dirs, 'tree_files': files}, None # Fetch information for showing dir content dav_url = '/'.join([self.env.abs_href().rsplit('/',1)[0], files_core.url_dav_path, self.env.project_identifier, '']) (parent_folders, current_folder, root_node) = self.get_breadcrumb_data(node) root_dirs, root_files = [], [] if node.relative_path == '.': root_dirs, root_files = dirs, files else: if 'FILES_VIEW' in req.perm: root_dirs, root_files = root_node.get_dirs_and_files() elif 'FILES_DOWNLOADS_VIEW': root_dirs, root_files = self.get_dirs_and_files(True, root_node) if node.is_download(): can_edit = 'FILES_DOWNLOADS_ADMIN' in req.perm else: can_edit = 'FILES_ADMIN' in req.perm files_core.order_files_and_dirs(req, node.is_download(), dirs, files) # Setup downloads data old_downloads = [] user_by_id = {} if node.is_download(): if not can_edit: # Show only those downloads which are available available_files = [] for file in files: if file.download().is_available(): available_files.append(file) files = available_files for file in files: download = file.download() if download.uploader_id and not user_by_id.has_key(download.uploader_id): user_by_id[download.uploader_id] = user_store.getUserWhereId( download.uploader_id) old_downloads = ProjectDownloadEntry.get_all_download_entries(node_factory.project_id, only_deleted=True) for old_download in old_downloads: old_download.filename = os.path.basename(old_download.download_path) if old_download.uploader_id and not user_by_id.has_key(old_download.uploader_id): user_by_id[old_download.uploader_id] = user_store.getUserWhereId( old_download.uploader_id) table_mode = 'no_mode' files_entry_class = lambda node: '' if target_filename: if current_mode: ok_modes = ('edit_mode', 'move_mode', 'show_mode', 'delete_mode') if current_mode not in ok_modes: add_warning(req, _('The mode argument was not one of follows: %(list)s', list=','.join(ok_modes))) current_mode = 'show_mode' files_entry_class = lambda node: current_mode if node.filename == target_filename else '' else: if current_mode: ok_modes = ('move_multiple_mode', 'delete_multiple_mode', 'add_mode', 'upload_mode', 'modify_mode') if current_mode not in ok_modes: add_warning(req, _('The mode argument was not one of follows: %(list)s', list=','.join(ok_modes))) current_mode = '' if current_mode.endswith('multiple_mode'): table_mode = 'modify_mode' elif current_mode == 'modify_mode': table_mode = 'modify_mode' current_mode = 'modify_mode' else: table_mode = current_mode action_row_attrs = None if can_edit: action_row_attrs = {} not_selected = {'row': {}, 'td': {}, 'div': {}} for key in ('modify_mode', 'add_mode', 'upload_mode'): if key == table_mode: action_row_attrs[key] = {'row': {'style': 'display: table-row;'}, 'td': {'style': 'display: table-cell;'}, 'div': {'style': 'display: block;'}} else: action_row_attrs[key] = not_selected data = {'dir_node': node, 'parent_folders': parent_folders, 'files_entry_class': files_entry_class, 'current_folder': current_folder, 'can_edit': can_edit, 'target_filename': target_filename, 'current_mode': current_mode, 'is_current_mode': _is_current_mode, 'current_table_mode': table_mode, 'action_row_attrs': action_row_attrs, 'user_by_id': user_by_id, 'files': files, 'dirs': dirs, 'root_files': root_files, 'root_dirs': root_dirs, 'url': req.base_path, 'dav_url': dav_url, 'helpurl': self.config.get('multiproject', 'dav_help_url', ''), 'old_downloads': old_downloads, 'format_filename': format_filename, 'get_div_class': get_div_class} add_stylesheet(req, 'multiproject/css/files.css') add_script(req, 'multiproject/js/files.js') if can_edit: add_script(req, 'multiproject/js/expand_dir.js') add_script_data(req, {'files_data': { 'is_download': 1 if node.is_download() else 0 }}) return 'multiproject_files.html', data, None
def show_dir(self, req, node, node_factory, files_core, user_store, target_filename="", current_mode=""): """ Shows the content of a dir in a browser :param MappedFileNode node: mapped file node """ only_downloads_dir = False try: node.require_read_perm(req.perm) except PermissionError as e: if node.relative_path == "." and "FILES_DOWNLOADS_VIEW" in req.perm: add_warning(req, _("You must have FILES_VIEW permission " "to view files in Home folder.")) only_downloads_dir = True else: raise dirs, files = self.get_dirs_and_files(only_downloads_dir, node) # Ajax request case (after permission check) if req.get_header("X-Requested-With") == "XMLHttpRequest": return "multiproject_files_tree.html", {"tree_dirs": dirs, "tree_files": files}, None # Fetch information for showing dir content dav_url = "/".join( [self.env.abs_href().rsplit("/", 1)[0], files_core.url_dav_path, self.env.project_identifier, ""] ) (parent_folders, current_folder, root_node) = self.get_breadcrumb_data(node) root_dirs, root_files = [], [] if node.relative_path == ".": root_dirs, root_files = dirs, files else: if "FILES_VIEW" in req.perm: root_dirs, root_files = root_node.get_dirs_and_files() elif "FILES_DOWNLOADS_VIEW": root_dirs, root_files = self.get_dirs_and_files(True, root_node) if node.is_download(): can_edit = "FILES_DOWNLOADS_ADMIN" in req.perm else: can_edit = "FILES_ADMIN" in req.perm files_core.order_files_and_dirs(req, node.is_download(), dirs, files) # Setup downloads data old_downloads = [] user_by_id = {} if node.is_download(): if not can_edit: # Show only those downloads which are available available_files = [] for file in files: if file.download().is_available(): available_files.append(file) files = available_files for file in files: download = file.download() if download.uploader_id and not user_by_id.has_key(download.uploader_id): user_by_id[download.uploader_id] = user_store.getUserWhereId(download.uploader_id) old_downloads = ProjectDownloadEntry.get_all_download_entries(node_factory.project_id, only_deleted=True) for old_download in old_downloads: old_download.filename = os.path.basename(old_download.download_path) if old_download.uploader_id and not user_by_id.has_key(old_download.uploader_id): user_by_id[old_download.uploader_id] = user_store.getUserWhereId(old_download.uploader_id) table_mode = "no_mode" files_entry_class = lambda node: "" if target_filename: if current_mode: ok_modes = ("edit_mode", "move_mode", "show_mode", "delete_mode") if current_mode not in ok_modes: add_warning(req, _("The mode argument was not one of follows: %(list)s", list=",".join(ok_modes))) current_mode = "show_mode" files_entry_class = lambda node: current_mode if node.filename == target_filename else "" else: if current_mode: ok_modes = ("move_multiple_mode", "delete_multiple_mode", "add_mode", "upload_mode", "modify_mode") if current_mode not in ok_modes: add_warning(req, _("The mode argument was not one of follows: %(list)s", list=",".join(ok_modes))) current_mode = "" if current_mode.endswith("multiple_mode"): table_mode = "modify_mode" elif current_mode == "modify_mode": table_mode = "modify_mode" current_mode = "modify_mode" else: table_mode = current_mode action_row_attrs = None if can_edit: action_row_attrs = {} not_selected = {"row": {}, "td": {}, "div": {}} for key in ("modify_mode", "add_mode", "upload_mode"): if key == table_mode: action_row_attrs[key] = { "row": {"style": "display: table-row;"}, "td": {"style": "display: table-cell;"}, "div": {"style": "display: block;"}, } else: action_row_attrs[key] = not_selected data = { "dir_node": node, "parent_folders": parent_folders, "files_entry_class": files_entry_class, "current_folder": current_folder, "can_edit": can_edit, "target_filename": target_filename, "current_mode": current_mode, "is_current_mode": _is_current_mode, "current_table_mode": table_mode, "action_row_attrs": action_row_attrs, "user_by_id": user_by_id, "files": files, "dirs": dirs, "root_files": root_files, "root_dirs": root_dirs, "url": req.base_path, "dav_url": dav_url, "helpurl": self.config.get("multiproject", "dav_help_url", ""), "old_downloads": old_downloads, "format_filename": format_filename, "get_div_class": get_div_class, } add_stylesheet(req, "multiproject/css/files.css") add_script(req, "multiproject/js/files.js") if can_edit: add_script(req, "multiproject/js/expand_dir.js") add_script_data(req, {"files_data": {"is_download": 1 if node.is_download() else 0}}) return "multiproject_files.html", data, None
def handle_change(self, download_config, new_downloads_dir, can_be_moved, node_factory, warning, notice): """ :param FilesDownloadConfig download_config: download_configuration configuration :returns: True if new """ old_node, old_dir_exists = self.get_dir_data(download_config, node_factory) try: download_config.downloads_dir = new_downloads_dir except DownloadDirValidationException as e: raise TracError( _('New downloads directory is not valid: ') + str(e)) new_node = FileSystemNode.from_path(download_config.downloads_dir, node_factory) if new_node.exists() and not new_node.is_dir(): raise TracError(_('Error: Destination path exists and is a file')) elif new_node.exists() and can_be_moved: raise TracError(_("Error: Destination path already exists")) try: download_config.save() notice(_('Your changes have been saved.')) except Exception as e: self.log.exception('Failed to save downloads directory') raise TracError(_('Saving new value failed')) was_created = False if old_dir_exists and can_be_moved: try: old_node.move(new_node.relative_path) notice(_('Moved old downloads directory to be new one')) was_created = True except Exception as e: self.log.exception( 'Exception while moving old directory to new one') warning(_('Error while moving the old directory.')) elif not new_node.exists(): try: new_node.get_parent_dir().create_dir(new_node.filename) notice(_('Created new downloads directory')) was_created = True except Exception as e: self.log.exception('Creating new downloads directory failed.') warning(_('Creating new downloads directory failed.')) else: # not can_be_moved if old_dir_exists: try: for entry in ProjectDownloadEntry.get_all_download_entries( node_factory.project_id): entry.delete() except Exception as e: warning(_("Marking files as deleted failed")) notice( _('Set the new downloads directory to be the directory chosen.' )) return was_created