class AllianceSubmission(plugins.SingletonPlugin): plugins.implements(plugins.IMediaSubmission) plugins.implements(plugins.IJSONSubmission) # Implements IJSONSubmission def before_processing_submission( self, request, user, project, form, assistant, json_file ): return 0, "" def after_processing_submission_in_repository( self, request, user, project, form, assistant, submission, error, json_file ): if project == request.registry.settings.get("ftp.project"): settings = {} for key, value in request.registry.settings.items(): if isinstance(value, str): settings[key] = value # Call the Celery process to process any images into the FTP ftp_transfer.apply_async( (settings, submission,), queue="FormShare", ) def after_processing_submission_not_in_repository( self, request, user, project, form, assistant, submission, json_file ): pass # Implements IMedia def after_storing_media_in_repository( self, request, user, project, form, assistant, submission, json_file, media_file ): if project == request.registry.settings.get("ftp.project"): image = imghdr.what(media_file) if image is None: image = False else: image = True if image: ftp_repository_path = request.registry.settings.get( "ftp.repository.path" ) repository_path = os.path.join(ftp_repository_path, *[submission]) if not os.path.exists(repository_path): os.makedirs(repository_path) file_name = submission + "_" + os.path.basename(media_file) repository_file = os.path.join(repository_path, *[file_name]) # Copy the file into the repository shutil.copy(media_file, repository_file) # Reducing media file to 100X100 thumbnail im = Image.open(media_file) im.thumbnail((100, 100)) im.save(media_file) def after_storing_media_not_in_repository( self, request, user, project, form, assistant, submission, json_file, media_file ): pass
class alliance_branding(plugins.SingletonPlugin): plugins.implements(plugins.IConfig) plugins.implements(plugins.ITranslation) def update_config(self, config): # We add here the templates of the plugin to the config u.add_templates_directory(config, "templates") u.add_static_view(config, "alliance", "static") def get_translation_directory(self): module = sys.modules["alliance_branding"] return os.path.join(os.path.dirname(module.__file__), "locale") def get_translation_domain(self): return "alliance_branding"
class AllianceODataDeployment(plugins.SingletonPlugin): plugins.implements(IWARFileCreated) def after_create(self, request, absolute_path): _ = request.translate scp_cert_file = request.registry.settings.get("odata.scp.certfile") scp_cert_user = request.registry.settings.get("odata.scp.user") scp_cert_host = request.registry.settings.get("odata.scp.host") scp_cert_directory = request.registry.settings.get( "odata.scp.directory") try: args = [ "scp", "-i", scp_cert_file, absolute_path, "{}@{}:{}".format(scp_cert_user, scp_cert_host, scp_cert_directory), ] log.error("Deploying {} through SCP. Command: {}".format( absolute_path, " ".join(args))) p = Popen(args, stdout=PIPE, stderr=PIPE) stdout, stderr = p.communicate() if p.returncode == 0: return True else: log.error( "Error while deploying WAR file {} through SCP. Error: {}". format(absolute_path, stdout.decode() + " " + stderr.decode())) return False except Exception as e: log.error( "Error while deploying WAR file {} through SCP. Error: {}". format(absolute_path, str(e))) return False
import formshare.plugins as plugins import formshare.plugins.utilities as u from .views import MyPublicView, MyPrivateView import sys import os class {{ cookiecutter.plugin_name }}(plugins.SingletonPlugin): plugins.implements(plugins.IRoutes) plugins.implements(plugins.IConfig) plugins.implements(plugins.ITranslation) plugins.implements(plugins.IDatabase) def before_mapping(self, config): # We don't add any routes before the host application return [] def after_mapping(self, config): # We add here a new route /json that returns a JSON custom_map = [ u.add_route( "plugin_mypublicview", "/mypublicview", MyPublicView, "public.jinja2" ), u.add_route( "plugin_myprivateview", "/user/{userid}/myprivateview", MyPrivateView, "private.jinja2", ), ]
class alliance_authentication(plugins.SingletonPlugin): plugins.implements(plugins.IConfig) plugins.implements(plugins.ITranslation) plugins.implements(plugins.IUserAuthentication) # Implements IConfig def update_config(self, config): # We add here the templates of the plugin to the config u.add_templates_directory(config, "templates") # Implements ITranslation def get_translation_directory(self): module = sys.modules["alliance_authentication"] return os.path.join(os.path.dirname(module.__file__), "locale") def get_translation_domain(self): return "alliance_authentication" # Implements IUserAuthentication def after_login(self, request, user): return True, "" def on_authenticate_user(self, request, user_id, user_is_email): return None, {} def on_authenticate_password(self, request, user_data, password): _ = request.translate java_java = request.registry.settings.get("java.authentication.jar") args = ["java", "-jar", java_java] if (request.registry.settings.get("java.authentication.remote", "false") == "true"): args.append("-r") args.append("-e") args.append(user_data["user_email"]) args.append("-p") args.append(password) time_out_flag = False def kill_time_out(process): nonlocal time_out_flag time_out_flag = True process.kill() try: p = Popen(args, stdout=PIPE, stderr=PIPE) time_out = Timer( 30, kill_time_out, [p]) # Wait 5 seconds to authenticate with CGIAR AD try: time_out.start() stdout, stderr = p.communicate() finally: time_out.cancel() except Exception as e: if not time_out_flag: log.error( "CGIARADAuthenticationError: " "Error while excuting Java authenticating user {}. Error: {}" .format(user_data["user_email"], str(e))) return ( False, _("Error while authenticating your account with the CGIAR AD" ), ) else: return ( False, _("Timeout while authenticating your account with the CGIAR AD" ), ) if time_out_flag: return ( False, _("Timeout while authenticating your account with the CGIAR AD" ), ) error_no = p.returncode if error_no == 0: return True, "" else: if error_no == 1: log.error( "CGIARADAuthenticationError: " "Error while authenticating user {}. Error: {}-{}".format( user_data["user_email"], stdout.decode(), stderr.decode())) return ( False, _("Error while authenticating your account with the CGIAR AD" ), ) if error_no == 2: log.error("CGIARADAuthenticationError: " "User {} provided an invalid password".format( user_data["user_email"])) return ( False, _("The email account does not exist or the password is invalid" ), ) def after_collaborator_login(self, request, collaborator): return True, ""
class odata(plugins.SingletonPlugin): plugins.implements(plugins.IRoutes) plugins.implements(plugins.IConfig) plugins.implements(plugins.ITranslation) plugins.implements(plugins.ISchema) plugins.implements(plugins.IResource) # Implements IResource def add_libraries(self, config): libraries = [u.add_library("odata", "resources")] return libraries def add_js_resources(self, config): odata_js = [ u.add_js_resource("odata", "footable", "footable/js/footable.min.js", None) ] return odata_js def add_css_resources(self, config): odata_css = [ u.add_css_resource("odata", "footable", "footable/css/footable.bootstrap.min.css", None) ] return odata_css # Implements IRoutes def before_mapping(self, config): # We don't add any routes before the host application return [] def after_mapping(self, config): # We add here a new route /json that returns a JSON custom_map = [ u.add_route( "odata_generate", "/user/{userid}/project/{projcode}/form/{formid}/odata/generate", ODataGenerateView, None, ), u.add_route( "odata_check", "/user/{userid}/project/{projcode}/form/{formid}/odata/check", ODataCheckView, None, ), u.add_route( "odata_users", "/user/{userid}/project/{projcode}/form/{formid}/odata/users", ODataUsersView, "odata/users_and_groups.jinja2", ), u.add_route( "odata_change_access", "/user/{userid}/project/{projcode}/form/{formid}/odata/change", ODataChangeAccessView, None, ), u.add_route( "odata_table_access", "/user/{userid}/project/{projcode}/form/{formid}/odata/tables/{odatauser}", ODataTableAccessView, "odata/user_access.jinja2", ), u.add_route( "odata_table_action", "/user/{userid}/project/{projcode}/form/{formid}/odata/tables/{odatauser}/action", ODataActionView, "json", ), ] return custom_map def update_config(self, config): # We add here the templates of the plugin to the config u.add_templates_directory(config, "templates") def get_translation_directory(self): module = sys.modules["odata"] return os.path.join(os.path.dirname(module.__file__), "locale") def get_translation_domain(self): return "odata" # Implements ISchema. This will include a field called OData as part of a form DB schema def update_schema(self, config): return [ u.add_field_to_form_schema("odata_artifact", "Artifact ID"), u.add_field_to_form_schema("odata_request", "Request ID"), u.add_field_to_form_schema("odata_status", "Request status"), u.add_field_to_form_schema("odata_url_v2", "Version 2 URL"), u.add_field_to_form_schema("odata_url_v4", "Version 4 URL"), u.add_field_to_form_access_schema( "odata_access", "Whether the assistant has OData access"), ]
class ODataAccess(plugins.SingletonPlugin): plugins.implements(plugins.IAssistant) plugins.implements(plugins.IFormAccess) plugins.implements(plugins.ITranslation) def get_translation_directory(self): module = sys.modules["odata"] return os.path.join(os.path.dirname(module.__file__), "locale") def get_translation_domain(self): return "odata" # Implements IAssistant def before_create(self, request, user, project, assistant_data): return assistant_data, True, "" def after_create(self, request, user, project, assistant_data): pass def before_edit(self, request, user, project, assistant, assistant_data): return assistant_data, True, "" def after_edit(self, request, user, project, assistant, assistant_data): if assistant_data.get("coll_active", 0) == 0: res = (request.dbsession.query( Odkform.form_id, Odkform.project_id, Odkform.form_schema, Odkform.extras, ).filter(Odkform.project_id == Formacces.form_project).filter( Odkform.form_id == Formacces.form_id).filter( Formacces.project_id == project).filter( Formacces.coll_id == assistant).filter( Odkform.form_schema.isnot(None)).filter( Odkform.extras.isnot(None)).all()) mapped_data = map_from_schema(res) if mapped_data: for an_assistant in mapped_data: if an_assistant.get("odata_status", 0) == 1: sql = "DELETE FROM {}.odatauser WHERE user_name = '{}'".format( an_assistant["form_schema"], assistant) try: request.dbsession.execute(sql) mapped_data = map_to_schema( Formacces, {"odata_access": "0"}) request.dbsession.query(Formacces).filter( Formacces.project_id == project).filter( Formacces.coll_id == assistant).filter( Formacces.form_project == an_assistant["project_id"]).filter( Formacces.form_id == an_assistant["form_id"]).update( mapped_data) except Exception as e: log.error("ODataAccess Error: {}".format(str(e))) def before_delete(self, request, user, project, assistant): res = (request.dbsession.query( Odkform.form_schema, Odkform.extras).filter( Odkform.project_id == Formacces.form_project).filter( Odkform.form_id == Formacces.form_id).filter( Formacces.project_id == project).filter( Formacces.coll_id == assistant).filter( Odkform.form_schema.isnot(None)).filter( Odkform.extras.isnot(None)).all()) mapped_data = map_from_schema(res) can_delete = True if mapped_data: for an_assistant in mapped_data: if an_assistant.get("odata_status", 0) == 1: sql = "SELECT count(*) FROM {}.odatauser WHERE user_name = '{}'".format( an_assistant["form_schema"], assistant) try: res = request.dbsession.execute(sql).fetchone() if res[0] != 0: can_delete = False break except Exception as e: log.error("ODataAccess Error: {}".format(str(e))) if can_delete: return True, "" else: _ = request.translate return ( False, _("This assistant has an OData access and cannot be deleted. " "Deactivate it first before deleting it"), ) def after_delete(self, request, user, project, assistant): pass def before_password_change(self, request, user, project, assistant, password): return True, "" def after_password_change(self, request, user, project, assistant, password): res = (request.dbsession.query( Odkform.form_schema, Odkform.extras).filter( Odkform.project_id == Formacces.form_project).filter( Odkform.form_id == Formacces.form_id).filter( Formacces.project_id == project).filter( Formacces.coll_id == assistant).filter( Odkform.form_schema.isnot(None)).filter( Odkform.extras.isnot(None)).all()) mapped_data = map_from_schema(res) if mapped_data: encrypted_password = encode_data(request, password) for an_assistant in mapped_data: if an_assistant.get("odata_status", 0) == 1: sql = "UPDATE {}.odatauser SET user_password = '******' WHERE user_name = '{}'".format( an_assistant["form_schema"], encrypted_password.decode(), assistant, ) try: request.dbsession.execute(sql) except Exception as e: log.error("ODataAccess Error: {}".format(str(e))) # Implements IFormAccess def before_giving_access( self, request, user, project, form, assistant_project, assistant_id, privilege_data, ): res = (request.dbsession.query( Odkform.form_schema, Odkform.extras).filter(Odkform.project_id == project).filter( Odkform.form_id == form).filter( Odkform.form_schema.isnot(None)).filter( Odkform.extras.isnot(None)).first()) mapped_data = map_from_schema(res) if mapped_data: if mapped_data.get("odata_status", 0) == 1: privilege_data["odata_access"] = 0 return privilege_data, True, "" def after_giving_access( self, request, user, project, form, assistant_project, assistant_id, privilege_data, ): pass def before_editing_access( self, request, user, project, form, assistant_project, assistant_id, privilege_data, ): res = (request.dbsession.query( Odkform.form_schema, Odkform.extras).filter(Odkform.project_id == project).filter( Odkform.form_id == form).filter( Odkform.form_schema.isnot(None)).filter( Odkform.extras.isnot(None)).first()) mapped_data = map_from_schema(res) if mapped_data: if mapped_data.get("odata_status", 0) == 1: if privilege_data["coll_privileges"] == "1": privilege_data["odata_access"] = 0 return privilege_data, True, "" def after_editing_access( self, request, user, project, form, assistant_project, assistant_id, privilege_data, ): res = (request.dbsession.query( Odkform.form_schema, Odkform.extras).filter(Odkform.project_id == project).filter( Odkform.form_id == form).filter( Odkform.form_schema.isnot(None)).filter( Odkform.extras.isnot(None)).first()) mapped_data = map_from_schema(res) if mapped_data: if mapped_data.get("odata_status", 0) == 1: if privilege_data["coll_privileges"] == "1": sql = "DELETE FROM {}.odatauser WHERE user_name = '{}'".format( mapped_data["form_schema"], assistant_id) try: request.dbsession.execute(sql) except Exception as e: log.error("ODataAccess Error: {}".format(str(e))) def before_revoking_access(self, request, user, project, form, assistant_project, assistant_id): return True, "" def after_revoking_access(self, request, user, project, form, assistant_project, assistant_id): res = (request.dbsession.query( Odkform.form_schema, Odkform.extras).filter(Odkform.project_id == project).filter( Odkform.form_id == form).filter( Odkform.form_schema.isnot(None)).filter( Odkform.extras.isnot(None)).first()) mapped_data = map_from_schema(res) if mapped_data: if mapped_data.get("odata_status", 0) == 1: sql = "DELETE FROM {}.odatauser WHERE user_name = '{}'".format( mapped_data["form_schema"], assistant_id) try: request.dbsession.execute(sql) except Exception as e: log.error("ODataAccess Error: {}".format(str(e)))
class ext_climate(plugins.SingletonPlugin): plugins.implements(plugins.IRoutes) plugins.implements(plugins.IConfig) plugins.implements(plugins.ISchema) plugins.implements(plugins.IProject) plugins.implements(plugins.IDatabase) plugins.implements(plugins.IResource) plugins.implements(plugins.IForm) def before_mapping(self, config): # We don't add any routes before the host application return [] def after_mapping(self, config): # We add here a new route /json that returns a JSON custom_map = [] custom_map.append( u.add_route("plugin_mypublicview", "/mypublicview", MyPublicView, "public.jinja2")) custom_map.append( u.add_route( "plugin_myprivateview", "/user/{userid}/myprivateview", MyPrivateView, "private.jinja2", )) custom_map.append( u.add_route( "status", "/user/{userid}/status/{prj}", PrjStatus, "json", )) custom_map.append( u.add_route( "sensimap", "/user/{userid}/sensimap/{prj}/{div}", SensiMap, "json", )) custom_map.append( u.add_route( "report", "/user/{userid}/report/{prj}", PrjReport, "json", )) return custom_map def update_config(self, config): # We add here the templates of the plugin to the config u.add_templates_directory(config, "templates") u.add_static_view(config, "climate", "static") def update_schema(self, config): new_fields = [ u.add_field_to_project_schema("is_climate", "Project is for climate") ] return new_fields def before_create(self, request, user, project_data): user_climate = request.registry.settings.get("climate.user", "") if user_climate == user: project_data["is_climate"] = 1 else: project_data["is_climate"] = 0 return project_data, True, "" def after_create(self, request, user, project_data): pass # Implements IDatabase def update_orm(self, metadata): t = Table( "extTask", metadata, Column("id_task", Unicode(120), primary_key=True), Column("project", Unicode(120)), ) metadata.create_all() mapper(ExtTask, t) # Implements IResource def add_libraries(self, config): # We add here our new library using the resources directory of the plugin libraries = [] libraries.append(u.add_library("myResource", "resources")) return libraries def add_js_resources(self, config): # You can add your JS resources here myJS = [] myJS.append( u.add_js_resource("myResource", "sparkline", "js/sparkline/jquery.sparkline.min.js")) myJS.append( u.add_js_resource("myResource", "flot", "js/flot/jquery.flot.js")) myJS.append( u.add_js_resource("myResource", "flotTooltip", "js/flot/jquery.flot.tooltip.min.js")) myJS.append( u.add_js_resource("myResource", "flotSpline", "js/flot/jquery.flot.spline.js")) myJS.append( u.add_js_resource("myResource", "flotResize", "js/flot/jquery.flot.resize.js")) myJS.append( u.add_js_resource("myResource", "chosen", "js/chosen/chosen.jquery.js", None)) myJS.append( u.add_js_resource("myResource", "chartjs", "js/chartJs/Chart.min.js", None)) myJS.append( u.add_js_resource("myResource", "ligthbox", "js/ligthbox/lightbox.js", None)) myJS.append( u.add_js_resource("myResource", "datepicker", "js/datapicker/bootstrap-datepicker.js", None)) myJS.append( u.add_js_resource("myResource", "datatablesB", "js/dataTables/dataTables.bootstrap4.min.js", None)) myJS.append( u.add_js_resource("myResource", "datatables", "js/dataTables/datatables.min.js", None)) return myJS def add_css_resources(self, config): # You can add your CSS resources here myCSS = [] # myCSS.append(u.addCSSResource('mylibrary', 'myCSSResource', 'relative/path/to/resources/myresource.css')) myCSS.append( u.add_css_resource('myResource', 'animate', 'css/animate.css')) myCSS.append( u.add_css_resource('myResource', 'bootstrap', 'css/bootstrap.css')) myCSS.append(u.add_css_resource('myResource', 'style', 'css/style.css')) myCSS.append( u.add_css_resource('myResource', 'font', 'css/font-awesome.css')) myCSS.append( u.add_css_resource('myResource', 'chosen', 'css/chosen/bootstrap-chosen.css', None)) myCSS.append( u.add_css_resource('myResource', 'ligthbox', 'css/ligthbox/lightbox.css', None)) myCSS.append( u.add_css_resource('myResource', 'datepicker', 'css/datapicker/datepicker3.css', None)) myCSS.append( u.add_css_resource('myResource', 'datatables', 'css/dataTables/datatables.min.css', None)) myCSS.append( u.add_css_resource('myResource', 'spinners', 'css/textSpinners/spinners.css', None)) return myCSS def after_form_checks(self, request, user, project, form, form_data, form_directory, survey_file, create_file, insert_file, itemsets_csv): if request.registry.settings.get("climate.user", "") == user: return validateForm(create_file) else: return True, ""
class CNE(plugins.SingletonPlugin): plugins.implements(plugins.IRoutes) plugins.implements(plugins.IConfig) plugins.implements(plugins.ITranslation) plugins.implements(plugins.IProduct) plugins.implements(plugins.IExport) plugins.implements(plugins.ITemplateHelpers) def before_mapping(self, config): # We don't add any routes before the host application return [] def after_mapping(self, config): # We add here a new route /json that returns a JSON custom_map = [ u.add_route( "form_export_cne", "/user/{userid}/project/{projcode}/form/{formid}/export/cne_cheets", ExportCNESheets, "dashboard/projects/forms/export/cne.jinja2", ), u.add_route( "form_download_cne_sheets", "/user/{userid}/project/{projcode}/form/{formid}/generate/cne_sheets", GenerateCNESheets, None, ), ] return custom_map def update_config(self, config): # We add here the templates of the plugin to the config u.add_templates_directory(config, "templates") def get_translation_directory(self): module = sys.modules["cne"] return os.path.join(os.path.dirname(module.__file__), "locale") def get_translation_domain(self): return "cne" def update_orm(self, config): config.include("cne.orm") def update_extendable_tables(self, tables_allowed): tables_allowed.append("cne_example") return tables_allowed def update_extendable_modules(self, modules_allowed): modules_allowed.append("cne.orm.cne") return modules_allowed # ITemplateHelpers def get_helpers(self): return {"is_cne_form": is_cne_form} # IProduct def register_products(self, config): return [ { "code": "cne_sheets", "hidden": False, "icon": "far fa-file-archive", "metadata": { "author": "QLands Technology Consultants", "version": "10", "Licence": "QLands", }, }, ] def get_product_description(self, request, product_code): if product_code == "cne_sheets": return "Cuadros 8 y 9 (Zip)" def before_download_private_product(self, request, project, form, product, output, file_name, mime_type): return True def before_partner_download_private_product(self, request, partner, project, form, product, output, file_name, mime_type): return True def before_download_public_product(self, request, project, form, product, output, file_name, mime_type): return True def before_download_product_by_api(self, request, project, form, product, output, file_name, mime_type): return True def before_partner_download_product_by_api(self, request, partner, project, form, product, output, file_name, mime_type): return True # IExport def has_export_for(self, request, export_type): if export_type == "CNE": return True return False def do_export(self, request, export_type): if export_type == "CNE": user_id = request.matchdict["userid"] project_code = request.matchdict["projcode"] form_id = request.matchdict["formid"] return HTTPFound(location=request.route_url( "form_export_cne", userid=user_id, projcode=project_code, formid=form_id, ))
class enketo(plugins.SingletonPlugin): plugins.implements(plugins.IRoutes) plugins.implements(plugins.IConfig) plugins.implements(plugins.ITranslation) plugins.implements(plugins.ISchema) plugins.implements(plugins.IForm) # Implement IRoutes functions def before_mapping(self, config): # We don't add any routes before the host application return [] def after_mapping(self, config): # We add here a new route /json that returns a JSON custom_map = [ u.add_route( "enketo_get_url", "/user/{userid}/project/{projcode}/form/{formid}/plugins/enketo/start", GenerateEnketoURLView, "json", ), ] return custom_map # Implement IConfig functions. This will allow us to extend the interface def update_config(self, config): # We add here the templates of the plugin to the config u.add_templates_directory(config, "templates") # Implement ITranslation functions def get_translation_directory(self): module = sys.modules["enketo"] return os.path.join(os.path.dirname(module.__file__), "locale") def get_translation_domain(self): return "enketo" # Implements ISchema. This will include a field called Enketo_url as part of a form DB schema def update_schema(self, config): return [u.add_field_to_form_schema("enketo_url", "Enketo URL")] # Implements IForm. This will allow us get and delete an Enketo URL when an ODK form is created, # updated or deleted def after_odk_form_checks( self, request, user, project, form, form_data, form_directory, survey_file, create_file, insert_file, itemsets_csv, ): return True, "" def before_adding_form(self, request, form_type, user_id, project_id, form_id, form_data): return True, "", form_data def after_adding_form(self, request, form_type, user_id, project_id, form_id, form_data): if form_type == "ODK": project_code = get_project_code_from_id(request, user_id, project_id) form_url = request.route_url("project_details", userid=user_id, projcode=project_code) survey_data = {"server_url": form_url, "form_id": form_id} survey_data = json.loads(json.dumps(survey_data)) enketo_survey_url = urljoin( request.registry.settings.get("enketo.url"), "api/v2/survey") try: # Online Survey r = requests.post( enketo_survey_url, data=survey_data, auth=(request.registry.settings.get("enketo.apikey"), ""), ) if r.status_code == 200 or r.status_code == 201: # OffLine survey enketo_survey_url = urljoin( request.registry.settings.get("enketo.url"), "api/v2/survey/offline", ) r = requests.post( enketo_survey_url, data=survey_data, auth=(request.registry.settings.get("enketo.apikey"), ""), ) if r.status_code == 200 or r.status_code == 201: enketo_url = json.loads(r.text)["offline_url"] mapped_data = map_to_schema(Odkform, {"enketo_url": enketo_url}) request.dbsession.query(Odkform).filter( Odkform.project_id == project_id).filter( Odkform.form_id == form_id).update(mapped_data) else: log.error( "ENKETO PLUGIN. Unable to activate off-line survey with URL {}. Status code: {}" .format(form_url, r.status_code)) else: log.error( "ENKETO PLUGIN. Unable to activate survey with URL {}. Status code: {}" .format(form_url, r.status_code)) except Exception as e: log.error( "ENKETO PLUGIN Exception. Unable to activate survey with URL {}. Error: {}" .format(form_url, str(e))) def before_updating_form(self, request, form_type, user_id, project_id, form_id, form_data): return True, "", form_data def after_updating_form(self, request, form_type, user_id, project_id, form_id, form_data): pass def before_deleting_form(self, request, form_type, user_id, project_id, form_id): return True, "" def after_deleting_form(self, request, form_type, user_id, project_id, form_id): if form_type == "ODK": project_code = get_project_code_from_id(request, user_id, project_id) form_url = request.route_url("project_details", userid=user_id, projcode=project_code) survey_data = {"server_url": form_url, "form_id": form_id} survey_data = json.loads(json.dumps(survey_data)) enketo_survey_url = urljoin( request.registry.settings.get("enketo.url"), "api/v2/survey") try: r = requests.delete( enketo_survey_url, data=survey_data, auth=(request.registry.settings.get("enketo.apikey"), ""), ) if r.status_code != 204: log.error( "ENKETO PLUGIN. Unable to deactivate survey with URL {}. Status code: {}" .format(form_url, r.status_code)) except Exception as e: log.error( "ENKETO PLUGIN. Unable to delete survey with URL {}. Error: {}" .format(form_url, str(e)))