def get_downloads(self, req, cursor, order_by='id', desc=False): columns = ('id', 'file', 'description', 'size', 'time', 'count', 'author', 'tags', 'component', 'version', 'architecture', 'platform', 'type') sql = "SELECT id, file, description, size, time, count, author, tags," \ " component, version, architecture, platform, type FROM download " \ "ORDER BY " + order_by + (" ASC", " DESC")[bool(desc)] self.log.debug(sql) cursor.execute(sql) downloads = [] for row in cursor: row = dict(zip(columns, row)) row['description'] = wiki_to_oneliner(row['description'], self.env) row['size'] = pretty_size(row['size']) row['time'] = pretty_timedelta(row['time']) row['count'] = row['count'] or 0 downloads.append(row) # Replace field ids with apropriate objects. for download in downloads: download['architecture'] = self.get_architecture( cursor, download['architecture']) download['platform'] = self.get_platform(cursor, download['platform']) download['type'] = self.get_type(cursor, download['type']) return downloads
def get_downloads(self, req, cursor, order_by = 'id', desc = False): columns = ('id', 'file', 'description', 'size', 'time', 'count', 'author', 'tags', 'component', 'version', 'architecture', 'platform', 'type') sql = "SELECT id, file, description, size, time, count, author, tags," \ " component, version, architecture, platform, type FROM download " \ "ORDER BY " + order_by + (" ASC", " DESC")[bool(desc)] self.log.debug(sql) cursor.execute(sql) downloads = [] for row in cursor: row = dict(zip(columns, row)) row['description'] = wiki_to_oneliner(row['description'], self.env) row['size'] = pretty_size(row['size']) row['time'] = pretty_timedelta(row['time']) row['count'] = row['count'] or 0 downloads.append(row) # Replace field ids with apropriate objects. for download in downloads: download['architecture'] = self.get_architecture(cursor, download['architecture']) download['platform'] = self.get_platform(cursor, download['platform']) download['type'] = self.get_type(cursor, download['type']) return downloads
def _render_directory(self, req, repos, node, rev=None): req.perm.assert_permission('BROWSER_VIEW') order = req.args.get('order', 'name').lower() req.hdf['browser.order'] = order desc = req.args.has_key('desc') req.hdf['browser.desc'] = desc and 1 or 0 info = [] for entry in node.get_entries(): entry_rev = rev and entry.rev info.append({ 'name': entry.name, 'fullpath': entry.path, 'is_dir': int(entry.isdir), 'content_length': entry.content_length, 'size': util.pretty_size(entry.content_length), 'rev': entry.rev, 'permission': 1, # FIXME 'log_href': util.escape(self.env.href.log(entry.path, rev=rev)), 'browser_href': util.escape( self.env.href.peerReviewBrowser(entry.path, rev=rev)) }) changes = get_changes(self.env, repos, [i['rev'] for i in info]) def cmp_func(a, b): dir_cmp = (a['is_dir'] and -1 or 0) + (b['is_dir'] and 1 or 0) if dir_cmp: return dir_cmp neg = desc and -1 or 1 if order == 'date': return neg * cmp(changes[b['rev']]['date_seconds'], changes[a['rev']]['date_seconds']) elif order == 'size': return neg * cmp(a['content_length'], b['content_length']) else: return neg * _natural_order(a['name'].lower(), b['name'].lower()) info.sort(cmp_func) req.hdf['browser.items'] = info req.hdf['browser.changes'] = changes
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')
def attachment_to_hdf(env, db, req, attachment): from trac.wiki import wiki_to_oneliner if not db: db = env.get_db_cnx() hdf = { 'filename': attachment.filename, 'description': wiki_to_oneliner(attachment.description, env, db), 'author': util.escape(attachment.author), 'ipnr': attachment.ipnr, 'size': util.pretty_size(attachment.size), 'time': time.strftime('%c', time.localtime(attachment.time)), 'href': attachment.href() } return hdf
def _render_view(self, req, data): """Display list of files in trac env htdocs dir""" target_path = os.path.join(self.env.path, 'htdocs') filelist = [] if os.path.exists(target_path) and os.path.isdir(target_path): dlist = os.listdir(target_path) for f in dlist: fsize = os.stat(os.path.join(target_path, f))[stat.ST_SIZE] filelist.append({'name' : f, 'link' : Markup('<a href="%s">%s</a>') % ( self.env.href.chrome('site', f), f), 'size' : pretty_size(fsize),}) continue data.update({'siteupload' : {'files' : filelist}}) return
def _edit_request(self, req, handler): self.log.debug('Handling file edit for "%s"', req.authname) # Retrieve fields # Form data arrives in req.args as unicode strings so the edited text # must be encoded before writing to disk, just as paths and commit # messages are. The difference is that subversion always takes paths # in utf-8 encoding. File encoding is not prescribed, to subversion # it's all just bytes. edit_text = req.args['bsop_edit_text'] commit_msg = req.args['bsop_edit_commit_msg'] max_edit_size = self.max_edit_size self.log.debug('Received %i characters of edited text', len(edit_text)) if max_edit_size > 0 and len(edit_text) > max_edit_size: raise TracError("The edited text is too long, " "the limit is %s (%i bytes)." % (pretty_size(max_edit_size), max_edit_size)) self.log.debug('Opening repository for file edit') reponame, repos, path = _get_repository(self.env, req) try: # Determine encoding to use # Try in order # - extract charset= from svn:mimetype property # - Encoding determined earlier and sent to client # - Default encoding (in case returned by client is invalid) node = repos.get_node(path) encoding = _encoding_from_mime_type(node.content_type) \ or req.args.get('bsop_edit_encoding', '') try: text_encoded = edit_text.encode(encoding) except (LookupError, UnicodeEncodeError), e: self.log.info('Failed to encode edited text with encoding ' '"%s" retrying with default. Error was: %s', encoding, e) encoding = self.config.get('trac', 'default_charset') try: text_encoded = edit_text.encode(encoding) except (LookupError, UnicodeEncodeError), e: self.log.error('Could not encode edited text with default ' 'encoding "%s": %s', encoding, e) raise TracError('Could not commit your text because it ' 'could not be encoded.')
def _edit_request(self, req, handler): self.log.debug('Handling file edit for "%s"', req.authname) # Retrieve fields # Form data arrives in req.args as unicode strings so the edited text # must be encoded before writing to disk, just as paths and commit # messages are. The difference is that subversion always takes paths # in utf-8 encoding. File encoding is not prescribed, to subversion # it's all just bytes. edit_text = req.args['bsop_edit_text'] commit_msg = req.args['bsop_edit_commit_msg'] max_edit_size = self.max_edit_size self.log.debug('Received %i characters of edited text', len(edit_text)) if max_edit_size > 0 and len(edit_text) > max_edit_size: raise TracError("The edited text is too long, " "the limit is %s (%i bytes)." % (pretty_size(max_edit_size), max_edit_size)) self.log.debug('Opening repository for file edit') reponame, repos, path = _get_repository(self.env, req) try: # Determine encoding to use # Try in order # - extract charset= from svn:mimetype property # - Encoding determined earlier and sent to client # - Default encoding (in case returned by client is invalid) node = repos.get_node(path) encoding = _encoding_from_mime_type(node.content_type) \ or req.args.get('bsop_edit_encoding', '') try: text_encoded = edit_text.encode(encoding) except (LookupError, UnicodeEncodeError), e: self.log.info( 'Failed to encode edited text with encoding ' '"%s" retrying with default. Error was: %s', encoding, e) encoding = self.config.get('trac', 'default_charset') try: text_encoded = edit_text.encode(encoding) except (LookupError, UnicodeEncodeError), e: self.log.error( 'Could not encode edited text with default ' 'encoding "%s": %s', encoding, e) raise TracError('Could not commit your text because it ' 'could not be encoded.')
def _render_directory(self, req, repos, node, rev=None): req.perm.assert_permission('BROWSER_VIEW') order = req.args.get('order', 'name').lower() req.hdf['browser.order'] = order desc = req.args.has_key('desc') req.hdf['browser.desc'] = desc and 1 or 0 info = [] for entry in node.get_entries(): entry_rev = rev and entry.rev info.append({ 'name': entry.name, 'fullpath': entry.path, 'is_dir': int(entry.isdir), 'content_length': entry.content_length, 'size': util.pretty_size(entry.content_length), 'rev': entry.rev, 'permission': 1, # FIXME 'log_href': util.escape(self.env.href.log(entry.path, rev=rev)), 'browser_href': util.escape(self.env.href.peerReviewBrowser(entry.path, rev=rev)) }) changes = get_changes(self.env, repos, [i['rev'] for i in info]) def cmp_func(a, b): dir_cmp = (a['is_dir'] and -1 or 0) + (b['is_dir'] and 1 or 0) if dir_cmp: return dir_cmp neg = desc and -1 or 1 if order == 'date': return neg * cmp(changes[b['rev']]['date_seconds'], changes[a['rev']]['date_seconds']) elif order == 'size': return neg * cmp(a['content_length'], b['content_length']) else: return neg * _natural_order(a['name'].lower(), b['name'].lower()) info.sort(cmp_func) req.hdf['browser.items'] = info req.hdf['browser.changes'] = changes
def _upload_request(self, req, handler): self.log.debug('Handling file upload for "%s"', req.authname) # Retrieve uploaded file upload_file = req.args['bsop_upload_file'] # Retrieve filename, normalize, use to check a file was uploaded # Filename checks adapted from trac/attachment.py filename = getattr(upload_file, 'filename', '') filename = unicodedata.normalize('NFC', unicode(filename, 'utf-8')) filename = filename.replace('\\', '/').replace(':', '/') filename = posixpath.basename(filename) if not filename: raise TracError('No file uploaded') # Check size of uploaded file, accepting 0 to max_upload_size bytes file_data = upload_file.value # Alternatively .file for file object file_size = len(file_data) if self.max_upload_size > 0 and file_size > self.max_upload_size: raise TracError('Uploaded file is too large, ' 'maximum upload size: %s' % pretty_size(self.max_upload_size)) self.log.debug('Received file %s with %i bytes', filename, file_size) commit_msg = req.args.get('bsop_upload_commit') self.log.debug('Opening repository for file upload') reponame, repos, path = _get_repository(self.env, req) try: repos_path = repos.normalize_path('/'.join([path, filename])) self.log.debug('Writing file %s to %s in %s', filename, repos_path, reponame) svn_writer = SubversionWriter(self.env, repos, req.authname) rev = svn_writer.put_content(repos_path, file_data, commit_msg) add_notice( req, _("Uploaded %s, creating revision %s.") % (filename, rev)) except Exception, e: self.log.exception("Failed when uploading file %s" % filename) add_warning(req, _("Failed to upload file: %s") % e)
def _render_view(self, req, data): """Display list of files in trac env htdocs dir""" target_path = os.path.join(self.env.path, 'htdocs') filelist = [] if os.path.exists(target_path) and os.path.isdir(target_path): dlist = os.listdir(target_path) for f in dlist: fsize = os.stat(os.path.join(target_path, f))[stat.ST_SIZE] filelist.append({ 'name': f, 'link': Markup('<a href="%s">%s</a>') % (self.env.href.chrome('site', f), f), 'size': pretty_size(fsize), }) continue data.update({'siteupload': {'files': filelist}}) return
def _upload_request(self, req, handler): self.log.debug('Handling file upload for "%s"', req.authname) # Retrieve uploaded file upload_file = req.args['bsop_upload_file'] # Retrieve filename, normalize, use to check a file was uploaded # Filename checks adapted from trac/attachment.py filename = getattr(upload_file, 'filename', '') filename = unicodedata.normalize('NFC', unicode(filename, 'utf-8')) filename = filename.replace('\\', '/').replace(':', '/') filename = posixpath.basename(filename) if not filename: raise TracError('No file uploaded') # Check size of uploaded file, accepting 0 to max_upload_size bytes file_data = upload_file.value # Alternatively .file for file object file_size = len(file_data) if self.max_upload_size > 0 and file_size > self.max_upload_size: raise TracError('Uploaded file is too large, ' 'maximum upload size: %s' % pretty_size(self.max_upload_size)) self.log.debug('Received file %s with %i bytes', filename, file_size) commit_msg = req.args.get('bsop_upload_commit') self.log.debug('Opening repository for file upload') reponame, repos, path = _get_repository(self.env, req) try: repos_path = repos.normalize_path('/'.join([path, filename])) self.log.debug('Writing file %s to %s in %s', filename, repos_path, reponame) svn_writer = SubversionWriter(self.env, repos, req.authname) rev = svn_writer.put_content(repos_path, file_data, commit_msg) add_notice(req, _("Uploaded %s, creating revision %s.") % (filename, rev)) except Exception, e: self.log.exception("Failed when uploading file %s" % filename) add_warning(req, _("Failed to upload file: %s") % e)
def _render_directory(self, req, repos, node, rev=None): req.perm.assert_permission('BROWSER_VIEW') order = req.args.get('order', 'name').lower() desc = req.args.has_key('desc') # Entries metadata class entry(object): __slots__ = 'name rev kind isdir path content_length'.split() def __init__(self, node): for f in entry.__slots__: setattr(self, f, getattr(n, f)) def display(self): result = '' for f in entry.__slots__: result = "%s slot: %s, value: %s;" % (result, f, getattr(n, f)) return result info = [] if order == 'date': def file_order(a): return changes[a.rev].date elif order == 'size': def file_order(a): return (a.content_length, embedded_numbers(a.name.lower())) else: def file_order(a): return embedded_numbers(a.name.lower()) dir_order = desc and 1 or -1 def browse_order(a): return a.isdir and dir_order or 0, file_order(a) for entry in node.get_entries(): entry_rev = rev and entry.rev info.append({ 'name': entry.name, 'fullpath': entry.path, 'is_dir': int(entry.isdir), 'content_length': entry.content_length, 'size': util.pretty_size(entry.content_length), 'rev': entry.rev, 'permission': 1, # FIXME 'log_href': util.escape(self.env.href.log(entry.path, rev=rev)), 'browser_href': util.escape( self.env.href.peerReviewBrowser(entry.path, rev=rev)) }) changes = get_changes(repos, [i['rev'] for i in info]) def cmp_func(a, b): dir_cmp = (a['is_dir'] and -1 or 0) + (b['is_dir'] and 1 or 0) if dir_cmp: return dir_cmp neg = desc and -1 or 1 if order == 'date': return neg * cmp(changes[b['rev']]['date_seconds'], changes[a['rev']]['date_seconds']) elif order == 'size': return neg * cmp(a['content_length'], b['content_length']) else: return neg * _natural_order(a['name'].lower(), b['name'].lower()) info.sort(cmp_func) return { 'order': order, 'desc': desc and 1 or None, 'items': info, 'changes': changes }