From a3841dfd8f9fc019eda1ccf57c91b7305cef1c7e Mon Sep 17 00:00:00 2001 From: Byron Jones Date: Wed, 16 Oct 2013 00:40:18 +0800 Subject: Bug 916906: attaching a file which just contains a github url should automatically redirect to it when viewing --- attachment.cgi | 4 + extensions/BMO/Extension.pm | 59 ++++++++++++++ extensions/BMO/bin/migrate-github-pull-requests.pl | 90 ++++++++++++++++++++++ extensions/BMO/lib/Data.pm | 5 +- template/en/default/attachment/edit.html.tmpl | 3 +- 5 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 extensions/BMO/bin/migrate-github-pull-requests.pl diff --git a/attachment.cgi b/attachment.cgi index 350cf91f1..95d793e75 100755 --- a/attachment.cgi +++ b/attachment.cgi @@ -52,6 +52,7 @@ use Bugzilla::Attachment; use Bugzilla::Attachment::PatchReader; use Bugzilla::Token; use Bugzilla::Keyword; +use Bugzilla::Hook; use Encode qw(encode find_encoding); @@ -386,6 +387,9 @@ sub view { # Return the appropriate HTTP response headers. $attachment->datasize || ThrowUserError("attachment_removed"); + # BMO add a hook for github url redirection + Bugzilla::Hook::process('attachment_view', { attachment => $attachment }); + $filename =~ s/^.*[\/\\]//; # escape quotes and backslashes in the filename, per RFCs 2045/822 $filename =~ s/\\/\\\\/g; # escape backslashes diff --git a/extensions/BMO/Extension.pm b/extensions/BMO/Extension.pm index fd9068fe7..1fdb7d3c2 100644 --- a/extensions/BMO/Extension.pm +++ b/extensions/BMO/Extension.pm @@ -33,6 +33,7 @@ use Bugzilla::Mailer; use Bugzilla::Product; use Bugzilla::Status; use Bugzilla::Token; +use Bugzilla::Install::Filesystem; use Bugzilla::User; use Bugzilla::User::Setting; use Bugzilla::Util; @@ -580,6 +581,55 @@ sub bug_end_of_create { } } +# detect github pull requests and set a unique content-type +sub attachment_process_data { + my ($self, $args) = @_; + my $attributes = $args->{attributes}; + + # quick checks - must be a text/plain non-patch + return if $attributes->{ispatch} || $attributes->{mimetype} ne 'text/plain'; + + # check the attachment size, and get attachment content if it isn't too large + my $data = $attributes->{data}; + my $url; + if (blessed($data) && blessed($data) eq 'Fh') { + # filehandle + my $size = -s $data; + return if $size > 256; + sysread($data, $url, $size); + seek($data, 0, 0); + } else { + # string + return if length($data) > 256; + $url = $data; + } + + # trim and check for the pull request url + $url = trim($url); + return if $url =~ /\s/; + return unless $url =~ m#^https://github\.com/[^/]+/[^/]+/pull/\d+$#i; + + # must be a valid pull-request + $attributes->{mimetype} = GITHUB_PR_CONTENT_TYPE; +} + +# redirect automatically to github urls +sub attachment_view { + my ($self, $args) = @_; + my $attachment = $args->{attachment}; + my $cgi = Bugzilla->cgi; + + # don't redirect if the content-type is specified explicitly + return if defined $cgi->param('content_type'); + + # must be our github content-type + return unless $attachment->contenttype eq GITHUB_PR_CONTENT_TYPE; + + # redirect + print $cgi->redirect(trim($attachment->data)); + exit; +} + sub install_before_final_checks { my ($self, $args) = @_; @@ -1064,4 +1114,13 @@ sub _check_default_product_security_group { } } +sub install_filesystem { + my ($self, $args) = @_; + my $files = $args->{files}; + my $extensions_dir = bz_locations()->{extensionsdir}; + $files->{"$extensions_dir/BMO/bin/migrate-github-pull-requests.pl"} = { + perms => Bugzilla::Install::Filesystem::OWNER_EXECUTE + }; +} + __PACKAGE__->NAME; diff --git a/extensions/BMO/bin/migrate-github-pull-requests.pl b/extensions/BMO/bin/migrate-github-pull-requests.pl new file mode 100644 index 000000000..eba0dd422 --- /dev/null +++ b/extensions/BMO/bin/migrate-github-pull-requests.pl @@ -0,0 +1,90 @@ +#!/usr/bin/perl + +# 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. + +use strict; +use warnings; + +use FindBin qw($RealBin); +use lib "$RealBin/../../.."; + +use Bugzilla; +BEGIN { Bugzilla->extensions() } + +use Bugzilla::Extension::BMO::Data; +use Bugzilla::Field; +use Bugzilla::Install::Util qw(indicate_progress); +use Bugzilla::User; +use Bugzilla::Util qw(trim); + +my $dbh = Bugzilla->dbh; +my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org' }); +my $field = Bugzilla::Field->check({ name => 'attachments.mimetype' }); + +# grab list of suitable attachments + +my $sql = < 0 + AND LENGTH(thedata) <= 256 +EOF +print "Searching for suitable attachments..\n"; +my $attachments = $dbh->selectall_arrayref($sql, { Slice => {} }); +my ($current, $total, $updated) = (1, scalar(@$attachments), 0); + +die "No suitable attachments found\n" unless $total; +print "About to check $total attachments for github pull requests, and\n"; +print "update content-type if required.\n"; +print "Press to start, or ^C to cancel...\n"; +<>; + +foreach my $attachment (@$attachments) { + indicate_progress({ current => $current++, total => $total, every => 25 }); + + # check payload + my $url = trim($attachment->{thedata}); + next if $url =~ /\s/; + next unless $url =~ m#^https://github\.com/[^/]+/[^/]+/pull/\d+$#i; + + $dbh->bz_start_transaction; + + # set content-type + $dbh->do( + "UPDATE attachments SET mimetype = ? WHERE attach_id = ?", + undef, + GITHUB_PR_CONTENT_TYPE, $attachment->{attach_id} + ); + + # insert into bugs_activity + my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); + $dbh->do( + "INSERT INTO bugs_activity(bug_id, who, bug_when, fieldid, removed, added) + VALUES (?, ?, ?, ?, ?, ?)", + undef, + $attachment->{bug_id}, $nobody->id, $timestamp, $field->id, + $attachment->{mimetype}, GITHUB_PR_CONTENT_TYPE + ); + $dbh->do( + "UPDATE bugs SET delta_ts = ?, lastdiffed = ? WHERE bug_id = ?", + undef, + $timestamp, $timestamp, $attachment->{bug_id} + ); + + $dbh->bz_commit_transaction; + $updated++; +} + +print "Attachments updated: $updated\n"; diff --git a/extensions/BMO/lib/Data.pm b/extensions/BMO/lib/Data.pm index e730f84ea..e070cd244 100644 --- a/extensions/BMO/lib/Data.pm +++ b/extensions/BMO/lib/Data.pm @@ -39,7 +39,10 @@ our @EXPORT = qw( $cf_visible_in_products %group_auto_cc %product_sec_groups %create_bug_formats - @default_named_queries ); + @default_named_queries + GITHUB_PR_CONTENT_TYPE ); + +use constant GITHUB_PR_CONTENT_TYPE => 'text/x-github-pull-request'; # Which custom fields are visible in which products and components. # diff --git a/template/en/default/attachment/edit.html.tmpl b/template/en/default/attachment/edit.html.tmpl index 530b2d04c..cbc66e95a 100644 --- a/template/en/default/attachment/edit.html.tmpl +++ b/template/en/default/attachment/edit.html.tmpl @@ -208,7 +208,8 @@ readonly = 'readonly' %] [% ELSE %] - -- cgit v1.2.3-24-g4f1b