Skip to content

Commit

Permalink
V 2.0.1
Browse files Browse the repository at this point in the history
Few post implementation fix
Evolutions for new release of ecotaxa portable
  • Loading branch information
laurent-n committed Feb 3, 2019
1 parent 564f312 commit 8c3206a
Show file tree
Hide file tree
Showing 15 changed files with 428 additions and 354 deletions.
6 changes: 4 additions & 2 deletions appli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
virtualprefix = sys.base_prefix
if hasattr(sys, 'real_prefix'):
sys.base_prefix = sys.real_prefix
if float(sys.winver) < 3.5:
if float(sys.winver.replace('-32','')) < 3.5:
from tkinter import _fix
if "TCL_LIBRARY" not in os.environ:
# reload module, so that sys.real_prefix be used
Expand Down Expand Up @@ -307,7 +307,7 @@ def JinjaGetManagerList(sujet=""):
sujet="?"+urllib.parse.urlencode({"subject":sujet}).replace('+','%20')
return " ".join(["<li><a href='mailto:{1}{0}'>{2} ({1})</a></li> ".format(sujet,*r) for r in LstUsers ])

ecotaxa_version="2.0.0"
ecotaxa_version="2.0.1"
def JinjaGetEcotaxaVersionText():
return ecotaxa_version+" 2019-01-25"

Expand All @@ -317,6 +317,8 @@ def JinjaGetEcotaxaVersionText():


