Beispiel #1
0
def part_prj_vpgraph(PrjId,offset):
    Prj=GetAll("""select pp.* from part_projects pp where pprojid=%s""",(PrjId,))
    if len(Prj)!=1:
        return PrintInCharte(ErrorFormat("Project doesn't exists"))
    Prj=Prj[0]
    if Prj['ownerid']!=current_user.id and not current_user.has_role(database.AdministratorLabel):
        return PrintInCharte(ErrorFormat("Access Denied"))
    g.headcenter="<h4>Particle Project %s : %s</h4><a href='/part/prj/%s'>Project home</a>"%(Prj['projid'],Prj['ptitle'],Prj['pprojid'],)
    dbsample = database.GetAll("""select psampleid,filename from part_samples s where pprojid=%s
          ORDER BY filename desc limit 50 OFFSET %s 
          """ % (PrjId,offset))
    txt="""<style>
    .idepth,.ipart {height: auto}
    </style>
    <button class='btn' onclick='dozoom(50);'>50%</button>
    <button class='btn' onclick='dozoom(75);'>75%</button>
    <button class='btn' onclick='dozoom(100);'>100%</button>
    <script>
    function dozoom(z) {
      $('.idepth').css('width',(800*z/100).toFixed().toString()+"px");
      $('.ipart').css('width',(1600*z/100).toFixed().toString()+"px");
    }
</script>
    """
    for s in dbsample:
        txt+="""<p class='ghead'>Graph for {psampleid} - {filename} - </p>
          <img src='/vault/{idepth}' class='idepth'> <img src='/vault/{ipart}' class='ipart'>
          """.format(psampleid=s['psampleid'],filename=s['filename']
                     ,idepth=uvp_sample_import.GetPathForImportGraph(s['psampleid'],'depth',True)
                     ,ipart =uvp_sample_import.GetPathForImportGraph(s['psampleid'],'particle',True))
    return PrintInCharte(txt)
Beispiel #2
0
def part_prj_main(PrjId):
    # Prj = partdatabase.part_projects.query.filter_by(pprojid=PrjId).first()
    Prj=GetAll("""select pp.*
                    ,oldestsampledate+make_interval(0,public_visibility_deferral_month) visibility_date  
                    ,oldestsampledate+make_interval(0,public_partexport_deferral_month) partexport_date 
                    ,oldestsampledate+make_interval(0,public_zooexport_deferral_month) zooexport_date 
                    from part_projects pp where pprojid=%s""",(PrjId,))
    if len(Prj)!=1:
        return PrintInCharte(ErrorFormat("Project doesn't exists"))
    Prj=Prj[0]
    if Prj['ownerid']!=current_user.id and not current_user.has_role(database.AdministratorLabel):
        return PrintInCharte(ErrorFormat("Access Denied"))
    g.headcenter="<h4>Particle Project %s : %s</h4><a href='/part/'>Particle Module Home</a>"%(Prj['projid'],Prj['ptitle'])
    dbsample = database.GetAll("""select profileid,psampleid,filename,stationid,firstimage,lastimg,lastimgused,sampleid
          ,histobrutavailable,comment,daterecalculhistotaxo,ctd_import_datetime,sampledate,imp_descent_filtered_row,imp_removed_empty_slice
          ,(select count(*) from part_histopart_det where psampleid=s.psampleid) nbrlinedet
          ,(select count(*) from part_histopart_reduit where psampleid=s.psampleid) nbrlinereduit
          ,(select count(*) from part_histocat where psampleid=s.psampleid) nbrlinetaxo
          ,(select count(*) from part_ctd where psampleid=s.psampleid) nbrlinectd
          from part_samples s
          where pprojid=%s
          ORDER BY filename desc
          """ % (PrjId))
    MinSampleDate=Prj['oldestsampledate']
    VisibilityText=""
    if MinSampleDate is not None :
        VisibilityText +="""<br> Oldest sample date is {0:%Y-%m-%d}, Visibility date is {1}
          , Particule export date is {2}, Zooplankton classification export date is {3} 
          """.format(MinSampleDate
                     , "Not Defined" if Prj['visibility_date'] is None else Prj['visibility_date'].strftime("%Y-%m-%d")
                     , "Not Defined" if Prj['partexport_date'] is None else Prj['partexport_date'].strftime("%Y-%m-%d")
                     , "Not Defined" if Prj['zooexport_date'] is None else Prj['zooexport_date'].strftime("%Y-%m-%d") )

    return PrintInCharte(
        render_template('part/prj_index.html', PrjId=PrjId, dbsample=dbsample, Prj=Prj,VisibilityText=VisibilityText))
Beispiel #3
0
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)
Beispiel #4
0
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)
Beispiel #5
0
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))
Beispiel #6
0
def dbadmin_viewsizes():
    g.headcenter = "Database objects size (public schema only)<br><a href=/admin/>Back to admin home</a>"

    sql = """SELECT c.relname, c.relkind, CASE WHEN c.relkind='i' THEN c2.tablename ELSE c.relname END fromtable,pg_relation_size(('"' || c.relname || '"')::regclass)/(1024*1024) szMB
FROM
 pg_namespace ns,
 pg_class c LEFT OUTER JOIN
 pg_indexes c2 ON c.relname = c2.indexname
WHERE c.relnamespace = ns.oid
 AND ns.nspname = 'public'
 AND c.relkind IN ('r' ,'i')
ORDER BY c.relkind DESC, pg_relation_size(('"' || c.relname || '"')::regclass) DESC
"""
    res = GetAll(sql)  #,debug=True
    txt = """<table class='table table-bordered table-condensed table-hover' style="width:500px;">
            <tr><th width=200>Object</td><th witdth=200>Table</td><th width=100>Size (Mb)</td></tr>"""
    for r in res:
        txt += """<tr><td>{0}</td>
        <td>{2}</td>
        <td>{3}</td>

        </tr>""".format(*r)
    txt += "</table>"

    return PrintInCharte(txt)
