def admin_edithomemessage(): g.headcenter = "Edit home page message<br><a href='/admin/'>Back to admin home</a>" txt = "<script src='//cdn.ckeditor.com/4.6.0/full/ckeditor.js'></script>" message = "" NomFichier = 'appli/static/home/appmanagermsg.html' if gvp("msg", None) is not None: with open(NomFichier, 'w', encoding='utf-8', newline="\n") as f: f.write(gvp("msg")) if os.path.exists(NomFichier): with open(NomFichier, 'r', encoding='utf-8') as f: message = f.read() txt += """<form action=? method=post> Enter bellow the message you want display : <button type=button class='btn btn-default btn-sm' onclick='EnableCK()'>Enable HTML Editor</button><br> <textarea name=msg style='width:1000px;height:200px;'>{0}</textarea> <br><button type=submit class='btn btn-primary'>Save</button> </form> <script> function EnableCK() {{ CKEDITOR.replace( 'msg' ); }} </script> """.format(message) return PrintInCharte(txt)
def QuestionProcess(self): txt = "<h1>Test Task</h1>" if self.task.taskstep == 0: txt += "<h3>Task Creation</h3>" if gvp('starttask') == "Y": for k, v in self.param.__dict__.items(): setattr(self.param, k, gvp(k)) # Verifier la coherence des données if (len(self.param.InData) < 5): flash("Champ In Data trop court", "error") else: return self.StartTask(self.param) return render_template('task/testcreate.html', header=txt, data=self.param) if self.task.taskstep == 1: txt += "<h3>Task Question 1</h3>" if gvp('starttask') == "Y": self.param.InData2 = gvp("InData2") # Verifier la coherence des données if (len(self.param.InData2) < 5): flash("Champ In Data 2 trop court", "error") else: return self.StartTask(self.param, step=2) return render_template('task/testquestion1.html', header=txt, data=self.param) return PrintInCharte(txt)
def QuestionProcessScreenSelectSourceTaxo(self,Prj): # Second écran de configuration, choix des taxon utilisés dans la source # recupere les categories et le nombre d'occurence dans les projet de base/learning # sql = """select n.classif_id,t.name||case when p1.name is not null and t.name not like '%% %%' then ' ('||p1.name||')' else ' ' end as name sql = """select n.classif_id,t.display_name as name ,n.nbr from (select o.classif_id,count(*) nbr from obj_head o where projid in ({0}) and classif_qual='V' group by classif_id) n JOIN taxonomy t on n.classif_id=t.id left join taxonomy p1 on t.parent_id=p1.id order by nbr desc,name""".format(database.CSVIntStringToInClause(gvp('src', gvg('src')))) g.TaxoList = GetAll(sql, None, cursor_factory=None) s = sum([r[2] for r in g.TaxoList]) # Nbr total d'objet par categorie d = DecodeEqualList(Prj.classifsettings) TaxoCSV=d.get('seltaxo') if TaxoCSV: TaxoList={int(x) for x in TaxoCSV.split(',')} else: TaxoList = {} g.TaxoList = [[r[0], r[1], r[2], round(100 * r[2] / s, 1), 'checked' if len(TaxoList)==0 or r[0] in TaxoList else ''] for r in g.TaxoList] # Ajout du % d'objet par categorie ExtraHeader="<input type='hidden' name='src' value='{}'>".format(gvp('src', gvg('src'))) ExtraHeader += self.GetFilterText() return render_template('task/classifauto2_create_lsttaxo.html' ,url=request.query_string.decode('utf-8') ,ExtraHeader=ExtraHeader,prj=Prj)
def routesettaxon(): """ Update a taxon or create a new one if 'id' parameter is not supplied. """ CheckInstanceSecurity() taxotype = gvp('taxotype') name = gvp('name') parent = gvp('parent_id') taxonid = gvp('id', '') with TaxoOperationLocker(): app.logger.info('In Locker') msg = checktaxon(taxotype, name, parent=parent, updatetarget=taxonid) if msg != 'ok': return jsonify(msg=msg) if taxonid != '': Taxon = database.Taxonomy.query.filter_by(id=int(taxonid)).first() CheckTaxonUpdateRight(Taxon) else: Taxon = database.Taxonomy() db.session.add(Taxon) UpdateObjectFromForm(Taxon) db.session.commit() ComputeDisplayName([Taxon.id]) return jsonify(msg='ok', id=Taxon.id)
def part_sampleedit(psampleid): model = partdatabase.part_samples.query.filter_by( psampleid=psampleid).first() form = UvpSampleForm(request.form, model) if gvp('delete') == 'Y': delete_sample(psampleid) return redirect("/part/prj/" + str(model.pprojid)) if request.method == 'POST' and form.validate(): for k, v in form.data.items(): setattr(model, k, v) db.session.commit() if gvp('forcerecalc') == 'Y': appli.part.prj.ComputeHistoDet(model.psampleid, model.project.instrumtype) appli.part.prj.ComputeHistoRed(model.psampleid, model.project.instrumtype) appli.part.prj.ComputeZooMatch(model.psampleid, model.project.projid) flash("Histograms have been recomputed", "success") return redirect("/part/prj/" + str(model.pprojid)) return PrintInCharte( render_template("part/sampleedit.html", form=form, prjid=model.pprojid, psampleid=model.psampleid))
def CheckInstanceSecurity(): id_instance = gvp('id_instance', '') if not id_instance.isdigit(): abort(jsonify(msg="invalid instance id format")) Instance = database.GetAll( "select sharedsecret from ecotaxainst WHERE id=%s", [int(id_instance)]) if len(Instance) != 1: abort(jsonify(msg="invalid instance")) if Instance[0]['sharedsecret'] != gvp('sharedsecret'): time.sleep(random.random()) abort(jsonify(msg="invalid instance secret")) g.ecotaxa_version = gvp('ecotaxa_version') g.ecotaxa_version_int = 0 re_match = re.match(r"(\d+).(\d+).(\d+)", g.ecotaxa_version) if re_match: g.ecotaxa_version_int = int(re_match.group(1)) * 10000 + int( re_match.group(2)) * 100 + int(re_match.group(3)) else: abort(jsonify(msg='invalid version')) g.MsgVersion = "ok" if g.ecotaxa_version_int < 20000: g.MsgVersion = "Current Ecotaxa version is 2.0.0 it's recommanded to upgrade your version (%s.%s.%s) ." % ( re_match.group(1), re_match.group(2), re_match.group(3)) if g.ecotaxa_version_int < 20000: abort(jsonify(msg='Your Ecotaxa version is too old, you must upgrade'))
def routegettaxon(): sql = """select t.id,t.parent_id,t.name,t.taxotype,t.display_name,t.id_source,t.source_url,t.source_desc ,t.creator_email ,to_char(t.creation_datetime,'YYYY-MM-DD HH24:MI:SS') creation_datetime ,to_char(t.lastupdate_datetime,'YYYY-MM-DD HH24:MI:SS') lastupdate_datetime,t.id_instance,t.taxostatus,t.rename_to from taxonomy t where 1=1 """ sqlparam = {} filtertype = gvp('filtertype') if filtertype == 'id': sql += " and id=%(id)s " sqlparam['id'] = int(gvp('id')) elif filtertype == 'since': sql += """ and lastupdate_datetime>=to_timestamp(%(startdate)s,'YYYY-MM-DD HH24:MI:SS') """ # and (taxostatus!='N' or id_instance=%(id_instance)s) ==> Désactivé dans un premier temps sqlparam['startdate'] = gvp('startdate') # sqlparam['id_instance']=gvp('id_instance') else: return jsonify(msg='filtertype required') sql += " order by lastupdate_datetime " res = database.GetAll(sql, sqlparam, cursor_factory=psycopg2.extras.RealDictCursor) if len(res) == 0 and filtertype == 'id': return jsonify(msg='no data found') return jsonify(res)
def PrjEdit(PrjId): g.useselect4 = True Prj = database.Projects.query.filter_by(projid=PrjId).first() g.headcenter = "<h4><a href='/prj/{0}'>{1}</a></h4>".format( Prj.projid, XSSEscape(Prj.title)) if Prj is None: flash("Project doesn't exists", 'error') return PrintInCharte("<a href=/prj/>Select another project</a>") if not Prj.CheckRight(2): # Level 0 = Read, 1 = Annotate, 2 = Admin flash('You cannot edit settings for this project', 'error') return PrintInCharte("<a href=/prj/>Select another project</a>") if gvp('save') == "Y": PreviousCNN = Prj.cnn_network_id for f in request.form: if f in dir(Prj): setattr(Prj, f, gvp(f)) if PreviousCNN != Prj.cnn_network_id: database.ExecSQL( "delete from obj_cnn_features where objcnnid in (select objid from obj_head where projid=%s)", [PrjId]) flash("SCN features erased", "success") Prj.visible = True if gvp('visible') == 'Y' else False # print(request.form) for m in Prj.projmembers: if gvp('priv_%s_delete' % m.id) == 'Y': db.session.delete(m) elif gvp('priv_%s_member' % m.id) != '': # si pas delete c'est update m.member = int(gvp('priv_%s_member' % m.id)) m.privilege = gvp('priv_%s_privilege' % m.id) if gvp('priv_new_member') != '': new = database.ProjectsPriv(member=int(gvp('priv_new_member')), privilege=gvp('priv_new_privilege'), projid=PrjId) db.session.add(new) try: db.session.commit() flash("Project settings Saved successfuly", "success") except Exception as E: flash("Database exception : %s" % E, "error") db.session.rollback() if Prj.initclassiflist is None: lst = [] else: lst = [int(x) for x in Prj.initclassiflist.split(",") if x.isdigit()] g.predeftaxo = GetAll( """select t.id,t.display_name as name from taxonomy t left join taxonomy t2 on t.parent_id=t2.id where t.id= any(%s) order by upper(t.display_name) """, (lst, )) g.users = GetAssoc2Col("select id,name from users order by lower(name)", dicttype=collections.OrderedDict) g.maplist = [ 'objtime', 'objdate', 'latitude', 'longitude', 'depth_min', 'depth_max' ] + sorted(DecodeEqualList(Prj.mappingobj).values()) g.scn = GetSCNNetworks() return render_template('project/editproject.html', data=Prj)
def TaskCreateRouter(ClassName): gvp( 'dummy' ) # Protection bug flask connection reset si on fait post sans lire les champs AddTaskSummaryForTemplate() t = TaskFactory(ClassName) t.task.owner_id = current_user.get_id() return t.QuestionProcess()
def routechecktaxonHTML(): # CheckInstanceSecurity() taxotype = gvp('taxotype') name = gvp('name') parent = gvp('parent_id') updatetarget = gvp('updatetarget') msg = checktaxon(taxotype, name, parent=parent, updatetarget=updatetarget) if msg == 'ok': return FormatSuccess("Naming rules OK") else: return FormatError(msg)
def routechecktaxon(): CheckInstanceSecurity() taxotype = gvp('taxotype') name = gvp('name') parent = gvp('parent_id') updatetarget = gvp('updatetarget') res = { "msg": checktaxon(taxotype, name, parent=parent, updatetarget=updatetarget) } return json.dumps(res)
def PrjEditPriv(PrjId): Prj=database.Projects.query.filter_by(projid=PrjId).first() g.headcenter="<h4><a href='/prj/{0}'>{1}</a></h4>".format(Prj.projid,XSSEscape(Prj.title)) if Prj is None: flash("Project doesn't exists",'error') return PrintInCharte("<a href=/prj/>Select another project</a>") if not Prj.CheckRight(2): # Level 0 = Read, 1 = Annotate, 2 = Admin flash('You cannot edit settings for this project','error') return PrintInCharte("<a href=/prj/>Select another project</a>") if gvp('save')=="Y": # print(request.form) for m in Prj.projmembers: if gvp('priv_%s_delete'%m.id)=='Y': db.session.delete(m) elif gvp('priv_%s_member'%m.id)!='': # si pas delete c'est update m.member=int(gvp('priv_%s_member'%m.id)) m.privilege=gvp('priv_%s_privilege'%m.id) if gvp('priv_new_member')!='': new=database.ProjectsPriv(member=int(gvp('priv_new_member')),privilege=gvp('priv_new_privilege'),projid=PrjId) db.session.add(new) try: db.session.commit() flash("Project settings Saved successfuly","success") except Exception as E: flash("Database exception : %s"%E,"error") db.session.rollback() g.users=GetAssoc2Col("select id,name from users order by lower(name)",dicttype=collections.OrderedDict) return render_template('project/editprojectpriv.html',data=Prj)
def routetaxodel(): txt = "" try: taxoid = int(gvp('id')) params = dict(id=taxoid) UsedTaxon = database.GetAll( """select 1 from taxonomy t where id=(%s) and ( exists(select 1 from taxonomy p where p.parent_id=t.id) or exists(select 1 from obj_head where classif_id=t.id) ) """, [taxoid]) if len(UsedTaxon) > 0: return appli.ErrorFormat( "This Taxon is used locally, you cannot remove it") database.ExecSQL("delete from taxonomy t where id=%s", [taxoid]) j = request_withinstanceinfo("/deltaxon/", params) if j['msg'] != 'ok': return appli.ErrorFormat("deltaxon Error :" + j['msg']) txt = """<script> DoSync(); At2PopupClose(0); </script>""" return txt except Exception as e: import traceback tb_list = traceback.format_tb(e.__traceback__) return appli.FormatError("Saving Error : {}\n{}", e, "__BR__".join(tb_list[::-1]))
def CheckTaxonUpdateRight(Taxon): if Taxon is None: abort(jsonify(msg="unable to update a non existing id")) if Taxon.taxostatus != 'N': abort(jsonify(msg="unable to update a validated taxon")) if Taxon.id_instance != int(gvp('id_instance')): abort(jsonify(msg="Only instance author of a taxon can update it"))
def dbadmin_console(): sql = gvp("sql") if len( request.form ) > 0 and request.referrer != request.url: # si post doit venir de cette page return PrintInCharte("Invalid referer") g.headcenter = "<font color=red style='font-size:18px;'>Warning : This screen must be used only by experts</font><br><a href=/admin/>Back to admin home</a>" txt = "<form method=post>SQL : <textarea name=sql rows=15 cols=100>%s</textarea><br>" % escape( sql) txt += """<input type=submit class='btn btn-primary' name=doselect value='Execute Select'> <input type=submit class='btn btn-primary' name=dodml value='Execute DML'> Note : For DML ; can be used, but only the result of the last query displayed </form>""" if gvp("doselect"): txt += "<br>Select Result :" cur = db.engine.raw_connection().cursor() try: cur.execute(sql) txt += "<table class='table table-condensed table-bordered'>" for c in cur.description: txt += "<td>%s</td>" % c[0] for r in cur: s = "<tr>" for c in r: s += "<td>%s</td>" % c txt += s + "</tr>" txt += "</table>" except Exception as e: txt += "<br>Error = %s" % e cur.connection.rollback() finally: cur.close() if gvp("dodml"): txt += "<br>DML Result :" cur = db.engine.raw_connection().cursor() try: cur.execute(sql) txt += "%s rows impacted" % cur.rowcount cur.connection.commit() except Exception as e: txt += "<br>Error = %s" % e cur.connection.rollback() finally: cur.close() return PrintInCharte(txt)
def routedeltaxon(): CheckInstanceSecurity() with TaxoOperationLocker(): Taxon = database.Taxonomy.query.filter_by(id=int(gvp('id'))).first() CheckTaxonUpdateRight(Taxon) db.session.delete(Taxon) db.session.commit() return jsonify(msg='ok')
def routesetstat(): CheckInstanceSecurity() id_instance = int(gvp('id_instance')) database.ExecSQL("delete from ecotaxainststat WHERE id_instance=%s" % id_instance) # sql="insert into ecotaxainststat(id_instance, id_taxon, nbr) VALUES ({},%s,%s)".format(id_instance) sql = "insert into ecotaxainststat(id_instance, id_taxon, nbr) VALUES " stat = json.loads(gvp('data')) if len(stat) > 0: # to avoid error on empty DB sql += ",".join("({},{},{})".format(id_instance, int(k), int(v)) for (k, v) in stat.items()) database.ExecSQL(sql) database.ExecSQL( "update ecotaxainst set laststatupdate_datetime=timezone('utc',now()),ecotaxa_version=%s WHERE id=%s", [g.ecotaxa_version, id_instance]) PurgeDeprecatedTaxon() return jsonify(msg='ok', msgversion=g.MsgVersion)
def objectdetailsupdate(objid): request.form # Force la lecture des données POST sinon il y a une erreur 504 obj = database.Objects.query.filter_by(objid=objid).first() Prj = obj.project if not Prj.CheckRight(2): # Level 0 = Read, 1 = Annotate, 2 = Admin return '<span class="label label-danger">You cannot edit data on this project</span>' table = gvp("table") field = gvp("field") if table == "object": if hasattr(obj, field): target = obj elif hasattr(obj.objfrel, field): target = obj.objfrel else: return '<span class="label label-danger">Invalid field %s.%s</span>' % ( table, field) elif table == "sample": target = obj.sample elif table == "acquis": target = obj.acquis elif table == "processrel": target = obj.processrel else: return '<span class="label label-danger">Invalid table %s</span>' % ( table, ) oldval = getattr(target, field) newval = gvp("newval") try: dbval = newval if field == "objdate": dbval = datetime.date(int(newval[0:4]), int(newval[5:7]), int(newval[8:10])) if dbval == "": dbval = None setattr(target, field, dbval) db.session.commit() except Exception as E: return '<span class="label label-danger">Data update error %s</span>' % ( str(E)[0:100], ) return "<span class='label label-success'>changed value '%s' by '%s'" % ( oldval, newval)
def QuestionProcessScreenSelectModel(self, Prj): Models=self.ReadModels() # app.logger.info("Modèles = %s",Models) # Premier écran de configuration pour prédiction depuis un modèle, choix du projet du modèle PreviousTxt = self.GetFilterText() d = DecodeEqualList(Prj.classifsettings) g.posttaxomapping=d.get('posttaxomapping',"") # TargetFeatures = set(DecodeEqualList(Prj.mappingobj).values()) TargetFeatures =set(self.GetReverseObjMap(Prj).keys()) TblBody = "" sortedmodellist=sorted(Models.keys(),key=str.lower) for modeldir in sortedmodellist: r=Models[modeldir] # bug sur les fichiers initiaux qui avaient : en trop dans le nom de cette entrée ModelFeatures=set(r.get('zooprocess_fields',r.get('zooprocess_fields:'))) MatchingFeatures = len(ModelFeatures & TargetFeatures) if MatchingFeatures < int(gvp("filt_featurenbr") if gvp("filt_featurenbr") else 10): continue if gvp('filt_title'): if r['name'].lower().find(gvp('filt_title').lower())<0 and modeldir.lower().find(gvp('filt_title').lower())<0: continue Radio = "" # Pour être compatible foit utiliser le même SCN que le projet ou ne pas en utiliser if (r['scn_model']==Prj.cnn_network_id) or (r['scn_model']==''): Radio="<input name=selmodel type='radio' class='selmodel ' data-modeldir='{0}' {1}>".format(modeldir ,"checked" if modeldir == d.get('usemodel_foldername') else "") if len(ModelFeatures)!=MatchingFeatures: MatchingFeatures='Missing' Radio = "" TaxoDetails=" <span class='showcat'>Show categories</span><span style='display: none'><br>"\ +TaxoNameAddSpaces(', '.join(sorted(r.get('categories',{}).values(),key=lambda v: v.upper())))+"</span>" TblBody += """<tr><td> {6}</td> <td>{0} - {1}{7}{5}</td><td>{2:0.0f}</td><td>{3}</td><td>{4}</td> </tr>""".format(modeldir, r['name'],r['n_objects'],MatchingFeatures, r['scn_model'] ,"<br>Comments : "+JinjaNl2BR(r.get('comments')) if r.get('comments') else "" ,Radio,TaxoDetails) return render_template('task/classifauto2_create_selectmodel.html' , url=request.query_string.decode('utf-8') , TblBody=TblBody , PreviousTxt=PreviousTxt)
def QuestionProcess(self): txt = "<h1>Taxonomy Import Task</h1>" if self.task.taskstep == 0: txt += "<h3>Task Creation</h3>" if gvp('starttask') == "Y": for k, v in self.param.__dict__.items(): setattr(self.param, k, gvp(k)) if len(self.param.host) < 7: flash("Host Field Too short", "error") elif len(self.param.port) < 2: flash("Port Field Too short", "error") elif len(self.param.database) < 2: flash("database Field Too short", "error") else: return self.StartTask(self.param) return render_template('task/taxosynccreate.html', header=txt, data=self.param) return PrintInCharte(txt)
def QuestionProcessScreenSelectModelTaxo(self,Prj): # Second écran de configuration, mapping des taxon utilisés dans le modele PreviousTxt = self.GetFilterText() g.modeldir=gvp('modeldir') ModelFolder = Path("RF_models") / g.modeldir Meta = json.load((ModelFolder / "meta.json").open("r")) categories=Meta.get("categories","") g.TaxoList = database.GetTaxoNameFromIdList([int(x) for x in categories]) return render_template('task/classifauto2_create_lsttaxo_frommodel.html' ,url=request.query_string.decode('utf-8') ,prj=Prj, PreviousTxt=PreviousTxt)
def PrjUpdateComment(ObjId): Obj=database.Objects.query.filter_by(objid=ObjId).first() if Obj is None: return "Object doesnt exists" Prj=database.Projects.query.filter_by(projid=Obj.projid).first() if not Prj.CheckRight(1): # Level 0 = Read, 1 = Annotate, 2 = Admin return "You cannot Annotate this project" Obj.complement_info=gvp('comment') db.session.commit() return '<span class="label label-success">Database update Successfull</span>'
def browseinstancesavepopup(): try: # txt = json.dumps(request.form) instance_id = gvp('id') if instance_id != 'new': instance = database.EcotaxaInst.query.filter_by( id=instance_id).first() if instance is None: raise Exception("Instance not found in Database") else: instance = database.EcotaxaInst() db.session.add(instance) instance.url = gvp('url') instance.name = gvp('name') instance.sharedsecret = gvp('sharedsecret') db.session.commit() return "<script>location.reload(true);</script>" except Exception as e: tb_list = traceback.format_tb(e.__traceback__) return FormatError("Saving Error : {}\n{}", e, "__BR__".join(tb_list[::-1]))
def routetaxosave(): txt = "" try: params = {} for c in [ 'parent_id', 'name', 'taxotype', 'source_desc', 'source_url', 'creation_datetime', 'creator_email' ]: params[c] = gvp(c) if int(gvp('id')) > 0: params['id'] = int(gvp('id')) params['taxostatus'] = 'N' j = request_withinstanceinfo("/settaxon/", params) if j['msg'] != 'ok': return appli.ErrorFormat("settaxon Error :" + j['msg']) txt = """<script> DoSync(); At2PopupClose(0); </script>""" return txt except Exception as e: import traceback tb_list = traceback.format_tb(e.__traceback__) return appli.FormatError("Saving Error : {}\n{}", e, "__BR__".join(tb_list[::-1]))
def routetaxobrowse(): BackProjectBtn = '' if gvp('updatestat') == 'Y': # DoSyncStatUpdate() DoFullSync() if gvg('fromprj'): BackProjectBtn = "<a href='/prj/{}' class='btn btn-default btn-primary'>{} Back to project</a> ".format( int(gvg('fromprj')), FAIcon('arrow-left')) if gvg('fromtask'): BackProjectBtn = "<a href='/Task/Question/{}' class='btn btn-default btn-primary'>{} Back to importation task</a> ".format( int(gvg('fromtask')), FAIcon('arrow-left')) if not (current_user.has_role(database.AdministratorLabel) or current_user.has_role(database.ProjectCreatorLabel)): # /prj/653 txt = "You cannot create tanonomy category, you must request to your project manager (check project page)" if gvg('fromprj'): txt += "<br>" + BackProjectBtn return PrintInCharte(FormatError(txt, DoNotEscape=True)) g.taxoserver_url = app.config.get('TAXOSERVER_URL') if current_user.has_role(database.AdministratorLabel): ExtraWehereClause = "" else: ExtraWehereClause = "and t.creator_email='{}'".format( current_user.email) lst = GetAll( """select t.id,t.parent_id,t.display_name as name,case t.taxotype when 'M' then 'Morpho' when 'P' then 'Phylo' else t.taxotype end taxotype,t.taxostatus,t.creator_email,t.id_source ,to_char(t.creation_datetime,'yyyy-mm-dd hh24:mi') creation_datetime,to_char(t.lastupdate_datetime,'yyyy-mm-dd hh24:mi') lastupdate_datetime,{} from taxonomy t {} where t.id_instance ={} {} order by case t.taxostatus when 'N' then 1 else 2 end,t.id LIMIT 400 """.format(SQLTreeSelect, SQLTreeJoin, app.config.get('TAXOSERVER_INSTANCE_ID'), ExtraWehereClause)) for lstitem in lst: # lstitem['tree']=PackTreeTxt(lstitem['tree']) #evite les problèmes de safe if lstitem['parent_id'] is None: lstitem['parent_id'] = "" # nbrtaxon=GetAll("select count(*) from taxonomy")[0][0] # return render_template('browsetaxo.html',lst=lst,nbrtaxon=nbrtaxon) return PrintInCharte( render_template('taxonomy/browse.html', lst=lst, BackProjectBtn=BackProjectBtn))
def QuestionProcess(self): g.headcenter = "<h3>TAXONOMY IMPORTATION</h3><a href='/admin'/>Back to admin home</a>" txt = "<h1>Taxonomy Text File Importation Task</h1>" errors = [] if self.task.taskstep == 0: # txt+="<h3>Task Creation</h3>" if not current_user.has_role(database.AdministratorLabel): return PrintInCharte( "ACCESS DENIED reserved to administrators") if gvp('starttask') == "Y": FileToSave = None FileToSaveFileName = None # Verifier la coherence des données uploadfile = request.files.get("uploadfile") if uploadfile is not None and uploadfile.filename != '': # import d'un fichier par HTTP FileToSave = uploadfile # La copie est faite plus tard, car à ce moment là, le repertoire de la tache n'est pas encore créé FileToSaveFileName = "uploaded.txt" self.param.InData = "uploaded.txt" else: errors.append("txt file is missing") if len(errors) > 0: for e in errors: flash(e, "error") else: return self.StartTask( self.param, FileToSave=FileToSave, FileToSaveFileName=FileToSaveFileName) else: # valeurs par default pass return render_template('task/taxoimport_create.html', header=txt, data=self.param, ServerPath=gvp("ServerPath"), TxtTaxoMap=gvp("TxtTaxoMap")) return PrintInCharte(txt)
def browseinstancedelpopup(): try: instance_id = gvp('id') instance = database.EcotaxaInst.query.filter_by(id=instance_id).first() if instance is None: raise Exception("Instance not found in Database") database.ExecSQL("delete from ecotaxainststat where id_instance=%s", [instance.id]) db.session.delete(instance) db.session.commit() return "<script>location.reload(true);</script>" except Exception as e: tb_list = traceback.format_tb(e.__traceback__) return FormatError("Saving Error : {}\n{}", e, "__BR__".join(tb_list[::-1]))
def part_prjcalc(PrjId): Prj = partdatabase.part_projects.query.filter_by(pprojid=PrjId).first() if Prj.ownerid!=current_user.id and not current_user.has_role(database.AdministratorLabel): return PrintInCharte(ErrorFormat("Access Denied")) txt="" CheckedSampleList=[] for f in request.form: if f[0:2] == "s_" and request.form.get(f)=='Y': CheckedSampleList.append(int(f[2:])) app.logger.info("request.form=%s", request.form) app.logger.info("CheckedSampleList=%s", CheckedSampleList) app.logger.info("dohistodet=%s,domatchecotaxa=%s,dohistotaxo=%s", gvp('dohistodet'), gvp('domatchecotaxa'), gvp('dohistotaxo')) dbsample = database.GetAll("""select profileid,psampleid,filename,sampleid,histobrutavailable ,(select count(*) from part_histopart_det where psampleid=s.psampleid) nbrlinedet from part_samples s where pprojid=%s and psampleid = any (%s)""" , (PrjId,CheckedSampleList)) for S in dbsample: prefix="<br>{profileid} :".format(**S) if gvp('delete') == 'Y': sampleedit.delete_sample(S['psampleid']) txt += prefix + " deleted" continue if gvp('dohistodet')=='Y': txt += prefix + ComputeHistoDet(S['psampleid'], Prj.instrumtype) if gvp('dohistored')=='Y': txt += prefix + ComputeHistoRed(S['psampleid'], Prj.instrumtype) if gvp('domatchecotaxa') == 'Y': txt += prefix +ComputeZooMatch(S['psampleid'],Prj.projid) if gvp('dohistotaxo') == 'Y': txt += prefix + ComputeZooHisto(S['psampleid']) # try: # uvp_sample_import.GenerateTaxonomyHistogram(S['psampleid']) # txt += prefix + " Taxonomy Histogram computed" # except Exception as E: # txt += prefix + " <span style='color: red;'>Taxonomy Histogram can't be computed : %s </span>"%(E) if gvp('doctdimport') == 'Y': if common_import.ImportCTD(S['psampleid'],current_user.name,current_user.email): txt += prefix + " CTD imported" else: txt += prefix + " <span style='color: red;'>CTD No file</span>" # # txt+="CheckedSampleList=%s"%(CheckedSampleList) # txt+="<br>dbsample = %s"%(dbsample) txt += "<br><br><a href=/part/prj/%s class='btn btn-primary'><span class='glyphicon glyphicon-arrow-left'></span> Back to project samples list</a>"%PrjId return PrintInCharte(txt)
def QuestionProcessScreenSelectSource(self,Prj): # Premier écran de configuration, choix du projet de base PreviousTxt = self.GetFilterText() d = DecodeEqualList(Prj.classifsettings) TargetFeatures = set(DecodeEqualList(Prj.mappingobj).values()) PreviousLS=d.get("baseproject", "") if PreviousLS != "": BasePrj = GetAll("select projid,title from projects where projid in ({0})".format(PreviousLS)) if len(BasePrj): PreviousTxt += """<a class='btn btn-primary' href='?{0}&src={1}'> USE previous Learning Set : {2}</a><br><br>OR USE another project<br><br>""".format( request.query_string.decode("utf-8"),PreviousLS, " + ".join(["#{0} - {1}".format(*r) for r in BasePrj]) ) from flask_login import current_user sql = """select projid,title,round(coalesce(objcount,0)*coalesce(pctvalidated,0)/100) objvalid ,mappingobj,coalesce(cnn_network_id,'') cnn_network_id from projects where 1=1 """ sqlparam=[] if gvp('filt_title'): sql += " and title ilike (%s) " sqlparam.append(("%"+gvp('filt_title')+"%")) if gvp('filt_instrum', '') != '': sql += " and projid in (select distinct projid from acquisitions where instrument ilike '%%'||(%s) ||'%%' ) " sqlparam.append(gvp('filt_instrum')) sql += " order by title" ProjList = database.GetAll(sql,sqlparam,doXSSEscape=True) TblBody="" for r in ProjList: MatchingFeatures = len(set(DecodeEqualList(r['mappingobj']).values()) & TargetFeatures) if MatchingFeatures<int(gvp("filt_featurenbr") if gvp("filt_featurenbr") else 10): continue TblBody += """<tr><td><input type='checkbox' class='selproj' data-prjid='{projid}'></td> <td>#{projid} - {title}</td><td>{objvalid:0.0f}</td><td>{MatchingFeatures}</td><td>{cnn_network_id}</td> </tr>""".format(MatchingFeatures=MatchingFeatures, **r) return render_template('task/classifauto2_create_lstproj.html' ,url=request.query_string.decode('utf-8') ,TblBody=TblBody ,PreviousTxt=PreviousTxt)
def QuestionProcess(self): ServerRoot = Path(app.config['SERVERLOADAREA']) txt = "<h1>Text File Importation Task</h1>" errors = [] if self.task.taskstep == 0: txt += "<h3>Task Creation</h3>" Prj = database.Projects.query.filter_by(projid=gvg("p")).first() g.prjtitle = Prj.title g.prjprojid = Prj.projid g.prjmanagermailto = Prj.GetFirstManagerMailto() txt = "" if Prj.CheckRight(2) == False: return PrintInCharte("ACCESS DENIED for this project") if gvp('starttask') == "Y": FileToSave = None FileToSaveFileName = None self.param.ProjectId = gvg("p") self.param.updateclassif = gvp("updateclassif") TaxoMap = {} for l in gvp('TxtTaxoMap').splitlines(): ls = l.split('=', 1) if len(ls) != 2: errors.append( "Taxonomy Mapping : Invalid format for line %s" % (l)) else: TaxoMap[ls[0].strip().lower()] = ls[1].strip().lower() # Verifier la coherence des données uploadfile = request.files.get("uploadfile") if uploadfile is not None and uploadfile.filename != '': # import d'un fichier par HTTP FileToSave = uploadfile # La copie est faite plus tard, car à ce moment là, le repertoire de la tache n'est pas encore créé FileToSaveFileName = "uploaded.zip" self.param.InData = "uploaded.zip" elif len(gvp("ServerPath")) < 2: errors.append("Input Folder/File Too Short") else: sp = ServerRoot.joinpath(Path(gvp("ServerPath"))) if not sp.exists(): #verifie que le repertoire existe errors.append("Input Folder/File Invalid") else: self.param.InData = sp.as_posix() if len(errors) > 0: for e in errors: flash(e, "error") else: self.param.TaxoMap = TaxoMap # on stocke le dictionnaire et pas la chaine return self.StartTask( self.param, FileToSave=FileToSave, FileToSaveFileName=FileToSaveFileName) else: # valeurs par default self.param.ProjectId = gvg("p") return render_template('task/importupdate_create.html', header=txt, data=self.param, ServerPath=gvp("ServerPath"), TxtTaxoMap=gvp("TxtTaxoMap")) if self.task.taskstep == 1: PrjId = self.param.ProjectId Prj = database.Projects.query.filter_by(projid=PrjId).first() g.prjtitle = Prj.title g.appmanagermailto = GetAppManagerMailto() # self.param.TaxoFound['agreia pratensis']=None #Pour TEST A EFFACER NotFoundTaxo = [ k for k, v in self.param.TaxoFound.items() if v == None ] NotFoundUsers = [ k for k, v in self.param.UserFound.items() if v.get('id') == None ] app.logger.info("Pending Taxo Not Found = %s", NotFoundTaxo) app.logger.info("Pending Users Not Found = %s", NotFoundUsers) if gvp('starttask') == "Y": app.logger.info("Form Data = %s", request.form) for i in range(1, 1 + len(NotFoundTaxo)): orig = gvp( "orig%d" % (i) ) #Le nom original est dans origXX et la nouvelle valeur dans taxolbXX newvalue = gvp("taxolb%d" % (i)) if orig in NotFoundTaxo and newvalue != "": t = database.Taxonomy.query.filter( database.Taxonomy.id == int(newvalue)).first() app.logger.info(orig + " associated to " + t.name) self.param.TaxoFound[orig] = t.id else: errors.append( "Taxonomy Manual Mapping : Invalid value '%s' for '%s'" % (newvalue, orig)) for i in range(1, 1 + len(NotFoundUsers)): orig = gvp( "origuser%d" % (i) ) #Le nom original est dans origXX et la nouvelle valeur dans taxolbXX newvalue = gvp("userlb%d" % (i)) if orig in NotFoundUsers and newvalue != "": t = database.users.query.filter( database.users.id == int(newvalue)).first() app.logger.info("User " + orig + " associated to " + t.name) self.param.UserFound[orig]['id'] = t.id else: errors.append( "User Manual Mapping : Invalid value '%s' for '%s'" % (newvalue, orig)) app.logger.info("Final Taxofound = %s", self.param.TaxoFound) self.UpdateParam() # On met à jour ce qui à été accepté # Verifier la coherence des données if len(errors) == 0: return self.StartTask(self.param, step=2) for e in errors: flash(e, "error") NotFoundTaxo = [ k for k, v in self.param.TaxoFound.items() if v == None ] NotFoundUsers = [ k for k, v in self.param.UserFound.items() if v.get('id') == None ] return render_template('task/import_question1.html', header=txt, taxo=NotFoundTaxo, users=NotFoundUsers, task=self.task) return PrintInCharte(txt)