Rest api with perl » History » Version 2

Hiroo Hayashi, 2016-03-12 09:05
add description about locale settings.

1 1 Hiroo Hayashi
h1. Using the REST API with Perl
2 1 Hiroo Hayashi
3 2 Hiroo Hayashi
The followings are Perl scripts that demonstrate how to use the Redmine REST API.  They guess file encodings from the locale environment variables. See "open":http://perldoc.perl.org/open.html for more details.
4 1 Hiroo Hayashi
5 1 Hiroo Hayashi
h2. GET
6 1 Hiroo Hayashi
7 1 Hiroo Hayashi
<pre><code class="perl">
8 1 Hiroo Hayashi
#!/usr/bin/perl
9 1 Hiroo Hayashi
#	restget : GET a representation of a REST resource
10 1 Hiroo Hayashi
use strict;
11 1 Hiroo Hayashi
use warnings;
12 1 Hiroo Hayashi
use Getopt::Std;
13 1 Hiroo Hayashi
use LWP::UserAgent;
14 1 Hiroo Hayashi
use JSON;
15 1 Hiroo Hayashi
use open ':locale';	# probe the locale environment variables like LANG
16 1 Hiroo Hayashi
17 1 Hiroo Hayashi
sub HELP_MESSAGE {
18 1 Hiroo Hayashi
    print STDERR <<"EOM";
19 1 Hiroo Hayashi
usage : $0 [-p] [-k API_KEY] url
20 1 Hiroo Hayashi
        -p: pretty print
21 1 Hiroo Hayashi
        -k API_KEY: API Access Key
22 1 Hiroo Hayashi
EOM
23 1 Hiroo Hayashi
    exit 0;
24 1 Hiroo Hayashi
}
25 1 Hiroo Hayashi
our ($opt_p, $opt_k);
26 1 Hiroo Hayashi
getopts('pk:') or HELP_MESSAGE();
27 1 Hiroo Hayashi
my $url = shift;
28 1 Hiroo Hayashi
HELP_MESSAGE() unless $url;
29 1 Hiroo Hayashi
#################################################
30 1 Hiroo Hayashi
my $ua = new LWP::UserAgent;
31 1 Hiroo Hayashi
$ua->timeout(10);	# default: 180sec
32 1 Hiroo Hayashi
$ua->ssl_opts( verify_hostname => 0 );	# skip hostname verification
33 1 Hiroo Hayashi
$ua->default_header('X-Redmine-API-Key' => $opt_k) if $opt_k;
34 1 Hiroo Hayashi
35 1 Hiroo Hayashi
my $res = $ua->get($url);
36 1 Hiroo Hayashi
die $res->message if $res->is_error;
37 1 Hiroo Hayashi
38 1 Hiroo Hayashi
my $content =  $res->content;
39 1 Hiroo Hayashi
utf8::decode($content);	# convert UTF-8 binary to text
40 1 Hiroo Hayashi
if ($opt_p) {		# pretty print
41 1 Hiroo Hayashi
    my $perl_ref = from_json($content);
42 1 Hiroo Hayashi
    print to_json($perl_ref, {pretty=>1});
43 1 Hiroo Hayashi
} else {
44 1 Hiroo Hayashi
    print $content, "\n";
45 1 Hiroo Hayashi
}
46 1 Hiroo Hayashi
exit 0;
47 1 Hiroo Hayashi
</code></pre>
48 1 Hiroo Hayashi
49 1 Hiroo Hayashi
Note:
50 1 Hiroo Hayashi
51 1 Hiroo Hayashi
<pre><code>
52 1 Hiroo Hayashi
    my $perl_ref = from_json($content);