Beispiel #7
0
def part_prj():
    params={}
    sql="""select pprojid,ptitle,up.ownerid,u.name,u.email,rawfolder,instrumtype,ep.title
            ,(select count(*) from part_samples where pprojid=up.pprojid) samplecount
            from part_projects up
            left JOIN projects ep on up.projid=ep.projid
            LEFT JOIN users u on ownerid=u.id
          """
    sql += " where 1=1 "
    if not current_user.has_role(database.AdministratorLabel):
        sql+="  and ownerid=%d"%(current_user.id,)
    if gvg('filt_title','')!='':
        sql +=" and (  up.ptitle ilike '%%'||%(title)s ||'%%' or to_char(up.pprojid,'999999') like '%%'||%(title)s or ep.title ilike '%%'||%(title)s ||'%%' or to_char(ep.projid,'999999') like '%%'||%(title)s) "
        params['title']=gvg('filt_title')
    if gvg('filt_instrum','')!='':
        sql +=" and up.instrumtype ilike '%%'||%(filt_instrum)s ||'%%'  "
        params['filt_instrum']=gvg('filt_instrum')
    sql+=" order by lower(ep.title),lower(ptitle)"
    res = GetAll(sql,params) #,debug=True
    # app.logger.info("res=%s",res)
    CanCreate=False
    if current_user.has_role(database.AdministratorLabel) or current_user.has_role(database.ProjectCreatorLabel):
        CanCreate=True
    g.headcenter = "<h4>Particle Projects management</h4><a href='/part/'>Particle Module Home</a>"
    return PrintInCharte(
        render_template('part/list.html', PrjList=res, CanCreate=CanCreate, AppManagerMailto=appli.GetAppManagerMailto()
                        , filt_title=gvg('filt_title'), filt_subset=gvg('filt_subset'), filt_instrum=gvg('filt_instrum')))
Beispiel #8
0
    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)
Beispiel #9
0
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)
Beispiel #10
0
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))
Beispiel #11
0
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)
Beispiel #12
0
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)
Beispiel #13
0
 def ShowCustomDetails(self):
     txt = "<h3>Import Task details view</h3>"
     txt = "<p><u>Used mapping, usable for next import</u></p>"
     taxo = database.GetAssoc2Col(
         "select id,name from taxonomy where id = any(%s)",
         (list(set(self.param.TaxoFound.values())), ))
     for k, v in self.param.TaxoFound.items():
         if v in taxo:
             txt += "{0}={1}<br>".format(k, taxo[v])
     return PrintInCharte(txt)
Beispiel #14
0
def TaskMonitor(TaskID):
    AddTaskSummaryForTemplate()
    try:
        task = LoadTask(TaskID)
        ProjectID = getattr(task.param, 'ProjectId', None)
        if ProjectID:
            Prj = database.Projects.query.filter_by(projid=ProjectID).first()
            g.headcenter = "<h4>Project : <a href='/prj/{0}'>{1}</a></h4>".format(
                Prj.projid, XSSEscape(Prj.title))
        return render_template('task/monitor.html', TaskID=task.task.id)
    except:
        return PrintInCharte(
            "This task doesn't exists anymore, peraphs it was automaticaly purged"
        )
Beispiel #15
0
def TaskClean(TaskID):
    AddTaskSummaryForTemplate()
    if gvg('thengotoproject') == 'Y':
        task = LoadTask(TaskID)
        ProjectID = getattr(task.param, 'ProjectId', None)
    else:
        ProjectID = ''
    Msg = DoTaskClean(TaskID)
    Msg += '<br><a href="/Task/listall"><span class="label label-info"> Back to Task List</span></a>'
    if ProjectID:
        Msg += """"<script>
            window.location.href = "/prj/%s"
        </script>""" % (ProjectID, )
    return PrintInCharte(Msg)
Beispiel #16
0
 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)
Beispiel #17
0
def dbadmin_viewtaxoerror():
    g.headcenter="Database Taxonomy errors<br><a href=/admin/>Back to admin home</a>"

    sql="""Select 'Missing parent' reason,t.id,t.parent_id,t.name,t.id_source
from taxonomy t where parent_id not in (select id from taxonomy);
"""
    cur = db.engine.raw_connection().cursor()
    try:
        txt="<table class='table table-bordered table-condensed table-hover'>"
        cur.execute(sql)
        txt+="<tr><td>"+("</td><td>".join([x[0] for x in cur.description]))+"</td></tr>"
        for r in cur:
            txt+="<tr><td>"+("</td><td>".join([str(x) for x in r]))+"</td></tr>"
        txt+="</table>"
    finally:
        cur.close()

    return PrintInCharte(txt)
Beispiel #18
0
def dbadmin_merge2taxon():
    if gvg("src","")=="" or gvg("dest","")=="":
        txt="Select source Taxon (will be deleted after merge) :"
        txt+="<br>Select Target Taxon :"
        return render_template('search/merge2taxo.html')
    TaxoSrc=database.Taxonomy.query.filter_by(id=int(gvg("src",""))).first()
    TaxoDest=database.Taxonomy.query.filter_by(id=int(gvg("dest",""))).first()
    N1=ExecSQL("update obj_head set classif_id=%(dest)s where  classif_id=%(src)s",{"src":TaxoSrc.id,"dest":TaxoDest.id})
    N2=ExecSQL("update obj_head set classif_auto_id=%(dest)s where  classif_auto_id=%(src)s",{"src":TaxoSrc.id,"dest":TaxoDest.id})
    N3=ExecSQL("update objectsclassifhisto set classif_id=%(dest)s where  classif_id=%(src)s",{"src":TaxoSrc.id,"dest":TaxoDest.id})
    N4=ExecSQL("update taxonomy set parent_id=%(dest)s where  parent_id=%(src)s",{"src":TaxoSrc.id,"dest":TaxoDest.id})
    N5=ExecSQL("delete from taxonomy where id=%(src)s",{"src":TaxoSrc.id,"dest":TaxoDest.id})
    return PrintInCharte("""Merge of '%s' in '%s' done
    <br>%d Objects Manuel classification  updated
    <br>%d Objects Automatic classification  updated
    <br>%d Objects classification historical updated
    <br>%d Taxonomy child updated
    <br>%d Taxonomy Node deleted
    """%(TaxoSrc.name,TaxoDest.name,N1,N2,N3,N4,N5))
