def getEm(): options = { 'server': 'https://jira.server.com' } jira = JIRA( options=options, basic_auth=('user','pass') ) tickets = jira.search_issues( 'Participants = currentUser() AND updated > startOfDay() ORDER BY updated DESC' ) for ticket in tickets: comments = jira.comments( ticket.key ) for comment in comments: if comment.author.name == 'username': t = comment.created t = unicodedata.normalize( 'NFKD', t ).encode( 'UTF-8', 'ignore' ) t = t.split("T") t = t[0] now = time.strftime("%Y-%m-%d") if t == now: minute_len = len( comment.body.split() ) if minute_len <= 40: minutes = "3m" else: minutes = str( int( round( math.ceil( minute_len/40 )*3 ) ) ) + "m" jira.add_worklog( issue=str(ticket.key), timeSpent=minutes )
def log_to_jira( worklog ): config_path = os.path.expanduser( '~/.worklog/config.json' ) try: with open( config_path ) as json_data: auth_file = json.load( json_data ) try: options = { 'server': '{}'.format( auth_file['server'] ) } except KeyError: server = imput( '\nJira Server: ' ) options = { 'server': server } try: username = auth_file['username'] except KeyError: username = input( '\nJira Username: '******'password'] except KeyError: password = getpass() except OSError as e: if e.errno == errno.ENOENT: username = input( '\nJira Username: '******'{}-{}-{}T{}:{}:00.000-0400'.format( task.start.year, task.start.month, task.start.day, task.start.hour, task.start.minute ) ticket = jira.issue( task.ticket ) sys.stdout.write( '\nLogging {} to ticket {}\n'.format( time, ticket ) ) jira.add_worklog( issue = ticket, timeSpent = str( time ), started = datetime.strptime( started, '%Y-%m-%dT%H:%M:%S.000%z' ) )
def log_to_jira(worklog, config): with open(config.jira.oauth_pem_filename) as pem: pem_data = pem.read() oauth_dict = { 'access_token': config.jira.oauth_token, 'access_token_secret': config.jira.oauth_token_secret, 'consumer_key': config.jira.oauth_consumer_key, 'key_cert': pem_data } options = {'server': config.jira.server or input('\nJira Server: ')} username = config.jira.username or input('\nJira Username: '******'Logging work ...') if len(worklog) > 0: for task, next_task in worklog.pairwise(): if isinstance(task, GoHome): continue if task.ticket and not task.logged: duration = Duration(delta=next_task.start - task.start) if not duration.seconds: continue started = '{}-{}-{}T{}:{}:00.000-0400'.format( task.start.year, task.start.month, task.start.day, task.start.hour, task.start.minute) print('ticket', task.ticket) ticket = jira.issue(task.ticket) print('\nLogging {} to ticket {}'.format(duration, ticket)) jira.add_worklog(issue=ticket, timeSpent=str(duration), started=datetime.strptime( started, '%Y-%m-%dT%H:%M:%S.000%z')) task.logged = True print('Done.')
def jira_enter(user, password, start, end): shared, internal, project, project_jiras, total = query_db(user, start, end) time_entry = check_time(shared, internal, project) jira_password = password jira = JIRA(basic_auth=(user, jira_password), options={"server": "https://jira.crossview.inc", "verify": False}) end_s = end.split("-") # print end_s if_cal = calendar.monthrange(int(end_s[0]), int(end_s[1])) if_cal = int(if_cal[1]) if int(end_s[2]) == if_cal or int(end_s[2]) == (if_cal - 1): # If it is the either last day or one more day until last of the month, input previous Sunday. Just taking one day off start date. new_date = end new_date = datetime.strptime(new_date, "%Y-%m-%d").toordinal() sunday = new_date - (new_date % 7) new_date = datetime.fromordinal(sunday) print new_date new_date = new_date.isoformat() new_date = new_date + ".937-0500" print "Entering on date %s" % new_date else: # If it is NOT he last day of the month, input on Saturday. Taking 1 day from end date day = int(end_s[2]) - 1 new_date = "%s-%s-%s" % (end_s[0], end_s[1], day) new_date = datetime.strptime(new_date, "%Y-%m-%d").isoformat() new_date = new_date + ".937-0500" print "Entering on date %s" % new_date ignoretimes = ["TIME-3", "TIME-7", "TIME-9", "TIME-45", "TIME-590", "TIME-720", "TIME-820", "TIME-821"] for key, value in time_entry.iteritems(): if key == "TIME-654": list_jiras = [] for i in project_jiras[0]: list_jiras.append(i) project_jiras = ", ".join(list_jiras) print "adding worklog for %s timespent %sh and comment %s, on %s" % (key, value, project_jiras, new_date) jira.add_worklog(issue=key, timeSpent="%sh" % value, started=new_date, comment=project_jiras) elif key in ignoretimes: print "ignoring %s entry" % key else: print "adding worklog for %s timespent %sh on %s" % (key, value, new_date) jira.add_worklog(issue=key, timeSpent="%sh" % value, started=new_date)
def handle_noargs(self, **options): jira = JIRA(basic_auth=(settings.JIRA_USERNAME, settings.JIRA_PASSWORD), options={'server': settings.JIRA_BASE_URL}) print "Logged in..." categories = [p.key for p in jira.projects()] tag_logged, _ = Tag.objects.get_or_create(name='_logged_') facts = Fact.objects \ .exclude(tags=tag_logged) \ .exclude(end_time=None) \ .filter(activity__category__name__in=categories) for f in facts: reopened = False try: issue_key = '%s-%s' % (f.category, f.activity.name) issue = jira.issue(issue_key) if issue.fields.status.name in ('Closed', 'Resolve'): reopened = True # reopen to allow worklogs jira.transition_issue(issue, TO_REOPEN) jira.add_comment(issue, 'hamster2jira: Automatically reopened for a' 'while to allow add a worklog') except JIRAError: continue spent = days_hours_minutes(f.duration) #and post the fact into dotproject! worklog = jira.add_worklog(issue, spent) worklog.update(comment=f.description) #create a tag to associate this worklog whit the fact wl_tag = Tag.objects.create(name='wl%s' % worklog.id) FactTag.objects.create(tag=wl_tag, fact=f) print "Succesfully log %s into %s" % (spent, issue_key) #then mark the fact as logged. FactTag.objects.create(fact=f, tag=tag_logged) if reopened: jira.transition_issue(issue, TO_CLOSE)
class JiraClient(object): def __init__(self, server, username, password, default_project=None): self.username = username self.password = password self.default_project = default_project self.server = server self.jira = JIRA(options={'server': self.server}, basic_auth=(self.username, self.password)) def my(self, **kwargs): self._list_my_issues(**kwargs) def issue(self, **kwargs): issue_id = kwargs['issue_id'] issue = self.jira.issue(issue_id) print 'ID: %s' % issue.key print 'URL: %s/browse/%s' % (self.server, issue.key) print 'Assignee: %s' % issue.fields.assignee.name print 'Status: %s' % issue.fields.status.name print '' print 'Summary: %s' % issue.fields.summary print '' print 'Details: %s' % issue.fields.description def log(self, **kwargs): issue_id = kwargs['issue_id'] issue = self.jira.issue(issue_id) time_spent = kwargs['time'] msg = kwargs['message'] #FIXME: add comment as a part of worklog (investigate API) self.jira.add_comment(issue, msg) self.jira.add_worklog(issue, time_spent) print 'Your worklog was saved' def resolve(self, **kwargs): issue_id = kwargs['issue_id'] issue = self.jira.issue(issue_id) self.jira.transition_issue(issue, '5', resolution={'name': 'Implemented'}) print 'Issue %s was resolved as implemented' % issue_id def assign(self, **kwargs): issue_id = kwargs['issue_id'] issue = self.jira.issue(issue_id) self.jira.assign_issue(issue, self.username) print 'Issue %s was assigned to %s' % (issue_id, self.username) if kwargs['start']: self.jira.transition_issue(issue, '4') print 'Issue %s was started' % issue_id def todo(self, **kwargs): query_parts = ['status = Open', 'type != Story', 'created >= "-14d"'] if kwargs['project'] is not None: query_parts.append('project=%s' % kwargs['project']) elif self.default_project is not None: query_parts.append('project=%s' % self.default_project) query = ' and '.join(query_parts) self._perform_and_print_query(query) def _list_my_issues(self, **kwargs): query_parts = ['assignee=%s' % (self.username)] if kwargs['project'] is not None: query_parts.append('project=%s' % kwargs['project']) elif self.default_project is not None: query_parts.append('project=%s' % self.default_project) if kwargs['unresolved']: query_parts.append('resolution=unresolved') query = ' and '.join(query_parts) self._perform_and_print_query(query) def _perform_and_print_query(self, query): my_issues = self.jira.search_issues(query) for issue in my_issues: print '%s\t%s' % (issue.key, issue.fields.summary)
class JiraRestBridge(JiraBridge): def __init__(self, base_url, config, persist=False): super(JiraRestBridge, self).__init__(base_url, config, persist) self.jira = None @cached('resolutions') def get_resolutions(self): return dict((r.name.lower(), rest_recursive_dict(r.raw)) for r in self.jira.resolutions()) @cached('filters') def get_filters(self): filters = dict((f.name, rest_recursive_dict(f.raw)) for f in self.jira.favourite_filters()) return filters def clean_issue(self, issue): _issue = {} for k,v in list(issue.fields.__dict__.items()): if isinstance(v, Resource): _issue[k] = map_rest_resource(v) elif v is not None: _issue[k] = v _issue['key'] = issue.key _issue['type'] = map_rest_resource(_issue['issuetype']) return _issue def get_issue(self, issue_id, raw=False): try: if not raw: return self.clean_issue(self.jira.issue(issue_id)) else: return self.jira.issue(issue_id) except: return None def search_issues(self, free_text, project=None, limit=100): query = '(summary~"%s" or description~"%s")' % (free_text, free_text) if project: query += ' and project=%s' % project query += ' order by key' return [self.clean_issue(issue) for issue in self.jira.search_issues(query,maxResults=100)] def search_issues_jql(self, query, limit=100, project=None): return [self.clean_issue(issue) for issue in self.jira.search_issues(query, maxResults=100)] def get_issues_by_filter(self, *filters): return self.search_issues_jql( "filter in (%s)" % ",".join(['"%s"' % f for f in filters]) ) def add_comment(self, issue, comment): self.jira.add_comment(issue, comment) def transition_issue(self, issue, transition, resolution): transitions = self.get_available_transitions(issue) fields = {} if resolution: fields["resolution"] = self.get_resolutions()[resolution.lower()] try: return self.jira.transition_issue(issue, transitions[transition]['id'], fields=fields) except KeyError: raise JiraCliError("Invalid transition '%s'. Use one of [%s]" % (transition, ",".join(transitions))) def ping(self): return False def create_issue(self, project, type='bug', summary="", description="", priority="minor", parent=None, assignee="", reporter="", labels=[], components={}, **extras): issue = { "project": {'key':project.upper()}, "summary": summary, "description": description, "priority": {'id':self.get_priorities()[priority.lower()]["id"]}, "components": [{"name": k} for k in list(components.keys())] } if labels: issue['labels'] = labels if not issue["components"]: issue.pop("components") if type.lower() == 'epic': issue['customfield_11401'] = summary if parent: issue['issuetype'] = {'id':self.get_subtask_issue_types()[type.lower()]['id']} issue['parent'] = {'key':parent} else: issue['issuetype'] = {'id':self.get_issue_types()[type.lower()]['id']} if extras: issue.update(extras) issue = self.jira.create_issue(issue) if not (assignee or reporter): return self.clean_issue(issue) else: key = issue.key if assignee: issue = self.clean_issue(self.assign_issue(key, assignee)) if reporter: issue = self.clean_issue(self.change_reporter(key, reporter)) return issue def login(self, username, password): try: self.jira = JIRA(options={'server': self.base_url, 'check_update': False}, basic_auth=(username, password), get_server_info=False, validate=False ) except JIRAError: raise JiraAuthenticationError('failure to authenticate') except RequestException: raise JiraInitializationError('failure to communicate with jira') def get_available_transitions(self, issue): return dict((t['name'].lower(), t) for t in self.jira.transitions(issue)) @cached('issue_types') def get_issue_types(self): types = dict((k.name.lower(), k.raw) for k in self.jira.issue_types() if not k.subtask) for k in types: if k=='id': types['id'] = types['id'][0] return types @cached('subtask_types') def get_subtask_issue_types(self): types = dict((k.name.lower(), k.raw) for k in self.jira.issue_types() if k.subtask) for k in types: if k=='id': types['id'] = types['id'][0] return types def update_issue(self, issue_id, update={}, **kwargs): issue = self.jira.issue(issue_id) issue.update(update=update, **kwargs) return self.jira.issue(issue_id) def assign_issue(self, issue_id, assignee): return self.update_issue( issue_id, assignee={"name": assignee} ) def change_reporter(self, issue_id, reporter): return self.update_issue( issue_id, reporter={"name": reporter} ) def add_labels(self, issue_id, labels, merge=False): issue = self.jira.issue(issue_id) issue.fields.labels.extend(labels) return issue.update(fields={"labels": issue.fields.labels}) @cached('projects') def get_projects(self): return dict((k.name.lower(), k.raw) for k in self.jira.projects()) @cached('priorities') def get_priorities(self): return dict((k.name.lower(), dict(k.raw)) for k in self.jira.priorities()) @cached('components') def get_components(self, project): return [k.raw for k in self.jira.project_components(project)] def list_versions(self, project): versions = self.jira.project(project).versions versions.sort(cmp=lambda l, r: cmp(l.id, l.id)) return [k.raw for k in versions] @cached('statuses') def get_statuses(self): return dict((k.name.lower(), dict(k.raw)) for k in self.jira.statuses()) def get_issue_comments(self, issue): return [ dict(author=comment.author.name , body=comment.body , created=comment.created ) for comment in self.jira.comments(issue) ] def add_versions(self, issue, versions, type): args = {} if type == 'fix': args = {'fixVersions': [{"add": {"name": v}} for v in versions]} elif type == 'affects': args = {'versions': [{"add": {"name": v}} for v in versions]} return self.update_issue(issue, **args) def remove_versions(self, issue, versions, type): args = {} if type == 'fix': args = {'fixVersions': [{"remove": {"name": v}} for v in versions]} elif type == 'affects': args = {'versions': [{"remove": {"name": v}} for v in versions]} return self.update_issue(issue, **args) def log_work(self, issue, spent, remaining=None, comment=""): if remaining is None: adjust = "auto" else: adjust = "new" self.jira.add_worklog(issue=issue, timeSpent=spent, comment=comment, newEstimate=remaining, adjustEstimate=adjust)
class JiraIssueTrackingPlugin(BaseNotificationPlugin): def __init__(self, server, username, password, ticket_regexps): super(JiraIssueTrackingPlugin, self).__init__() self.jira = JIRA(server, basic_auth=(username, password)) self.ticket_regexps = ticket_regexps def execute_if_it_has_to(self, company): # jira doesn't need to check if it _has_to_ pending_updates = Task.select().join(Company).switch(Task).join( JiraTaskUpdated, JOIN_LEFT_OUTER).where((Company.id == company.id) & ( (~(fn.Exists(JiraTaskUpdated.select().where( JiraTaskUpdated.task == Task.id)))) | (JiraTaskUpdated.updated_at < Task.updated_at))) company_tz = pytz.timezone(company.timezone) for task in list(pending_updates): # get the ticket id current_best_position = len(task.description) current_match = None for regexp in self.ticket_regexps: match = re.search('\\b(' + regexp + ')\\b', task.description) if match is not None and match.start( 1) < current_best_position: current_best_position = match.start(1) current_match = match.group(1) if current_match is not None: issue = None try: issue = self.jira.issue(current_match) except: pass if issue is not None: # found a ticket! description = task.description if current_best_position == 0: description = re.sub( '^[^a-zA-Z0-9\\(]*', '', task.description[len(current_match):]) worklog_ready = False for worklog in self.jira.worklogs(issue.id): started = parse( worklog.started).astimezone(company_tz).date() if task.date == started and worklog.comment == description: if worklog.timeSpentSeconds != task.time_spent_seconds: worklog.update( timeSpentSeconds=task.time_spent_seconds) worklog_ready = True if not worklog_ready: # get the timezone suffix on the task's date (considering DST) task_date_with_time = datetime.datetime.combine( task.date, datetime.datetime.min.time()) suffix = company_tz.localize( task_date_with_time).strftime('%z') # make it 6pm wherever they are dt = parse( task.date.strftime('%Y-%m-%dT18:00:00') + suffix) self.jira.add_worklog( issue.id, timeSpentSeconds=task.time_spent_seconds, started=dt, comment=description) if task.jira_tasks_updated.count() == 0: task_updated = JiraTaskUpdated() else: task_updated = task.jira_tasks_updated[0] task_updated.task = task task_updated.updated_at = datetime.datetime.utcnow() task_updated.save()
print("\n") print("Comments ") print("=================================================") print(issue.fields.comment.comments) userResponse = str(input("Enter (Y/y) to continue: ")) if userResponse.lower() != "y": executionFlag = False elif command == "5": timeSpent = str( input( "Please enter the time you want to log (eg. 3w 4d 12h 30m): ")) jira.add_worklog(issue, timeSpent=timeSpent, timeSpentSeconds=None, adjustEstimate=None, newEstimate=None, reduceBy=None, comment=None, started=None, user=None) userResponse = str(input("Enter (Y/y) to continue: ")) if userResponse.lower() != "y": executionFlag = False elif command == "6": jira.assign_issue(issue.id, username) userResponse = str(input("Enter (Y/y) to continue: ")) if userResponse.lower() != "y": executionFlag = False elif command == "7": # print(issue.fields.project.key)
class ExportRtController(gtk.Object): __gsignals__ = { "on-close": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), } def __init__(self, parent = None, facts = None): gtk.Object.__init__(self) self.source = conf.get("activities_source") self.rt = None self.redmine = None self.jira = None if self.source == SOURCE_RT: # Init RT self.rt_url = conf.get("rt_url") self.rt_user = conf.get("rt_user") self.rt_pass = conf.get("rt_pass") self.rt = rt.Rt(self.rt_url, self.rt_user, self.rt_pass) if not self.rt.login(): self.rt = None elif self.source == SOURCE_REDMINE: self.rt_url = conf.get("rt_url") self.rt_user = conf.get("rt_user") self.rt_pass = conf.get("rt_pass") if self.rt_url and self.rt_user and self.rt_pass: try: self.redmine = redmine.Redmine(self.rt_url, auth=(self.rt_user,self.rt_pass)) if not self.redmine: self.source = SOURCE_NONE except: self.source = SOURCE_NONE else: self.source = SOURCE_NONE elif jira_active and self.source == SOURCE_JIRA: self.jira_url = conf.get("jira_url") self.jira_user = conf.get("jira_user") self.jira_pass = conf.get("jira_pass") self.jira_query = conf.get("jira_query") self.jira_category = conf.get("jira_category_field") self.jira_fields=','.join(['summary', self.jira_category]) if self.jira_url and self.jira_user and self.jira_pass: try: options = {'server': self.jira_url} self.jira = JIRA(options, basic_auth = (self.jira_user, self.jira_pass), validate = True) except Exception as e: logging.warn('jira connection failed: '+str(e)) self.source = SOURCE_NONE else: self.source = SOURCE_NONE self._gui = load_ui_file("export_rt.ui") self.window = self.get_widget('report_rt_window') self.parent, self.facts = parent, facts self.done_button = self.get_widget("done_button") # self.done_button.set_sensitive(False) # Model self.tree_store = gtk.TreeStore(gobject.TYPE_PYOBJECT) self.rows = list([ExportRow(fact) for fact in facts]) self.rows.sort(key = lambda row: row.id) grouped_rows = {} for issue_id, rows in groupby(self.rows, lambda export_row: export_row.id): grouped_rows[issue_id] = list(rows) for issue_id in grouped_rows.keys(): #ściągnąć nazwę ticketa if self.source == SOURCE_RT: row_data = self.rt.get_ticket(issue_id) # row_data['source'] = SOURCE_RT elif self.source == SOURCE_REDMINE: issue = self.redmine.getIssue(issue_id) row_data = {} row_data['id'] = issue.id row_data['Subject'] = str(issue_id)+': '+issue.fields.summary # row_data['source'] = SOURCE_REDMINE elif self.source == SOURCE_JIRA: issue = self.jira.issue(issue_id) row_data = {} row_data['id'] = issue.id row_data['Subject'] = issue.fields.summary # row_data['source'] = SOURCE_JIRA if row_data: parent = self.tree_store.append( None, (TicketRow(row_data), ) ) for row in grouped_rows[issue_id]: self.tree_store.append(parent, (row, )) # self.tree_store.append(parent, (row.comment)) self.view = gtk.TreeView(self.tree_store); self.view.set_headers_visible(False) id_cell = gtk.CellRendererText() id_column = gtk.TreeViewColumn("", id_cell, text=0) id_column.set_cell_data_func(id_cell, id_painter) id_column.set_max_width(100) self.view.append_column(id_column) name_comment_cell = gtk.CellRendererText() name_comment_cell.connect("edited", self.on_comment_edited) name_comment_column = gtk.TreeViewColumn("", name_comment_cell, text=0) name_comment_column.set_cell_data_func(name_comment_cell, name_comment_painter) name_comment_column.set_expand(True) self.view.append_column(name_comment_column) time_cell = gtk.CellRendererSpin() time_cell.connect("edited", self.on_time_worked_edited) time_column = gtk.TreeViewColumn("", time_cell, text=0) time_column.set_cell_data_func(time_cell, time_painter) time_column.set_min_width(60) self.view.append_column(time_column) self.view.expand_all() self.start_button = self.get_widget("start_button") self.get_widget("activities").add(self.view) self.aggregate_comments_checkbox = self.get_widget("aggregate_comments_checkbox") self.aggregate_comments_checkbox.set_active(True) self.test_checkox = self.get_widget("test_checkbox") self.test_checkox.set_active(False) self.progressbar = self.get_widget("progressbar") self.progressbar.set_text(_("Waiting for action")) self.progressbar.set_orientation(gtk.PROGRESS_LEFT_TO_RIGHT) self._gui.connect_signals(self) self.window.show_all() def on_time_worked_edited(self, widget, path, value): row = self.tree_store[path][0] row.time_worked = int(value) def on_comment_edited(self, widget, path, value): row = self.tree_store[path][0] row.comment = value def get_widget(self, name): """ skip one variable (huh) """ return self._gui.get_object(name) def show(self): self.window.show() def on_start_activate(self, button): if self.rt or self.redmine or self.jira: group_comments = self.aggregate_comments_checkbox.get_active() it = self.tree_store.get_iter_first() to_report_list = [] while it: ticket_row = self.tree_store.get_value(it, 0) child_iter = self.tree_store.iter_children(it) #get childs export_rows = [] while child_iter: export_rows.append(self.tree_store.get_value(child_iter, 0)) child_iter = self.tree_store.iter_next(child_iter) #report tickets if group_comments: comment = "\n".join("%s - %s min"% (row.comment, row.time_worked) for row in export_rows) time_worked = sum([row.time_worked for row in export_rows]) facts = [row.fact for row in export_rows] to_report_list.append({'id':ticket_row.id, 'name':ticket_row.name, 'comment':comment, 'time':time_worked, 'facts':facts, 'date': row.date}) else: for row in export_rows: to_report_list.append({'id':ticket_row.id, 'name':ticket_row.name, 'comment':"%s - %s min"% (row.comment, row.time_worked), 'time':row.time_worked, 'facts':[row.fact], 'date': row.date}) # self.__add_rt_worklog(ticket_row.id, "%s - %s min"% (row.comment, row.time_worked), row.time_worked, [row.fact]) it = self.tree_store.iter_next(it) to_report_len = len(to_report_list) self.progressbar.set_fraction(0.0) for i in range(to_report_len): to_report = to_report_list[i] self.progressbar.set_text(_("Reporting: #%s: %s - %smin") % (to_report['id'], to_report['name'], to_report['time'])) self.progressbar.set_fraction(float(i)/to_report_len) while gtk.events_pending(): gtk.main_iteration() if self.source == SOURCE_RT: self.__add_rt_worklog(to_report['id'], to_report['comment'], to_report['time'], to_report['facts']) elif self.source == SOURCE_REDMINE: self.__add_redmine_worklog(to_report['id'], to_report['date'], math.ceil(to_report['time']*100/60)/100, to_report['comment'], to_report['facts']) elif self.source == SOURCE_JIRA: self.__add_jira_worklog(to_report['id'], to_report['comment'], to_report['time'], to_report['facts']) self.progressbar.set_text("Done") self.progressbar.set_fraction(1.0) # for fact in self.facts: # match = re.match(TICKET_NAME_REGEX, fact.activity) # if fact.end_time and match: # ticket_id = match.group(1) # text = self.get_text(fact) # time_worked = stuff.duration_minutes(fact.delta) # logging.warn(ticket_id) # logging.warn(text) # logging.warn("minutes: %s" % time_worked) ## external.rt.comment(ticket_id, text, time_worked) # else: # logging.warn("Not a RT ticket or in progress: %s" % fact.activity) else: logging.warn(_("Not connected to/logged in RT")) self.start_button.set_sensitive(False) #TODO only if parent is overview self.parent.search() def __add_rt_worklog(self, ticket_id, text, time_worked, facts): test = self.test_checkox.get_active() # logging.warn(_("updating ticket #%s: %s min, comment: \n%s") % (ticket_id, time_worked, text)) if not test: time = time_worked else: time = 0 if self.rt.comment(ticket_id, text, time) and not test: for fact in facts: runtime.storage.update_fact(fact.id, fact, False,True) # fact_row.selected = False def __add_jira_worklog(self, issue_id, text, time_worked, facts): test = self.test_checkox.get_active() # logging.warn(_("updating ticket #%s: %s min, comment: \n%s") % (ticket_id, time_worked, text)) if not test: time = time_worked else: time = 0 if self.jira.add_worklog(issue = issue_id, comment = text, timeSpent = time) and not test: for fact in facts: runtime.storage.update_fact(fact.id, fact, False,True) def __add_redmine_worklog(self, issue_id, spent_on, hours, comments, facts): test = self.test_checkox.get_active() logging.warn(_("updating issue #%s: %s hrs, comment: \n%s") % (issue_id, hours, comments)) time_entry_data = {'time_entry': {}} time_entry_data['time_entry']['issue_id'] = issue_id time_entry_data['time_entry']['spent_on'] = spent_on time_entry_data['time_entry']['hours'] = hours time_entry_data['time_entry']['comments'] = comments time_entry_data['time_entry']['activity_id'] = 9 r = self.redmine.createTimeEntry(time_entry_data) logging.warn(r.status_code) logging.warn(r.content) if r.status_code == 201 and not test: for fact in facts: runtime.storage.update_fact(fact.id, fact, False,True) # fact_row.selected = False def get_text(self, fact): text = "%s, %s-%s" % (fact.date, fact.start_time.strftime("%H:%M"), fact.end_time.strftime("%H:%M")) if fact.description: text += ": %s" % (fact.description) if fact.tags: text += " ("+", ".join(fact.tags)+")" return text def on_window_key_pressed(self, tree, event_key): popups = self.start_date.popup.get_property("visible") or \ self.start_time.popup.get_property("visible") or \ self.end_time.popup.get_property("visible") or \ self.new_name.popup.get_property("visible") or \ self.new_tags.popup.get_property("visible") if (event_key.keyval == gtk.keysyms.Escape or \ (event_key.keyval == gtk.keysyms.w and event_key.state & gtk.gdk.CONTROL_MASK)): if popups: return False self.close_window() elif event_key.keyval in (gtk.keysyms.Return, gtk.keysyms.KP_Enter): if popups: return False self.on_save_button_clicked(None) def on_done_activate(self, button): self.on_close(button, None) def on_close(self, widget, event): if self.source == SOURCE_RT: self.rt.logout(); self.close_window() def close_window(self): if not self.parent: gtk.main_quit() else: self.window.destroy() self.window = None self._gui = None self.emit("on-close") def show_facts(self): self.view.detach_model() for fact in self.facts: self.view.add_fact(fact) self.view.attach_model()