git-remote-mediawiki: factoring code between git-remote-mediawiki and Git::Mediawiki
For now, Git::Mediawiki contains nothing. This first patch moves some of git-remote-mediawiki.perl's factorisable code into Git::Mediawiki. In the same time, it removes the side effects of that code and renames the fucntions and constants moved to expose a better API. Signed-off-by: Benoit Person <benoit.person@ensimag.fr> Signed-off-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Benoit Person committed
Jul 4, 2013 at 22:38 UTC
192f7a080469ea3e7a702f04e08ba7e709c0b3c3
2 files changed
+89
-73
contrib/mw-to-git/Git/Mediawiki.pm
+76
-1
@@ -18,7 +18,82 @@ require Exporter;
18
@EXPORT = ();
19
20
# Methods which can be called as standalone functions as well:
21
-@EXPORT_OK = ();
21
+@EXPORT_OK = qw(clean_filename smudge_filename connect_maybe
22
+ EMPTY HTTP_CODE_OK);
23
+}
24
+
25
+# Mediawiki filenames can contain forward slashes. This variable decides by which pattern they should be replaced
26
+use constant SLASH_REPLACEMENT => '%2F';
27
+
28
+# Used to test for empty strings
29
+use constant EMPTY => q{};
30
+
31
+# HTTP codes
32
+use constant HTTP_CODE_OK => 200;
33
+
34
+sub clean_filename {
35
+ my $filename = shift;
36
+ $filename =~ s{@{[SLASH_REPLACEMENT]}}{/}g;
37
+ # [, ], |, {, and } are forbidden by MediaWiki, even URL-encoded.
38
+ # Do a variant of URL-encoding, i.e. looks like URL-encoding,
39
+ # but with _ added to prevent MediaWiki from thinking this is
40
+ # an actual special character.
41
+ $filename =~ s/[\[\]\{\}\|]/sprintf("_%%_%x", ord($&))/ge;
42
+ # If we use the uri escape before
43
+ # we should unescape here, before anything
44
+
45
+ return $filename;
46
+}
47
+
48
+sub smudge_filename {
49
+ my $filename = shift;
50
+ $filename =~ s{/}{@{[SLASH_REPLACEMENT]}}g;
51
+ $filename =~ s/ /_/g;
52
+ # Decode forbidden characters encoded in clean_filename
53
+ $filename =~ s/_%_([0-9a-fA-F][0-9a-fA-F])/sprintf('%c', hex($1))/ge;
54
+ return $filename;
55
+}
56
+
57
+sub connect_maybe {
58
+ my $wiki = shift;
59
+ if ($wiki) {
60
+ return $wiki;
61
+ }
62
+
63
+ my $remote_name = shift;
64
+ my $remote_url = shift;
65
+ my ($wiki_login, $wiki_password, $wiki_domain);
66
+
67
+ $wiki_login = Git::config("remote.${remote_name}.mwLogin");
68
+ $wiki_password = Git::config("remote.${remote_name}.mwPassword");
69
+ $wiki_domain = Git::config("remote.${remote_name}.mwDomain");
70
+
71
+ $wiki = MediaWiki::API->new;
72
+ $wiki->{config}->{api_url} = "${remote_url}/api.php";
73
+ if ($wiki_login) {
74
+ my %credential = (
75
+ 'url' => $remote_url,
76
+ 'username' => $wiki_login,
77
+ 'password' => $wiki_password
78
+ );
79
+ Git::credential(\%credential);
80
+ my $request = {lgname => $credential{username},
81
+ lgpassword => $credential{password},
82
+ lgdomain => $wiki_domain};
83
+ if ($wiki->login($request)) {
84
+ Git::credential(\%credential, 'approve');
85
+ print {*STDERR} qq(Logged in mediawiki user "$credential{username}".\n);
86
+ } else {
87
+ print {*STDERR} qq(Failed to log in mediawiki user "$credential{username}" on ${remote_url}\n);
88
+ print {*STDERR} ' (error ' .
89
+ $wiki->{error}->{code} . ': ' .
90
+ $wiki->{error}->{details} . ")\n";
91
+ Git::credential(\%credential, 'reject');
92
+ exit 1;
93
+ }
94
+ }
95
+
96
+ return $wiki;
97
}
98
99
1; # Famous last words
contrib/mw-to-git/git-remote-mediawiki.perl
+13
-72
@@ -14,6 +14,8 @@
14
use strict;
15
use MediaWiki::API;
16
use Git;
17
+use Git::Mediawiki qw(clean_filename smudge_filename connect_maybe
18
+ EMPTY HTTP_CODE_OK);
19
use DateTime::Format::ISO8601;
20
use warnings;
21
@@ -23,9 +25,6 @@ binmode STDOUT, ':encoding(UTF-8)';
25
26
use URI::Escape;
27
26
-# Mediawiki filenames can contain forward slashes. This variable decides by which pattern they should be replaced
27
-use constant SLASH_REPLACEMENT => '%2F';
28
-
28
# It's not always possible to delete pages (may require some
29
# privileges). Deleted pages are replaced with this content.
30
use constant DELETED_CONTENT => "[[Category:Deleted]]\n";
@@ -40,8 +39,6 @@ use constant NULL_SHA1 => '0000000000000000000000000000000000000000';
39
# Used on Git's side to reflect empty edit messages on the wiki
40
use constant EMPTY_MESSAGE => '*Empty MediaWiki Message*';
41
43
-use constant EMPTY => q{};
44
-
42
# Number of pages taken into account at once in submodule get_mw_page_list
43
use constant SLICE_SIZE => 50;
44
@@ -50,8 +47,6 @@ use constant SLICE_SIZE => 50;
47
# the number of links to be returned (500 links max).
48
use constant BATCH_SIZE => 10;
49
53
-use constant HTTP_CODE_OK => 200;
54
-
50
if (@ARGV != 2) {
51
exit_error_usage();
52
}
@@ -199,37 +194,6 @@ sub parse_command {
194
# MediaWiki API instance, created lazily.
195
my $mediawiki;
196
202
-sub mw_connect_maybe {
203
- if ($mediawiki) {
204
- return;
205
- }
206
- $mediawiki = MediaWiki::API->new;
207
- $mediawiki->{config}->{api_url} = "${url}/api.php";
208
- if ($wiki_login) {
209
- my %credential = (
210
- 'url' => $url,
211
- 'username' => $wiki_login,
212
- 'password' => $wiki_passwd
213
- );
214
- Git::credential(\%credential);
215
- my $request = {lgname => $credential{username},
216
- lgpassword => $credential{password},
217
- lgdomain => $wiki_domain};
218
- if ($mediawiki->login($request)) {
219
- Git::credential(\%credential, 'approve');
220
- print {*STDERR} qq(Logged in mediawiki user "$credential{username}".\n);
221
- } else {
222
- print {*STDERR} qq(Failed to log in mediawiki user "$credential{username}" on ${url}\n);
223
- print {*STDERR} ' (error ' .
224
- $mediawiki->{error}->{code} . ': ' .
225
- $mediawiki->{error}->{details} . ")\n";
226
- Git::credential(\%credential, 'reject');
227
- exit 1;
228
- }
229
- }
230
- return;
231
-}
232
-
197
sub fatal_mw_error {
198
my $action = shift;
199
print STDERR "fatal: could not $action.\n";
@@ -339,7 +303,7 @@ sub get_mw_first_pages {
303
304
# Get the list of pages to be fetched according to configuration.
305
sub get_mw_pages {
342
- mw_connect_maybe();
306
+ $mediawiki = connect_maybe($mediawiki, $remotename, $url);
307
308
print {*STDERR} "Listing pages on remote wiki...\n";
309
@@ -529,7 +493,7 @@ sub get_last_local_revision {
493
# avoid a loop onto all tracked pages. This is useful for the fetch-by-rev
494
# option.
495
sub get_last_global_remote_rev {
532
- mw_connect_maybe();
496
+ $mediawiki = connect_maybe($mediawiki, $remotename, $url);
497
498
my $query = {
499
action => 'query',
@@ -545,7 +509,7 @@ sub get_last_global_remote_rev {
509
# Get the last remote revision concerning the tracked pages and the tracked
510
# categories.
511
sub get_last_remote_revision {
548
- mw_connect_maybe();
512
+ $mediawiki = connect_maybe($mediawiki, $remotename, $url);
513
514
my %pages_hash = get_mw_pages();
515
my @pages = values(%pages_hash);
@@ -601,29 +565,6 @@ sub mediawiki_smudge {
565
return "${string}\n";
566
}
567
604
-sub mediawiki_clean_filename {
605
- my $filename = shift;
606
- $filename =~ s{@{[SLASH_REPLACEMENT]}}{/}g;
607
- # [, ], |, {, and } are forbidden by MediaWiki, even URL-encoded.
608
- # Do a variant of URL-encoding, i.e. looks like URL-encoding,
609
- # but with _ added to prevent MediaWiki from thinking this is
610
- # an actual special character.
611
- $filename =~ s/[\[\]\{\}\|]/sprintf("_%%_%x", ord($&))/ge;
612
- # If we use the uri escape before
613
- # we should unescape here, before anything
614
-
615
- return $filename;
616
-}
617
-
618
-sub mediawiki_smudge_filename {
619
- my $filename = shift;
620
- $filename =~ s{/}{@{[SLASH_REPLACEMENT]}}g;
621
- $filename =~ s/ /_/g;
622
- # Decode forbidden characters encoded in mediawiki_clean_filename
623
- $filename =~ s/_%_([0-9a-fA-F][0-9a-fA-F])/sprintf('%c', hex($1))/ge;
624
- return $filename;
625
-}
626
-
568
sub literal_data {
569
my ($content) = @_;
570
print {*STDOUT} 'data ', bytes::length($content), "\n", $content;
@@ -831,7 +772,7 @@ sub mw_import_ref {
772
return;
773
}
774
834
- mw_connect_maybe();
775
+ $mediawiki = connect_maybe($mediawiki, $remotename, $url);
776
777
print {*STDERR} "Searching revisions...\n";
778
my $last_local = get_last_local_revision();
@@ -945,7 +886,7 @@ sub mw_import_revids {
886
my %commit;
887
$commit{author} = $rev->{user} || 'Anonymous';
888
$commit{comment} = $rev->{comment} || EMPTY_MESSAGE;
948
- $commit{title} = mediawiki_smudge_filename($page_title);
889
+ $commit{title} = smudge_filename($page_title);
890
$commit{mw_revision} = $rev->{revid};
891
$commit{content} = mediawiki_smudge($rev->{'*'});
892
@@ -1006,7 +947,7 @@ sub mw_upload_file {
947
}
948
# Deleting and uploading a file requires a priviledged user
949
if ($file_deleted) {
1009
- mw_connect_maybe();
950
+ $mediawiki = connect_maybe($mediawiki, $remotename, $url);
951
my $query = {
952
action => 'delete',
953
title => $path,
@@ -1022,7 +963,7 @@ sub mw_upload_file {
963
# Don't let perl try to interpret file content as UTF-8 => use "raw"
964
my $content = run_git("cat-file blob ${new_sha1}", 'raw');
965
if ($content ne EMPTY) {
1025
- mw_connect_maybe();
966
+ $mediawiki = connect_maybe($mediawiki, $remotename, $url);
967
$mediawiki->{config}->{upload_url} =
968
"${url}/index.php/Special:Upload";
969
$mediawiki->edit({
@@ -1070,7 +1011,7 @@ sub mw_push_file {
1011
my $old_sha1 = $diff_info_split[2];
1012
my $page_created = ($old_sha1 eq NULL_SHA1);
1013
my $page_deleted = ($new_sha1 eq NULL_SHA1);
1073
- $complete_file_name = mediawiki_clean_filename($complete_file_name);
1014
+ $complete_file_name = clean_filename($complete_file_name);
1015
1016
my ($title, $extension) = $complete_file_name =~ /^(.*)\.([^\.]*)$/;
1017
if (!defined($extension)) {
@@ -1093,7 +1034,7 @@ sub mw_push_file {
1034
$file_content = run_git("cat-file blob ${new_sha1}");
1035
}
1036
1096
- mw_connect_maybe();
1037
+ $mediawiki = connect_maybe($mediawiki, $remotename, $url);
1038
1039
my $result = $mediawiki->edit( {
1040
action => 'edit',
@@ -1279,7 +1220,7 @@ sub mw_push_revision {
1220
}
1221
1222
sub get_allowed_file_extensions {
1282
- mw_connect_maybe();
1223
+ $mediawiki = connect_maybe($mediawiki, $remotename, $url);
1224
1225
my $query = {
1226
action => 'query',
@@ -1303,7 +1244,7 @@ my %cached_mw_namespace_id;
1244
# Return MediaWiki id for a canonical namespace name.
1245
# Ex.: "File", "Project".
1246
sub get_mw_namespace_id {
1306
- mw_connect_maybe();
1247
+ $mediawiki = connect_maybe($mediawiki, $remotename, $url);
1248
my $name = shift;
1249
1250
if (!exists $namespace_id{$name}) {