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 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)
def main(): clause2method = {'insert':'POST', 'update':'PUT', 'query':'GET', 'delete':'DELETE'} combined_sql_list = [] # eventually is written to a file # [Generate API sql file] print('Generate API') print(' - load api configuration, generate funcPattern key and values') # get configuration file name {folder: "", name: ""} # get list of files of type .json in folder ./config # [Use a configuration file] config_folder = '{}'.format(os.getcwd().replace('_tasks','config')) # [Select API Source ] sourceConfiguration = open_api(config_folder,file_type="source") if not sourceConfiguration: print('cancel') exit(0) # [Select API Target ] targetConfiguration = open_api(config_folder,file_type="target") if not targetConfiguration: print('cancel') exit(0) # [Merge Source and Target] sourceConfiguration.update(targetConfiguration) apiConfiguration = sourceConfiguration # setup default environment homeDev = HomeDevelopment().setup() # [Create missing folders] sourceDev = HomeDevelopment().setup() targetDev = HomeDevelopment().setup() # [Scan configuration for home, source, and target environment configurations] for apiName in apiConfiguration: if apiName == 'source': # [Configure input sources from GIT repositories] sourceDev = get_environment(apiConfiguration[apiName]) elif apiName == 'target': # [Configure output targets from GIT repositories] targetDev = get_environment(apiConfiguration[apiName]) print('=================') report(homeDev, sourceDev, targetDev) print('=================') print('=================') print('Base Tests Combined') print('=================') #fileList = Util().getFileList(sourceDev.getDbFolder('sql'),'static.sql') fileList = Util().getFileList(sourceDev.getFolder('scripts'),'base.test.sql') fileList.sort() # [Replace project specific values] replace_ = ['one_db', 'hapi-api'] replace_with = [targetDev.getName('db'), targetDev.getName('db_api')] targetName = '90.base.test.sql' combinedDocument = Document(targetDev.getFolder('scripts'), targetName) # [Backup the target file] backup = Util().makeBackupFile(targetDev.getFolder('scripts'), targetName) print(' - backup : {}'.format(backup)) # [Move Static Files to Target Folder] for fileName in fileList: # [Combine base tests into one file] # [Copy from a source folder to a target folder] staticDocument = Document(sourceDev.getFolder('scripts'), fileName) \ .load() \ .replace(replace_, replace_with) combinedDocument.extend(staticDocument) combinedDocument.save() print('=================') print('API Tests') print('=================') apiNameList = [nm for nm in apiConfiguration if apiConfiguration[nm]['kind'] == 'api-definition' or apiConfiguration[nm]['kind'] == 'api-static'] # [Move Static Files to Target Folder] #targetNames = [] #sourceNames = [] names = [] src_folder = sourceDev.getFolder('scripts') tmpl_folder = '../templates' trg_folder = targetDev.getFolder('scripts') clauses = ['insert','query','update','delete'] for apiName in apiNameList: schema = apiConfiguration[apiName]['schema'].replace('_','.') prefix = apiConfiguration[apiName]['prefix-test'] # make list of existing test files names = [{"source":'{}.test.{}.{}.{}.api.test.sql'.format(prefix,schema, apiName.upper(), clause), "target":'{}.{}.{}.api.test.sql'.format(prefix,apiName.upper(), clause), "template": '{}.test.sql.template'.format(clause), "clause": '{}'.format(clause), "method": '{}'.format(clause2method[clause])} for clause in clauses] names = [pair for pair in names if Util().file_exists(src_folder, pair['source'])] # for pair in names: backup = None #print('pair', pair, 'kind', apiConfiguration[apiName]['kind']) if apiConfiguration[apiName]['kind'] == 'api-definition': # handle backup if Util().file_exists(trg_folder, pair['target']): backup = Util().makeBackupFile(targetDev.getFolder('scripts'), pair['target']) # Use Template if Util().file_exists(tmpl_folder, pair['template']): # Use Template # Use Template print(' - generate test {} FROM {}'.format(pair['target'], pair['template'])) if backup: print(' -- backup ', backup) templateDoc = TestTemplate(apiName, pair['method'], pair['template']) \ .apply(apiConfiguration)\ .saveAs(trg_folder, pair['target']) elif Util().file_exists(src_folder, pair['source']): # Copy from existing file # Copy from source print(' - copy test {} FROM {} '.format(pair['target'],pair['source'])) # load # replace # save doc = Document(src_folder, pair['source']) \ .load() \ .replace(replace_, replace_with)\ .saveAs(trg_folder,pair['target']) else: # No test available print('No Test Available for ', pair['source']) elif apiConfiguration[apiName]['kind'] == 'api-static': #print('template', tmpl_folder) print(' - copy test for api-static ', pair['source']) # [Backup the target file] #print(' - backup : {}'.format(fileName)) apiNameList = [nm for nm in apiConfiguration if apiConfiguration[nm]['kind'] == 'api-static'] # [Move Static Files to Target Folder] '''