Beispiel #19
0
def index():
    txt = """<div style='margin:5px;'><div id="homeText"'>"""
    #lecture du message de l'application manager
    NomFichier = 'appli/static/home/appmanagermsg.html'
    if os.path.exists(NomFichier):
        with open(NomFichier, 'r', encoding='utf8') as f:
            message = f.read()
            if len(message) > 5:
                txt += """
                    <div class="alert alert-warning alert-dismissable" role="alert">
                        <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                        <p><strong>Message from the application manager</strong></p>{0}
                    </div>
                """.format(message)
    # Lecture de la partie Haute
    NomFichier = 'appli/static/home/home.html'
    if not os.path.exists(NomFichier):
        NomFichier = 'appli/static/home/home-model.html'
    with open(NomFichier, 'r', encoding='utf8') as f:
        txt += f.read()
    txt += """
	</div>
	<div class="row" id="homeSelectors" style="margin-top: 20px; margin-bottom: 20px;">
		<div class="col-sm-4">
        <a href="/explore/" class="btn btn-primary btn-lg btn-block">Explore images</a>
		</div>
		<div class="col-sm-4">
        <a href="/prj/" class="btn btn-primary btn-lg  btn-block">Contribute to a project</a>
		</div>		
		<div class="col-sm-4">
        <a href="/part/" class="btn btn-primary btn-lg  btn-block">Particle module</a>
		</div>		
	</div>
"""
    NomFichier = 'appli/static/home/homebottom.html'
    if not os.path.exists(NomFichier):
        NomFichier = 'appli/static/home/homebottom-model.html'
    txt += """<div class="row" id="homeLegal"><div class="col-sm-12">"""
    with open(NomFichier, 'r', encoding='utf8') as f:
        txt += f.read()
    txt += """<br><a href='/privacy'>Privacy</a></div></div></div>"""
    return PrintInCharte(txt)
Beispiel #20
0
    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)
Beispiel #21
0
def index():
    txt = """<div style='margin:5px;'><div id="homeText"'>"""
    #lecture du message de l'application manager
    NomFichier = 'appli/static/home/appmanagermsg.html'
    if os.path.exists(NomFichier):
        with open(NomFichier, 'r', encoding='utf8') as f:
            message = f.read()
            if len(message) > 5:
                txt += """
                    <div class="alert alert-warning alert-dismissable" role="alert">
                        <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                        <p><strong>Message from the application manager</strong></p>{0}
                    </div>
                """.format(message)
    # Lecture de la partie Haute
    NomFichier = 'appli/static/home/home.html'
    if not os.path.exists(NomFichier):
        NomFichier = 'appli/static/home/home-model.html'
    with open(NomFichier, 'r', encoding='utf8') as f:
        txt += f.read()
    # txt+="""<br><a href='/privacy'>Privacy</a></div></div></div>"""
    return PrintInCharte(txt)
Beispiel #22
0
def indexPart():
    class FiltForm(Form):
        filt_proj = SelectMultipleField(choices=[['', '']] + database.GetAll(
            "SELECT projid,concat(title,' (',cast(projid AS VARCHAR),')') FROM projects where projid in (select projid from part_projects) ORDER BY lower(title)"
        ))
        filt_uproj = SelectMultipleField(choices=[['', '']] + database.GetAll(
            "SELECT pprojid,concat(ptitle,' (',cast(pprojid AS VARCHAR),')') FROM part_projects ORDER BY lower(ptitle)"
        ))
        gpr = SelectMultipleField(
            choices=[("cl%d" % i, "# l-1 %02d : " % i +
                      GetClassLimitTxt(PartRedClassLimit, i))
                     for i in range(1, 16)] +
            [("bv%d" % i,
              "BV %02d : " % i + GetClassLimitTxt(PartRedClassLimit, i))
             for i in range(1, 16)])
        gpd = SelectMultipleField(
            choices=[("cl%d" % i, "# l-1 %02d : " % i +
                      GetClassLimitTxt(PartDetClassLimit, i))
                     for i in range(1, 46)] +
            [("bv%d" % i,
              "BV %02d : " % i + GetClassLimitTxt(PartDetClassLimit, i))
             for i in range(1, 46)])
        ctd = SelectMultipleField(
            choices=sorted([(k, v) for v, k in CTDFixedCol.items()],
                           key=operator.itemgetter(1)))
        filt_proftype = SelectField(
            choices=[['', 'All'], ['V', 'Vertical'], ['H', 'Horizontal']])

    filt_data = request.args
    form = FiltForm(filt_data)
    g.headcenter = """<h1 style='text-align: center;cursor: pointer;' >
      <span onclick="$('#particleinfodiv').toggle()"><b>PARTICLE</b> module <span class='glyphicon glyphicon-info-sign'></span> </span> 
      <a href='/' style='font-size:medium;margin-left: 50px;'>Go to Ecotaxa</a></h2>"""
    g.useselect4 = True
    return PrintInCharte(
        render_template('part/index.html',
                        form=form,
                        LocalGIS=app.config.get("LOCALGIS", False),
                        reqfields=request.args))
Beispiel #23
0
def TaskShow(TaskID):
    AddTaskSummaryForTemplate()
    try:
        task = LoadTask(TaskID)
    except:
        return PrintInCharte(
            "This task doesn't exists anymore, peraphs it was automaticaly purged"
        )

    txt = ""
    if gvg('log') == "Y":
        WorkingDir = task.GetWorkingDir()
        # app.send_static_file(os.path.join(WorkingDir,"TaskLog.txt"))
        return flask.send_from_directory(WorkingDir, "TaskLog.txt")
    if gvg('CustomDetails') == "Y":
        return task.ShowCustomDetails()
    if "GetResultFile" in dir(task):
        f = task.GetResultFile()
        if f is None:
            txt += "Error, final file not available"
        else:
            txt += "<a href='/Task/GetFile/%d/%s' class='btn btn-primary btn-sm ' role='button'>Get file %s</a>" % (
                TaskID, f, f)

    CustomDetailsAvail = "ShowCustomDetails" in dir(task)
    try:
        decodedsteperrors = json.loads(task.task.inputparam).get("steperrors")
    except:
        decodedsteperrors = ["Task Decoding Error"]
    ProjectID = getattr(task.param, 'ProjectId', None)
    if ProjectID:
        Prj = database.Projects.query.filter_by(projid=ProjectID).first()
        g.headcenter = "<h4>Project : <a href='/prj/{0}'>{1}</a></h4>".format(
            Prj.projid, XSSEscape(Prj.title))
    return render_template('task/show.html',
                           task=task.task,
                           steperror=decodedsteperrors,
                           CustomDetailsAvail=CustomDetailsAvail,
                           extratext=txt)