53 1 Hiroo Hayashi
</code></pre>
54 1 Hiroo Hayashi
55 1 Hiroo Hayashi
Here a "Perl reference":http://perldoc.perl.org/perlref.html" @$perl_ref@ is a reference to a whole data structure parsed.
56 1 Hiroo Hayashi
57 1 Hiroo Hayashi
Usage examples:
58 1 Hiroo Hayashi
59 1 Hiroo Hayashi
<pre><code>
60 1 Hiroo Hayashi
./restget http://www.redmine.org/issues/22097.json
61 1 Hiroo Hayashi
./restget -k 57acc39afc967564aa79a6bd329897d7040a9bc8 http://demo.redmine.org/issues/117594.json
62 1 Hiroo Hayashi
</code></pre>
63 1 Hiroo Hayashi
64 1 Hiroo Hayashi
The next commands put a textile table into the clipboard.
65 1 Hiroo Hayashi
66 1 Hiroo Hayashi
<pre><code>
67 1 Hiroo Hayashi
./restget http://www.redmine.org/projects/redmine/versions.json | perl -MJSON -nle 'for $v (sort{$a->{name} cmp $b->{name}}@{decode_json($_)->{versions}}){$d=$v->{description};print qq/|version:"$v->{name}"|$d|/ if $d}' > /dev/clipboard
68 1 Hiroo Hayashi
</code></pre>
69 1 Hiroo Hayashi
70 1 Hiroo Hayashi
You can paste it on your Wiki page as follows.
71 1 Hiroo Hayashi
72 1 Hiroo Hayashi
|version:"0.7.1"|Bug fix release|
73 1 Hiroo Hayashi
|version:"0.7.2"|Bug fix release|
74 1 Hiroo Hayashi
|version:"0.7.3"|Security+Bug fix release|
75 1 Hiroo Hayashi
|version:"0.9.0"|0.9 release candidate 1|
76 1 Hiroo Hayashi
|version:"0.9.6"|Security release|
77 1 Hiroo Hayashi
|version:"1.0.1"|Bug fixes for the 1.0.0 RC - (Estimated release date)|
78 1 Hiroo Hayashi
|version:"1.2.3"|Bug fix release for the 1.2.x serie|
79 1 Hiroo Hayashi
|version:"1.3.1"|Maintenance release|
80 1 Hiroo Hayashi
|version:"1.4.3"|Maintenance release|
81 1 Hiroo Hayashi
|version:"1.4.7"|security release|
82 1 Hiroo Hayashi
|version:"2.0.2"|Maintenance release|
83 1 Hiroo Hayashi
|version:"2.6.10"|For Rails 3.2 due to JRuby Nokogiri/Loofah does not support Rails 4.2|
84 1 Hiroo Hayashi
|version:"Candidate for next major release"|Features that the contributors would like to add in the next major version|
85 1 Hiroo Hayashi
|version:"Candidate for next minor release"|Fixes that the contributors would like to add in the next minor version|
86 1 Hiroo Hayashi
|version:"Unplanned"|Features that the core contributors of Redmine would like to add in a future version|
87 1 Hiroo Hayashi
88 1 Hiroo Hayashi
h2. PUT
89 1 Hiroo Hayashi
90 1 Hiroo Hayashi
<pre><code class="perl">
91 1 Hiroo Hayashi
#!/usr/bin/perl
92 1 Hiroo Hayashi
#	restput : PUT a representation of a REST resource
93 1 Hiroo Hayashi
use strict;
94 1 Hiroo Hayashi
use warnings;
95 1 Hiroo Hayashi
use Getopt::Std;
96 1 Hiroo Hayashi
use LWP::UserAgent;
97 1 Hiroo Hayashi
use open ':locale';	# probe the locale environment variables like LANG
98 1 Hiroo Hayashi
99 1 Hiroo Hayashi
sub HELP_MESSAGE {
100 1 Hiroo Hayashi
    print STDERR <<"EOM";
101 1 Hiroo Hayashi
usage : $0 [-p API_KEY] url [files...]
102 1 Hiroo Hayashi
        -k API_KEY: API Access Key
103 1 Hiroo Hayashi
EOM
104 1 Hiroo Hayashi
    exit 0;
105 1 Hiroo Hayashi
}
106 1 Hiroo Hayashi
our ($opt_k);
107 1 Hiroo Hayashi
getopts('k:') or HELP_MESSAGE();
108 1 Hiroo Hayashi
my $url = shift;
109 1 Hiroo Hayashi
HELP_MESSAGE() unless $url;
110 1 Hiroo Hayashi
#################################################
111 1 Hiroo Hayashi
my $ua = new LWP::UserAgent;
112 1 Hiroo Hayashi
$ua->timeout(10);	# default: 180sec
113 1 Hiroo Hayashi
$ua->ssl_opts( verify_hostname => 0 );	# skip hostname verification
114 1 Hiroo Hayashi
$ua->default_header('X-Redmine-API-Key' => $opt_k) if $opt_k;
115 1 Hiroo Hayashi
116 1 Hiroo Hayashi
my $content;
117 1 Hiroo Hayashi
{
118 1 Hiroo Hayashi
    local $/;
119 1 Hiroo Hayashi
    $content = <>;	# gets whole input
120 1 Hiroo Hayashi
}
121 1 Hiroo Hayashi
utf8::encode($content);	# convert UTF-8 binary to text
122 1 Hiroo Hayashi
my $res = $ua->put($url,
123 1 Hiroo Hayashi
                   'Content-Type' => 'application/json;charset=utf-8',
124 1 Hiroo Hayashi
                   'Content' => $content);
