예제 #1
0
    def get_work_log(self, mode='all'):
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        if mode == 'user':
            cursor.execute('SELECT wl.user, s.value, wl.starttime, wl.endtime, wl.ticket, t.summary, t.status, wl.comment '
                           'FROM work_log wl '
                           'INNER JOIN ticket t ON wl.ticket=t.id '
                           'LEFT JOIN session_attribute s ON wl.user=s.sid AND s.name=\'name\' '
                           'WHERE wl.user=%s '
                           'ORDER BY wl.lastchange DESC', (self.authname,))
        elif mode == 'summary':
            cursor.execute('SELECT wl.user, s.value, wl.starttime, wl.endtime, wl.ticket, t.summary, t.status, wl.comment '
                           'FROM (SELECT user,MAX(lastchange) lastchange FROM work_log GROUP BY user) wlt '
                           'INNER JOIN work_log wl ON wlt.user=wl.user AND wlt.lastchange=wl.lastchange '
                           'INNER JOIN ticket t ON wl.ticket=t.id '
                           'LEFT JOIN session_attribute s ON wl.user=s.sid AND s.name=\'name\' '
                           'ORDER BY wl.lastchange DESC, wl.user')
        else:
            cursor.execute('SELECT wl.user, s.value, wl.starttime, wl.endtime, wl.ticket, t.summary, t.status, wl.comment '
                           'FROM work_log wl '
                           'INNER JOIN ticket t ON wl.ticket=t.id '
                           'LEFT JOIN session_attribute s ON wl.user=s.sid AND s.name=\'name\' '
                           'ORDER BY wl.lastchange DESC, wl.user')
        
        rv = []
        for user,name,starttime,endtime,ticket,summary,status,comment  in cursor:
            starttime = float(starttime)
            endtime = float(endtime)
            
            started = datetime.fromtimestamp(starttime)
            
            dispname = user
            if name:
                dispname = '%s (%s)' % (name, user)
            
            if not endtime == 0:
                finished = datetime.fromtimestamp(endtime)
                delta = 'Worked for %s (between %s %s and %s %s)' % \
                        (pretty_timedelta(started, finished),
                         format_date(starttime), format_time(starttime),
                         format_date(endtime), format_time(endtime))
            else:
                delta = 'Started %s ago (%s %s)' % \
                        (pretty_timedelta(started),
                         format_date(starttime), format_time(starttime))

            rv.append({'user': user,
                       'name': name,
                       'dispname': dispname,
                       'starttime': int(starttime),
                       'endtime': int(endtime),
                       'delta': delta,
                       'ticket': ticket,
                       'summary': summary,
                       'status': status,
                       'comment': comment})
        return rv
        
예제 #2
0
    def get_timeline_events(self, req, start, stop, filters):
        # Worklog changes
        show_starts = 'workstart' in filters
        show_stops = 'workstop' in filters
        if show_starts or show_stops:
            add_stylesheet(req, "worklog/worklogplugin.css")
            
            ts_start = to_timestamp(start)
            ts_stop = to_timestamp(stop)

            ticket_realm = Resource('ticket')
            db = self.env.get_db_cnx()
            cursor = db.cursor()

            cursor.execute("""SELECT wl.worker,wl.ticket,wl.time,wl.starttime,wl.comment,wl.kind,t.summary,t.status,t.resolution,t.type
                             FROM (
                             
                             SELECT worker, ticket, starttime AS time, starttime, comment, 'start' AS kind
                             FROM work_log

                             UNION

                             SELECT worker, ticket, endtime AS time, starttime, comment, 'stop' AS kind
                             FROM work_log

                             ) AS wl
                             INNER JOIN ticket t ON t.id = wl.ticket 
                                 AND wl.time>=%s AND wl.time<=%s 
                           ORDER BY wl.time"""
                           % (ts_start, ts_stop))
            previous_update = None
            for worker,tid,ts,ts_start,comment,kind,summary,status,resolution,type in cursor:
                ticket = ticket_realm(id=tid)
                time = datetime.fromtimestamp(ts, utc)
                started = None
                if kind == 'start':
                    if not show_starts:
                        continue
                    yield ('workstart', time, worker, (ticket,summary,status,resolution,type, started, ""))
                else:
                    if not show_stops:
                        continue
                    started = datetime.fromtimestamp(ts_start, utc)
                    if comment:
                        comment = "(Time spent: %s)[[BR]]%s" % (pretty_timedelta(started, time), comment)
                    else:
                        comment = '(Time spent: %s)' % pretty_timedelta(started, time)
                    yield ('workstop', time, worker, (ticket,summary,status,resolution,type, started, comment))
