def refresh_metadata(): """ Cycle through all documents for all users and regenerate their cache and metadata entries. This needs a """ raise RuntimeError("Must be able to document.set_host") data = get_redis_client() for user_slug in data.userSet_list(): for doc_slug in data.userDocumentSet_list(user_slug): document = Document(data) document.set_host() # <-- TODO document.load(user_slug, doc_slug) document.save()
def download_txt(user_slug, doc_slug): """ Creates a single text file to download. """ document = Document(data) document.set_host(domain_name(bottle.request)) if not document.load(user_slug, doc_slug): msg = "Document '{:s}' not found." bottle.abort(HTTP_NOT_FOUND, msg.format(doc_slug)) file_name, text = document.export_txt_file() attach_as_file = 'attachment; filename="{:s}"'.format(file_name) bottle.response.set_header('Content-Type', 'text/plain') bottle.response.set_header('Content-Disposition', attach_as_file) return text
def delete_part(user_slug, doc_slug, part_slug): """ Delete a part from a document. Must be logged in, and be the owner. To Do: - Form and confirmation step? - Delete parts including unused? """ require_authority_for_user(user_slug) # or 401 document = Document(data) document.set_host(domain_name(bottle.request)) if not document.load(user_slug, doc_slug): msg = "Document '{:s}/{:s}' not found." bottle.abort(HTTP_NOT_FOUND, msg.format(user_slug, doc_slug)) document.delete_part(part_slug) if len(document.parts) > 0: document.save() bottle.redirect('/read/{:s}/{:s}'.format(user_slug, doc_slug)) else: document.delete() bottle.redirect('/user/{:s}'.format(user_slug))
def post_upload_txt(user_slug, doc_slug): """ Create a document from an download file. @todo: Show a diff? """ require_authority_for_user(user_slug) # else 401s upload = bottle.request.files.get('upload') # Validation limit = int(config['UPLOAD_LIMIT_KB']) if upload.content_length > (limit * 1024): msg = "The uploaded file is too large (limit: {:d}K)." bottle.abort(msg.format(limit)) name = upload.filename prefix = 'article-wiki_{:s}_{:s}_'.format(user_slug, doc_slug) if not name.startswith(prefix) or not name.endswith('.txt'): msg = "A '{:s}*.txt' filename is expected." bottle.abort(400, msg.format(prefix)) # Load contents filepath = '/tmp/' + upload.filename if os.path.exists(filepath): os.unlink(filepath) upload.save('/tmp') try: contents = codecs.open(filepath, 'r', 'utf-8').read() except Exception: msg = "Failed to read path '{:s}'." bottle.abort(HTTP_NOT_FOUND, msg.format(user_slug)) os.unlink(filepath) document = Document(data) host = domain_name(bottle.request) document.set_host(host) document.import_txt_file(user_slug, doc_slug, contents) document.save() uri = '/read/{:s}/{:s}'.format(user_slug, doc_slug) bottle.redirect(uri)
def post_edit_part(user_slug, doc_slug, part_slug): """ Wiki editor for existing doc part (or '_' if new). """ if user_slug == '_': # New user msg = "Blank user '_' not supported." bottle.abort(HTTP_BAD_REQUEST, msg) if doc_slug == '_' and part_slug == '_': msg = "Blank document and part '_/_' not supported." bottle.abort(HTTP_BAD_REQUEST, msg) if 'they_selected_save' in bottle.request.forms: require_authority_for_user(user_slug) if 'content' not in bottle.request.forms: bottle.abort(HTTP_BAD_REQUEST, "Form data was missing.") new_text = clean_text(bottle.request.forms.content) # Default slugs unless we change them new_part_slug = part_slug new_doc_slug, old_doc_slug = doc_slug, doc_slug document = Document(data) host = domain_name(bottle.request) document.set_host(host) if doc_slug == "_": # New article... new_doc_slug = document.set_index(new_text) new_doc_slug = data.userDocument_unique_slug(user_slug, new_doc_slug) document.set_slugs(user_slug, new_doc_slug) elif document.load(user_slug, doc_slug): if part_slug == 'index': new_doc_slug = document.set_index(new_text) if new_doc_slug != doc_slug: unique_slug = data.userDocument_unique_slug( user_slug, new_doc_slug) document.set_slugs(user_slug, unique_slug) else: new_part_slug = document.set_part(part_slug, new_text) else: msg = "Document '{:s}/{:s}' not found." bottle.abort(HTTP_NOT_FOUND, msg.format(user_slug, doc_slug)) okay_to_save = all([ 'they_selected_save' in bottle.request.forms, has_authority_for_user(user_slug) ]) if okay_to_save: new_doc_slug = document.save(pregenerate=True) old_doc = Document(data) if old_doc.load(user_slug, old_doc_slug): if old_doc.doc_slug != new_doc_slug: old_doc.delete() # Special redirects when editing fixtures uri = '/read/{:s}/{:s}'.format(user_slug, new_doc_slug) if doc_slug == 'fixtures': if part_slug == 'homepage': uri = '/' elif part_slug == 'author': uri = '/user/{:s}'.format(user_slug) bottle.redirect(uri) is_preview = 'they_selected_preview' in bottle.request.forms return show_editor(new_text, document.user_slug, document.doc_slug, new_part_slug, is_preview, can_be_saved=has_authority_for_user(user_slug))
def test_repr_save_load_delete(): """ Confirms data in data out. Builds upon data.py. """ data.redis.flushdb() user_slug = random_slug('test-user-') doc_slug = random_slug('test-doc-') doc = Document(data) doc.set_host('http://example.org') doc.set_parts(user_slug, doc_slug, minimal_document) # Create new_doc_slug = doc.save(pregenerate=True, update_doc_slug=True) assert user_slug in str(doc) assert new_doc_slug in str(doc) assert "(3 parts)" in str(doc) assert new_doc_slug == 'example-document' assert data.userSet_exists(user_slug) assert data.userDocument_exists(user_slug, new_doc_slug) latest_slugs = [ _['slug'] for _ in data.userDocumentLastChanged_list(user_slug) ] assert new_doc_slug in latest_slugs assert data.userDocumentMetadata_exists(user_slug, new_doc_slug) assert data.userDocumentCache_exists(user_slug, new_doc_slug) assert data.userDocumentSet_exists(user_slug, new_doc_slug) # Rename doc.set_index( trim(""" New Example Document Text Goes Here! """)) new_doc_slug = doc.save(pregenerate=True, update_doc_slug=True) assert new_doc_slug == "new-example-document" assert not data.userDocumentSet_exists(user_slug, doc_slug) assert not data.userDocument_exists(user_slug, doc_slug) assert not data.userDocumentMetadata_exists(user_slug, doc_slug) assert not data.userDocumentCache_exists(user_slug, doc_slug) latest_metadata = data.userDocumentLastChanged_list(user_slug) assert not any([_.get('slug') == doc_slug for _ in latest_metadata]) assert any([_.get('slug') == new_doc_slug for _ in latest_metadata]) assert data.userDocumentSet_exists(user_slug, new_doc_slug) assert data.userDocument_exists(user_slug, new_doc_slug) assert data.userDocumentMetadata_exists(user_slug, new_doc_slug) assert data.userDocumentCache_exists(user_slug, new_doc_slug) assert data.userDocumentSet_exists(user_slug, new_doc_slug) doc2 = Document(data) doc2.load(user_slug, new_doc_slug) assert doc.user_slug == doc2.user_slug assert doc.doc_slug == doc2.doc_slug assert doc.parts == doc2.parts # Delete doc.delete() assert not data.userDocument_exists(user_slug, new_doc_slug) assert not data.userDocumentSet_exists(user_slug, new_doc_slug) assert not data.userDocumentMetadata_exists(user_slug, new_doc_slug) latest_metadata = data.userDocumentLastChanged_list(user_slug) assert not any([_.get('slug') == new_doc_slug for _ in latest_metadata]) assert not data.userDocumentCache_exists(user_slug, new_doc_slug)