def get(self): ''' Returns the configuration in JSON format. ''' cnfg = ConfigurationModel.find() if cnfg: return cnfg.tojson() return {'message': "Client settings not found"}, 404 #not found
def post(self,name): ''' Creates a new client inquriy, if not already existing under the same name. ''' cnfg = ConfigurationModel.find() if cnfg is None or cnfg.dsgvo != 1: return {'message': "Configuration error. Check your GDPR/DSGVO settings."}, 400 #bad request if ClientInquiriesModel.find_by_name(name): return {'message': "Inquiry with name '{}' already exists.".format(name)}, 400 #bad request #schreibe zeugs in db data = resources.parsers.ParseClientInquiriesPost.parser.parse_args() #check if description is empty description = "" if (data['qdescription'] is not None): description = data['qdescription'] # answer, prr_answer and irr_answer will set to 0 answer = [0]* len(data['options']) prr = [0]* len(data['options']) irr = [0]* len(data['options']) #validity checks if not check_type(data['type']): return {'message': "type must be 'cbx', 'mc' or 'bool'."}, 400 #bad request if (data['type'] == 'bool' and len(data['options']) != 2): return {'message': "when type 'bool' is chosen, only 2 answer options are possible."}, 400 #bad request if not check_if_bits(answer): return {'message': "only 0s and 1s allowed in answers"}, 400 #bad request if not check_fpq(config_f, config_p, config_q): return {'message': "f,p and q must have values between 0.0 and 1.0"}, 400 #bad request inquiry = ClientInquiriesModel(name, data['type'], json.dumps(data['options']), json.dumps(answer), #json.dumps(data['answer']), json.dumps(prr), json.dumps(irr), description, False, #responded is False, because inquiry is created but not answered yet. config_locked, #data['locked'], cnfg.global_f, #config_f, until first edit by the user global values are used instead of data['f'], cnfg.global_p, #config_p, #until first edit by the user global values are used instead of data['p'], cnfg.global_q) #config_q) #until first edit by the user global values are used instead of data['q']) try: inquiry.save_to_db() except: return {'message': "error while inserting inquiry with name '{}'.".format(name)}, 500 #internal server error return inquiry.tojson(), 201 #created
def inquiries_create(): ''' Create new inquiries (web GUI). ''' cnfg = ConfigurationModel.find() if cnfg is None: abort(404) form = InquiryCreateForm() if form.validate_on_submit(): inquiries = json.loads(form.questions.data) # print("client inquiries") # print(type(inquiries)) # print(inquiries) for inquiry in inquiries: #length_options_list = len(json.loads(inquiry['options'])) length_options_list = len(inquiry['options']) print("inquiry") print(inquiry) print("liste laenge") print(length_options_list) options = inquiry['options'] print("options") print(options) inq = ClientInquiriesModel( name=inquiry['name'], type=inquiry['type'], options=json.dumps(inquiry['options']), answer=json.dumps([0] * length_options_list), prr_answer=json.dumps([0] * length_options_list), irr_answer=json.dumps([0] * length_options_list), qdescription=inquiry['description'], responded=False, locked=True, f=cnfg.global_f, p=cnfg.global_p, q=cnfg.global_q) try: inq.save_to_db() except: return render_template('/error_pages/500.html', title='error while creating inquiry.') return redirect('inquiries/') return render_template('inquiries/create.html', form=form, title='create new inquiries')
def settings(): ''' Configuration page (web GUI). ''' cnfg = ConfigurationModel.find() if cnfg is None: abort(404) form = SettingsForm() #sets the values in the form if request.method != 'POST': form.dsgvo.default = cnfg.dsgvo form.quiz.default = cnfg.quizmode form.f.default = cnfg.global_f form.p.default = cnfg.global_p form.q.default = cnfg.global_q form.process() if form.validate_on_submit(): dsgvo = form.dsgvo.data quiz = form.quiz.data f = form.f.data p = form.p.data q = form.q.data if not check_fpq(f, p, q): print("Only values between 0 and 1 allowed for f,p,q!") #debug flash("Only values between 0 and 1 allowed for f,p,q!") return render_template('settings.html', form=form, cnfg=cnfg, title='client settings') cnfg.dsgvo = dsgvo cnfg.quizmode = quiz cnfg.global_f = f cnfg.global_p = p cnfg.global_q = q try: cnfg.save_to_db() except: return render_template( '/error_pages/500.html', title='error while trying to save inquiries.') return render_template('settings.html', form=form, cnfg=cnfg, title='client settings')
def inquiries_privacy(id): ''' This is for privacy settings. ''' #access is only allowed if gdpr is set to true cnfg = ConfigurationModel.find() if cnfg is None: abort(404) if cnfg.dsgvo != 1: print("info works") return redirect(url_for('gdpr')) inq = ClientInquiriesModel.find_by_id(id) if inq is None: abort(404) form = PrivacyForm() if form.validate_on_submit(): #answer = form.answer.data locked = form.locked.data f = form.f.data p = convert_range(form.p.data) q = convert_range(form.q.data) if not check_fpq(f, p, q): print("Only values between 0 and 1 allowed for f,p,q!") #debug flash("Only values between 0 and 1 allowed for f,p,q!") return render_template('inquiries/privacy.html', inq=inq, form=form, title='privacy settings') inq.f = f inq.p = p inq.q = q try: inq.save_to_db() except: return render_template( '/error_pages/500.html', title='error while trying to save inquiries.') return render_template('inquiries/privacy.html', inq=inq, form=form, title='privacy')
def inquiries_list(): ''' List all client inquiries (web GUI). ''' #access is only allowed if gdpr is set to true cnfg = ConfigurationModel.find() if cnfg is None: abort(404) if cnfg.dsgvo != 1: print("info works") return redirect(url_for('gdpr')) inqs = (db.session.query(ClientInquiriesModel).order_by( ClientInquiriesModel.id.desc()).all()) return render_template('inquiries/inquiries.html', inqs=inqs, title='list of inquiries')
def put(self): ''' Allows to change the configuration. There is no post request, because the configuration is treated as singleton. ''' data = resources.parsers.ParseConfiguration.parser.parse_args() cnfg = ConfigurationModel.find() if cnfg is None: return {'message': "No configuration available"}, 400 #bad request if not check_fpq(data['global_f'],data['global_p'],data['global_q']): return {'message': "Global f,p and q must have values between 0.0 and 1.0"}, 400 #bad request cnfg.global_f = data['global_f'] cnfg.global_p = data['global_p'] cnfg.global_q = data['global_q'] cnfg.dsgvo = data['dsgvo'] cnfg.quizmode = data['quizmode'] try: cnfg.save_to_db() except: return {'message': "Error while setting configuration data."}, 500 return cnfg.tojson(), 201 # created
def put(self,name): ''' Changes a client inquiry by its name. The following values can be changed by the user: answers, description, locked, f,p and q. ''' cnfg = ConfigurationModel.find() if cnfg is None or cnfg.dsgvo != 1: return {'message': "Configuration error. Check your GDPR/DSGVO settings."}, 400 #bad request data = resources.parsers.ParseClientInquiriesPut.parser.parse_args() inquiry = ClientInquiriesModel.find_by_name(name) if inquiry is None: return {'message': "Can not change status, inquiry '{}' does not exist".format(name)}, 400 #bad request #check if description is empty description = data['qdescription'] if (data['qdescription'] is None): description = inquiry.qdescription #check if the lengt of the answer is correct (still the same). if not (len(data['answer']) == len(json.loads(inquiry.answer))): print("laenge") print(len(data['answer'])) print(len(json.loads(inquiry.answer))) return {'message': "old and new answer must have the same amount of options."}, 400 #bad request #check bool if not check_bool(inquiry.type,data['answer']): return {'message': "error: give a correct answer for type 'bool'."}, 400 #bad request #check mc if not check_mc(inquiry.type,data['answer']): return {'message': "error: only one answer options is allowed for mc questions."}, 400 #bad request #answer must be a list of 0s and 1s if not check_if_bits(data['answer']): return {'message': "only 0s and 1s allowed in answers"}, 400 #bad request # user answer must have as many values as inquiry options if (len(json.loads(inquiry.options)) is not len(data['answer'])): return {'message': "Your answer must have as many values as options are available"}, 400 #bad request if not check_fpq(data['f'],data['p'],data['q']): return {'message': "f,p and q must have values between 0.0 and 1.0"}, 400 #bad request # PRR and IRR will be only made if answer changes if (inquiry.answer != json.dumps(data['answer'])): inquiry.answer = json.dumps(data['answer']) # a PRR will be made after a answer is was changed prr = permanent_RandomizedResponse(float(data['f']),data['answer']) inquiry.prr_answer = json.dumps(prr) # a PRR will be made after a answer is was changed irr = instantaneous_RandomizedResponse(float(data['p']),float(data['q']),prr) inquiry.irr_answer = json.dumps(irr) # if a answer was given by the user, responded will be set to TRUE inquiry.responded = True inquiry.qdescription = description #data['qdescription'] inquiry.locked = data['locked'] inquiry.f = data['f'] inquiry.p = data['p'] inquiry.q = data['q'] try: inquiry.save_to_db() except: return {'message': "error while saving inquiry with name: '{}'.".format(name)}, 500 #internal server error return inquiry.tojson(), 202 #accepted
def create_configuration(): cnfg = ConfigurationModel.find() if cnfg is None: client = ConfigurationModel() client.save_to_db()
def inquiries_detail(id): ''' Detailed view of an inquiry (web GUI). ''' #access is only allowed if gdpr is set to true cnfg = ConfigurationModel.find() if cnfg is None: abort(404) if cnfg.dsgvo != 1: print("info works") return redirect(url_for('gdpr')) inq = ClientInquiriesModel.find_by_id(id) if inq is None: abort(404) # if the user changes a client inquiry, responded will be set to TRUE # and a PRR will be made with the answer value form = InquiryDetailForm() if inq.type == 'mc': form.radio_elem.description = inq.qdescription form.radio_elem.choices = [('_'.join(o.lower().split(' ')), o) for o in json.loads(inq.options)] form.radio_elem.name = inq.name elif inq.type == 'cbx': form.checkbox_elem.description = inq.qdescription form.checkbox_elem.name = inq.name form.checkbox_elem.choices = [('_'.join(o.lower().split(' ')), o) for o in json.loads(inq.options)] elif inq.type == 'bool': form.boolean_elem.description = inq.qdescription form.boolean_elem.name = inq.name form.boolean_elem.choices = [('_'.join(o.lower().split(' ')), o) for o in json.loads(inq.options)] else: abort(400, "Unknown question type {}".format(inq.type)) if form.validate_on_submit(): answer = form.answer.data locked = form.locked.data f = inq.f p = inq.p q = inq.q # check length of answer if not (len(json.loads(answer)) == len(json.loads(inq.answer))): print("answer must have the same ordinal values!") #debug flash("answer must have the same ordinal values!") return render_template('inquiries/inquiry.html', inq=inq, form=form, title='question') # if bits are zero and one if not check_if_bits(json.loads(answer)): print("only 0s and 1s allowed in the answer list") #debug flash("only 0s and 1s allowed in the answer list") return render_template('inquiries/inquiry.html', inq=inq, form=form, title='question') # a PRR and IRR will be set after a answer is was changed if (inq.answer != answer): prr = permanent_RandomizedResponse(float(f), json.loads(answer)) inq.prr_answer = json.dumps(prr) irr = instantaneous_RandomizedResponse(float(p), float(q), prr) inq.irr_answer = json.dumps(irr) inq.answer = answer inq.responded = True # if a answer was given by the user, responed will be set to TRUE inq.locked = locked # inq.f = inq.f # inq.p = inq.p # inq.q = inq.q try: inq.save_to_db() except: return render_template( '/error_pages/500.html', title='error while trying to save inquiries.') return render_template('inquiries/inquiry.html', inq=inq, form=form, title='question')
def get(self): ''' The get request fetches all client inquiries which are not locked and answered by the use If they match in name, type and length of options they will be stored in reports belonging to a specific survey id. ''' # clinet inquiries which are not locked and answered by the user client = ClientInquiriesModel.query.filter_by(locked='0').filter_by( responded='1').all() cnfg = ConfigurationModel.find() # all server inquiries server = ServerInquiriesModel.query.all() # print('client inquiries') #debug # print(client) #debug # print('server inquiries') #debug # print(server) #debug # print("---------------------") #debug # 1st: find all matches matches = find_matches(client, server) # print("matches") #debug # print(matches) #debug # print("---------------------") #debug # 2nd: identify all surveyids which have an match surveys = find_matching_surveys(matches) # print("surveys which have matches matches") #debug # print(surveys) #debug # print("---------------------") #debug # 3) generate report data and save the reports to the database for survey in surveys: surveyid = survey prr = 1 #deprecated, since every inquiry gets an PRR irr = 1 #for future usage: Basic RAPPOR mode. f = cnfg.global_f p = cnfg.global_p q = cnfg.global_q #3b) generate answers json.dumps(data['answers']) answers = generate_answers_by_surveyid(survey, matches) print("testanswers") print(answers) print(type(answers)) # save them to the db report = ReportModel(surveyid, prr, irr, f, p, q, json.dumps(answers)) if not ReportModel.find_report_by_surveyid(surveyid): try: report.save_to_db() return { 'message': "report sucessful matched and saved to db" }, 202 #accepted except: return { 'message': "error while inserting report for surveyid'{}'. ". format(surveyid) }, 500 #internal server error return {'message': "no new matches."}, 200 #ok
def get(self): ''' Request new surveys from the server. If the data is valid, the surveys are stored into the server inquiries table. If quizmode is activated, they will be also saved in the client inquiries table. ''' # contact the server of the serviceprovider. get surveys if suceed cnfg = ConfigurationModel.find() if cnfg is None: return { 'message': "Configuration error." }, 500 #internal server error try: r = requests.get(serviceprovider_surveys) umfragen = r.json() listevonsurveys = (umfragen['surveys']) except requests.exceptions.ConnectionError as e: print(e) #debug return { 'message': "server not available. no survey was requested: {} ".format(e) }, 400 #bad request #this creates client inquiries if quizmode is set. print(cnfg.quizmode) if cnfg.quizmode is 1: print("quizmode is true") for survey in listevonsurveys: inquiries = (survey['questions'] ) #fuer jedes dictonairy in der liste for inq in inquiries: name = inq['name'] qtype = inq['type'] options = inq['options'] options_count = len(inq['options']) answer = [0] * options_count prr_answer = [0] * options_count irr_answer = [0] * options_count qdescription = inq['description'] responded = False locked = config_locked f = cnfg.global_f p = cnfg.global_p q = cnfg.global_q if ClientInquiriesModel.find_by_name(name): print("client inquiry with name " + name + "already in db") #debug continue else: if check_type(qtype): inquiry = ClientInquiriesModel( name, qtype, json.dumps(options), json.dumps(answer), json.dumps(prr_answer), json.dumps(irr_answer), qdescription, responded, locked, f, p, q) inquiry.save_to_db() print( "quizmode on: new inquiry with name '{}' saved to client inquiry." .format(name)) continue #print("error: Type '{}' not correct.".format(qtype)) # creates questions and save the to the db for survey in listevonsurveys: #for every dictonairy in a list of dictionairies #generate surveyids, serviceprovider for the questions format surveyid = (survey['surveyid']) serviceprovider = (survey['serviceprovider']) #generate qid, qname, qtype, qoptions and qdescpritons for the questions format questions = (survey['questions']) for question in questions: qid = question['qid'] name = question['name'] qtype = question['type'] options = question['options'] qdescription = question['description'] #save question to the db, only if it is not already known by surveyid #if survey is in archive, inquiries will not saved. if ArchiveModel.find_by_surveyid(surveyid): print( "survey already in archive. ".format(surveyid)) #debug continue elif ServerInquiriesModel.already_in_db(surveyid, name): print( "survey and matching inquiries already in DB") #debug continue else: print("surveyid: " + surveyid) #debug print("serviceprovider: " + serviceprovider) #debug print("qid: " + str(qid)) #debug print("qname: " + name) #debug print("qtype: " + qtype) #debug print("qoptions: " + json.dumps(options)) #debug print("qdescription: " + qdescription) #debug print("____________________________") #debug if check_type(qtype): frage = ServerInquiriesModel( qid, surveyid, serviceprovider, name, qtype, json.dumps(options), qdescription, config_locked, cnfg.quizmode) frage.save_to_db() print( "new survey with surveyid '{}' available and fetched from the server." .format(surveyid)) print("error: Type '{}' not correct.".format(qtype)) # create a new entry in the archive: if not ArchiveModel.find_by_surveyid(surveyid): rchv = ArchiveModel(surveyid) rchv.save_to_db() return {'message': "done."}, 200 #ok
def get(self): ''' Sends a report to the server. After the report was sent, it deletes the report from the client and server inquiries belonging to them. ''' cnfg = ConfigurationModel.find() if cnfg is None or cnfg.dsgvo != 1: return { 'message': "Can't send reports with GDPR/DSGVO consent." }, 400 #bad request if ReportModel.query.first(): report = ReportModel.query.first() print('report') #debug print(report) #debug print('------------------------------------') #debug print("Name of the surveyid: " + report.surveyid) #debug surveyid = report.surveyid report_serviceprovider = { 'prr': 1, 'irr': 1, 'f': report.f, 'p': report.p, 'q': report.q, 'answers': json.loads(report.answers) } print(report_serviceprovider) #debug # contact the server of the serviceprovider. send report if suceed try: r = requests.post(serviceprovider_reports + surveyid, json=report_serviceprovider) code_response = r.status_code print(r.json()) #debug print(code_response) #debug except requests.exceptions.ConnectionError as e: print(e) #debug return { 'message': "server not available. no report was sent: {} ".format(e) }, 500 #ok # a archive entry is made, for not answering surveys twice. report_to_delete = ReportModel.find_by_surveyid(surveyid) #new rchv = ArchiveModel.find_by_surveyid(surveyid) rchv.processed = True rchv.exit = datetime.now().strftime('%d.%m.%Y - %H:%M:%S') # after the report was sent to the server, it should be deleted from the DB if report_to_delete: try: ServerInquiriesModel.delete_all_inqs_by_surveyid(surveyid) report_to_delete.delete_from_db() rchv.save_to_db() if config_quizmode: #TODO: delete also all client inquries. #ClientInquiriesModel.delete_all_client_inquiries() pass print( 'report and all server inquiries belonging to the report deleted from db.' ) #debug except: return { 'message': "error while deleting report" }, 500 #internal server error return { 'message': "report to surveyid '{}' was sent to the serviceprovider.". format(surveyid) }, 200 #ok return {'message': "no reports to send."}, 200 #ok