예제 #3
0
   def get_ticket_js(self, who, since):
       timedelta = pretty_timedelta(datetime.fromtimestamp(since), None);
       script = """
 li_tctk = document.createElement('li');
 ul.appendChild(li_tctk);
 li_tctk.appendChild(document.createTextNode('""" + who + """ has been working on this ticket for """ + timedelta + """'));"""
       return script;
예제 #4
0
   def get_ticket_js(self, who, since):
       timedelta = pretty_timedelta(datetime.fromtimestamp(since), None)
       script = """
 li_tctk = document.createElement('li');
 ul.appendChild(li_tctk);
 li_tctk.appendChild(document.createTextNode('""" + who + """ has been working on this ticket for """ + timedelta + """'));"""
       return script
예제 #5
0
 def get_task_markup(self, req, ticket, task):
     if not task:
         return ''
     
     ticket_text = 'ticket #' + str(task['ticket'])
     if task['ticket'] == ticket:
         ticket_text = 'this ticket'
     timedelta = pretty_timedelta(datetime.fromtimestamp(task['starttime']), None);
     
     return '<li>%s</li>' % wiki_to_oneliner('You have been working on %s for %s' % (ticket_text, timedelta), self.env, req=req)
예제 #6
0
    def get_task_markup(self, req, ticket, task):
        if not task:
            return ''

        ticket_text = 'ticket #' + str(task['ticket'])
        if task['ticket'] == ticket:
            ticket_text = 'this ticket'
        timedelta = pretty_timedelta(datetime.fromtimestamp(task['starttime']),
                                     None)

        return '<li>%s</li>' % wiki_to_oneliner(
            'You have been working on %s for %s' % (ticket_text, timedelta),
            self.env,
            req=req)
예제 #7
0
    def get_task_js(self, req, ticket, task):
        script = """
  li_task = document.createElement('li');
  ul.appendChild(li_task);
  li_task.appendChild(document.createTextNode('You have been working on '));"""
        if task:
            if ticket == task['ticket']:
                script += """
  li_task.appendChild(document.createTextNode('this ticket'));"""
            else:
                script += """
  li_task.appendChild(document.createTextNode('ticket '));
  var a = document.createElement('a');
  a.setAttribute('href', '""" + req.href.ticket(task['ticket']) + """');
  a.setAttribute('title', '""" + task['summary'].replace("'", "\\'") + """');
  a.appendChild(document.createTextNode('#""" + str(task['ticket']) + """'));
  li_task.appendChild(a);"""

            timedelta = pretty_timedelta(datetime.fromtimestamp(task['starttime']), None);
            script += """
  li_task.appendChild(document.createTextNode(' for """ + timedelta + """'));"""
        return script;
예제 #8
0
    def get_task_js(self, req, ticket, task):
        script = """
  li_task = document.createElement('li');
  ul.appendChild(li_task);
  li_task.appendChild(document.createTextNode('You have been working on '));"""
        if task:
            if ticket == task['ticket']:
                script += """
  li_task.appendChild(document.createTextNode('this ticket'));"""
            else:
                script += """
  li_task.appendChild(document.createTextNode('ticket '));
  var a = document.createElement('a');
  a.setAttribute('href', '""" + req.href.ticket(task['ticket']) + """');
  a.setAttribute('title', '""" + task['summary'].replace("'", "\\'") + """');
  a.appendChild(document.createTextNode('#""" + str(task['ticket']) + """'));
  li_task.appendChild(a);"""

            timedelta = pretty_timedelta(
                datetime.fromtimestamp(task['starttime']), None)
            script += """
  li_task.appendChild(document.createTextNode(' for """ + timedelta + """'));"""
        return script
