def karma(request,P,C): adm = get_admin(request,'unknown') if not hasperm_db(C,adm,'karma'): return Error403('no sufficient permissions for %s'%adm) received={} k = get_karma_receivers(C) return basevars(request,P,C,{'receivers':k})
def tag_pri(request,P,C): adm = get_admin(request,'unknown') if not hasperm_db(C,adm,'prioritization'): return Error403('no sufficient permissions for %s'%adm) qry = "INSERT INTO tags (name, pri) VALUES (%s, %s) ON CONFLICT (name) DO UPDATE SET pri = %s" nm = request.params.get('name') val = request.params.get('val') with P as p: C = p.cursor() C.execute(qry,(nm,val,val)) return {'name':nm,'val':val}
def gantt(request,P,C,tid=None): global dhtmlgantt_dfmt adm = get_admin(request,'unknown') if not hasperm_db(C,adm,'gantt'): return Error403('no sufficient permissions for %s'%adm) qry = "select id from tasks where show_in_gantt=false" res = C.execute(qry) fa = C.fetchall() dismissed = [r['id'] for r in fa if r] qry = "select * from gantt where 1=1" args=[] if tid: qry+=" and tid=%s or parent_id=%s" args.append(tid) ; args.append(tid) else: qry+=" and (we is not null and t is not null )" qry+=" and ( (t_l>=now()-interval '2 weeks' or c_l>=now()-interval '2 weeks'))" print(qry,args) C.execute(qry,args) #and created_at>=now()-interval '12 month' res = C.fetchall() print((len(res),'initial tasks fetched')) # retrieve missing parents? while True: missing = list(set([r['parent_id'] for r in res if r['parent_id'] and r['parent_id'] not in dismissed and r['parent_id'] not in [r2['tid'] for r2 in res]])) missing2=[] for r in res: ct = Task.get(C,r['tid']) try: missing2+=ct['dependencies'] except KeyError: pass for r in res: if r['tid'] in missing2: missing2.remove(r['tid']) missing+=missing2 print(('calculated',len(missing),'missing parents:',missing)) if not len(missing): break #C.execute("select * from gantt where tid ANY %s",(list(missing),)) C.execute("select * from gantt where tid in %(missing)s",{'missing':tuple(missing,)}) res+=C.fetchall() tasks=[] links=[] assignees=[] ; colors=[] for r in res: gr = gantt_info_row(r,excl=()) created_at=r['created_at'] tid=r['tid'] assignee=r['assignee'] parent_id=r['parent_id'] summary=r['summary'] status=r['status'] we=r['we'] fd=r['finish_date'] t=r['t'] # tracking t_f=r['t_f'] t_l=r['t_l'] c=r['c'] c_f=r['c_f'] c_l = r['c_l'] assert re.compile('^([0-9\/]{3,})$').search(tid),Exception("got bad tid",tid,"from ",r) start_date = gr['taf'][0] if assignee not in assignees: assignees.append(assignee) if parent_id in dismissed: parent=None else: parent=parent_id text = summary #'%s:%s:%s'%(tid,gr['dt'],summary) nstart_date = start_date and start_date.strftime(dhtmlgantt_dfmt) or None apnd = {'id':tid, 'assignee':assignee, 'summary':summary, 'status':status, 'text':tid+' : '+assignee, 'start_date':nstart_date, # when was it in fact started to be worked on 'duration':gr['dur'], # total REAL or estimated duration 'progress':gr['ce'], # progress estimation 'parent':parent } #if parent_id in dismissed: raise Exception(apnd) tasks.append(apnd) ct = Task.get(C,tid) try: for dep in ct['dependencies']: tp = '0' tdep = {'source': tid, 'target': dep, 'type': tp, 'id': tid+'-'+dep+'-'+tp} links.append(tdep) except KeyError as e: pass assignees.sort() assignees_colors = {} seed(1) for i in range(len(assignees)): clr = '%06X' % randint(0, 0xFFFFFF) colors.append(clr) assignees_colors[assignees[i]]=clr return basevars(request,P,C,{'tasks':json.dumps({'data':tasks, 'links':links }), 'assignees_colors':assignees_colors })
def time_tracking_dashboard(request,P,C,rangeback='7 day',persons=None,mode='provider',tids=None): adm = get_admin(request,'unknown') if not hasperm_db(C,adm,'gantt'): return Error403('no sufficient permissions for %s'%adm) if persons: cond = "dt>=now()-interval '%s' and provider in (%s)"%(rangeback,",".join(["'%s'"%p for p in persons.split(",")])) else: cond = "dt>=now()-interval '%s'"%rangeback # TODO: allow a tid rows mode # if tids: # cond += " and ("+(" or ".join([" tids=any('%s')"%tid for tid in tids.split(",")])+")") with P as p: C = p.cursor() qry = "select provider,sum(tracked),min(dt),max(dt) from tracking_by_day where %s group by provider order by sum(tracked) desc"%cond C.execute(qry) trackers = C.fetchall() C.execute("select unnest(tids) tid,sum(tracked),min(dt),max(dt) from tracking_by_day where %s group by unnest(tids) order by sum(tracked) desc"%cond) tids = C.fetchall() qry = "select tbd.*,tbd.dt::timestamp dtt,t.contents->>'status' status,t.contents->>'summary' summary from tracking_by_day tbd,tasks t where t.id=any(tbd.tids) and %s order by provider,dt asc,tbd.tracked asc"%cond print(qry) C.execute(qry) tasks = C.fetchall() tasks_t = [{ 'startDate':t['dtt'].isoformat(), 'startDate_raw':t['dtt'], 'endDate':(t['dtt']+t['tracked']).isoformat(), 'endDate_raw':(t['dtt']+t['tracked']), 'tracked_raw':t['tracked'], 'tracked':"%4.2f"%(float(t['tracked'].seconds)/60/60), 'taskName':t['provider'], #",".join(t['tids']), 'descr':",".join(t['tids']), 'summary':t['summary'], 'status':t['status']} for t in tasks] dates = set([t['startDate_raw'].date() for t in tasks_t]) providers = set([t['taskName'] for t in tasks_t]) tasks_rt=[] for p in providers: for d in dates: #print('going over provider, task',p,d) tasks_p = [x for x in tasks_t if x['taskName']==p and x['startDate_raw'].date()==d] inc=datetime.timedelta(0) for i in range(1,len(tasks_p)): pt = tasks_p[i-1] t = tasks_p[i] assert pt['taskName']==t['taskName'] and t['startDate_raw'].date()==pt['startDate_raw'].date(),"%s != %s"%(pt,t) inc+=pt['tracked_raw'] try: t['startDate_raw']+=inc t['endDate_raw']+=inc t['startDate']=t['startDate_raw'].isoformat() t['endDate']=t['endDate_raw'].isoformat() except KeyError: print((t,pt)) raise tasks_rt+=tasks_p #print('len of tasks_rt, increased by',len(tasks_rt),len(tasks_p)) for t in tasks_t: for fn in ['tracked','startDate','endDate']: del t['%s_raw'%fn] return basevars(request,P,C,{'providers':[t['provider'] for t in trackers], 'tids':[t['tid'] for t in tids], 'mode':mode, 'rangeback':rangeback, 'tasks':tasks_rt, 'json':json})
def prioritization(request,P,C): adm = get_admin(request,'unknown') if not hasperm_db(C,adm,'prioritization'): return Error403('no sufficient permissions for %s'%adm) fields = ['ages','statuses','assignees','handlers'] agesl = ['new','recent','old','ancient'] ages = dict([(agesl[i],chr(ord('a')+i)) for i in range(len(agesl))]) C.execute("select * from statuses") statuses = dict([(r['status'],r['cnt']) for r in C.fetchall()]) C.execute("select * from assignees") assignees = dict([(r['assignee'],r['cnt']) for r in C.fetchall()]) C.execute("select * from handlers") handlers = dict([(r['hndlr'],r['cnt']) for r in C.fetchall()]) rt={'fields':fields, 'values':{}} if not len(request.params): setall=True else: setall=False for fn in fields: if setall: vset = list(locals()[fn].keys()) if fn=='statuses': for ds in cfg.DONESTATES: if ds in vset: vset.remove(ds) elif fn=='ages': vset.remove('ancient') #vset.remove('old') else: vset = ['-'.join(k.split('-')[1:]) for k in request.params if k.startswith(fn+'-')] rt['values'][fn]={'avail':locals()[fn], 'set':vset} qry ="select * from tasks_pri_comb where 1=1" params=[] for fn in fields: vset1 = rt['values'][fn]['set'] vsetraw = [v=='None' and None or v for v in vset1] vset = tuple(vsetraw) if vset and fn=='statuses': qry+=" and st in %s" params.append(vset) elif vset and fn=='assignees': qry+=" and asgn in %s" params.append(vset) elif vset and fn=='handlers': qry+=" and hby in %s" params.append(vset) elif vset and fn=='ages': qry+=" and age in %s" params.append(vset) elif vset: raise Exception(fn,vset) qry+=" order by comb_pri desc,crat desc " #print('executing:',qry,params) C.execute(qry,params) orders={} cnt=0 assignees={} assignee_pri={} handlers={} statuses={} for tp in C.fetchall(): cnt+=1 a = tp['asgn'] if a not in orders: orders[a]=[] orders[a].append(tp) if a not in assignees: assignees[a]=0 assignee_pri[a]=0 assignees[a]+=1 assignee_pri[a]+=tp['comb_pri'] h = tp['hby'] if h not in handlers: handlers[h]=0 handlers[h]+=1 s = tp['st'] if s not in statuses: statuses[s]=0 statuses[s]+=1 rt['fresh'] = datetime.datetime.now().date()-datetime.timedelta(days=3) rt['tasks_cnt']=cnt rt['handlers']=handlers rt['statuses']=statuses rt['assignees']=assignees rt['orders'] = orders rt['recent'] = datetime.datetime.now()-datetime.timedelta(days=30) rt['humanize'] = humanize rt['doingstates'] = cfg.DOINGSTATES rt['donestates'] = cfg.DONESTATES rt['assignee_pri'] = assignee_pri return basevars(request,P,C,rt)