125 1 Hiroo Hayashi
die $res->message if $res->is_error;
126 1 Hiroo Hayashi
print $res->content();
127 1 Hiroo Hayashi
exit 0;
128 1 Hiroo Hayashi
</code></pre>
129 1 Hiroo Hayashi
130 1 Hiroo Hayashi
Usage examples:
131 1 Hiroo Hayashi
132 1 Hiroo Hayashi
<pre><code>
133 1 Hiroo Hayashi
# change my name
134 1 Hiroo Hayashi
echo '{"user":{"firstname":"James","lastname":"Bond"}}' | ./restput -k 57acc39afc967564aa79a6bd329897d7040a9bc8 http://demo.redmine.org/users/current.json
135 1 Hiroo Hayashi
</code></pre>
136 1 Hiroo Hayashi
137 1 Hiroo Hayashi
The following script converts a Wiki content to JSON format.
138 1 Hiroo Hayashi
139 1 Hiroo Hayashi
<pre><code class="perl">
140 1 Hiroo Hayashi
#!/usr/bin/perl
141 1 Hiroo Hayashi
#	restwiki : convert a Wiki content to JSON format
142 1 Hiroo Hayashi
use strict;
143 1 Hiroo Hayashi
use warnings;
144 1 Hiroo Hayashi
use Getopt::Std;
145 1 Hiroo Hayashi
use JSON;
146 1 Hiroo Hayashi
use open ':locale';
147 1 Hiroo Hayashi
148 1 Hiroo Hayashi
sub HELP_MESSAGE {
149 1 Hiroo Hayashi
    print STDERR <<"EOM";
150 1 Hiroo Hayashi
usage :    $0 [-c comment] [files...]
151 1 Hiroo Hayashi
    -c : comment
152 1 Hiroo Hayashi
EOM
153 1 Hiroo Hayashi
    exit 0;
154 1 Hiroo Hayashi
}
155 1 Hiroo Hayashi
our ($opt_c);
156 1 Hiroo Hayashi
getopts('c:') or HELP_MESSAGE();
157 1 Hiroo Hayashi
#################################################
158 1 Hiroo Hayashi
my $ref;
159 1 Hiroo Hayashi
{
160 1 Hiroo Hayashi
    local $/;	# enable slurp mode
161 1 Hiroo Hayashi
    $ref->{wiki_page}->{text} = <>;
162 1 Hiroo Hayashi
}
163 1 Hiroo Hayashi
$ref->{wiki_page}->{comments} = $opt_c if $opt_c;
164 1 Hiroo Hayashi
print to_json($ref);
165 1 Hiroo Hayashi
exit 0;
166 1 Hiroo Hayashi
</code></pre>
167 1 Hiroo Hayashi
168 1 Hiroo Hayashi
The following commands create or update a Wiki page "Test Page".
169 1 Hiroo Hayashi
170 1 Hiroo Hayashi
<pre><code>
171 1 Hiroo Hayashi
./restwiki foo | ./restput -k 57acc39afc967564aa79a6bd329897d7040a9bc8 http://my.redmine.local/projects/test-project/wiki/Test_Page.json
172 1 Hiroo Hayashi
</code></pre>
173 1 Hiroo Hayashi
174 1 Hiroo Hayashi
You, a one-liner, may want to do as follows;
175 1 Hiroo Hayashi
176 1 Hiroo Hayashi
<pre><code>
177 1 Hiroo Hayashi
perl -MJSON -e 'local $/;$ref->{wiki_page}->{text} = <>;print to_json($ref)' foo | ./restput -k 57acc39afc967564aa79a6bd329897d7040a9bc8 http://my.redmine.local/projects/test-project/wiki/Test_Page.json
178 1 Hiroo Hayashi
</code></pre>
179 1 Hiroo Hayashi
180 1 Hiroo Hayashi
h2. Resources
181 1 Hiroo Hayashi
182 1 Hiroo Hayashi
* "LWP::UserAgent":http://search.cpan.org/~ether/libwww-perl-6.15/lib/LWP/UserAgent.pm
183 1 Hiroo Hayashi
* "JSON":http://search.cpan.org/~makamaka/JSON-2.90/lib/JSON.pm
184 1 Hiroo Hayashi
* "perlref - Perl references and nested data structures":http://perldoc.perl.org/perlref.html
185 1 Hiroo Hayashi
* "perlunitut - Perl Unicode Tutorial":http://perldoc.perl.org/perlunitut.html