From eab44b1aad3f243dd69b1d30519b73a1e537fda2 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Mon, 7 Apr 2014 02:41:11 -0400 Subject: Bug 489028 - Record last-visited time of bugs when logged in r=glob a=justdave --- Bugzilla/WebService/BugUserLastVisit.pm | 208 +++++++++++++++++++++ Bugzilla/WebService/Constants.pm | 13 +- Bugzilla/WebService/Server/REST.pm | 1 + .../Server/REST/Resources/BugUserLastVisit.pm | 52 ++++++ 4 files changed, 268 insertions(+), 6 deletions(-) create mode 100644 Bugzilla/WebService/BugUserLastVisit.pm create mode 100644 Bugzilla/WebService/Server/REST/Resources/BugUserLastVisit.pm (limited to 'Bugzilla/WebService') diff --git a/Bugzilla/WebService/BugUserLastVisit.pm b/Bugzilla/WebService/BugUserLastVisit.pm new file mode 100644 index 000000000..71b637fef --- /dev/null +++ b/Bugzilla/WebService/BugUserLastVisit.pm @@ -0,0 +1,208 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::WebService::BugUserLastVisit; + +use 5.10.1; +use strict; + +use parent qw(Bugzilla::WebService); + +use Bugzilla::Bug; +use Bugzilla::Error; +use Bugzilla::WebService::Util qw( validate filter ); +use Bugzilla::Constants; + +sub update { + my ($self, $params) = validate(@_, 'ids'); + my $user = Bugzilla->user; + my $dbh = Bugzilla->dbh; + + $user->login(LOGIN_REQUIRED); + + my $ids = $params->{ids} // []; + ThrowCodeError('param_required', { param => 'ids' }) unless @$ids; + + # Cache permissions for bugs. This highly reduces the number of calls to the + # DB. visible_bugs() is only able to handle bug IDs, so we have to skip + # aliases. + $user->visible_bugs([grep /^[0-9]$/, @$ids]); + + $dbh->bz_start_transaction(); + my @results; + my $last_visit_ts = $dbh->selectrow_array('SELECT NOW()'); + foreach my $bug_id (@$ids) { + my $bug = Bugzilla::Bug->check({ id => $bug_id, cache => 1 }); + + ThrowUserError('user_not_involved', { bug_id => $bug->id }) + unless $user->is_involved_in_bug($bug); + + $bug->update_user_last_visit($user, $last_visit_ts); + + push( + @results, + $self->_bug_user_last_visit_to_hash( + $bug, $last_visit_ts, $params + )); + } + $dbh->bz_commit_transaction(); + + return \@results; +} + +sub get { + my ($self, $params) = validate(@_, 'ids'); + my $user = Bugzilla->user; + my $ids = $params->{ids}; + + $user->login(LOGIN_REQUIRED); + + if ($ids) { + # Cache permissions for bugs. This highly reduces the number of calls to + # the DB. visible_bugs() is only able to handle bug IDs, so we have to + # skip aliases. + $user->visible_bugs([grep /^[0-9]$/, @$ids]); + } + + my @last_visits = @{ $user->last_visits }; + + if ($ids) { + # remove bugs that we arn't interested in if ids is passed in. + my %id_set = map { ($_ => 1) } @$ids; + @last_visits = grep { $id_set{ $_->bug_id } } @last_visits; + } + + return [ + map { + $self->_bug_user_last_visit_to_hash($_->bug_id, $_->last_visit_ts, + $params) + } @last_visits + ]; +} + +sub _bug_user_last_visit_to_hash { + my ($self, $bug_id, $last_visit_ts, $params) = @_; + + my %result = (id => $self->type('int', $bug_id), + last_visit_ts => $self->type('dateTime', $last_visit_ts)); + + return filter($params, \%result); +} + +1; + +__END__ +=head1 NAME + +Bugzilla::WebService::BugUserLastVisit - Find and Store the last time a user +visited a bug. + +=head1 METHODS + +See L for a description of how parameters are passed, +and what B, B, and B mean. + +Although the data input and output is the same for JSONRPC, XMLRPC and REST, +the directions for how to access the data via REST is noted in each method +where applicable. + +=head2 update + +B + +=over + +=item B + +Update the last visit time for the specified bug and current user. + +=item B + +To add a single bug id: + + POST /rest/bug_user_last_visit/ + +Tp add one or more bug ids at once: + + POST /rest/bug_user_last_visit + +The returned data format is the same as below. + +=item B + +=over + +=item C (array) - One or more bug ids to add. + +=back + +=item B + +=over + +=item C - An array of hashes containing the following: + +=over + +=item C - (int) The bug id. + +=item C - (string) The timestamp the user last visited the bug. + +=back + +=back + +=back + +=head2 get + +B + +=over + +=item B + +Get the last visited timestamp for one or more specified bug ids or get a +list of the last 20 visited bugs and their timestamps. + +=item B + +To return the last visited timestamp for a single bug id: + +GET /rest/bug_visit/ + +To return more than one bug timestamp or the last 20: + +GET /rest/bug_visit + +The returned data format is the same as below. + +=item B + +=over + +=item C (integer) - One or more optional bug ids to get. + +=back + +=item B + +=over + +=item C - An array of hashes containing the following: + +=over + +=item C - (int) The bug id. + +=item C - (string) The timestamp the user last visited the bug. + +=back + +=back + +=back diff --git a/Bugzilla/WebService/Constants.pm b/Bugzilla/WebService/Constants.pm index 4085c2cbd..e18e2b8ec 100644 --- a/Bugzilla/WebService/Constants.pm +++ b/Bugzilla/WebService/Constants.pm @@ -266,12 +266,13 @@ sub WS_DISPATCH { Bugzilla::Hook::process('webservice', { dispatch => \%hook_dispatch }); my $dispatch = { - 'Bugzilla' => 'Bugzilla::WebService::Bugzilla', - 'Bug' => 'Bugzilla::WebService::Bug', - 'Classification' => 'Bugzilla::WebService::Classification', - 'Group' => 'Bugzilla::WebService::Group', - 'Product' => 'Bugzilla::WebService::Product', - 'User' => 'Bugzilla::WebService::User', + 'Bugzilla' => 'Bugzilla::WebService::Bugzilla', + 'Bug' => 'Bugzilla::WebService::Bug', + 'Classification' => 'Bugzilla::WebService::Classification', + 'Group' => 'Bugzilla::WebService::Group', + 'Product' => 'Bugzilla::WebService::Product', + 'User' => 'Bugzilla::WebService::User', + 'BugUserLastVisit' => 'Bugzilla::WebService::BugUserLastVisit', %hook_dispatch }; return $dispatch; diff --git a/Bugzilla/WebService/Server/REST.pm b/Bugzilla/WebService/Server/REST.pm index 7aac95170..ba8304a5f 100644 --- a/Bugzilla/WebService/Server/REST.pm +++ b/Bugzilla/WebService/Server/REST.pm @@ -27,6 +27,7 @@ use Bugzilla::WebService::Server::REST::Resources::Classification; use Bugzilla::WebService::Server::REST::Resources::Group; use Bugzilla::WebService::Server::REST::Resources::Product; use Bugzilla::WebService::Server::REST::Resources::User; +use Bugzilla::WebService::Server::REST::Resources::BugUserLastVisit;; use Scalar::Util qw(blessed reftype); use MIME::Base64 qw(decode_base64); diff --git a/Bugzilla/WebService/Server/REST/Resources/BugUserLastVisit.pm b/Bugzilla/WebService/Server/REST/Resources/BugUserLastVisit.pm new file mode 100644 index 000000000..a434d4bef --- /dev/null +++ b/Bugzilla/WebService/Server/REST/Resources/BugUserLastVisit.pm @@ -0,0 +1,52 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::WebService::Server::REST::Resources::BugUserLastVisit; + +use 5.10.1; +use strict; +use warnings; + +BEGIN { + *Bugzilla::WebService::BugUserLastVisit::rest_resources = \&_rest_resources; +} + +sub _rest_resources { + return [ + # bug-id + qr{^/bug_user_last_visit/(\d+)$}, { + GET => { + method => 'get', + params => sub { + return { ids => $_[0] }; + }, + }, + POST => { + method => 'update', + params => sub { + return { ids => $_[0] }; + }, + }, + }, + ]; +} + +1; +__END__ + +=head1 NAME + +Bugzilla::Webservice::Server::REST::Resources::BugUserLastVisit - The +BugUserLastVisit REST API + +=head1 DESCRIPTION + +This part of the Bugzilla REST API allows you to lookup and update the last time +a user visited a bug. + +See L for more details on how to use +this part of the REST API. -- cgit v1.2.1