예제 #9
0
    def stop_work(self, stoptime=None, comment=''):
        active = self.get_active_task()
        if not active:
            self.explanation = 'You cannot stop working as you appear to be a complete slacker already!'
            return False

        if stoptime:
            if stoptime <= active['starttime']:
                self.explanation = 'You cannot set your stop time to that value as it is before the start time!'
                return False
            elif stoptime >= self.now:
                self.explanation = 'You cannot set your stop time to that value as it is in the future!'
                return False
        else:
            stoptime = self.now - 1

        stoptime = float(stoptime)
        
        db = self.env.get_db_cnx();
        cursor = db.cursor()
        cursor.execute('UPDATE work_log '
                       'SET endtime=%s, lastchange=%s, comment=%s '
                       'WHERE user=%s AND lastchange=%s AND endtime=0',
                       (stoptime, stoptime, comment, self.authname, active['lastchange']))
        db.commit()

        message = ''
        # Leave a comment if the user has configured this or if they have entered
        # a work log comment.
        if self.config.getbool('worklog', 'comment') or comment:
            started = datetime.fromtimestamp(active['starttime'])
            finished = datetime.fromtimestamp(stoptime)
            message = '%s worked on this ticket for %s between %s %s and %s %s.' % \
                      (self.authname, pretty_timedelta(started, finished), \
                       format_date(active['starttime']), format_time(active['starttime']), \
                       format_date(stoptime), format_time(stoptime))
            if comment:
                message += "\n[[BR]]\n" + comment
            
        if self.config.getbool('worklog', 'timingandestimation') and \
               self.config.get('ticket-custom', 'hours'):
            if not message:
                message = 'Hours recorded automatically by the worklog plugin.'

            round_delta = float(self.config.getint('worklog', 'roundup') or 1)
            
            # Get the delta in minutes
            delta = float(int(stoptime) - int(active['starttime'])) / float(60)
            
            # Round up if needed
            delta = int(round((delta / round_delta) + float(0.5))) * int(round_delta)
            
            db = self.env.get_db_cnx()
            tckt = Ticket(self.env, active['ticket'], db)
            
            # This hideous hack is here because I don't yet know how to do variable-DP rounding in python - sorry!
            # It's meant to round to 2 DP, so please replace it if you know how.  Many thanks, MK.
            tckt['hours'] = str(float(int(100 * float(delta) / 60) / 100.0))
            self.save_ticket(tckt, db, message)
            message = ''

        if message:
            db = self.env.get_db_cnx()
            tckt = Ticket(self.env, active['ticket'], db)
            self.save_ticket(tckt, db, message)
        
        return True
예제 #10
0
 def get_ticket_markup(self, who, since):
     timedelta = pretty_timedelta(datetime.fromtimestamp(since), None)
     return '<li>%s has been working on this ticket for %s</li>' % (
         who, timedelta)
예제 #11
0
 def get_ticket_markup(self, who, since):
     timedelta = pretty_timedelta(datetime.fromtimestamp(since), None);
     return '<li>%s has been working on this ticket for %s</li>' % (who, timedelta)