"""Changelog
2019.02.01 : V 2.0.1
Fix implementation minor bug
2019.01.25 : V 2.0.0
Integration with EcotaxoServer
Handling new display_name child<parent #87,#172
Expand Down
6 changes: 5 additions & 1 deletion appli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,11 @@ def before_request_security():
if current_user.has_role(database.AdministratorLabel) or current_user.has_role(database.ProjectCreatorLabel) :
g.menu.append(("","SEP"))
# g.menu.append(("/taxo/browse/","Manage Taxonomy"))
g.menu.append(("javascript:PostDynForm('/taxo/browse/',{updatestat:'Y'});", "Manage Taxonomy"))
if request.endpoint=='indexPrj':
g.menu.append(("javascript:PostDynForm('/taxo/browse/?fromprj=%d',{updatestat:'Y'});"%(request.view_args.get('PrjId'),), "Manage Taxonomy"))
else:
g.menu.append(("javascript:PostDynForm('/taxo/browse/',{updatestat:'Y'});", "Manage Taxonomy"))
# ?fromprj={{ g.Projid }}
if current_user.has_role(database.AdministratorLabel) or current_user.has_role(database.UserAdministratorLabel) :
g.menu.append(("","SEP"))
g.menu.append(("/admin/","Admin Screen"))
Expand Down
266 changes: 133 additions & 133 deletions appli/project/ajaxprocess.py
Original file line number Diff line number Diff line change
@@ -1,133 +1,133 @@
from flask import Blueprint, render_template, g, flash,request,url_for,json
from flask_login import current_user
from appli import app,ObjectToStr,PrintInCharte,database,gvg,gvp,user_datastore,DecodeEqualList,ScaleForDisplay,ntcv
from pathlib import Path
from flask_security import Security, SQLAlchemyUserDatastore
from flask_security import login_required
from flask_security.decorators import roles_accepted
import os,time,math,collections,psycopg2.extras,sys
from appli.database import GetAll,GetClassifQualClass,db,ExecSQL

@app.route('/prj/ManualClassif/<int:PrjId>', methods=['GET', 'POST'])
@login_required
def PrjManualClassif(PrjId):
request.form # Force la lecture des données POST sinon il y a une erreur 504
Changement=[]
Prj=database.Projects.query.filter_by(projid=PrjId).first()
if not Prj.CheckRight(1): # Level 0 = Read, 1 = Annotate, 2 = Admin
return '<span class="label label-danger">You cannot Annotate this project</span>'

changes={k[8:-1]:v for k,v in request.form.items() if k[0:7]=="changes"}
if len(changes)==0:
return '<span class="label label-warning">No pending change to update</span>'

sql="""select o.objid,o.classif_auto_id,o.classif_auto_when,o.classif_auto_score,o.classif_id,o.classif_qual,o.classif_when,o.classif_who
from obj_head o
where o.objid in ("""+",".join(changes.keys())+")"
prev={r['objid']:r for r in GetAll(sql,debug=False)}
sql="update obj_head set classif_id=%(classif_id)s,classif_qual=%(classif_qual)s,classif_who=%(classif_who)s,classif_when=now() where objid=%(objid)s "
# sqli="""INSERT INTO objectsclassifhisto (objid, classif_date, classif_type, classif_id, classif_qual, classif_who)
# VALUES (%(objid)s,%(classif_when)s,'M',%(classif_id)s,%(classif_qual)s,%(classif_who)s )"""
# Traitement global de l'historisation afin de réduire les commandes SQL + test qu'il n'y a pas de doublons
sqli="""INSERT INTO objectsclassifhisto(objid, classif_date, classif_type, classif_id, classif_qual, classif_who, classif_score)
SELECT objid, classif_when, 'M' classif_type, classif_id, classif_qual, classif_who, null classif_score
from obj_head oh
where objid= any(%s)
and classif_when is not null
and not exists(select 1 from objectsclassifhisto och where oh.objid=och.objid and oh.classif_when=och.classif_date )"""
try:
params=[[int(x) for x in changes.keys()] ]
ExecSQL(sqli, params, True)
except:
app.logger.warning("Unable to add historical information, non-blocking %s" % (sys.exc_info(),))
BatchParam=[]
for k,v in changes.items():
ki=int(k)
if v=="-1" or v=="" : # utilisé dans validate all
v=prev[ki]['classif_id']
if prev[ki]['classif_qual']!=gvp('qual') or prev[ki]['classif_who']!=current_user.id or prev[ki]['classif_id']!=int(v):
# il y a eu au moins un changement
params={'objid':k,'classif_id':v,'classif_who':current_user.id,'classif_qual':gvp('qual')}
BatchParam.append(params)
# ExecSQL(sql,params,False)
Changement.append({'prev_id':prev[ki]['classif_id'],'prev_qual':prev[ki]['classif_qual']
,'id':int(v),'qual':gvp('qual')})
# params={'objid':k,'classif_id':prev[ki]['classif_id'],'classif_who':prev[ki]['classif_who']
# ,'classif_qual':prev[ki]['classif_qual'],'classif_when':prev[ki]['classif_when']}
# try:
# if ntcv(params['classif_when']) !="" : # si pas de date, violation PK
# ExecSQL(sqli,params,True)
# except:
# app.logger.warning("Unable to add historical information, non-blocking %s"%(prev,))
if prev[ki]['classif_id']!=int(v): # il y a eu un changement de classif on maintient la liste des classifs MRU
with app.MRUClassif_lock:
tbl=app.MRUClassif.get(current_user.id,[])
for i,t in enumerate(tbl):
if t["id"]==int(v):
if i>0: # on met cet item au début pour gérer un MRU
tbl=[t]+tbl[0:i]+tbl[i+1:]
break
else: # si pas trouvé dans la liste des MRU on l'ajoute au début si on trouve bien son nom dans la taxo
Taxon=GetAll("""select tf.name||case when p1.name is not null and tf.name not like '%% %%' then ' ('||p1.name||')' else ' ' end as name
from taxonomy tf
left join taxonomy p1 on tf.parent_id=p1.id
where tf.id=%(id)s """,{"id":v})
if len(Taxon)==1:
Taxon=Taxon[0].get('name', "")
tbl.insert(0,{"id": int(v), "pr": 0, "text": Taxon})
if len(tbl)>10:
tbl=tbl[0:10]
app.MRUClassif[current_user.id]=tbl
if len(BatchParam)>0:
upcur = db.engine.raw_connection().cursor()
try:
upcur.executemany(sql, BatchParam)
upcur.connection.commit()
except:
upcur.close()
app.logger.warning("Unable to save changes %s" % (sys.exc_info(),))
return '<span class="label label-danger">Unable to save changes</span>'
upcur.close()

app.logger.info("Changement = %s",Changement)
# applique les changements dans projects_taxo_stat
Empty = {'n': 0, 'V': 0, 'P': 0, 'D': 0}
Changes = {}
for c in Changement:
if c['prev_id'] is None: c['prev_id'] = -1
if c['prev_id'] not in Changes: Changes[c['prev_id']] = Empty.copy()
if c['id'] is None: c['id'] = -1
if c['id'] not in Changes: Changes[c['id']] = Empty.copy()
Changes[c['prev_id']]['n'] -= 1
Changes[c['id']]['n'] += 1
if c['prev_qual'] in ('V', 'P', 'D'):
Changes[c['prev_id']][c['prev_qual']] -= 1
if c['qual'] in ('V', 'P', 'D'):
Changes[c['id']][c['qual']] += 1
LstIdInDB=[x[0] for x in database.GetAll("select id from projects_taxo_stat where projid=%s",[PrjId])]
for k,c in Changes.items():
if k not in LstIdInDB:
database.ExecSQL("insert into projects_taxo_stat(projid, id, nbr, nbr_v, nbr_d, nbr_p) values (%s,%s,0,0,0,0)",[PrjId,k])
sqlparam={'projid':PrjId,'id':k,'n':c['n'],'v':c['V'],'d':c['D'],'p':c['P']}
database.ExecSQL("""update projects_taxo_stat set
nbr=nbr+%(n)s, nbr_v=nbr_v+%(v)s, nbr_d=nbr_d+%(d)s, nbr_p=nbr_p+%(p)s
where projid=%(projid)s and id=%(id)s""",sqlparam)

return '<span class="label label-success">Database update Successfull</span>'


@app.route('/prj/UpdateComment/<int:ObjId>', methods=['GET', 'POST'])
@login_required
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>'

from flask import Blueprint, render_template, g, flash,request,url_for,json
from flask_login import current_user
from appli import app,ObjectToStr,PrintInCharte,database,gvg,gvp,user_datastore,DecodeEqualList,ScaleForDisplay,ntcv
from pathlib import Path
from flask_security import Security, SQLAlchemyUserDatastore
from flask_security import login_required
from flask_security.decorators import roles_accepted
import os,time,math,collections,psycopg2.extras,sys
from appli.database import GetAll,GetClassifQualClass,db,ExecSQL

@app.route('/prj/ManualClassif/<int:PrjId>', methods=['GET', 'POST'])
@login_required
def PrjManualClassif(PrjId):
request.form # Force la lecture des données POST sinon il y a une erreur 504
Changement=[]
Prj=database.Projects.query.filter_by(projid=PrjId).first()
if not Prj.CheckRight(1): # Level 0 = Read, 1 = Annotate, 2 = Admin
return '<span class="label label-danger">You cannot Annotate this project</span>'

changes={k[8:-1]:v for k,v in request.form.items() if k[0:7]=="changes"}
if len(changes)==0:
return '<span class="label label-warning">No pending change to update</span>'

sql="""select o.objid,o.classif_auto_id,o.classif_auto_when,o.classif_auto_score,o.classif_id,o.classif_qual,o.classif_when,o.classif_who
from obj_head o
where o.objid in ("""+",".join(changes.keys())+")"
prev={r['objid']:r for r in GetAll(sql,debug=False)}
sql="update obj_head set classif_id=%(classif_id)s,classif_qual=%(classif_qual)s,classif_who=%(classif_who)s,classif_when=now() where objid=%(objid)s "
# sqli="""INSERT INTO objectsclassifhisto (objid, classif_date, classif_type, classif_id, classif_qual, classif_who)
# VALUES (%(objid)s,%(classif_when)s,'M',%(classif_id)s,%(classif_qual)s,%(classif_who)s )"""
# Traitement global de l'historisation afin de réduire les commandes SQL + test qu'il n'y a pas de doublons
sqli="""INSERT INTO objectsclassifhisto(objid, classif_date, classif_type, classif_id, classif_qual, classif_who, classif_score)
SELECT objid, classif_when, 'M' classif_type, classif_id, classif_qual, classif_who, null classif_score
from obj_head oh
where objid= any(%s)
and classif_when is not null
and not exists(select 1 from objectsclassifhisto och where oh.objid=och.objid and oh.classif_when=och.classif_date )"""
try:
params=[[int(x) for x in changes.keys()] ]
ExecSQL(sqli, params, True)
except:
app.logger.warning("Unable to add historical information, non-blocking %s" % (sys.exc_info(),))
BatchParam=[]
for k,v in changes.items():
ki=int(k)
if v=="-1" or v=="" : # utilisé dans validate all
v=prev[ki]['classif_id']
if prev[ki]['classif_qual']!=gvp('qual') or prev[ki]['classif_who']!=current_user.id or prev[ki]['classif_id']!=int(v):
# il y a eu au moins un changement
params={'objid':k,'classif_id':v,'classif_who':current_user.id,'classif_qual':gvp('qual')}
BatchParam.append(params)
# ExecSQL(sql,params,False)
Changement.append({'prev_id':prev[ki]['classif_id'],'prev_qual':prev[ki]['classif_qual']
,'id':int(v),'qual':gvp('qual')})
# params={'objid':k,'classif_id':prev[ki]['classif_id'],'classif_who':prev[ki]['classif_who']
# ,'classif_qual':prev[ki]['classif_qual'],'classif_when':prev[ki]['classif_when']}
# try:
# if ntcv(params['classif_when']) !="" : # si pas de date, violation PK
# ExecSQL(sqli,params,True)
# except:
# app.logger.warning("Unable to add historical information, non-blocking %s"%(prev,))
if prev[ki]['classif_id']!=int(v): # il y a eu un changement de classif on maintient la liste des classifs MRU
with app.MRUClassif_lock:
tbl=app.MRUClassif.get(current_user.id,[])
for i,t in enumerate(tbl):
if t["id"]==int(v):
if i>0: # on met cet item au début pour gérer un MRU
tbl=[t]+tbl[0:i]+tbl[i+1:]
break
else: # si pas trouvé dans la liste des MRU on l'ajoute au début si on trouve bien son nom dans la taxo
Taxon=GetAll("""select tf.display_name as name
from taxonomy tf
left join taxonomy p1 on tf.parent_id=p1.id
where tf.id=%(id)s """,{"id":v})
if len(Taxon)==1:
Taxon=Taxon[0].get('name', "")
tbl.insert(0,{"id": int(v), "pr": 0, "text": Taxon})
if len(tbl)>10:
tbl=tbl[0:10]
app.MRUClassif[current_user.id]=tbl
if len(BatchParam)>0:
upcur = db.engine.raw_connection().cursor()
try:
upcur.executemany(sql, BatchParam)
upcur.connection.commit()
except:
upcur.close()
app.logger.warning("Unable to save changes %s" % (sys.exc_info(),))
return '<span class="label label-danger">Unable to save changes</span>'
upcur.close()

app.logger.info("Changement = %s",Changement)
# applique les changements dans projects_taxo_stat
Empty = {'n': 0, 'V': 0, 'P': 0, 'D': 0}
Changes = {}
for c in Changement:
if c['prev_id'] is None: c['prev_id'] = -1
if c['prev_id'] not in Changes: Changes[c['prev_id']] = Empty.copy()
if c['id'] is None: c['id'] = -1
if c['id'] not in Changes: Changes[c['id']] = Empty.copy()
Changes[c['prev_id']]['n'] -= 1
Changes[c['id']]['n'] += 1
if c['prev_qual'] in ('V', 'P', 'D'):
Changes[c['prev_id']][c['prev_qual']] -= 1
if c['qual'] in ('V', 'P', 'D'):
Changes[c['id']][c['qual']] += 1
LstIdInDB=[x[0] for x in database.GetAll("select id from projects_taxo_stat where projid=%s",[PrjId])]
for k,c in Changes.items():
if k not in LstIdInDB:
database.ExecSQL("insert into projects_taxo_stat(projid, id, nbr, nbr_v, nbr_d, nbr_p) values (%s,%s,0,0,0,0)",[PrjId,k])
sqlparam={'projid':PrjId,'id':k,'n':c['n'],'v':c['V'],'d':c['D'],'p':c['P']}
database.ExecSQL("""update projects_taxo_stat set
nbr=nbr+%(n)s, nbr_v=nbr_v+%(v)s, nbr_d=nbr_d+%(d)s, nbr_p=nbr_p+%(p)s
where projid=%(projid)s and id=%(id)s""",sqlparam)

return '<span class="label label-success">Database update Successfull</span>'


@app.route('/prj/UpdateComment/<int:ObjId>', methods=['GET', 'POST'])
@login_required
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>'
2 changes: 1 addition & 1 deletion appli/project/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def indexProjects(Others=False):
if current_user.has_role(database.AdministratorLabel) or current_user.has_role(database.ProjectCreatorLabel):
CanCreate=True
PDT=database.PersistantDataTable.query.first()
if (datetime.datetime.now()-PDT.lastserverversioncheck_datetime).days>7 :
if PDT is None or PDT.lastserverversioncheck_datetime is None or (datetime.datetime.now()-PDT.lastserverversioncheck_datetime).days>7 :
fashtxt="Taxonomy synchronization and Ecotaxa version check wasn’t done during the last 7 days, Ask application administrator to do it." #+str(PDT.lastserverversioncheck_datetime)
fashtxt+=" <a href='/taxo/browse/' class='btn btn-primary btn-xs'>Synchronize to check Ecotaxa version</a>"
flash(Markup(fashtxt),'warning')
Expand Down
58 changes: 0 additions & 58 deletions appli/static/ecotaxa.css

This file was deleted.

Loading

0 comments on commit 8c3206a

Please sign in to comment.