Beispiel #24
0
 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)
Beispiel #25
0
def PrjMerge(PrjId):
    Prj = database.Projects.query.filter_by(projid=PrjId).first()
    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>")
    g.headcenter = "<h4><a href='/prj/{0}'>{1}</a></h4>".format(
        Prj.projid, XSSEscape(Prj.title))
    txt = "<h3>Project Merge / Fusion </h3>"

    if not gvg('src'):
        txt += """<ul><li>You are allowed to merge projects that you are allowed to manage
<li>User privileges from both projects will be added
<li>This tool allow to merge two projects in a single projet (called Current project). The added project will then be automatically deleted. If object data are not consistent between both projects :
<ul><li>New data fields are added to the Current project
    <li>The resulting project will thus contain partially documented datafields.
</ul><li>Note : Next screen will indicate compatibility issues (if exists) and allow you to Confirm the merging operation.
</ul>
                """
        sql = "select p.projid,title,status,coalesce(objcount,0) objcount,coalesce(pctvalidated,0) pctvalidated,coalesce(pctclassified,0) pctclassified from projects p"
        if not current_user.has_role(database.AdministratorLabel):
            sql += " Join projectspriv pp on p.projid = pp.projid and pp.member=%d" % (
                current_user.id, )
        sql += " where p.projid!=%d order by title" % Prj.projid
        res = GetAll(sql, doXSSEscape=True)  #,debug=True
        txt += """<table class='table table-bordered table-hover table-verycondensed'>
                <tr><th width=120>ID</td><th>Title</td><th width=100>Status</th><th width=100>Nbr Obj</th>
            <th width=100>% Validated</th><th width=100>% Classified</th></tr>"""
        for r in res:
            txt += """<tr><td><a class="btn btn-primary" href='/prj/merge/{activeproject}?src={projid}'>Select</a> {projid}</td>
            <td>{title}</td>
            <td>{status}</td>
            <td>{objcount:0.0f}</td>
            <td>{pctvalidated:0.2f}</td>
            <td>{pctclassified:0.2f}</td>
            </tr>""".format(activeproject=Prj.projid, **r)
        txt += "</table>"
        return PrintInCharte(txt)

    PrjSrc = database.Projects.query.filter_by(projid=int(gvg('src'))).first()
    if PrjSrc is None:
        flash("Source project doesn't exists", 'error')
        return PrintInCharte("<a href=/prj/>Select another project</a>")
    if not PrjSrc.CheckRight(2):  # Level 0 = Read, 1 = Annotate, 2 = Admin
        flash('You cannot merge for this project', 'error')
        return PrintInCharte("<a href=/prj/>Select another project</a>")
    txt += """<h4>Source Project : {0} - {1} (This project will be destroyed)</h4>
            """.format(PrjSrc.projid, XSSEscape(PrjSrc.title))
    if not gvg('merge'):  # Ici la src à été choisie et vérifiée
        if PrjSrc.mappingobj != Prj.mappingobj:
            flash("Object mapping differ With source project ", "warning")
        if PrjSrc.mappingsample != Prj.mappingsample:
            flash("Sample mapping differ With source project ", "warning")
        if PrjSrc.mappingacq != Prj.mappingacq:
            flash("Acquisition mapping differ With source project ", "warning")
        if PrjSrc.mappingprocess != Prj.mappingprocess:
            flash("Process mapping differ With source project ", "warning")
        txt += FormatError(
            """ <span class='glyphicon glyphicon-warning-sign'></span>
        Warning project {1} - {2}<br>
        Will be destroyed, its content will be transfered in the target project.<br>
        This operation is irreversible</p>
        <br><a class='btn btn-lg btn-warning' href='/prj/merge/{0}?src={1}&merge=Y'>Start Project Fusion</a>        
        """,
            Prj.projid,
            PrjSrc.projid,
            XSSEscape(PrjSrc.title),
            DoNotEscape=True)
        return PrintInCharte(txt)

    if gvg('merge') == 'Y':
        ExecSQL("update acquisitions set projid={0} where projid={1}".format(
            Prj.projid, PrjSrc.projid))
        ExecSQL("update process set projid={0} where projid={1}".format(
            Prj.projid, PrjSrc.projid))
        ExecSQL("update samples set projid={0} where projid={1}".format(
            Prj.projid, PrjSrc.projid))
        ExecSQL("update obj_head set projid={0} where projid={1}".format(
            Prj.projid, PrjSrc.projid))
        ExecSQL("update part_projects set projid={0} where projid={1}".format(
            Prj.projid, PrjSrc.projid))
        # garde le privilege le plus elevé des 2 projets
        ExecSQL("""UPDATE projectspriv ppdst
                  set privilege=case when 'Manage' in (ppsrc.privilege,ppdst.privilege) then 'Manage'
                        when 'Annotate' in (ppsrc.privilege,ppdst.privilege) then 'Annotate'
                        else 'View' end
                from projectspriv  ppsrc
                where ppsrc.projid={1} and ppdst.projid={0} and ppsrc.member=ppdst.member"""
                .format(Prj.projid, PrjSrc.projid),
                debug=True)
        # Transfere les privilege depuis le projet source
        ExecSQL("""update projectspriv
                set projid={0}
                where projid={1} and member not in (select member from projectspriv where projid={0})"""
                .format(Prj.projid, PrjSrc.projid))
        # Efface ceux qui etait des 2 cotés
        ExecSQL("delete from projectspriv where projid={0}".format(
            PrjSrc.projid))
        ExecSQL("delete from projects where projid={0}".format(PrjSrc.projid))
        appli.project.main.RecalcProjectTaxoStat(Prj.projid)
        appli.project.main.UpdateProjectStat(Prj.projid)

        txt += "<div class='alert alert-success' role='alert'>Fusion Done successfully</div>"
        txt += "<br><a class='btn btn-lg btn-primary' href='/prj/%s'>Back to target project</a>" % Prj.projid
        return PrintInCharte(txt)