예제 #12
0
    def get_work_log(self, mode='all'):
        db = self.env.get_db_cnx()
        cursor = db.cursor()
        if mode == 'user':
            cursor.execute(
                'SELECT wl.worker, s.value, wl.starttime, wl.endtime, wl.ticket, t.summary, t.status, wl.comment '
                'FROM work_log wl '
                'INNER JOIN ticket t ON wl.ticket=t.id '
                'LEFT JOIN session_attribute s ON wl.worker=s.sid AND s.name=\'name\' '
                'WHERE wl.worker=%s '
                'ORDER BY wl.lastchange DESC', (self.authname, ))
        elif mode == 'summary':
            cursor.execute(
                'SELECT wl.worker, s.value, wl.starttime, wl.endtime, wl.ticket, t.summary, t.status, wl.comment '
                'FROM (SELECT worker,MAX(lastchange) AS lastchange FROM work_log GROUP BY worker) wlt '
                'INNER JOIN work_log wl ON wlt.worker=wl.worker AND wlt.lastchange=wl.lastchange '
                'INNER JOIN ticket t ON wl.ticket=t.id '
                'LEFT JOIN session_attribute s ON wl.worker=s.sid AND s.name=\'name\' '
                'ORDER BY wl.lastchange DESC, wl.worker')
        else:
            cursor.execute(
                'SELECT wl.worker, s.value, wl.starttime, wl.endtime, wl.ticket, t.summary, t.status, wl.comment '
                'FROM work_log wl '
                'INNER JOIN ticket t ON wl.ticket=t.id '
                'LEFT JOIN session_attribute s ON wl.worker=s.sid AND s.name=\'name\' '
                'ORDER BY wl.lastchange DESC, wl.worker')

        rv = []
        for user, name, starttime, endtime, ticket, summary, status, comment in cursor:
            starttime = float(starttime)
            endtime = float(endtime)

            started = datetime.fromtimestamp(starttime)

            dispname = user
            if name:
                dispname = '%s (%s)' % (name, user)

            if not endtime == 0:
                finished = datetime.fromtimestamp(endtime)
                delta = 'Worked for %s (between %s %s and %s %s)' % \
                        (pretty_timedelta(started, finished),
                         format_date(starttime), format_time(starttime),
                         format_date(endtime), format_time(endtime))
            else:
                delta = 'Started %s ago (%s %s)' % \
                        (pretty_timedelta(started),
                         format_date(starttime), format_time(starttime))

            rv.append({
                'user': user,
                'name': name,
                'dispname': dispname,
                'starttime': int(starttime),
                'endtime': int(endtime),
                'delta': delta,
                'ticket': ticket,
                'summary': summary,
                'status': status,
                'comment': comment
            })
        return rv
예제 #13
0
    def stop_work(self, stoptime=None, comment=''):
        active = self.get_active_task()
        if not active:
            self.explanation = 'You cannot stop working as you appear to be a complete slacker already!'
            return False

        if stoptime:
            if stoptime <= active['starttime']:
                self.explanation = 'You cannot set your stop time to that value as it is before the start time!'
                return False
            elif stoptime >= self.now:
                self.explanation = 'You cannot set your stop time to that value as it is in the future!'
                return False
        else:
            stoptime = self.now - 1

        stoptime = float(stoptime)

        db = self.env.get_db_cnx()
        cursor = db.cursor()
        cursor.execute(
            'UPDATE work_log '
            'SET endtime=%s, lastchange=%s, comment=%s '
            'WHERE worker=%s AND lastchange=%s AND endtime=0',
            (stoptime, stoptime, comment, self.authname, active['lastchange']))
        db.commit()

        plugtne = self.config.getbool(
            'worklog', 'timingandestimation') and self.config.get(
                'ticket-custom', 'hours')
        plughrs = self.config.getbool('worklog',
                                      'trachoursplugin') and self.config.get(
                                          'ticket-custom', 'totalhours')

        message = ''
        hours = '0.0'

        # Leave a comment if the user has configured this or if they have entered
        # a work log comment.
        if plugtne or plughrs:
            round_delta = float(self.config.getint('worklog', 'roundup') or 1)

            # Get the delta in minutes
            delta = float(int(stoptime) - int(active['starttime'])) / float(60)

            # Round up if needed
            delta = int(
                round((delta / round_delta) + float(0.5))) * int(round_delta)

            # This hideous hack is here because I don't yet know how to do variable-DP rounding in python - sorry!
            # It's meant to round to 2 DP, so please replace it if you know how.  Many thanks, MK.
            hours = str(float(int(100 * float(delta) / 60) / 100.0))

        if plughrs:
            message = 'Hours recorded automatically by the worklog plugin. %s hours' % hours
        elif self.config.getbool('worklog', 'comment') or comment:
            started = datetime.fromtimestamp(active['starttime'])
            finished = datetime.fromtimestamp(stoptime)
            message = '%s worked on this ticket for %s between %s %s and %s %s.' % \
                      (self.authname, pretty_timedelta(started, finished), \
                       format_date(active['starttime']), format_time(active['starttime']), \
                       format_date(stoptime), format_time(stoptime))
        if comment:
            message += "\n[[BR]]\n" + comment

        if plugtne or plughrs:
            if not message:
                message = 'Hours recorded automatically by the worklog plugin.'

            tckt = Ticket(self.env, active['ticket'])

            if plugtne:
                tckt['hours'] = hours
            self.save_ticket(tckt, message)
            message = ''

        if message:
            tckt = Ticket(self.env, active['ticket'])
            self.save_ticket(tckt, message)

        return True