class TableModelView(CaravelModelView, DeleteMixin): # noqa datamodel = SQLAInterface(models.SqlaTable) list_columns = [ 'table_link', 'database', 'sql_link', 'is_featured', 'changed_by_', 'changed_on', 'perm' ] add_columns = [ 'table_name', 'database', 'schema', 'default_endpoint', 'offset', 'cache_timeout' ] edit_columns = [ 'table_name', 'is_featured', 'database', 'schema', 'description', 'owner', 'main_dttm_col', 'default_endpoint', 'offset', 'cache_timeout' ] related_views = [TableColumnInlineView, SqlMetricInlineView] base_order = ('changed_on', 'desc') description_columns = { 'offset': "Timezone offset (in hours) for this datasource", 'schema': ("Schema, as used only in some databases like Postgres, Redshift " "and DB2"), 'description': Markup( "Supports <a href='https://daringfireball.net/projects/markdown/'>" "markdown</a>"), } def post_add(self, table): try: table.fetch_metadata() except Exception as e: logging.exception(e) flash( "Table [{}] doesn't seem to exist, " "couldn't fetch metadata".format(table.table_name), "danger") utils.merge_perm(sm, 'datasource_access', table.perm) def post_update(self, table): self.post_add(table)
class DruidClusterModelView(CaravelModelView, DeleteMixin): # noqa datamodel = SQLAInterface(models.DruidCluster) add_columns = [ 'cluster_name', 'coordinator_host', 'coordinator_port', 'coordinator_endpoint', 'broker_host', 'broker_port', 'broker_endpoint', ] edit_columns = add_columns list_columns = ['cluster_name', 'metadata_last_refreshed'] label_columns = { 'cluster_name': _("Cluster"), 'coordinator_host': _("Coordinator Host"), 'coordinator_port': _("Coordinator Port"), 'coordinator_endpoint': _("Coordinator Endpoint"), 'broker_host': _("Broker Host"), 'broker_port': _("Borker Port"), 'broker_endpoint': _("Broker Endpoint"), }
class TableColumnInlineView(CompactCRUDMixin, CaravelModelView): # noqa datamodel = SQLAInterface(models.TableColumn) can_delete = False edit_columns = [ 'column_name', 'description', 'groupby', 'filterable', 'table', 'count_distinct', 'sum', 'min', 'max', 'expression', 'is_dttm' ] add_columns = edit_columns list_columns = [ 'column_name', 'type', 'groupby', 'filterable', 'count_distinct', 'sum', 'min', 'max', 'is_dttm' ] page_size = 500 description_columns = { 'is_dttm': ("Whether to make this column available as a " "[Time Granularity] option, column has to be DATETIME or " "DATETIME-like"), 'expression': utils.markdown( "a valid SQL expression as supported by the underlying backend. " "Example: `substr(name, 1, 1)`", True), }
class TaskModelView(ModelView): datamodel = SQLAInterface(Task) add_form_extra_fields = { 'type': SelectField( 'Type', choices=TASK_TYPES, description=('The type of task so the implant knows how to ' 'handle the Command or Data'), widget=Select2Widget()) } edit_form_extra_fields = { 'type': SelectField( 'Type', choices=TASK_TYPES, description=('The type of task so the implant knows how to ' 'handle the Command or Data'), widget=Select2Widget()) } label_columns = {'implant': 'Implant'} list_columns = ['id', 'task_type', 'command', 'data'] show_fieldsets = [ ('Summary', { 'fields': ['task_type'] }), ('Details', { 'fields': ['command', 'data'] }), ] add_columns = ['type', 'command', 'data'] description_columns = { 'command': ('String of command(s) used by simple ' 'command execution task types'), 'data': ('File used by task types that require a data object (e.g. exe)'), } edit_columns = ['type', 'command', 'data']
class JobModelView(ModelView): datamodel = SQLAInterface(Job) list_columns = ['name', 'start_time', 'PAYLOAD'] #add_columns = ['name', 'PAYLOAD'] add_columns = [] show_fieldsets = [ ('Summary', { 'fields': ['name', 'PAYLOAD'] }), ('Job Info', { 'fields': [ 'module_type', 'start_time', 'SRVHOST', 'SRVPORT', 'LHOST', 'LPORT' ], 'expanded': False }), ] @action("job_kill", "Kill", "Kill all selected?", "fa-rocket") def kill(self, items): if isinstance(items, list): for item in items: result = "test result" flash(str(item.id), "info") flash(str(result), "info") else: result = "test result" flash(str(items.id), "info") flash(str(result), "info") self.update_redirect() return redirect(self.get_redirect()) @action("job_stop", "Stop", "Stop all selected?", "fa-rocket") def stop(self, items): print "stopping" return redirect(self.get_redirect())
class DruidDatasourceModelView(CaravelModelView, DeleteMixin): # noqa datamodel = SQLAInterface(models.DruidDatasource) list_columns = [ 'datasource_link', 'cluster', 'changed_by_', 'modified', 'offset' ] related_views = [DruidColumnInlineView, DruidMetricInlineView] edit_columns = [ 'datasource_name', 'cluster', 'description', 'owner', 'is_featured', 'is_hidden', 'default_endpoint', 'offset', 'cache_timeout' ] add_columns = edit_columns page_size = 500 base_order = ('datasource_name', 'asc') description_columns = { 'offset': _("Timezone offset (in hours) for this datasource"), 'description': Markup("Supports <a href='" "https://daringfireball.net/projects/markdown/'>markdown</a>"), } label_columns = { 'datasource_name': _("Data Source"), 'cluster': _("Cluster"), 'description': _("Description"), 'owner': _("Owner"), 'is_featured': _("Is Featured"), 'is_hidden': _("Is Hidden"), 'default_endpoint': _("Default Endpoint"), 'offset': _("Time Offset"), 'cache_timeout': _("Cache Timeout"), } def post_add(self, datasource): datasource.generate_metrics() utils.merge_perm(sm, 'datasource_access', datasource.perm) def post_update(self, datasource): self.post_add(datasource)
class SliceModelView(CaravelModelView, DeleteMixin): # noqa datamodel = SQLAInterface(models.Slice) add_template = "caravel/add_slice.html" can_add = False label_columns = { 'created_by_': 'Creator', 'datasource_link': 'Datasource', } list_columns = [ 'slice_link', 'viz_type', 'datasource_link', 'created_by_', 'modified'] order_columns = utils.list_minus(list_columns, ['created_by_', 'modified']) edit_columns = [ 'slice_name', 'description', 'viz_type', 'druid_datasource', 'table', 'dashboards', 'params', 'cache_timeout'] base_order = ('changed_on', 'desc') description_columns = { 'description': Markup( "The content here can be displayed as widget headers in the " "dashboard view. Supports " "<a href='https://daringfireball.net/projects/markdown/'>" "markdown</a>"), }
class DatabaseView(PanoramixModelView, DeleteMixin): datamodel = SQLAInterface(models.Database) list_columns = ['database_name', 'sql_link', 'created_by', 'changed_on_'] add_columns = ['database_name', 'sqlalchemy_uri'] search_exclude_columns = ('password',) edit_columns = add_columns add_template = "panoramix/models/database/add.html" edit_template = "panoramix/models/database/edit.html" base_order = ('changed_on','desc') description_columns = { 'sqlalchemy_uri': ( "Refer to the SqlAlchemy docs for more information on how " "to structure your URI here: " "http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html") } def pre_add(self, db): conn = sqla.engine.url.make_url(db.sqlalchemy_uri) db.password = conn.password conn.password = "******" * 10 if conn.password else None db.sqlalchemy_uri = str(conn) # hides the password def pre_update(self, db): self.pre_add(db)
class SqlMetricInlineView(CompactCRUDMixin, CaravelModelView): # noqa datamodel = SQLAInterface(models.SqlMetric) list_columns = ['metric_name', 'verbose_name', 'metric_type'] edit_columns = [ 'metric_name', 'description', 'verbose_name', 'metric_type', 'expression', 'table' ] description_columns = { 'expression': utils.markdown( "a valid SQL expression as supported by the underlying backend. " "Example: `count(DISTINCT userid)`", True), } add_columns = edit_columns page_size = 500 label_columns = { 'metric_name': _("Metric"), 'description': _("Description"), 'verbose_name': _("Verbose Name"), 'metric_type': _("Type"), 'expression': _("SQL Expression"), 'table': _("Table"), }
class VotersView(ModelView): datamodel = SQLAInterface(Voters) add_form = MyForm edit_form = MyForm add_columns = [ 'first_name', 'middle_name', 'last_name', 'gender', 'date_of_birth', 'document_type', 'document_number', 'ward', 'vote_mobile', 'telephone' ] edit_columns = [ 'first_name', 'middle_name', 'last_name', 'gender', 'date_of_birth', 'document_type', 'document_number', 'ward', 'vote_mobile', 'telephone' ] list_columns = [ 'full_name', 'document_number', 'sex', 'telephone', 'ward', 'ward.constituency', 'ward.constituency.county' ] search_columns = [ 'first_name', 'middle_name', 'last_name', 'document_number' ] order_columns = [None] def post_add(self, item): if item.vote_mobile: item.voter_pin = randint(1000, 9999) db.session.commit() '''PUT this in Outgoing DB''' message = "Welcome %s. Youve been registered as voter in %s. "\ "Your Mobile voting pin is: %s " % \ (item, item.ward, item.voter_pin) logged = SmsloggerLoggedmessage() logged.direction = SMSForm.DIRECTION_OUTGOING logged.text = message logged.identity = item.telephone logged.status = SMSForm.STATUS_PENDING db.session.add(logged) db.session.commit()
class GroupModelView(ModelView): base_permissions = ['can_add', 'can_delete', 'can_list', 'can_show'] # can_edit base_filters = [ #['created_by', FilterEqualFunction, get_user], ['name', FilterStartsWith, 'F'] ] list_columns = ['name', 'my_name'] datamodel = SQLAInterface(ContactGroup) related_views = [ContactModelView ] # create a master/detail view on the show and edit # action will be shown in both list & show: can be used to implement request approval / rejection @action("myaction", "Do something on this record", "Do you really want to?", "fa-rocket") def myaction(self, item): """ do something with the item record """ # return list on list view, object on show view #if isinstance(items, list): # self.datamodel.delete_all(items) # self.update_redirect() #else: # self.datamodel.delete(items) return redirect(self.get_redirect()) # action will be shown in list only @action("muldelete", "Delete", "Delete all Really?", "fa-rocket", single=False) def muldelete(self, items): self.datamodel.delete_all(items) self.update_redirect() return redirect(self.get_redirect())
class SliceModelView(CaravelModelView, DeleteMixin): # noqa datamodel = SQLAInterface(models.Slice) add_template = "caravel/add_slice.html" can_add = False label_columns = { 'datasource_link': 'Datasource', } list_columns = [ 'slice_link', 'viz_type', 'datasource_link', 'creator', 'modified' ] edit_columns = [ 'slice_name', 'description', 'viz_type', 'druid_datasource', 'table', 'owners', 'dashboards', 'params', 'cache_timeout' ] base_order = ('changed_on', 'desc') description_columns = { 'description': Markup("The content here can be displayed as widget headers in the " "dashboard view. Supports " "<a href='https://daringfireball.net/projects/markdown/'>" "markdown</a>"), } base_filters = [['id', FilterSlice, lambda: []]] label_columns = { 'cache_timeout': _("Cache Timeout"), 'creator': _("Creator"), 'dashboards': _("Dashboards"), 'datasource_link': _("Datasource"), 'description': _("Description"), 'modified': _("Last Modified"), 'owners': _("Owners"), 'params': _("Parameters"), 'slice_link': _("Slice"), 'slice_name': _("Name"), 'table': _("Table"), 'viz_type': _("Visualization Type"), }
class ContactModelView(ModelView): datamodel = SQLAInterface(Contact) label_columns = {'contact_group.name': 'Contacts Group'} list_columns = ['name', 'personal_celphone', 'birthday', 'contact_group.name'] list_template = 'contact.html' base_order = ('name', 'asc') show_fieldsets = [ ('Summary', {'fields': ['name', 'gender', 'contact_group']}), ( 'Personal Info', {'fields': ['address', 'birthday', 'personal_phone', 'personal_celphone'], 'expanded': False}), ] add_fieldsets = show_fieldsets edit_fieldsets = show_fieldsets @action("muldelete", "Delete", "Delete all Really?", "fa-rocket", single=False) def muldelete(self, items): self.datamodel.delete_all(items) self.update_redirect() return redirect(self.get_redirect())
class DruidDatasourceModelView(PanoramixModelView, DeleteMixin): datamodel = SQLAInterface(models.DruidDatasource) list_columns = [ 'datasource_link', 'cluster', 'owner', 'created_by', 'created_on', 'changed_by_', 'changed_on', 'offset'] related_views = [DruidColumnInlineView, DruidMetricInlineView] edit_columns = [ 'datasource_name', 'cluster', 'description', 'owner', 'is_featured', 'is_hidden', 'default_endpoint', 'offset'] page_size = 500 base_order = ('datasource_name', 'asc') description_columns = { 'offset': "Timezone offset (in hours) for this datasource", 'description': Markup("Supports <a href='https://daringfireball.net/projects/markdown/'>markdown</a>"), } def post_add(self, datasource): datasource.generate_metrics() utils.merge_perm(sm, 'datasource_access', datasource.perm) def post_update(self, datasource): self.post_add(datasource)
class CaseCategoryView(ModelView): datamodel = SQLAInterface(CaseCategory) list_columns = add_columns = edit_columns = ['name', 'description']
class CaseTypeView(ModelView): datamodel = SQLAInterface(CaseType) hidden_list = hide_list list_columns = add_columns = edit_columns = ['name', 'description']
class ConstituencyView(ModelView): datamodel = SQLAInterface(Constituency) hidden_list = hide_list list_columns = add_columns = edit_columns = ['name']
class RegionView(ModelView): datamodel = SQLAInterface(Region) list_columns = ['id', 'name', 'capital'] add_columns = edit_columns = ['name', 'capital', 'districts'] related_views = [DistrictView]
class DistrictView(ModelView): datamodel = SQLAInterface(District) related_views = [TownView] list_columns = add_columns = edit_columns = ['name', 'capital', 'towns']
class TownView(ModelView): datamodel = SQLAInterface(Town) list_columns = add_columns = edit_columns = ['name']
class CssTemplateModelView(CaravelModelView, DeleteMixin): datamodel = SQLAInterface(models.CssTemplate) list_columns = ['template_name'] edit_columns = ['template_name', 'css'] add_columns = edit_columns
class DatabaseView(ModelView, DeleteMixin): datamodel = SQLAInterface(models.Database) list_columns = ['database_name'] add_columns = ['database_name', 'sqlalchemy_uri'] edit_columns = add_columns
class PersonView(ModelView): datamodel = SQLAInterface(Person)
class CourtView(ModelView): datamodel = SQLAInterface(Court) list_columns = add_columns = edit_columns = [ 'name', 'description', 'district' ] #'mobile', 'alt_mobile', 'email', 'facebook','twitter' , 'gcode' ] search_list = ['name', 'district', 'mobile', 'email']
class PoliceStatView(ModelView): datamodel = SQLAInterface(PoliceStation) list_columns = add_columns = edit_columns = [ 'name', 'description', 'officer_commanding', 'mobile', 'alt_mobile', 'email', 'facebook', 'twitter', 'gcode' ]
class GenderView(ModelView): datamodel = SQLAInterface(Gender) list_fieldset = ref_fieldset
class CaseView(ModelView): datamodel = SQLAInterface(Case) list_columns = [ 'open_date', 'ob_number', 'case_type', 'case_category', 'case_closed' ] #add_columns = ['ob_number', 'open_date', 'case_type', 'case_category', 'status', 'report', 'people' ] related_views = [PersonView] show_template = 'appbuilder/general/model/show_cascade.html' edit_exclude_columns = hide_list add_fieldsets = show_fieldsets = [ ('Category', { 'fields': ['open_date', 'case_type', 'case_category', 'status'] }), ('Responsibility', { 'fields': ['reporting_officer', 'investigating_officer'], 'expanded': False }), ('Investigation', { 'fields': [ 'investigating_officer', 'investigation_status', 'investigation_outcomes' ], 'expanded': False }), ('Arrest', { 'fields': [ 'arresting_officer', 'arrest_location', 'arrest_narrative', 'warrant_date', 'warrant_details' ], 'expanded': False }), ('Documentation', { 'fields': [ 'evidence_collected', 'evidence_pictures', 'document_list', 'document_count', 'documents' ], 'expanded': False }), ('Charge', { 'fields': [ 'charge_date', 'charge_description', 'document_count', 'documents' ], 'expanded': False }), ('Court', { 'fields': [ 'charge_court', 'first_hearing_date', 'hearing_dates', 'court_outcome', 'case_duration' ], 'expanded': False }), ('Offenders', { 'fields': ['offender_picture'], 'expanded': False }), ]
class TeacherView(ModelView): datamodel = SQLAInterface(Teacher)
class GroupModelView(ModelView): datamodel = SQLAInterface(ContactGroup) related_views = [ContactModelView]
class LogModelView(CaravelModelView): datamodel = SQLAInterface(models.Log) list_columns = ('user', 'action', 'dttm') edit_columns = ('user', 'action', 'dttm', 'json') base_order = ('dttm', 'desc')