def delete(id_: int) -> None: user = UserMapper.get_by_id(id_) if not is_authorized('manager') or user.id == current_user.id or ( (user.group == 'admin' and not is_authorized('admin'))): abort(403) # pragma: no cover sql = 'DELETE FROM web."user" WHERE id = %(user_id)s;' g.execute(sql, {'user_id': id_})
def user_view(id_: int) -> str: user = User.get_by_id(id_) info = { _('username'): user.username, _('group'): user.group, _('full name'): user.real_name, _('email'): user.email if is_authorized('manager') or user.settings['show_email'] else '', _('language'): user.settings['language'], _('last login'): format_date(user.login_last_success), _('failed logins'): user.login_failed_count if is_authorized('manager') else '' } return render_template( 'user/view.html', user=user, info=info, title=user.username, crumbs=[[_('admin'), f"{url_for('admin_index')}#tab-user"], user.username])
def profile_index() -> str: tabs = {'profile': Tab( 'profile', content=display_info(get_form_settings(ProfileForm(), True)), buttons=[manual('tools/profile')])} if is_authorized('contributor'): tabs['modules'] = Tab( 'modules', content=display_info(get_form_settings(ModulesForm(), True)), buttons=[manual('tools/profile')]) tabs['display'] = Tab( 'display', content=display_info(get_form_settings(DisplayForm(), True)), buttons=[manual('tools/profile')]) if not app.config['DEMO_MODE']: tabs['profile'].buttons += [ button(_('edit'), url_for('profile_settings', category='profile')), button(_('change password'), url_for('profile_password'))] if is_authorized('contributor'): tabs['modules'].buttons.append( button( _('edit'), url_for('profile_settings', category='modules'))) tabs['display'].buttons.append( button(_('edit'), url_for('profile_settings', category='display'))) return render_template( 'tabs.html', tabs=tabs, title=_('profile'), crumbs=[_('profile')])
def reference_view(id_): reference = EntityMapper.get_by_id(id_) tables = { 'info': get_entity_data(reference), 'file': {'id': 'files', 'data': [], 'header': app.config['TABLE_HEADERS']['file'] + ['page'] + [_('main image')]}} for name in ['source', 'event', 'actor', 'place', 'feature', 'stratigraphic-unit', 'find']: header = app.config['TABLE_HEADERS'][name] + ['page'] tables[name] = {'id': name, 'header': header, 'data': []} for link_ in reference.get_links('P67', True): domain = link_.domain data = get_base_table_data(domain) if is_authorized('editor'): url = url_for('link_delete', id_=link_.id, origin_id=reference.id) + '#tab-file' data.append(display_remove_link(url, domain.name)) tables['file']['data'].append(data) profile_image_id = reference.get_profile_image_id() for link_ in reference.get_links(['P67', 'P128']): range_ = link_.range data = get_base_table_data(range_) data.append(truncate_string(link_.description)) if range_.view_name == 'file': # pragma: no cover ext = data[3].replace('.', '') data.append(get_profile_image_table_link(range_, reference, ext, profile_image_id)) if not profile_image_id and ext in app.config['DISPLAY_FILE_EXTENSIONS']: profile_image_id = range_.id if is_authorized('editor'): url = url_for('reference_link_update', link_id=link_.id, origin_id=reference.id) data.append('<a href="' + url + '">' + uc_first(_('edit')) + '</a>') url = url_for('link_delete', id_=link_.id, origin_id=reference.id) data.append(display_remove_link(url + '#tab-' + range_.table_name, range_.name)) tables[range_.table_name]['data'].append(data) return render_template('reference/view.html', reference=reference, tables=tables, profile_image_id=profile_image_id)
def object_view(id_: int) -> str: object_ = EntityMapper.get_by_id(id_, nodes=True) object_.note = UserMapper.get_note(object_) tables = { 'info': get_entity_data(object_), 'source': Table(Table.HEADERS['source']), 'event': Table(Table.HEADERS['event']) } for link_ in object_.get_links('P128'): data = get_base_table_data(link_.range) if is_authorized('contributor'): url = url_for('link_delete', id_=link_.id, origin_id=object_.id) data.append( display_remove_link(url + '#tab-' + link_.range.table_name, link_.range.name)) tables['source'].rows.append(data) for link_ in object_.get_links('P25', inverse=True): data = get_base_table_data(link_.domain) if is_authorized('contributor'): url = url_for('link_delete', id_=link_.id, origin_id=object_.id) data.append( display_remove_link(url + '#tab-' + link_.range.table_name, link_.range.name)) tables['event'].rows.append(data) return render_template('object/view.html', object_=object_, tables=tables)
def user_view(id_): user = UserMapper.get_by_id(id_) data = {'info': [ (_('username'), link(user)), (_('group'), user.group), (_('full name'), user.real_name), (_('email'), user.email if is_authorized('manager') or user.settings['show_email'] else ''), (_('language'), user.settings['language']), (_('last login'), format_date(user.login_last_success)), (_('failed logins'), user.login_failed_count if is_authorized('manager') else '')]} return render_template('user/view.html', user=user, data=data)
def event_view(id_): event = EntityMapper.get_by_id(id_) event.set_dates() tables = { 'info': get_entity_data(event), 'file': {'id': 'files', 'data': [], 'header': app.config['TABLE_HEADERS']['file'] + [_('main image')]}, 'subs': {'id': 'sub-event', 'data': [], 'header': app.config['TABLE_HEADERS']['event']}, 'source': {'id': 'source', 'data': [], 'header': app.config['TABLE_HEADERS']['source']}, 'actor': {'id': 'actor', 'data': [], 'header': ['actor', 'class', 'involvement', 'first', 'last', 'description']}, 'reference': {'id': 'reference', 'data': [], 'header': app.config['TABLE_HEADERS']['reference'] + ['pages']}} for link_ in event.get_links(['P11', 'P14', 'P22', 'P23']): first = link_.first if not link_.first and event.first: first = '<span class="inactive" style="float:right">' + str(event.first) + '</span>' last = link_.last if not link_.last and event.last: last = '<span class="inactive" style="float:right">' + str(event.last) + '</span>' data = ([link(link_.range), g.classes[link_.range.class_.code].name, link_.type.name if link_.type else '', first, last, truncate_string(link_.description)]) if is_authorized('editor'): update_url = url_for('involvement_update', id_=link_.id, origin_id=event.id) unlink_url = url_for('link_delete', id_=link_.id, origin_id=event.id) + '#tab-actor' data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') data.append(display_remove_link(unlink_url, link_.range.name)) tables['actor']['data'].append(data) profile_image_id = event.get_profile_image_id() for link_ in event.get_links('P67', True): domain = link_.domain data = get_base_table_data(domain) if domain.view_name == 'file': # pragma: no cover extension = data[3].replace('.', '') data.append(get_profile_image_table_link(domain, event, extension, profile_image_id)) if not profile_image_id and extension in app.config['DISPLAY_FILE_EXTENSIONS']: profile_image_id = domain.id if domain.view_name not in ['source', 'file']: data.append(truncate_string(link_.description)) if is_authorized('editor'): update_url = url_for('reference_link_update', link_id=link_.id, origin_id=event.id) data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') if is_authorized('editor'): url = url_for('link_delete', id_=link_.id, origin_id=event.id) data.append(display_remove_link(url + '#tab-' + domain.view_name, domain.name)) tables[domain.view_name]['data'].append(data) for sub_event in event.get_linked_entities('P117', True): tables['subs']['data'].append(get_base_table_data(sub_event)) return render_template('event/view.html', event=event, tables=tables, profile_image_id=profile_image_id)
def reference_view(id_: int) -> str: reference = EntityMapper.get_by_id(id_, nodes=True) reference.note = UserMapper.get_note(reference) tables = { 'info': get_entity_data(reference), 'file': Table(Table.HEADERS['file'] + ['page', _('main image')]) } for name in [ 'source', 'event', 'actor', 'place', 'feature', 'stratigraphic-unit', 'find' ]: header_label = 'link text' if reference.system_type == 'external reference' else 'page' tables[name] = Table(Table.HEADERS[name] + [header_label]) for link_ in reference.get_links('P67', True): domain = link_.domain data = get_base_table_data(domain) if is_authorized('contributor'): url = url_for('link_delete', id_=link_.id, origin_id=reference.id) + '#tab-file' data.append(display_remove_link(url, domain.name)) tables['file'].rows.append(data) profile_image_id = reference.get_profile_image_id() for link_ in reference.get_links(['P67', 'P128']): range_ = link_.range data = get_base_table_data(range_) data.append(truncate_string(link_.description)) if range_.view_name == 'file': # pragma: no cover ext = data[3].replace('.', '') data.append( get_profile_image_table_link(range_, reference, ext, profile_image_id)) if not profile_image_id and ext in app.config[ 'DISPLAY_FILE_EXTENSIONS']: profile_image_id = range_.id if is_authorized('contributor'): url = url_for('reference_link_update', link_id=link_.id, origin_id=reference.id) data.append('<a href="' + url + '">' + uc_first(_('edit')) + '</a>') url = url_for('link_delete', id_=link_.id, origin_id=reference.id) data.append( display_remove_link(url + '#tab-' + range_.table_name, range_.name)) tables[range_.table_name].rows.append(data) return render_template('reference/view.html', reference=reference, tables=tables, profile_image_id=profile_image_id)
def export_csv(): path = app.config['EXPORT_FOLDER_PATH'] + '/csv' writeable = True if os.access(path, os.W_OK) else False form = ExportCsvForm() if form.validate_on_submit() and writeable: Export.export_csv(form) logger.log('info', 'database', 'CSV export') flash(_('data was exported as CSV'), 'info') return redirect(url_for('export_csv')) table = {'id': 'csv', 'header': ['name', 'size'], 'data': [], 'sort': 'sortList: [[0, 1]],headers: {0: { sorter: "text" }}'} for file in [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]: name = basename(file) if name == '.gitignore': continue link = '<a href="{url}">{label}</a>'.format(url=url_for('download_csv', filename=name), label=uc_first(_('download'))) data = [name, convert_size(os.path.getsize(path + '/' + name)), link] if is_authorized('admin') and writeable: confirm = ' onclick="return confirm(\'' + _('Delete %(name)s?', name=name) + '\')"' delete = '<a href="' + url_for('delete_csv', filename=name) delete += '" ' + confirm + '>' + uc_first(_('delete')) + '</a>' data.append(delete) table['data'].append(data) return render_template('export/export_csv.html', form=form, table=table, writeable=writeable)
def export_sql(): path = app.config['EXPORT_FOLDER_PATH'] + '/sql' writeable = True if os.access(path, os.W_OK) else False form = ExportSqlForm() if form.validate_on_submit() and writeable: if Export.export_sql(): logger.log('info', 'database', 'SQL export') flash(_('data was exported as SQL'), 'info') else: # pragma: no cover logger.log('error', 'database', 'SQL export failed') flash(_('SQL export failed'), 'error') return redirect(url_for('export_sql')) table = {'id': 'sql', 'header': ['name', 'size'], 'data': [], 'sort': 'sortList: [[0, 1]],headers: {0: { sorter: "text" }}'} for file in [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]: name = basename(file) if name == '.gitignore': continue url = url_for('download_sql', filename=name) data = [name, convert_size(os.path.getsize(path + '/' + name)), '<a href="' + url + '">' + uc_first(_('download')) + '</a>'] if is_authorized('admin') and writeable: confirm = ' onclick="return confirm(\'' + _('Delete %(name)s?', name=name) + '\')"' delete = '<a href="' + url_for('delete_sql', filename=name) delete += '" ' + confirm + '>' + uc_first(_('delete')) + '</a>' data.append(delete) table['data'].append(data) return render_template('export/export_sql.html', form=form, table=table, writeable=writeable)
def note_set_private(id_: int) -> Union[str, Response]: if not is_authorized('manager'): abort(403) # pragma: no cover note = User.get_note_by_id(id_) User.update_note(note['id'], note['text'], False) flash(_('note updated'), 'info') return redirect(f"{url_for('view', id_=note['entity_id'])}#tab-note")
def note_view(id_: int) -> str: note = User.get_note_by_id(id_) if not note['public'] and note['user_id'] != current_user.id: abort(403) # pragma: no cover entity = Entity.get_by_id(note['entity_id']) buttons: list[str] = [manual('tools/notes')] if note['user_id'] == current_user.id: buttons += [ button(_('edit'), url_for('note_update', id_=note['id'])), button(_('delete'), url_for('note_delete', id_=note['id'])) ] elif is_authorized('manager'): # pragma: no cover buttons += [ button(_('set private'), url_for('note_set_private', id_=note['id'])) ] tabs = { 'info': Tab('info', buttons=buttons, content=f"<h1>{uc_first(_('note'))}</h1>{note['text']}") } return render_template('tabs.html', tabs=tabs, entity=entity, crumbs=[[ _(entity.class_.view), url_for('index', view=entity.class_.view) ], link(entity), _('note')])
def profile_settings(category: str) -> Union[str, Response]: if category not in ['profile', 'display'] and not is_authorized('contributor'): abort(403) # pragma: no cover form = getattr( importlib.import_module('openatlas.forms.setting'), uc_first(category) + 'Form')() if form.validate_on_submit(): for field in form: if field.type in ['CSRFTokenField', 'HiddenField', 'SubmitField']: continue if field.name == 'name': current_user.real_name = field.data elif field.name == 'email': current_user.email = field.data else: current_user.settings[field.name] = field.data Transaction.begin() try: current_user.update() current_user.update_settings(form) Transaction.commit() session['language'] = current_user.settings['language'] flash(_('info update'), 'info') except Exception as e: # pragma: no cover Transaction.rollback() logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') return redirect(url_for('profile_index') + '#tab-' + category) set_form_settings(form, True) return render_template( 'display_form.html', form=form, manual_page='profile', title=_('profile'), crumbs=[[_('profile'), url_for('profile_index') + '#tab-' + category], _(category)])
def add_tabs_for_reference_system(entity: ReferenceSystem) -> dict[str, Tab]: tabs = {} for name in entity.classes: tabs[name] = Tab( name, entity=entity, table=Table([_('entity'), 'id', _('precision')])) for link_ in entity.get_links('P67'): name = link_.description if entity.resolver_url: name = \ f'<a href="{entity.resolver_url}{name}"' \ f' target="_blank" rel="noopener noreferrer">{name}</a>' tabs[link_.range.class_.name].table.rows.append([ link(link_.range), name, link_.type.name]) for name in entity.classes: tabs[name].buttons = [] if not tabs[name].table.rows and is_authorized('manager'): tabs[name].buttons = [button( _('remove'), url_for( 'reference_system_remove_class', system_id=entity.id, class_name=name))] return tabs
def delete_entity(id_: int) -> Optional[str]: url = None entity = Entity.get_by_id(id_) if not is_authorized(entity.class_.write_access): abort(403) # pragma: no cover if isinstance(entity, ReferenceSystem): if entity.system: abort(403) if entity.forms: flash(_('Deletion not possible if forms are attached'), 'error') return url_for('entity_view', id_=id_) if entity.class_.view in ['artifact', 'place']: if entity.get_linked_entities('P46'): flash(_('Deletion not possible if subunits exists'), 'error') return url_for('entity_view', id_=id_) parent = None \ if entity.class_.name == 'place' \ else entity.get_linked_entity('P46', True) entity.delete() logger.log_user(id_, 'delete') flash(_('entity deleted'), 'info') if parent: tab = f"#tab-{entity.class_.name.replace('_', '-')}" url = url_for('entity_view', id_=parent.id) + tab else: Entity.delete_(id_) logger.log_user(id_, 'delete') flash(_('entity deleted'), 'info') if entity.class_.name == 'file': try: delete_files(id_) except Exception as e: # pragma: no cover logger.log('error', 'file', 'file deletion failed', e) flash(_('error file delete'), 'error') return url
def admin_file_delete(filename: str) -> str: # pragma: no cover if filename != 'all': try: os.remove(app.config['UPLOAD_FOLDER_PATH'] + '/' + filename) flash(filename + ' ' + _('was deleted'), 'info') except Exception as e: logger.log('error', 'file', 'deletion of ' + filename + ' failed', e) flash(_('error file delete'), 'error') return redirect(url_for('admin_orphans') + '#tab-orphaned-files') if is_authorized('admin'): # Get all files with entities file_ids = [str(entity.id) for entity in EntityMapper.get_by_system_type('file')] # Get orphaned files (no corresponding entity) path = app.config['UPLOAD_FOLDER_PATH'] for file in [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]: filename = basename(file) if filename != '.gitignore' and splitext(filename)[0] not in file_ids: try: os.remove(app.config['UPLOAD_FOLDER_PATH'] + '/' + filename) except Exception as e: logger.log('error', 'file', 'deletion of ' + filename + ' failed', e) flash(_('error file delete'), 'error') return redirect(url_for('admin_orphans') + '#tab-orphaned-files')
def sex(id_: int) -> Union[str, Response]: entity = Entity.get_by_id(id_, types=True) buttons = [manual('tools/anthropological_analyses')] if is_authorized('contributor'): buttons.append(button(_('edit'), url_for('sex_update', id_=entity.id))) data = [] for item in SexEstimation.get_types(entity): type_ = g.types[item['id']] feature = SexEstimation.features[type_.name] data.append({ 'name': type_.name, 'category': feature['category'], 'feature_value': feature['value'], 'option_value': SexEstimation.options[item['description']], 'value': item['description'] }) return render_template('anthropology/sex.html', entity=entity, buttons=buttons, data=data, result=print_result(entity), crumbs=[ entity, [ _('anthropological analyses'), url_for('anthropology_index', id_=entity.id) ], _('sex estimation') ])
def get_groups() -> List[Tuple[str, str]]: """List groups from weakest permissions to strongest""" choices = [(name, name) for name in ['readonly', 'contributor', 'editor', 'manager']] if is_authorized('admin'): choices.append(('admin', 'admin')) return choices
def admin_file_delete(filename: str) -> Response: # pragma: no cover if filename != 'all': # Delete one file try: (app.config['UPLOAD_DIR'] / filename).unlink() flash(f"{filename} {_('was deleted')}", 'info') except Exception as e: logger.log('error', 'file', f'deletion of {filename} failed', e) flash(_('error file delete'), 'error') return redirect(f"{url_for('admin_orphans')}#tab-orphaned-files") if is_authorized('admin'): # Delete all files with no corresponding entity entity_file_ids = [entity.id for entity in Entity.get_by_class('file')] for file in app.config['UPLOAD_DIR'].iterdir(): if file.name != '.gitignore' and int( file.stem) not in entity_file_ids: try: (app.config['UPLOAD_DIR'] / file.name).unlink() except Exception as e: logger.log( 'error', 'file', f'deletion of {file.name} failed', e) flash(_('error file delete'), 'error') return redirect(f"{url_for('admin_orphans')}#tab-orphaned-files")
def admin_settings(category: str) -> Union[str, Response]: if category in ['general', 'mail'] and not is_authorized('admin'): abort(403) # pragma: no cover form = getattr(importlib.import_module('openatlas.forms.setting'), uc_first(category) + 'Form')() # Get forms dynamically if form.validate_on_submit(): Transaction.begin() try: Settings.update(form) logger.log('info', 'settings', 'Settings updated') Transaction.commit() flash(_('info update'), 'info') except Exception as e: # pragma: no cover Transaction.rollback() logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') tab = 'data' if category == 'api' else category tab = 'email' if category == 'mail' else tab return redirect(url_for('admin_index') + '#tab-' + tab) set_form_settings(form) return render_template('display_form.html', form=form, manual_page='admin/' + category, title=_('admin'), crumbs=[[ _('admin'), url_for('admin_index') + '#tab-' + ('data' if category == 'api' else category) ], _(category)])
def export_csv() -> str: path = app.config['EXPORT_FOLDER_PATH'] + '/csv' writeable = True if os.access(path, os.W_OK) else False form = ExportCsvForm() if form.validate_on_submit() and writeable: Export.export_csv(form) logger.log('info', 'database', 'CSV export') flash(_('data was exported as CSV'), 'info') return redirect(url_for('export_csv')) table = Table(['name', 'size'], order='[[0, "desc"]]') for file in [ f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f)) ]: name = basename(file) if name == '.gitignore': continue link = '<a href="{url}">{label}</a>'.format(url=url_for('download_csv', filename=name), label=uc_first( _('download'))) data = [name, convert_size(os.path.getsize(path + '/' + name)), link] if is_authorized('admin') and writeable: confirm = ' onclick="return confirm(\'' + _('Delete %(name)s?', name=name) + '\')"' delete = '<a href="' + url_for('delete_csv', filename=name) delete += '" ' + confirm + '>' + uc_first(_('delete')) + '</a>' data.append(delete) table.rows.append(data) return render_template('export/export_csv.html', form=form, table=table, writeable=writeable)
def __init__(self, name: str, content: Optional[str] = None, table: Optional[Table] = None, buttons: Optional[List[str]] = None, entity: Optional['Entity'] = None) -> None: self.name = name self.content = content self.title = uc_first(_(name.replace('_', ' '))) self.entity = entity self.table = table if table else Table() id_ = None view = None class_ = None if entity: id_ = entity.id view = entity.class_.view class_ = entity.class_ self.table.header = g.table_headers[name] if name == 'reference' or entity and entity.class_.view == 'reference': self.table.header = self.table.header + ['page'] buttons = buttons if buttons else [] self.add_buttons(name, buttons, view, id_, class_) self.buttons = buttons \ if buttons and is_authorized('contributor') else []
def add_buttons(entity: Entity, type_problem: bool = False) -> list[str]: if not is_authorized(entity.class_.write_access): return [] # pragma: no cover buttons = [] if isinstance(entity, Type): if entity.root and entity.category != 'system': buttons.append(button(_('edit'), url_for('update', id_=entity.id))) buttons.append(display_delete_link(entity)) elif isinstance(entity, ReferenceSystem): buttons.append(button(_('edit'), url_for('update', id_=entity.id))) if not entity.classes and not entity.system: buttons.append(display_delete_link(entity)) elif entity.class_.name == 'source_translation': buttons.append(button(_('edit'), url_for('update', id_=entity.id))) buttons.append(display_delete_link(entity)) else: if not type_problem: buttons.append(button(_('edit'), url_for('update', id_=entity.id))) if entity.class_.view != 'place' \ or not entity.get_linked_entities('P46'): buttons.append(display_delete_link(entity)) if entity.class_.name == 'stratigraphic_unit': buttons.append( button(_('tools'), url_for('anthropology_index', id_=entity.id))) return buttons
def reference_view(id_, unlink_id=None): reference = EntityMapper.get_by_id(id_) if unlink_id: LinkMapper.delete_by_id(unlink_id) flash(_('link removed'), 'info') tables = { 'info': get_entity_data(reference), 'file': { 'id': 'files', 'data': [], 'header': app.config['TABLE_HEADERS']['file'] + ['page'] } } for name in [ 'source', 'event', 'actor', 'place', 'feature', 'stratigraphic-unit', 'find' ]: header = app.config['TABLE_HEADERS'][name] + ['page'] tables[name] = {'id': name, 'header': header, 'data': []} for link_ in reference.get_links('P67', True): data = get_base_table_data(link_.domain) if is_authorized('editor'): unlink = url_for('reference_view', id_=reference.id, unlink_id=link_.id) + '#tab-file' data.append(display_remove_link(unlink, link_.domain.name)) tables['file']['data'].append(data) for link_ in reference.get_links(['P67', 'P128']): view_name = get_view_name(link_.range) view_name = view_name if view_name != 'place' else link_.range.system_type.replace( ' ', '-') data = get_base_table_data(link_.range) data.append(truncate_string(link_.description)) if is_authorized('editor'): update_url = url_for('reference_link_update', link_id=link_.id, origin_id=reference.id) data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') unlink_url = url_for('reference_view', id_=reference.id, unlink_id=link_.id) + '#tab-' + view_name data.append(display_remove_link(unlink_url, link_.range.name)) tables[view_name]['data'].append(data) return render_template('reference/view.html', reference=reference, tables=tables)
def get_buttons(view: str) -> list[str]: buttons = [] for name in [view] if view in ['artifact', 'place'] \ else g.view_class_mapping[view]: if is_authorized(g.classes[name].write_access): buttons.append( button(g.classes[name].label, url_for('insert', class_=name))) return buttons
def get_groups() -> list: """ Returns groups, hardcoded because order is relevant (weakest permissions to strongest)""" choices = [(name, name) for name in ['readonly', 'contributor', 'editor', 'manager']] if is_authorized('admin'): choices.append( ('admin', 'admin')) # admin group is only available for admins return choices
def get_groups() -> list[tuple[str, str]]: choices = [(name, name) for name in [ # Weakest to strongest permissions 'readonly', 'contributor', 'editor', 'manager']] if is_authorized('admin'): choices.append(('admin', 'admin')) return choices
def remove_link(name: str, link_: Link, origin: Entity, tab: str) -> Optional[str]: if not is_authorized('contributor'): return None # pragma: no cover url = url_for('link_delete', id_=link_.id, origin_id=origin.id) return link(_('remove'), f'{url}#tab-{tab}', js="return confirm('{x}')".format( x=_('Remove %(name)s?', name=name.replace("'", ''))))
def file_view(id_: int) -> str: file = EntityMapper.get_by_id(id_, nodes=True) path = get_file_path(file.id) tables = {'info': get_entity_data(file)} for name in [ 'source', 'event', 'actor', 'place', 'feature', 'stratigraphic-unit', 'find', 'reference' ]: tables[name] = Table(Table.HEADERS[name] + (['page'] if name == 'reference' else [])) for link_ in file.get_links('P67'): range_ = link_.range data = get_base_table_data(range_) view_name = range_.view_name view_name = view_name if view_name != 'place' else range_.system_type.replace( ' ', '-') if is_authorized('contributor'): url = url_for('link_delete', id_=link_.id, origin_id=file.id) data.append( display_remove_link(url + '#tab-' + view_name, range_.name)) tables[view_name].rows.append(data) for link_ in file.get_links('P67', True): data = get_base_table_data(link_.domain) data.append(link_.description) if is_authorized('contributor'): update_url = url_for('reference_link_update', link_id=link_.id, origin_id=file.id) data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') unlink_url = url_for('link_delete', id_=link_.id, origin_id=file.id) data.append( display_remove_link(unlink_url + '#tab-reference', link_.domain.name)) tables['reference'].rows.append(data) return render_template( 'file/view.html', missing_file=False if path else True, entity=file, tables=tables, preview=True if path and preview_file(path) else False, filename=os.path.basename(path) if path else False)
def file_view(id_, unlink_id=None): file = EntityMapper.get_by_id(id_) if unlink_id: LinkMapper.delete_by_id(unlink_id) flash(_('link removed'), 'info') path = get_file_path(file.id) tables = {'info': get_entity_data(file)} for name in [ 'source', 'event', 'actor', 'place', 'feature', 'stratigraphic-unit', 'find', 'reference' ]: header = app.config['TABLE_HEADERS'][name] + (['page'] if name == 'reference' else []) tables[name] = {'id': name, 'data': [], 'header': header} for link_ in file.get_links('P67'): view_name = get_view_name(link_.range) view_name = view_name if view_name != 'place' else link_.range.system_type.replace( ' ', '-') data = get_base_table_data(link_.range) if is_authorized('editor'): unlink_url = url_for('file_view', id_=file.id, unlink_id=link_.id) + '#tab-' + view_name data.append(display_remove_link(unlink_url, link_.range.name)) tables[view_name]['data'].append(data) for link_ in file.get_links('P67', True): data = get_base_table_data(link_.domain) data.append(link_.description) if is_authorized('editor'): update_url = url_for('reference_link_update', link_id=link_.id, origin_id=file.id) data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') unlink_url = url_for('file_view', id_=file.id, unlink_id=link_.id) + '#tab-reference' data.append(display_remove_link(unlink_url, link_.domain.name)) tables['reference']['data'].append(data) return render_template( 'file/view.html', missing_file=False if path else True, entity=file, tables=tables, preview=True if path and preview_file(path) else False, filename=os.path.basename(path) if path else False)
def source_view(id_): source = EntityMapper.get_by_id(id_) tables = { 'info': get_entity_data(source), 'text': {'id': 'translation', 'data': [], 'header': ['text', 'type', 'content']}, 'file': {'id': 'files', 'data': [], 'header': app.config['TABLE_HEADERS']['file'] + [_('main image')]}, 'reference': {'id': 'source', 'data': [], 'header': app.config['TABLE_HEADERS']['reference'] + ['page']}} for text in source.get_linked_entities('P73'): tables['text']['data'].append([ link(text), next(iter(text.nodes)).name if text.nodes else '', truncate_string(text.description)]) for name in ['actor', 'event', 'place', 'feature', 'stratigraphic-unit', 'find']: tables[name] = {'id': name, 'header': app.config['TABLE_HEADERS'][name], 'data': []} for link_ in source.get_links('P67'): range_ = link_.range data = get_base_table_data(range_) if is_authorized('editor'): url = url_for('link_delete', id_=link_.id, origin_id=source.id) data.append(display_remove_link(url + '#tab-' + range_.table_name, range_.name)) tables[range_.table_name]['data'].append(data) profile_image_id = source.get_profile_image_id() for link_ in source.get_links(['P67', 'P128'], True): domain = link_.domain data = get_base_table_data(domain) if domain.view_name == 'file': # pragma: no cover extension = data[3].replace('.', '') data.append(get_profile_image_table_link(domain, source, extension, profile_image_id)) if not profile_image_id and extension in app.config['DISPLAY_FILE_EXTENSIONS']: profile_image_id = domain.id if domain.view_name not in ['file']: data.append(link_.description) if is_authorized('editor'): update_url = url_for('reference_link_update', link_id=link_.id, origin_id=source.id) data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') if is_authorized('editor'): url = url_for('link_delete', id_=link_.id, origin_id=source.id) data.append(display_remove_link(url + '#tab-' + domain.view_name, domain.name)) tables[domain.view_name]['data'].append(data) return render_template('source/view.html', source=source, tables=tables, profile_image_id=profile_image_id)
def add_remove_link(data: List[Any], name: str, link_: Link, origin: Entity, tab: str) -> List[Any]: if is_authorized('contributor'): data.append( link(_('remove'), url_for('link_delete', id_=link_.id, origin_id=origin.id) + '#tab-' + tab, js="return confirm('{x}')".format( x=_('Remove %(name)s?', name=name.replace("'", ''))))) return data
def source_view(id_, unlink_id=None): source = EntityMapper.get_by_id(id_) if unlink_id: LinkMapper.delete_by_id(unlink_id) flash(_('link removed'), 'info') tables = { 'info': get_entity_data(source), 'text': {'id': 'translation', 'data': [], 'header': ['text', 'type', 'content']}, 'file': {'id': 'files', 'data': [], 'header': app.config['TABLE_HEADERS']['file']}, 'reference': { 'id': 'source', 'data': [], 'header': app.config['TABLE_HEADERS']['reference'] + ['page']}} for text in source.get_linked_entities('P73'): tables['text']['data'].append([ link(text), next(iter(text.nodes)).name if text.nodes else '', truncate_string(text.description)]) for name in ['actor', 'event', 'place', 'feature', 'stratigraphic-unit', 'find']: tables[name] = {'id': name, 'header': app.config['TABLE_HEADERS'][name], 'data': []} for link_ in source.get_links('P67'): data = get_base_table_data(link_.range) view_name = get_view_name(link_.range) view_name = view_name if view_name != 'place' else link_.range.system_type.replace(' ', '-') if is_authorized('editor'): unlink = url_for('source_view', id_=source.id, unlink_id=link_.id) + '#tab-' + view_name data.append(display_remove_link(unlink, link_.range.name)) tables[view_name]['data'].append(data) for link_ in source.get_links(['P67', 'P128'], True): data = get_base_table_data(link_.domain) view_name = get_view_name(link_.domain) if view_name not in ['file']: data.append(link_.description) if is_authorized('editor'): update_url = url_for('reference_link_update', link_id=link_.id, origin_id=source.id) data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') if is_authorized('editor'): unlink = url_for('source_view', id_=source.id, unlink_id=link_.id) + '#tab-' + view_name data.append(display_remove_link(unlink, link_.domain.name)) tables[view_name]['data'].append(data) return render_template('source/view.html', source=source, tables=tables)
def note(self, entity: Entity) -> str: if not current_user.settings['module_notes'] or not util.is_authorized( 'contributor'): return '' # pragma no cover if not entity.note: url = url_for('note_insert', entity_id=entity.id) return '<p><a href="' + url + '">+ ' + util.uc_first( _('note')) + '</a></p>' url = url_for('note_update', entity_id=entity.id) html = '<h2>' + util.uc_first( _('note')) + '</h2><p>' + entity.note + '</p>' html += '<a href="' + url + '">' + util.uc_first(_('edit note')) + '</a>' return html
def __init__(self, name: str, content: Optional[str] = None, table: Optional[Table] = None, buttons: Optional[list[str]] = None, entity: Optional[Entity] = None) -> None: self.name = name self.content = content self.title = uc_first(_(name.replace('_', ' '))) self.entity = entity self.table = table if table else Table() self.set_table_headers(name, entity) self.buttons: list[str] = [] if is_authorized('contributor'): self.set_buttons(name, buttons, entity)
def actor_view(id_): actor = EntityMapper.get_by_id(id_) actor.set_dates() objects = [] info = get_entity_data(actor) residence = actor.get_linked_entity('P74') if residence: object_ = residence.get_linked_entity('P53', True) objects.append(object_) info.append((uc_first(_('residence')), link(object_))) first = actor.get_linked_entity('OA8') if first: object_ = first.get_linked_entity('P53', True) objects.append(object_) info.append((uc_first(_('appears first')), link(object_))) last = actor.get_linked_entity('OA9') if last: object_ = last.get_linked_entity('P53', True) objects.append(object_) info.append((uc_first(_('appears last')), link(object_))) tables = { 'info': info, 'file': {'id': 'files', 'data': [], 'header': app.config['TABLE_HEADERS']['file'] + [_('main image')]}, 'source': {'id': 'source', 'data': [], 'header': app.config['TABLE_HEADERS']['source']}, 'reference': {'id': 'reference', 'data': [], 'header': app.config['TABLE_HEADERS']['reference'] + ['pages']}, 'event': {'id': 'event', 'data': [], 'header': ['event', 'class', 'involvement', 'first', 'last', 'description']}, 'relation': {'id': 'relation', 'data': [], 'sort': 'sortList:[[0,0]]', 'header': ['relation', 'actor', 'first', 'last', 'description']}, 'member_of': {'id': 'member_of', 'data': [], 'header': ['member of', 'function', 'first', 'last', 'description']}} profile_image_id = actor.get_profile_image_id() for link_ in actor.get_links('P67', True): domain = link_.domain data = get_base_table_data(domain) if domain.view_name == 'file': extension = data[3].replace('.', '') data.append(get_profile_image_table_link(domain, actor, extension, profile_image_id)) if not profile_image_id and extension in app.config['DISPLAY_FILE_EXTENSIONS']: profile_image_id = domain.id if domain.view_name not in ['source', 'file']: data.append(truncate_string(link_.description)) if is_authorized('editor'): update_url = url_for('reference_link_update', link_id=link_.id, origin_id=actor.id) data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') if is_authorized('editor'): url = url_for('link_delete', id_=link_.id, origin_id=actor.id) data.append(display_remove_link(url + '#tab-' + domain.view_name, domain.name)) tables[domain.view_name]['data'].append(data) # Todo: Performance - getting every place of every object for every event is very costly for link_ in actor.get_links(['P11', 'P14', 'P22', 'P23'], True): event = link_.domain first = link_.first place = event.get_linked_entity('P7') if place: objects.append(place.get_linked_entity('P53', True)) if not link_.first and event.first: first = '<span class="inactive" style="float:right">' + str(event.first) + '</span>' last = link_.last if not link_.last and event.last: last = '<span class="inactive" style="float:right">' + str(event.last) + '</span>' data = ([link(event), g.classes[event.class_.code].name, link_.type.name if link_.type else '', first, last, truncate_string(link_.description)]) if is_authorized('editor'): update_url = url_for('involvement_update', id_=link_.id, origin_id=actor.id) unlink_url = url_for('link_delete', id_=link_.id, origin_id=actor.id) + '#tab-event' data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') data.append(display_remove_link(unlink_url, link_.domain.name)) tables['event']['data'].append(data) for link_ in actor.get_links('OA7') + actor.get_links('OA7', True): if actor.id == link_.domain.id: type_ = link_.type.get_name_directed() if link_.type else '' related = link_.range else: type_ = link_.type.get_name_directed(True) if link_.type else '' related = link_.domain data = ([type_, link(related), link_.first, link_.last, truncate_string(link_.description)]) if is_authorized('editor'): update_url = url_for('relation_update', id_=link_.id, origin_id=actor.id) unlink_url = url_for('link_delete', id_=link_.id, origin_id=actor.id) + '#tab-relation' data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') data.append(display_remove_link(unlink_url, related.name)) tables['relation']['data'].append(data) for link_ in actor.get_links('P107', True): data = ([link(link_.domain), link_.type.name if link_.type else '', link_.first, link_.last, truncate_string(link_.description)]) if is_authorized('editor'): update_url = url_for('member_update', id_=link_.id, origin_id=actor.id) unlink_url = url_for('link_delete', id_=link_.id, origin_id=actor.id) + '#tab-member-of' data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') data.append(display_remove_link(unlink_url, link_.domain.name)) tables['member_of']['data'].append(data) if actor.class_.code in app.config['CLASS_CODES']['group']: tables['member'] = {'id': 'member', 'data': [], 'header': ['member', 'function', 'first', 'last', 'description']} for link_ in actor.get_links('P107'): data = ([link(link_.range), link_.type.name if link_.type else '', link_.first, link_.last, truncate_string(link_.description)]) if is_authorized('editor'): update_url = url_for('member_update', id_=link_.id, origin_id=actor.id) unlink_url = url_for('link_delete', id_=link_.id, origin_id=actor.id) + '#tab-member' data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') data.append(display_remove_link(unlink_url, link_.range.name)) tables['member']['data'].append(data) gis_data = GisMapper.get_all(objects) if objects else None if gis_data and gis_data['gisPointSelected'] == '[]': gis_data = None return render_template('actor/view.html', actor=actor, tables=tables, gis_data=gis_data, profile_image_id=profile_image_id)
def is_authorized(self, group): return util.is_authorized(group)
def delete(id_): from openatlas.util.util import is_authorized if not is_authorized('editor'): # pragma: no cover abort(403) g.cursor.execute("DELETE FROM model.link WHERE id = %(id)s;", {'id': id_}) debug_model['link sql'] += 1