shabda
Comments
Reactions

Unfuddle Summary Script

By : Shabda Raaj

Unfuddle is our preferred tool for private repos, project management and ticketing. We recently wrote a slick script to summarize our Unfuddle status. So here is it.


import getpass
import simplejson
import sys
import urllib2

from datetime import datetime, date

try:
    from settings import *
except ImportError:
    ACCOUNT_DETAILS = {
        'account': '',
        'username': '', 
        'password': '',
    }
    SEND_MAIL = False

if not ACCOUNT_DETAILS['account']:
    ACCOUNT_DETAILS['account'] = raw_input('Enter unfuddle account name: ')

if not ACCOUNT_DETAILS['username']:
    ACCOUNT_DETAILS['username'] = raw_input('Username: ')

if not ACCOUNT_DETAILS['password']:
    ACCOUNT_DETAILS['password'] = getpass.getpass()

class Unfuddle(object):
    def __init__(self):
        self.base_url = 'https://%s.unfuddle.com' % (ACCOUNT_DETAILS['account'])
        self.api_base_path = '/api/v1/'

def get_data(self, api_end_point):
        # url = 'https://agiliq.unfuddle.com/api/v1/projects'
        url = self.base_url + self.api_base_path + api_end_point

auth_handler = urllib2.HTTPBasicAuthHandler() 
        auth_handler.add_password(realm='Unfuddle API', 
                                  uri=url, 
                                  user=ACCOUNT_DETAILS['username'], 
                                  passwd=ACCOUNT_DETAILS['password'])

opener = urllib2.build_opener(auth_handler) 
        opener.addheaders = [('Content-Type', 'application/xml'), ('Accept', 'application/json')]

# print '\n', url, '\n'
        try: 
            response = opener.open(url).read().strip() 
            # print 'response:', response 
            return simplejson.loads(response)
        except IOError, e: 
            print IOError, e

def get_projects(self):
        return self.get_data('projects')

def select_project(self):
        projects = self.get_projects()
        if len(projects) == 1:
            print 'There is only one project "%s"' % (projects[0]['title'])
            return projects[0]
        for index, project in enumerate(projects):
            print '%s. %s' % (index+1, project['title'])
        project_index = int(raw_input('Enter the project number: ')) - 1
        return projects[project_index]

def get_tickets(self, project=None):
        if not project:
            project = self.select_project()
        api_end_point = 'projects/%s/tickets' % (project['id'])
        tickets = self.get_data(api_end_point)
        return project, tickets

def dynamic_report(self, project=None, query_string=None):
        if project:
            api_end_point = 'projects/%s/ticket_reports/dynamic' % (project['id'])
        else:
            api_end_point = 'ticket_reports/dynamic'
        if query_string:
            api_end_point += '?%s' % (query_string)
        dynamic_report = self.get_data(api_end_point)
        return dynamic_report

def get_ticket_report():
    unfuddle = Unfuddle()
    project, tickets = unfuddle.get_tickets()
    print '\n'
    print 'Total tickets in project:', len(tickets)

today_new_tickets = []
    today_resolved_tickets = []
    today_closed_tickets = []
    total_closed_tickets = 0
    total_resolved_tickets = 0
    total_pending_tickets = 0

for ticket in tickets:
        if datetime.strptime(ticket['created_at'], '%Y-%m-%dT%H:%M:%SZ').date() == datetime.utcnow().date():
            today_new_tickets.append(ticket)
        elif datetime.strptime(ticket['updated_at'], '%Y-%m-%dT%H:%M:%SZ').date() == datetime.utcnow().date() and ticket['status'] == 'resolved':
            today_resolved_tickets.append(ticket)
        elif datetime.strptime(ticket['updated_at'], '%Y-%m-%dT%H:%M:%SZ').date() == datetime.utcnow().date() and ticket['status'] == 'closed':
            today_closed_tickets.append(ticket)

if ticket['status'] == 'closed':
            total_closed_tickets += 1
        elif ticket['status'] == 'resolved':
            total_resolved_tickets += 1
        else:
            total_pending_tickets += 1

print '\n'
    print 'Today new tickets:', len(today_new_tickets)
    print 'Today resolved tickets:', len(today_resolved_tickets)
    print 'Today closed tickets:', len(today_closed_tickets)
    print '\n'
    print 'Total closed tickets:', total_closed_tickets
    print 'Total resolved tickets:', total_resolved_tickets
    print 'Total pending tickets:', total_pending_tickets

query_string = 'group_by=assignee'
    query_string += '&conditions_string=status-neq-closed,status-neq-resolved'
    dynamic_report = unfuddle.dynamic_report(project, query_string=query_string)

print '\n'
    print 'Number of tickets in each person queue'
    for group in sorted(dynamic_report['groups'], cmp=lambda x, y: cmp(len(y['tickets']), len(x['tickets']))):
        if not group:
            continue
        print '\t', group['title'], ' ' * (25 - len(group.get('title', ''))), '-', len(group['tickets'])

"""
    query_string = 'group_by=assignee'
    query_string += '&conditions_string=status-eq-closed|status-eq-resolved' 
    # query_string += '&updated_at=%s' % (date.today().strftime('%Y-%m-%dT%H:%M:%SZ'))
    dynamic_report = unfuddle.dynamic_report(project, query_string=query_string)

dynamic_report['new_groups'] = []
    for group in dynamic_report['groups']:
        new_group = group.copy()
        new_group['tickets'] = filter(lambda x: datetime.strptime(x['updated_at'], '%Y-%m-%dT%H:%M:%SZ').date() == datetime.utcnow().date(), group['tickets'])
        if new_group['title'] == 'Javed K.':
            print new_group
        dynamic_report['new_groups'].append(new_group)

print '\n'
    print 'Number of tickets closed/resolved by each person today'
    for group in sorted(dynamic_report['new_groups'], cmp=lambda x, y: cmp(len(y['tickets']), len(x['tickets']))):
        if not group:
            continue
        print '\t', group['title'], ' ' * (25 - len(group.get('title', ''))), '-', len(group['tickets'])
    """

if __name__ == '__main__':
    get_ticket_report()

Here is an sample output from it.

Enter unfuddle account name: agiliq
Username: shabda
Password: 
1. account
2. AgiliqSolutions
3. [Redacted]
....
Enter the project number: 3

Total tickets in project: 159

Today new tickets: 0
Today resolved tickets: 1
Today closed tickets: 0

Total closed tickets: 140
Total resolved tickets: 3
Total pending tickets: 16

Number of tickets in each person queue
    [Redacted]                   - 6
    Ashok R.                   - 3
    [Redacted]                   - 3
    Shabda R.                  - 3
                         - 1



Can we help you build amazing apps? Contact us today.

Comments

rosetta stone

As the leading language-learning software in the world, Rosetta Stone makes learning a new language second nature. Millions of learners in more than 150 countries have already used our software to gain the confidence that comes with truly knowing a new language. We’re continually improving our software technology and adding new products. With Rosetta Stone at the helm, the future of language learning is very bright indeed.

commmenttor

Reactions

shabda

http://agiliq.com/blog/2010/11/unfuddle-summary-script/ Our script to sumarize our daily@Unfuddle activity. *VERY* useful, IMO.

commmenttor
Post a comment Name :

Email :

Your site url:

Comment :

© Agiliq, 2009-2012