Beispiel #26
0
def doimporttext():
    # test avec D:\temp\Downloads\taxoexport_20181228_101007.tsv
    txt=""
    uploadfile = request.files.get("uploadfile")
    if uploadfile is None:
        return PrintInCharte(FormatError("You must send a file"))
    Desctxt="{0} on {1:%Y-%m-%d %H:%M:%S} ".format(uploadfile.filename,datetime.datetime.now())
    app.logger.info('Load file {} by {}'.format(uploadfile.filename,current_user))
    #creation d'un fichier temporaire qui s'efface automatiquement
    tmpfile =tempfile.TemporaryFile(mode='w+b')
    # app.logger.info('TMP file is {}'.format(tmpfile.name))
    uploadfile.save(tmpfile) # on copie le contenu dedants
    tmpfile.seek(0) # on se remet au debut
    fichier= TextIOWrapper(tmpfile, encoding = 'latin_1', errors = 'replace') # conversion du format binaire au format texte

    app.logger.info("Analyzing file %s" % (fichier))
    # lecture en mode dictionnaire basé sur la premiere ligne
    rdr = csv.reader(fichier, delimiter='\t', quotechar='"', )
    # lecture la la ligne des titre
    LType = rdr.__next__()
    # Lecture du contenu du fichier
    RowCount = 0
    ExecSQL("truncate table temp_taxo")
    sqlinsert = "INSERT INTO temp_taxo(idparent,idtaxo,name,status,typetaxo) values(%s,%s,%s,%s,%s)"
    for lig in rdr:
        if lig[0].strip() == '':  # Ligne vide
            continue
        database.ExecSQL(sqlinsert, (
        lig[0].strip(), lig[1].strip(), lig[2].replace('+', ' ').replace('_', ' ').strip(), lig[3].strip(),
        lig[4].strip()))
        if RowCount > 0 and RowCount % 1000 == 0:
            app.logger.info("Inserted %s lines" % RowCount)

        RowCount += 1
    app.logger.info("count=%d" % RowCount)

        # app.logger.info(str(r))
    # if len(UpdatedTaxon)>0:
    #     ComputeDisplayName(UpdatedTaxon)
    txt+="<p style='color: green'> %s taxon loaded </p> "%(RowCount)

    # MAJ des IDFinal dans la table temp pour tout ce qui existe.
    n = ExecSQL("""UPDATE temp_taxo tt set idfinal=tf.id
                from taxonomy tf where tf.id_source=tt.idtaxo or (lower(tf.name)=lower(tt.name) and tf.id_source is null)""")
    app.logger.info("%d Nodes already exists " % n)

    TSVal="to_timestamp('{}','YYYY-MM-DD HH24:MI:SS')".format(datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S'))
    TSUpdate="lastupdate_datetime="+TSVal
    # insertion des nouveaux noeud racines
    n = ExecSQL("""INSERT INTO taxonomy (id, parent_id, name, id_source,lastupdate_datetime,source_desc)
    select nextval('seq_taxonomy'),NULL,t.name,t.idtaxo,{} ,%s
    from temp_taxo t where idparent='-1' and idfinal is null and status='1'""".format(TSVal),["Created by "+Desctxt])
    app.logger.info("Inserted %d Root Nodes" % n)

    # MAJ de la table import existante
    n = ExecSQL("""UPDATE temp_taxo tt set idfinal=tf.id 
                from taxonomy tf where tf.id_source=tt.idtaxo
                and tt.idfinal is null and idparent='-1'""")
    app.logger.info("Updated %d inserted Root Nodes" % n)

    while True:
        # insertion des nouveaux noeud enfants à partir des parents deja insérés
        # n=ExecSQL("""INSERT INTO taxonomy (id, parent_id, name, id_source)
        #     select nextval('seq_taxonomy'),ttp.idfinal,tt.name,tt.idtaxo from temp_taxo tt join temp_taxo ttp on tt.idparent=ttp.idtaxo
        #     where tt.idfinal is null and ttp.idfinal is not null and status='1'""")
        n = ExecSQL("""INSERT INTO taxonomy (id, parent_id, name, id_source,taxotype,lastupdate_datetime,source_desc)
            select nextval('seq_taxonomy'),ttp.id,tt.name,tt.idtaxo,case when lower(tt.typetaxo)='taxa' then 'P' else 'M' end,{},%s
            from temp_taxo tt join taxonomy ttp on tt.idparent=ttp.id_source
            where tt.idfinal is null and status='1'""".format(TSVal),["Created by "+Desctxt])
        if n == 0:
            app.logger.info("No more data to import")
            break
        else:
            app.logger.info("Inserted %d Child Nodes" % n)

        # MAJ de la table import existante
        n = ExecSQL("""UPDATE temp_taxo tt set idfinal=tf.id
                    from taxonomy tf where tf.id_source=tt.idtaxo
                    and tt.idfinal is null """)
        app.logger.info("Updated %d inserted Child Nodes" % n)

    n = ExecSQL("""UPDATE taxonomy tf set name=tt.name,{},taxotype=case when lower(tt.typetaxo)='taxa' then 'P' else 'M' end
                      ,source_desc=%s  
                from temp_taxo tt where tf.id_source=tt.idtaxo
                and tt.status='1' and  (tf.name!=tt.name
                  or tf.taxotype!=case when lower(tt.typetaxo)='taxa' then 'P' else 'M' end )
                """.format(TSUpdate),["Updated by "+Desctxt])
    app.logger.info("Updated %d Nodes names" % n)

    n = ExecSQL("""UPDATE taxonomy tfu set parent_id=sq.idfinal,{},source_desc=%s
                from (select tf.id, ttp.idfinal from taxonomy tf
                ,temp_taxo tt LEFT JOIN temp_taxo ttp on tt.idparent=ttp.idtaxo  where tf.id_source=tt.idtaxo
                and tt.status='1' and coalesce(tf.parent_id,-1)!=coalesce(ttp.idfinal,-1)
                and (ttp.idfinal is not null or tt.idparent='-1' )) sq where tfu.id=sq.id""".format(TSUpdate),["Updated by "+Desctxt])
    app.logger.info("Updated %d Nodes Parents" % n)

    # while True:
    #     n = ExecSQL("""delete from taxonomy t
    #             using temp_taxo tt
    #             where t.id=tt.idfinal and tt.status='0'
    #             and not exists (select 1 from taxonomy where parent_id=t.id )
    #             and not exists (select 1 from objects where classif_id=t.id or classif_auto_id=t.id)""")
    #     if n == 0:
    #         app.logger.info("No more data to delete")
    #         break
    #     else:
    #         app.logger.info("Deleted %d Nodes" % n)

    # Lst = GetAll("""select t.name from taxonomy t,temp_taxo tt
    #             where t.id=tt.idfinal and tt.status='0'
    #             and (exists (select 1 from taxonomy where parent_id=t.id )
    #             or exists (select 1 from objects where classif_id=t.id or classif_auto_id=t.id))""")
    # for r in Lst:
    #     app.logger.info("Can't Delete '%s' because it's used " % r[0])
    txt+="<br><a href='/browsetaxo/' class='btn btn-primary'><i class='fas fa-arrow-left'></i> Back to taxonomy</a>"
    LstId=[x['idfinal'] for x in GetAll("select idfinal from temp_taxo where idfinal is not null")]
    ComputeDisplayName(LstId)
    app.logger.info("Updated Display name" )

    # if len(Errors):
    #     txt += "<p style='color: red'> %s errors <ul> " % (len(Errors))
    #     txt += "\n".join("<li>%s</li>"%x for x in Errors)
    #     txt += "</ul></p> "

    g.bodydivmargin="10px"
    return PrintInCharte(txt)
Beispiel #27
0
def doimportmassupdate():
    # test avec D:\temp\Downloads\taxoexport_20181228_101007.tsv
    txt = ""
    uploadfile = request.files.get("fichier")
    if uploadfile is None:
        return PrintInCharte(FormatError("You must send a file"))
    app.logger.info('Load file {} by {}'.format(uploadfile.filename,
                                                current_user))
    #creation d'un fichier temporaire qui s'efface automatiquement
    tmpfile = tempfile.TemporaryFile(mode='w+b')
    # app.logger.info('TMP file is {}'.format(tmpfile.name))
    uploadfile.save(tmpfile)  # on copie le contenu dedants
    tmpfile.seek(0)  # on se remet au debut
    f = TextIOWrapper(
        tmpfile, encoding='ascii',
        errors='replace')  # conversion du format binaire au format texte
    rdr = csv.DictReader(
        f,
        delimiter='\t',
        quotechar='"',
    )  # ouverture sous forme de reader dictionnaire
    champs = rdr.fieldnames
    app.logger.info("Loading file with this columns : %s" % str(champs))
    if 'id' not in champs:
        return PrintInCharte(FormatError("A column named 'id' is required"))
    IdList = {x['id'] for x in database.GetAll("select id from taxonomy")}
    InstanceList = {
        x['id']
        for x in database.GetAll("select id from ecotaxainst")
    }
    rowcount = 0
    Errors = []
    UpdatedTaxon = []
    UpdatableCols = [
        'parent_id', 'name', 'taxotype', 'taxostatus', 'id_source',
        'source_url', 'source_desc', 'creator_email', 'creation_datetime',
        'id_instance', 'rename_to'
    ]
    # 'lastupdate_datetime', 'display_name',
    for r in rdr:
        rowcount += 1
        id = int(r['id'])
        taxon = database.Taxonomy.query.filter_by(id=id).first()
        if taxon is None:
            Errors.append("id {} does not exists in the database".format(id))
            continue
        valueschanged = False
        SkipRow = False
        for c in champs:
            if c in UpdatableCols:
                oldvalue = str(ntcv(getattr(taxon, c))).replace('\r', '')
                newvalue = r[c].replace("\\n", "\n").strip()
                if c in ('parent_id', 'rename_to') and newvalue != '':
                    if int(newvalue) not in IdList:
                        Errors.append(
                            "id {} : {} {} does not exists in the database".
                            format(id, c, newvalue))
                        SkipRow = True
                        continue
                if c == 'taxotype':
                    if newvalue not in ('P', 'M'):
                        Errors.append("id {} : Invalid taxotype {} ".format(
                            id, newvalue))
                        SkipRow = True
                        continue
                if c == 'taxostatus':
                    if newvalue not in database.TaxoStatus:
                        Errors.append("id {} : Invalid status {} ".format(
                            id, newvalue))
                        SkipRow = True
                        continue
                if c == 'id_instance' and newvalue != '':
                    if int(newvalue) not in InstanceList:
                        Errors.append(
                            "id {} : {} is not a valid instance id".format(
                                id, newvalue))
                        SkipRow = True
                        continue
                if oldvalue != newvalue:
                    valueschanged = True
                    setattr(taxon, c, newvalue)
                    app.logger.info("id {} : update {} to {}".format(
                        id, oldvalue, newvalue))
        if SkipRow:
            continue
        if valueschanged:
            # db.session.add(taxon)
            UpdatedTaxon.append(id)
            taxon.lastupdate_datetime = datetime.datetime.utcnow()
            db.session.commit()
        # app.logger.info(str(r))
    if len(UpdatedTaxon) > 0:
        ComputeDisplayName(UpdatedTaxon)
    txt += "<p style='color: green'> %s taxon updated </p> " % (
        len(UpdatedTaxon))
    if len(Errors):
        txt += "<p style='color: red'> %s errors <ul> " % (len(Errors))
        txt += "\n".join("<li>%s</li>" % x for x in Errors)
        txt += "</ul></p> "
    txt += "<a href='/browsetaxo/' class='btn btn-primary'><i class='fas fa-arrow-left'></i> Back to Browse Taxonomy</a>"
    g.bodydivmargin = "10px"
    return PrintInCharte(txt)
    def QuestionProcess(self):
        ServerRoot = Path(app.config['SERVERLOADAREA'])
        txt = "<h1>Particle ZooScan folder Importation Task</h1>"
        errors = []
        txt += "<h3>Task Creation</h3>"
        Prj = partdatabase.part_projects.query.filter_by(
            pprojid=gvg("p")).first()
        if Prj is None:
            return PrintInCharte(ErrorFormat("This project doesn't exists"))
        if Prj.instrumtype not in LstInstrumType:
            return PrintInCharte(
                ErrorFormat("Instrument type '%s' not in list : %s" %
                            (Prj.instrumtype, ','.join(LstInstrumType))))
        g.prjtitle = Prj.ptitle
        g.prjprojid = Prj.pprojid
        # g.prjowner=Prj.owneridrel.name
        DossierUVPPath = ServerRoot / Prj.rawfolder
        self.param.DossierUVP = DossierUVPPath.as_posix()

        txt = ""
        # TODO gestion sécurité
        # if Prj.CheckRight(2)==False:
        #     return PrintInCharte("ACCESS DENIED for this project");

        self.param.pprojid = gvg("p")
        DirName = DossierUVPPath.name
        m = re.search(R"([^_]+)_(.*)", DirName)
        if m.lastindex != 2:
            return PrintInCharte(
                ErrorFormat("Le repertoire projet n'as pas un nom standard"))
        else:
            FichierHeader = DossierUVPPath / "meta" / (
                m.group(1) + "_header_" + m.group(2) + ".txt")

            if not FichierHeader.exists():
                return PrintInCharte(
                    ErrorFormat("Le fichier header n'existe pas :"******"""select profileid,psampleid,filename,stationid,firstimage,lastimg,lastimgused,comment,histobrutavailable
                      ,(select count(*) from part_histopart_det where psampleid=s.psampleid) nbrlinedet
                      ,(select count(*) from part_histopart_reduit where psampleid=s.psampleid) nbrlinereduit
                      ,(select count(*) from part_histocat where psampleid=s.psampleid) nbrlinetaxo
                      from part_samples s
                      where pprojid=%s""" % (self.param.pprojid))
                # print("ouverture de " + FichierHeader)
                with open(FichierHeader.as_posix()) as FichierHeaderHandler:
                    F = csv.DictReader(FichierHeaderHandler, delimiter=';')
                    for r in F:
                        r['psampleid'] = None
                        if r['profileid'] in dbsample:
                            r['psampleid'] = dbsample[
                                r['profileid']]['psampleid']
                            r['histobrutavailable'] = dbsample[
                                r['profileid']]['histobrutavailable']
                            r['nbrlinedet'] = dbsample[
                                r['profileid']]['nbrlinedet']
                            r['nbrlinereduit'] = dbsample[
                                r['profileid']]['nbrlinereduit']
                            r['nbrlinetaxo'] = dbsample[
                                r['profileid']]['nbrlinetaxo']
                        self.param.profilelistinheader.append(r)
                        # self.param.profilelistinheader[r['profileid']]=r
                    # Tri par 4eme colonne, profileid
                    self.param.profilelistinheader = sorted(
                        self.param.profilelistinheader,
                        key=lambda r: r['profileid'])

        if gvp('starttask') == "Y":
            self.param.ProcessOnlyMetadata = (gvp('onlymeta', 'N') == 'Y')
            self.param.user_name = current_user.name
            self.param.user_email = current_user.email
            for f in request.form:
                self.param.profiletoprocess[request.form.get(f)] = "Y"

            if len(self.param.profiletoprocess) == 0:
                errors.append("No sample to process selected")
            if len(errors) > 0:
                for e in errors:
                    flash(e, "error")
            else:
                return self.StartTask(self.param)
        else:  # valeurs par default

            if len(self.param.profilelistinheader) == 0:
                return PrintInCharte(
                    ErrorFormat("No sample available in file %s" %
                                (FichierHeader.as_posix())))
            print("%s" % (self.param.profilelistinheader))
        return render_template('task/uvpzooscanimport_create.html',
                               header=txt,
                               data=self.param,
                               ServerPath=gvp("ServerPath"),
                               TxtTaxoMap=gvp("TxtTaxoMap"))
Beispiel #29
0
def PrjConfusionMatrix(PrjId):
    sql = """select lower(case when tr.name like '% %' then tr.name else concat(tr.name,'(',trp.name,')') end ) ClassifReel
          ,lower(case when tp.name like '% %' then tp.name else concat(tp.name,'(',tpp.name,')') end)  ClassifPredict
from objects o
join taxonomy tp on tp.id=o.classif_auto_id
join taxonomy tr on tr.id=o.classif_id
left join taxonomy tpp on tp.parent_id=tpp.id 
left join taxonomy trp on tr.parent_id=trp.id
where projid ={} and classif_qual='V'""".format(PrjId)
    DBRes = np.array(GetAll(sql))
    txtbacktoproject = "<a href='/prj/%d'>Back to project</a>" % 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 len(DBRes) == 0:
        flash("No validated objects with prediction", 'error')
        return PrintInCharte(txtbacktoproject)
    CatTrue = DBRes[:, 0]
    CatPred = DBRes[:, 1]
    CatAll = [x for x in set(CatPred) | set(CatTrue)]
    CatAll.sort()
    cm = metrics.confusion_matrix(y_pred=CatPred, y_true=CatTrue)
    # Version Division par axe des Réel (somme horiz)
    SommeH = cm.sum(axis=1)
    SommeV = cm.sum(axis=0)
    SommeVNoZero = cm.sum(axis=0)
    SommeVNoZero[SommeVNoZero ==
                 0] = 999999  # pour eviter les division par zéro
    SommeHNoZero = cm.sum(axis=1)
    SommeHNoZero[SommeHNoZero ==
                 0] = 999999  # pour eviter les division par zéro
    TotalObj = CatPred.shape[0]
    D = np.diag(cm)

    if gvg("astsv"):
        t = [""]  #case haut gauche vide
        for c in CatAll:
            t.append("\t%s" % c)
        t.append("\tNb. true\t% true\tRecall")
        for c, cml, s, recall in zip(CatAll, cm, SommeH,
                                     100 * D / SommeHNoZero):
            t.append("\n%s" % c)
            for v in cml:
                t.append("\t%s" % v)
            t.append("\t%s\t%0.1f\t%0.1f" %
                     (s, 100 * s / TotalObj,
                      recall))  # Ajoute le total & Pct de la ligne
        t.append("\nNb. predicted")
        for s in SommeV:
            t.append("\t%s" % (s))  # Ajoute le total de la Colonne
        t.append("\n% of predicted")
        for s in SommeV:
            t.append("\t%0.1f" %
                     (100 * s / TotalObj))  # Ajoute le % de la Colonne
        t.append("\nPrecision")
        for s in 100 * D / SommeVNoZero:
            t.append("\t%0.1f" % (s))  # Ajoute la precision
        t.append("\n")
        return Response("".join(t),
                        mimetype="text/tsv",
                        headers={
                            "Content-Disposition":
                            "attachment; filename=confusionmatrix_%s.tsv" %
                            Prj.projid
                        })

    t = [
        """<style>
    th {
      vertical-align: bottom !important;
      background-color: #ddd
    }
    .table > tbody > tr > th.rotate {
      height: 140px;
      white-space: nowrap;
    }
    .table > tbody > tr > th.row_header{
      height: 140px;
      white-space: nowrap;
      vertical-align: top !important;
    }
    th.rotate > div {
      transform:
        rotate(270deg);
      width: 15px;
    }
    th.row_header > div {
      transform:
        translate(0px, 200px)
        rotate(270deg);
      width: 15px;
    }
  .margin {
      font-style: italic;
    }
  </style>
  <h2>Confusion matrix - <a href='?astsv=Y' style='font-size:medium' class='btn btn-primary btn-xs'>TSV Export</a> </h2>
  <p>This matrix is refreshed every time you access it. For more information on confusion statistics, please see the <a href='https://en.wikipedia.org/wiki/Precision_and_recall'>very well written Wikipedia page</a>.</p>
  
    <table class='table table-bordered table-hover table-condensed' style='font-size:12px;'>
    <tr>
      <th>&nbsp;</th>
      <th>&nbsp;</th>
      <th class='column_header' colspan='1000'>Predicted category</th>
    </tr>
    <tr>
      <th class='row_header' rowspan='1000'><div>True category</div></th>
      <th>&nbsp;</th>
    """
    ]
    # ligne titre des categorie
    for c in CatAll:
        t.append("<th class='rotate'><div>%s</div></th>" % c)
    t.append(
        "<th>Nb. true</th><th>% true</th><th><a href='https://en.wikipedia.org/wiki/Precision_and_recall#Recall' target='_blank'>Recall</a></th>"
    )
    for c, cml, s, recall in zip(CatAll, cm, SommeH, 100 * D / SommeHNoZero):
        t.append("</tr><tr><th>%s</th>" % c)
        for v in cml:
            t.append("<td>%s</td>" % v)
        t.append(
            "<td class='margin'>%s</td><td class='margin'>%0.1f</td class='margin'><td>%0.1f</td>"
            % (s, 100 * s / TotalObj,
               recall))  # Ajoute le total & Pct de la ligne
    t.append("</tr><tr><th>Nb. predicted</th>")
    for s in SommeV:
        t.append("<td class='margin'>%s</td>" %
                 (s))  # Ajoute le total de la Colonne
    t.append("</tr><tr><th>% of predicted</th>")
    for s in SommeV:
        t.append("<td class='margin'>%0.1f</td>" %
                 (100 * s / TotalObj))  # Ajoute le % de la Colonne
    t.append(
        "</tr><tr><th><a href='https://en.wikipedia.org/wiki/Precision_and_recall#Precision' target='_blank' >Precision</a></th>"
    )
    for s in 100 * D / SommeVNoZero:
        t.append("<td class='margin'>%0.1f</td>" % (s))  # Ajoute la precision
    t.append("</tr></table>")

    cm_normalized = cm.astype('float') / SommeHNoZero[:, np.newaxis]
    FigSize = int(SommeHNoZero.shape[0] / 3)
    if FigSize < 8: FigSize = 8  # 800x800 px
    g.Fig = plt.figure(figsize=(FigSize, FigSize), dpi=100)
    plot_confusion_matrix(cm_normalized, CatAll)
    RamImage = io.BytesIO()
    g.Fig.savefig(RamImage, dpi=100, format='png')
    t.append(
        "<h3>Confusion matrix divided by sum of lines</h3><p>The diagonal contains the <a href='https://en.wikipedia.org/wiki/Precision_and_recall#Recall' target='_blank'>recall</a> rate.</p><img src='data:image/png;base64,{}'/>"
        .format(base64.encodebytes(RamImage.getvalue()).decode()))

    # Version division par axe des prediction pas de div pas zero possible et permet de voir ce que c'est devenu (somme Vert.)
    cm_normalized = cm.astype('float') / SommeVNoZero
    # plt.figure(figsize=(8,8), dpi=100) # 800x800 px
    g.Fig.clf()
    plot_confusion_matrix(cm_normalized, CatAll)
    RamImage = io.BytesIO()
    g.Fig.savefig(RamImage, dpi=100, format='png')
    t.append(
        "<h3>Confusion matrix divided by sum of columns</h3><p>The diagonal contains the <a href='https://en.wikipedia.org/wiki/Precision_and_recall#Precision' target='_blank'>precision</a> rate.</p><img src='data:image/png;base64,{}'/>"
        .format(base64.encodebytes(RamImage.getvalue()).decode()))
    # t.append("<br>"+txtbacktoproject)
    return PrintInCharte("\n".join(t))
Beispiel #30
0
def AutoCleanManual():
    return PrintInCharte(AutoClean())