def edit_attachment(pagename, filename): # check if page exists if not storage.exists(get_filename(pagename)): return render_template('pagenotfound.html', title='404', subtitle='Page {} not found.'.format(pagename), name=pagename) if request.method == 'POST': # check access permissions if not has_attachment_access(): abort(403) # the button defines the operation operation = request.form.get('operation') if operation == "rename": newfilename = request.form.get('newfilename') if filename != newfilename: try: storage.rename(get_attachment_filename(pagename, filename), get_attachment_filename( pagename, newfilename), author=get_author()) except StorageError: flash("Renaming failed.", "error") else: flash("{} renamed to {}.".format(filename, newfilename), "success") return redirect(url_for(".attachments", pagename=pagename)) elif operation == "delete": fn = get_attachment_filename(pagename, filename) storage.delete(fn, message="{} removed.".format(fn), author=get_author()) flash("{} deleted.".format(filename), "success") return redirect(url_for(".attachments", pagename=pagename)) # find attachment, list all attachments files = storage.list_files(get_filename(pagename)[:-3]) # check if attachment exists if filename not in files: return render_template( 'page.html', title='404', subtitle='Attachment not found.'.format(filename), pagename=pagename, content="Error: Attachment <tt>{}</tt> not found.".format( filename)) try: log = storage.log(get_attachment_filename(pagename, filename)) except StorageNotFound: log = None return render_template( 'edit_attachment.html', title=pagename, subtitle="Attachment: {}".format(filename), pagename=pagename, filename=filename, log=log, )
def pageindex(): if not has_read_access(): flash('You lack the permissions to access this wiki. Please login.') return redirect(url_for('.login')) ls = [get_pagename(x) for x in storage.list_files() if x.endswith(".md")] idx = {} for f in ls: if f[0] in idx: idx[f[0]].append(f) else: idx[f[0]] = [f] return render_template( 'pageindex.html', title="Index of Pages", pageidx=idx, )
def rename(pagename): if not has_write_access(): abort(403) fn = get_filename(pagename) # check if the page exists first if not storage.exists(fn): flash("Page '{}' not found.".format(pagename), "error") return redirect(url_for(".index")) newname = request.form.get("newname") if request.method == 'POST': if newname is not None: newname = newname.strip() if len(newname) < 1: flash("The name is too short.", "error") elif newname == pagename: flash("Nothing to update.", "error") else: try: dirname = get_filename(pagename)[:-3] files = storage.list_files(dirname) # take care of the attachments if len(files) > 0: newdirname = get_filename(newname)[:-3] storage.rename(dirname, newdirname, author=get_author(), no_commit=True) # rename the file storage.rename(get_filename(pagename), get_filename(newname), author=get_author()) except StorageError as e: flash("Renaming failed.", "error") else: flash("{} renamed to {}.".format(pagename, newname), "success") return redirect(url_for(".view", pagename=newname)) return render_template( 'rename.html', title="Rename {}".format(pagename), pagename=pagename, newname=newname, )
def output_wiki_link(self, m): # initial style style = '' # parse for title and pagename title, pagename = self.wiki_link_iwlre.findall(m.group(1))[0] # fetch all existing pages pages = [ get_pagename(x).lower() for x in storage.list_files() if x.endswith(".md") ] # if the pagename is empty the title is the pagename if pagename == '': pagename = title # check if page exists if pagename.lower() not in pages: style = ' class="notfound"' # generate link url = url_for('view', pagename=pagename) link = '<a href="{}"{}>{}</a>'.format(url, style, title) return link
def search(): if not has_read_access(): flash('You lack the permissions to access this wiki. Please login.') return redirect(url_for('.login')) needle = request.form.get('needle') re_on = request.form.get('re') # match case is on mc_on = request.form.get('mc') result = {} if needle is not None and len(needle) > 0: try: if re_on: sre = re.compile(needle) sre_i = re.compile(needle, re.IGNORECASE) else: sre = re.compile(re.escape(needle)) sre_i = re.compile(re.escape(needle), re.IGNORECASE) except Exception as e: sre = None flash("Error in search term: {}".format(e.msg), "error") else: # find all markdown files md_files = [ filename for filename in storage.list_files() if filename.endswith(".md") ] for fn in md_files: r = [] # open file, read file haystack = storage.load(fn) m = sre.search(get_pagename(fn)) if mc_on is None and m is None: m = sre_i.search(get_pagename(fn)) if m is not None: # page name matches r.append([None, get_pagename(fn), m.group(0)]) for linernumber, line in enumerate(haystack.splitlines()): line = line.strip() m = sre.search(line) if not m and mc_on is None: # retry with ignore case m = sre_i.search(line) if m: r.append([ "{:04d}".format(linernumber + 1), line, m.group(0) ]) if len(r) > 0: result[get_pagename(fn)] = [] for match in r: hl = re.sub( "({})".format(re.escape(html_escape(match[2]))), r"::o::w::1::\1::o::w::2::", html_escape(match[1])) # shorten result line if len(match[1]) > 70: #splitter = "(::o::w::1::"+re.escape(match[2])+"::o::w::2::)" splitter = "(::o::w::1::" + match[ 2] + "::o::w::2::)" blocks = re.split(splitter, hl, flags=re.IGNORECASE) for num, block in enumerate(blocks): if len(block) < 10 or re.match( splitter, block, flags=re.IGNORECASE): continue words = re.split(r"(\S+)", block) placeholder = False while len(words) > 12: placeholder = True del (words[int(len(words) / 2)]) if placeholder: words.insert(int(len(words) / 2), " [...] ") blocks[num] = "".join(words) hl = "".join(blocks) # replace marker with html spans hl = hl.replace("::o::w::1::", "<span class=\"match\">") hl = hl.replace("::o::w::2::", "</span>") result[get_pagename(fn)].append(match + [hl]) # "reorder" results newresult = [{}, {}] # first all pagename matches for pagename in sorted(result.keys()): if result[pagename][0][0] is None: newresult[0][pagename] = result[pagename] else: newresult[1][pagename] = result[pagename] result = newresult return render_template( 'search.html', title="Search", needle=needle, re_on=re_on, mc_on=mc_on, result=result, )
def attachments(pagename): if not storage.exists(get_filename(pagename)): return render_template('pagenotfound.html', title='404', subtitle='Page {} not found.'.format(pagename), name=pagename) if request.method == 'POST': if not has_attachment_access(): abort(403) # debug help via curl -F "file=@./354.jpg" http://localhost:5000/Home/attachments to_commit = [] filename = request.form.get('filename') for file in request.files.getlist("file"): if file.filename == '': # no file selected continue # if filename is not None (update a attachment), replace only that if filename: fn = secure_filename(filename) else: fn = secure_filename(file.filename) ffn = get_attachment_full_filename(pagename, fn) to_commit.append(get_attachment_filename(pagename, fn)) # full directory name fdn = os.path.dirname(ffn) # make sure the directory exists os.makedirs(fdn, mode=0o777, exist_ok=True) # store attachment file.save(ffn) #print(ffn) if filename is not None: break if len(to_commit) > 0: # take care of the commit message message = request.form.get('message') # default message if filename is None: default_message = "Added attachment(s): {}.".format( ", ".join(to_commit)) else: default_message = "Updated attachment: {}.".format( ", ".join(to_commit)) if message is None or message == "": message = default_message # commit storage.commit(to_commit, message=message, author=get_author()) # notify the user flash(default_message) # find files files = storage.list_files(get_filename(pagename)[:-3]) attachments = [] for f in files: # prepare meta data dictionary d = {'filename': f, 'full': get_attachment_full_filename(pagename, f)} fn = get_attachment_filename(pagename, f) # store url d['url'] = url_for(".get_attachment", pagename=pagename, filename=f) try: d['meta'] = storage.metadata(get_attachment_filename(pagename, f)) except StorageNotFound: # TODO log error? continue d['size'] = sizeof_fmt(os.stat(d['full']).st_size) d['mtime'] = datetime.fromtimestamp(os.path.getmtime(d['full'])) mimetype, encoding = mimetypes.guess_type(fn) if mimetype is not None and mimetype.startswith('image'): d['thumbnail'] = url_for(".get_attachment_thumbnail", pagename=pagename, filename=f) attachments.append(d) return render_template( 'attachments.html', title=pagename, subtitle="Attachments", pagename=pagename, attachments=attachments, )