# Type: Input # Category: Task # Description: Shows issue details # Author: Andriy Lesyuk sub ShowIssue_Format($) { my $description = shift; my $number = 1; ${$description} =~ s/^ *h[1-3]\. +//mg; # h1. heading ${$description} =~ s/\[(\[[^\]]+?\])\]/$1/g; # [[wikilink]] ${$description} =~ s/!([^\s]+?)!/$1/g; # !image! ${$description} =~ s/^ *# +/sprintf("%d. ", $number++);/emg; # # item ${$description} =~ s/^ *\* +/o /mg; # * item ${$description} =~ s!
(.*?)
!$1!sg; #
text
${$description} =~ s!(.*?)!$1!sg; # text ${$description} =~ s/(?(?!\s)/> /mg; # adds space after > ${$description} =~ s/(\r?\n){3,}/$1$1/g; # 3 or more \n's ${$description} =~ s/(\r?\n)+$//g; # ending \n's } new Orangutan::Context( response => sub { my ($context, $user, $message) = @_; my @result = ( ); # Prepare tracker regexp my $regexp = 'issue'; my $trackers = $main::config->Get('redmine', '_trackers_regexp'); if ($trackers) { $regexp = "(?:issue|$trackers)"; } my @regexps = ( '(?:(?:Show|give) (?:me )?)?(?:details of )?(?:(?:the )?'.$regexp.' )?(?:#|No\.? ?)?([0-9]+)\?*!*\.*', 'What(?:\'| i)s (?:'.$regexp.' )?(?:#|No\.? ?)?([0-9]+)\?*!*\.*' ); # Extract issue ID foreach my $regexp (@regexps) { if ($message =~ /^$regexp$/i) { push(@result, 1); push(@result, $1); last; } } return @result; }, handler => sub { my ($context, $user, $item, $issueid) = @_; my $issue = $main::query->GetIssueEx($issueid); if ($issue) { if (!$user->IsCreator && !$user->IsManager && !$main::query->Can('view_issues', $user, $issue->{'project_id'})) { $user->SendMessage([ 'You have no permissions to see issues of the project...', 'I cannot show any information about this issue...', 'You may not see details of this issue...' ]); return; } utf8::decode($issue->{'project_name'}); utf8::decode($issue->{'subject'}); utf8::decode($issue->{'description'}); utf8::decode($issue->{'category_name'}); my $message = $issue->{'tracker_name'}; $message .= sprintf(" #%d: ", $issue->{'id'}); $message .= $issue->{'subject'}; if ($issue->{'done_ratio'} > 0) { $message .= sprintf(" [%d%%]", $issue->{'done_ratio'}); } if ($issue->{'is_closed'}) { $message .= ' (closed)'; } $message .= "\n"; $message .= 'Project: '.$issue->{'project_name'}."\n"; $message .= 'Status: '.$issue->{'status_name'}; if ($issue->{'is_closed'} && (lc($issue->{'status_name'}) ne 'closed')) { $message .= ' (closed)'; } $message .= "\n"; $message .= 'Priority: '.$issue->{'priority_name'}."\n"; if ($issue->{'category_name'}) { $message .= 'Category: '.$issue->{'category_name'}."\n"; } if ($issue->{'assigned_to_name'}) { $message .= 'Assigned to: '.Orangutan::User::GetDisplayName($issue->{'assigned_to_name'})."\n"; } if ($main::query->TableExists('votes') && $issue->{'votes'}) { my $votes = $main::query->GetVotes($issue->{'id'}, $user->GetUserID); if ($votes) { $message .= 'Votes: '; $message .= sprintf("%d", $votes->{'vote'}); if (($votes->{'yes'} != $issue->{'votes'}) && ($votes->{'no'} != $issue->{'votes'})) { $message .= sprintf(" - %d (%d%%) agreed and %d (%d%%) disagreed", $votes->{'yes'}, ($votes->{'yes'} * 100) / $issue->{'votes'}, $votes->{'no'}, ($votes->{'no'} * 100) / $issue->{'votes'}); } if ($votes->{'you'}) { $message .= ' ('; if ($votes->{'you'} == 1) { $message .= Orangutan::Context::Random( 'you voted for', 'you like it' ); } else { $message .= Orangutan::Context::Random( 'you voted against', "you don't like it" ); } $message .= ')'; } $message .= "\n"; } } if ($issue->{'start_date'}) { my ($day, $mon, $year, $wday) = (localtime($issue->{'start_date'}))[3..6]; $message .= 'Start date: '; $message .= sprintf("%s, %d %s %04d\n", $Orangutan::Date::weekdays[$wday], $day, $Orangutan::Date::months[$mon], $year + 1900); } if ($issue->{'due_date'}) { my ($day, $mon, $year, $wday) = (localtime($issue->{'due_date'}))[3..6]; $message .= 'Due date: '; $message .= sprintf("%s, %d %s %04d\n", $Orangutan::Date::weekdays[$wday], $day, $Orangutan::Date::months[$mon], $year + 1900); } if ($issue->{'estimated_hours'}) { $message .= 'Estimated hours: '; $message .= sprintf('%d:%02d', int($issue->{'estimated_hours'} / 3600), int(($issue->{'estimated_hours'} % 3600) / 60)); $message .= "\n"; } if ($issue->{'spent_time'}) { $message .= 'Spent time: '; $message .= sprintf('%d:%02d', int($issue->{'spent_time'} / 3600), int(($issue->{'spent_time'} % 3600) / 60)); if ($issue->{'estimated_hours'}) { $message .= sprintf(" (%.02f%%)", ($issue->{'spent_time'} * 100) / $issue->{'estimated_hours'}); } $message .= "\n"; } if ($main::query->GetIssueCustomFields($issue->{'id'})) { while (defined(my $field = $main::query->Next)) { utf8::decode($field->{'value'}); $message .= $field->{'name'}.': '; $message .= $field->{'value'}; $message .= "\n"; } } if ($issue->{'parent_id'}) { my $parent = $main::query->GetIssue($issue->{'parent_id'}); if (defined($parent)) { utf8::decode($parent->{'subject'}); $message .= "Parent issue: "; $message .= $parent->{'tracker_name'}.' #'.$parent->{'id'}.' - '; $message .= $parent->{'subject'}; $message .= "\n"; } } if ($main::query->GetRelatedIssues($issue->{'id'})) { my %map = ( relates => 'relates', duplicates => 'duplicated by', blocks => 'blocked by', precedes => 'follows', follows => 'precedes' ); $message .= "Related issues:\n"; while (defined(my $related = $main::query->Next)) { utf8::decode($related->{'subject'}); $message .= ' o '; if ($related->{'issue_from_id'} == $issue->{'id'}) { $message .= ucfirst($map{$related->{'relation_type'}}); } else { $message .= ucfirst($related->{'relation_type'}); } $message .= ' '.$related->{'tracker_name'}.' #'.$related->{'issue_to_id'}.': '; $message .= $related->{'subject'}; if ($related->{'delay'}) { $message .= ' ('.$related->{'delay'}.' days)'; } $message .= "\n"; } } if ($issue->{'childs'} > 0) { $message .= "Subissues:\n"; if ($main::query->GetSubissues($issue->{'id'})) { while (defined(my $subissue = $main::query->Next)) { utf8::decode($subissue->{'subject'}); $message .= ' o '; $message .= $subissue->{'tracker_name'}.' #'.$subissue->{'id'}.': '; $message .= $subissue->{'subject'}; $message .= "\n"; } } } if ($issue->{'description'}) { $message .= "\n"; ShowIssue_Format(\$issue->{'description'}); $message .= $issue->{'description'}."\n"; } $message .= "\n"; if ($main::query->GetAttachments($issue->{'id'})) { $message .= "Attachments:\n"; while (defined(my $attachment = $main::query->Next)) { utf8::decode($attachment->{'filename'}); utf8::decode($attachment->{'description'}); $message .= ' o '; $message .= sprintf("%s/attachments/%d/%s", $main::config->Get('redmine', 'base_url'), $attachment->{'id'}, $attachment->{'filename'}); if ($attachment->{'description'}) { $message .= ' - '.$attachment->{'description'}; } if ($attachment->{'filesize'} > 1048576) { $message .= sprintf(' (%.02f Mb)', $attachment->{'filesize'} / 1048576); } elsif ($attachment->{'filesize'} > 1024) { $message .= sprintf(' (%.02f kb)', $attachment->{'filesize'} / 1024); } else { $message .= sprintf(' (%d b)', $attachment->{'filesize'}); } $message .= "\n"; } $message .= "\n"; } if ($issue->{'notes'} > 0) { my $format; if ($issue->{'notes'} > 1) { $format = Orangutan::Context::Random( 'There are %d notes for this issue', 'The issue has %d comments' ); } else { $format = Orangutan::Context::Random( 'There is %d note for this issue', 'The issue has %d comment' ); } $message .= sprintf("$format...\n", $issue->{'notes'}); $message .= "\n"; } $message .= sprintf("URL: %s/issues/%d\n", $main::config->Get('redmine', 'base_url'), $issue->{'id'}); if ($main::query->GetWatchers($issue->{'id'})) { $message .= "Watched by"; my @watchers = ( ); while (defined(my $watcher = $main::query->Next)) { push(@watchers, $watcher->{'login'}); } for (my $i = 0; $i < scalar @watchers; $i++) { if ($i > 0) { if ($i == $#watchers) { $message .= ' and'; } else { $message .= ','; } } $message .= ' '.Orangutan::User::GetDisplayName($watchers[$i]); } $message .= ".\n"; } $message .= Orangutan::Context::Random('Reported', 'Added'); $message .= ' by '.Orangutan::User::GetDisplayName($issue->{'author_name'}); my ($min, $hour, $day, $mon, $year, $wday) = (localtime($issue->{'created_on'}))[1..6]; $message .= sprintf(" on %s, %d %s %04d %02d:%02d", $Orangutan::Date::weekdays[$wday], $day, $Orangutan::Date::months[$mon], $year + 1900, $hour, $min); if ($issue->{'updated_on'} > $issue->{'created_on'}) { $message .= ", "; $message .= Orangutan::Context::Random('updated', 'modified', 'changed'); ($min, $hour, $day, $mon, $year, $wday) = (localtime($issue->{'updated_on'}))[1..6]; $message .= sprintf(" on %s, %d %s %04d %02d:%02d", $Orangutan::Date::weekdays[$wday], $day, $Orangutan::Date::months[$mon], $year + 1900, $hour, $min); } $message .= "."; $user->SendMessage($message); } else { $user->SendMessage([ 'Such issue does not exist.', 'There is no such issue...', 'No such issue.' ]); } }, help => { title => 'How can I get more information about an issue?', question => [ '^(?:How )?(?:(?:can|do) I |to )(?:check|see|know|get) '. '(?:(?:an|the) )?issue(?: (?:details|information))?\?*!*\.*$', '^(?:How )?(?:(?:can|do) I |to )(?:check|see|know|get) '. '(?:more )?(?:details|information) (?:of|about) (?:(?:an|the) )?issue\?*!*\.*$' ], answer => "You can get a very detailed information about an issue.\n". "Sample queries:\n". " o Show me details of #257\n". " o Show bug #365\n". " o What is #329?\n". " o #470", weight => 900 } ); # kate: syntax perl