source: trunk/tools/ws.htm @ 22279

Last change on this file since 22279 was 20826, checked in by plg, 12 years ago

use jquery CDN instead of Google's (but it would be preferable to use Piwigo files instead)

  • Property svn:eol-style set to LF
File size: 19.9 KB
Line 
1<!DOCTYPE html>
2<html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr">
3<head>
4  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5  <title>Piwigo web API (web-services) explorer</title>
6 
7  <link rel="stylesheet" type="text/css" href="http://cdn.jsdelivr.net/tiptip/1.3/tipTip.css">
8  <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
9  <script type="text/javascript" src="https://cdn.jsdelivr.net/tiptip/1.3/jquery.tipTip.minified.js"></script>
10 
11  <style type="text/css">
12  /* BEGIN CSS RESET
13    http://meyerweb.com/eric/tools/css/reset
14    v2.0 | 20110126 | License: none (public domain) */
15  html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code,
16  del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li,
17  fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, 
18  figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video
19  {margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;}
20
21  article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {display:block;}
22  body {line-height:1.1;}
23  blockquote, q {quotes:none;}
24  blockquote:before, blockquote:after, q:before, q:after {content:'';content:none;}
25  table {border-collapse:collapse;border-spacing:0;}
26  /* END CSS RESET */
27
28  html {font-family:"Corbel","Lucida Grande","Verdana",sans-serif;color:#222;font-size:13px;}
29
30  a {color:#247EBF;text-decoration:none;}
31  a:hover {color:#EB9C39;border-bottom-width:1px;border-style:dotted;
32    text-shadow:1px 1px 0 #ddd;-moz-text-shadow:1px 1px 0 #ddd;-webkit-text-shadow:1px 1px 0 #ddd;
33  }
34  blockquote {border:1px solid #cdcdcd;background:#F9F9F9;padding:8px;}
35  hr {margin:10px 30px;color:#fff;}
36  ul {margin-left:25px;}
37  p {margin:8px 0;}
38
39  h1 {color:#fff;font-size:26px;padding:10px 15px;
40    text-shadow:1px 1px 0 #999;-moz-text-shadow:1px 1px 0 #999;-webkit-text-shadow:1px 1px 0 #999;
41    background:#45484d;background:-moz-linear-gradient(top, #45484d 0%, #333333 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#45484d), color-stop(100%,#333333));background:-webkit-linear-gradient(top, #45484d 0%,#333333 100%);background:-o-linear-gradient(top, #45484d 0%,#333333 100%);background:-ms-linear-gradient(top, #45484d 0%,#333333 100%);background:linear-gradient(to bottom, #45484d 0%,#333333 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#45484d', endColorstr='#333333',GradientType=0 );
42  }
43  h2 {color:#fff;font-size:20px;padding:5px 10px;
44    text-shadow:1px 1px 0 #555;-moz-text-shadow:1px 1px 0 #555;-webkit-text-shadow:1px 1px 0 #555;
45    background:#f2a841;background:-moz-linear-gradient(top, #f2a841 0%, #ef6b13 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f2a841), color-stop(100%,#ef6b13));background:-webkit-linear-gradient(top, #f2a841 0%,#ef6b13 100%);background:-o-linear-gradient(top, #f2a841 0%,#ef6b13 100%);background:-ms-linear-gradient(top, #f2a841 0%,#ef6b13 100%);background:linear-gradient(to bottom, #f2a841 0%,#ef6b13 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2a841', endColorstr='#ef6b13',GradientType=0 );
46  }
47  h2#errorWrapper {color:#F42C00;font-weight:normal;
48    background:#eaeaea;background:-moz-linear-gradient(top, #eaeaea 0%, #afafaf 100%);background:-webkit-gradient(linear, lefttop, leftbottom, color-stop(0%,#eaeaea), color-stop(100%,#afafaf));background:-webkit-linear-gradient(top, #eaeaea 0%, #afafaf 100%);background:-o-linear-gradient(top, #eaeaea 0%, #afafaf 100%);background:-ms-linear-gradient(top, #eaeaea 0%, #afafaf 100%);background:linear-gradient(tobottom, #eaeaea 0%, #afafaf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eaeaea', endColorstr='#afafaf', GradientType=0);
49  }
50  h3 {display:inline-block;padding:5px 10px;color:#555;font-weight:bold;text-align:center;
51    border-radius:8px 8px 0 0;-moz-border-radius:8px 8px 0 0;-webkit-border-radius:8px 8px 0 0;
52    text-shadow:1px 1px 0 #bbb;-moz-text-shadow:1px 1px 0 #bbb;-webkit-text-shadow:1px 1px 0 #bbb;
53    background:#f2f2f2;background:-moz-linear-gradient(top, #f2f2f2 0%, #cecece 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%,#f2f2f2), color-stop(100%,#cecece));background:-webkit-linear-gradient(top, #f2f2f2 0%,#cecece 100%);background:-o-linear-gradient(top, #f2f2f2 0%,#cecece 100%);background:-ms-linear-gradient(top, #f2f2f2 0%,#cecece 100%);background:linear-gradient(to bottom, #f2f2f2 0%,#cecece 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f2f2', endColorstr='#cecece',GradientType=0 );
54  }
55
56  #the_header {border-bottom:1px solid #cdcdcd;margin-bottom:1px;}
57  #the_footer {background:#EAEAEA;border-top:1px solid #cdcdcd;padding:10px;clear:both;}
58
59  #the_methods {width:250px;float:left;border-style:solid;border-color:#cdcdcd;border-width:1px 1px 0 0;
60    background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAH0lEQVQImSXHMQEAMAwCMOrfK0jIjuVL2gLBzyHJtgd7wBdU3Vt/7AAAAABJRU5ErkJggg==);
61  }
62  #the_methods ul {font-size:1.1em;margin:5px 0 10px 10px;list-style:none;}
63  #the_methods li:before {content:"\203A\00A0";font-weight:bold;color:#EB9C39;font-size:1.1em;}
64  #the_methods li:hover:before {content:"\00A0\203A";}
65
66  #the_page {margin-left:252px;border-style:solid;border-color:#cdcdcd;border-width:1px 0 0 1px;}
67  #the_content {padding:10px;}
68
69  #methodParams {display:inline-block;}
70  #methodParams thead td {background:#DEE3E9;font-weight:bold;padding:2px 5px;}
71  #methodParams td {padding:2px;border:1px solid #cdcdcd;vertical-align:middle;}
72  #methodParams tbody tr:nth-child(even) {background:#f7f7f7;}
73  #methodParams tbody tr td:first-child {font-family:monospace;font-size:0.95em;}
74  #methodParams td.mini {width:0px;text-align:center;}
75  #methodParams tfoot {font-size:0.95em;}
76  #methodParams td.input {text-align:center;}
77  #methodParams td.input input[type="text"] {width:97%;font-size:0.9em;background:#f7f7f7;border:1px solid #ccc;
78    border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;
79  }
80  #methodParams td.input input[type="text"]:hover, #methodParams td.input input[type="text"]:focus {border-color:#C7E2F1;border-top-color:#96BCD7;background:#fff;}
81
82  #testForm {display:inline-block;margin-left:15px;}
83  #testForm td {padding:2px 0;}
84  #testForm tr:last-child td {padding:8px 0 5px 0;}
85  #testForm blockquote {width:200px;}
86 
87  #introMessage {font-size:1.1em;}
88  #urlForm {margin-bottom:10px;}
89
90  a.button {color:#fff;padding:3px 8px;border:1px solid #91bb5c;font-size:0.9em;margin-right:3px;display:inline-block;
91    border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;
92    text-shadow:1px 1px 0 #666;-moz-text-shadow:1px 1px 0 #666;-webkit-text-shadow:1px 1px 0 #666;
93    background:#84bb3c;background:-moz-linear-gradient(top, #84bb3c 0%, #3f5a1d 100%);background:-webkit-gradient(linear, lefttop, leftbottom, color-stop(0%,#84bb3c), color-stop(100%,#3f5a1d));background:-webkit-linear-gradient(top, #84bb3c 0%, #3f5a1d 100%);background:-o-linear-gradient(top, #84bb3c 0%, #3f5a1d 100%);background:-ms-linear-gradient(top, #84bb3c 0%, #3f5a1d 100%);background:linear-gradient(tobottom, #84bb3c 0%, #3f5a1d 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#84bb3c', endColorstr='#3f5a1d', GradientType=0);
94  }
95  a.button:hover {color:#E5FF00;}
96 
97  .methodInfo {float:right;display:inline-block;width:16px;height:16px;font-size:12px;line-height:16px;background:#555;border-radius:8px;font-family:"Times New Roman",sans-serif;font-style:italic;font-weight:bold;text-align:center;color:#fff;}
98  .methodInfo:hover {border:none;text-shadow:none;background:#888;cursor:pointer;color:#fff;}
99 
100  #iframeWrapper {width:100%;height:300px;padding:3px 3px 20px 3px;background:#F9F9F9;border:1px solid #cdcdcd;overflow:hidden;position:relative;}
101  iframe {width:100%;height:100%;background:#fff;}
102  </style>
103 
104</head>
105
106<body>
107
108<div id="the_header">
109  <h1>Piwigo web API (web-services) explorer</h1>
110</div> <!-- the_header -->
111
112<div id="the_methods">
113  <h2>Available methods</h2>
114 
115  <ul id="methodsList">
116  </ul>
117</div> <!-- the_methods -->
118
119<div id="the_page">
120  <h2 id="methodName" style="display:none;"></h2>
121  <h2 id="errorWrapper" style="display:none;"></h2>
122 
123  <div id="the_content">
124    <form id="urlForm" style="display:none;">
125      <input type="text" name="ws_url" size="60">
126      <input type="submit" value="Go!">
127    </form>
128   
129    <blockquote id="introMessage">
130      <p>
131        <b>API = Application Programming Interface.</b><br>
132        This is the way other applications can communicate with Piwigo. This feature is also know as Web Services.
133      </p>
134
135      <p>Examples:</p>
136      <ul>
137        <li>Wordpress (web blog software) can display random photos from a Piwigo gallery in its sidebar</li>
138        <li>Lightroom (photo management software for desktop) can create albums and upload photos to Piwigo</li>
139      </ul>
140
141      <p>
142        This page lists all API methods available on your Piwigo installation, part of the Piwigo core or added by third-party plugins.
143        For each method you can consult required and optional parameters, and even test them in direct live!
144      </p>
145
146      <p>
147        For more information you can consult our Wiki <a href="http://piwigo.org/doc/doku.php?id=dev:webapi:start" target="_blank">Piwigo Web API</a> and <a href="http://piwigo.org/forum" target="_blank">our forums</a>.
148      </p>
149    </blockquote> <!-- introMessage -->
150
151
152    <form id="methodWrapper" style="display:none;">
153      <div id="methodDescription" style="display:none;">
154        <h3>Description</h3>
155        <blockquote>
156        </blockquote>
157        <br>
158      </div> <!-- methodDescription -->
159     
160      <div id="methodParams">
161        <h3>Method parameters</h3>
162        <table>
163          <thead>
164            <tr>
165              <td style="width:150px;">Name</td>
166              <td class="mini">Extra</td>
167              <td style="width:300px;">Value</td>
168              <td class="mini">Send</td>
169            </tr>
170          </thead>
171         
172          <tbody>
173          </tbody>
174         
175          <tfoot>
176            <tr>
177              <td colspan="4"><b>*</b>: required parameter, <b>?</b>: optional parameter, <b>[]</b>: parameter can be an array (use a pipe | to split values)</td>
178            </tr>
179          </tfoot>
180        </table>
181      </div> <!-- methodParams -->
182     
183      <div id="testForm">
184        <h3>Test</h3>
185        <blockquote>
186          <table>
187            <tr>
188              <td>Request format :</td>
189              <td>
190                <select id="requestFormat">
191                  <option value="get" selected="selected">GET</option>
192                  <option value="post">POST</option>
193                </select>
194              </td>
195            </tr>
196            <tr>
197              <td>Response format :</td>
198              <td>
199                <select id="responseFormat">
200                  <option value="rest" selected="selected">REST (xml)</option>
201                  <option value="json">JSON</option>
202                  <option value="php">PHP serial</option>
203                  <option value="xmlrpc">XML RPC</option>
204                </select>
205              </td>
206            </tr>
207            <tr>
208              <td colspan="2">
209                <a href="#" class="button" id="invokeMethod">INVOKE</a>
210                <a href="#" class="button" id="invokeMethodBlank">INVOKE (new window)</a>
211              </td>
212            </tr>
213          </table>
214        </blockquote>
215      </div> <!-- testForm -->
216     
217      <br><br>
218     
219      <h3>Result</h3>
220      <div id="iframeWrapper">
221        <iframe src="" id="invokeFrame" name="invokeFrame"></iframe>
222        <a href="#bottom" id="increaseIframe"><b>&darr;</b> increase height</a> &#8226; <a href="#bottom" id="decreaseIframe"><b>&uarr;</b> decrease height</a>
223        <a name="bottom"></a>
224      </div>
225    </form> <!-- iframeWrapper -->
226   
227    <!-- hidden form for POST submition -->
228    <form method="post" action="" target="" id="invokeForm" style="display:none;"></form>
229   
230  </div> <!-- the_content -->
231
232</div> <!-- the_page -->
233
234<div id="the_footer">
235  Copyright &copy; 2002-2013 <a href="http://piwigo.org">Piwigo Team</a>
236</div> <!-- the_footer -->
237
238
239<script type="text/javascript"> 
240// global vars
241var cachedMethods = new Array;
242var ws_url = "http://";
243
244// automatic detection of ws_url
245match = document.location.toString().match(/^(https?.*\/)tools\/ws\.html?/);
246if (match==null) {
247  askForUrl();
248}
249else {
250  ws_url = match[1]+'ws.php';
251  getMethodList();
252}
253
254// manual set of ws_url
255$("#urlForm").submit(function() {
256  ws_url = $(this).children("input[name='ws_url']").val();
257  getMethodList();
258  return false;
259});
260
261// invoke buttons
262$("#invokeMethod").click(function() {
263  invokeMethod($("#methodName").html(), false);
264  return false;
265});
266$("#invokeMethodBlank").click(function() {
267  invokeMethod($("#methodName").html(), true);
268  return false;
269});
270
271// resizable iframe
272$("#increaseIframe").click(function() {
273  $("#iframeWrapper").css('height', $("#iframeWrapper").height()+100);
274  adaptHeight();
275});
276$("#decreaseIframe").click(function() {
277  if ($("#iframeWrapper").height() > 200) {
278    $("#iframeWrapper").css('height', $("#iframeWrapper").height()-100);
279    adaptHeight();
280  }
281});
282
283// mask all wrappers
284function resetDisplay() {
285  $("#errorWrapper").hide();
286  $("#methodWrapper").hide();
287  $("#methodName").hide();
288  $("#urlForm").hide();
289  $("#methodDescription").hide();
290  $("#invokeFrame").attr('src','');
291}
292
293// give the same size to methods list and main page
294function adaptHeight()
295{
296  $("#the_page").css('height', 'auto');
297  $("#the_methods").css('height', 'auto');
298 
299  min_h = $(window).height()-$("#the_header").outerHeight()-$("#the_footer").outerHeight()-3;
300  h = Math.max(min_h, Math.max($("#the_methods").height(), $("#the_page").height()));
301 
302  $("#the_page").css('height', h);
303  $("#the_methods").css('height', h);
304}
305
306// display error wrapper
307function displayError(error) {
308  resetDisplay();
309  $("#errorWrapper").html("<b>Error:</b> "+ error).show();
310  adaptHeight();
311}
312
313// display ws_url form
314function askForUrl() {
315  if ($("#urlForm input[name='ws_url']").val() == "") {
316    $("#urlForm input[name='ws_url']").val(ws_url);
317  }
318  $("#urlForm").show();
319  displayError("can't contact web-services, please give absolute url to 'ws.php'");
320}
321
322// parse Piwigo JSON
323function parsePwgJSON(json) {
324  try {
325    resp = jQuery.parseJSON(json);
326    if (resp==null | resp.result==null | resp.stat==null | resp.stat!='ok') {
327      throw new Error();
328    }
329  }
330  catch(e) {
331    displayError("unable to parse JSON string");
332    resp = {"stat": "ko", "result": "null"};
333  }
334 
335  return resp.result;
336}
337
338// fetch methods list
339function getMethodList() {
340  resetDisplay();
341 
342  $.ajax({
343    type: "GET",
344    url: ws_url,
345    data: { format: "json", method: "reflection.getMethodList" }
346  }).done(function(result) {
347    result = parsePwgJSON(result);
348   
349    if (result!=null) {
350      methods = result.methods;
351     
352      var ml = '';
353      for (var i=0; i<methods.length; i++)
354      {
355        ml += '<li><a href="#">'+ methods[i]+'</a></li>';
356      }
357      $("#methodsList").html(ml).show();
358     
359      adaptHeight();
360     
361      // trigger method selection
362      $("#methodsList li a").click(function() {
363        selectMethod($(this).html());
364        return false;
365      });
366    }
367  }).error(function(jqXHR, textStatus, errorThrown) {
368    askForUrl();
369  });
370}
371
372// select method
373function selectMethod(methodName) {
374  $("#introMessage").hide();
375 
376  if (cachedMethods[ methodName ]) {
377    fillNewMethod(methodName);
378  }
379  else {
380    $.ajax({
381      type: "GET",
382      url: ws_url,
383      data: { format: "json", method: "reflection.getMethodDetails", methodName: methodName }
384    }).done(function(result) { 
385      result = parsePwgJSON(result);
386   
387      if (result!=null) {
388        cachedMethods[ methodName ] = result;
389        fillNewMethod(methodName);
390      }
391    }).error(function(jqXHR, textStatus, errorThrown) {
392      displayError("unknown error");
393    });
394  }
395}
396
397// display method details
398function fillNewMethod(methodName) {
399  resetDisplay();
400 
401  method = cachedMethods[ methodName ];
402 
403  $("#methodName").html(method.name).show();
404 
405  if (method.description != "") {
406    $("#methodDescription blockquote").html(method.description);
407    $("#methodDescription").show();
408  }
409 
410  var methodParams = '';
411  if (method.params && method.params.length>0) {
412    for (var i=0; i<method.params.length; i++) {
413      var isOptional = method.params[i].optional;
414      var acceptArray = method.params[i].acceptArray;
415      var defaultValue = method.params[i].defaultValue == null ? '' : method.params[i].defaultValue;
416      var info = method.params[i].info == null ? '' : '<a class="methodInfo" title="'+ method.params[i].info + '">i</a>';
417     
418      // if an array is direclty printed, the delimiter is a comma where we use a pipe
419      if (typeof defaultValue == 'object') {
420        defaultValue = defaultValue.join('|');
421      }
422
423      methodParams+= '<tr>'+
424        '<td>'+ method.params[i].name + info +'</td>'+
425        '<td class="mini">'+ (isOptional ? '?':'*') + (acceptArray ? ' []':'') +'</td>'+
426        '<td class="input"><input type="text" class="methodParameterValue" data-id="'+ i +'" value="'+ defaultValue +'"></td>'+
427        '<td class="mini"><input type="checkbox" class="methodParameterSend" data-id="'+ i +'" '+ (isOptional ? '':'checked="checked"') +'></td>'+
428      '</tr>';
429    }
430        }
431  else {
432    methodParams = '<tr><td colspan="4">This method takes no parameters</td></tr>';
433  }
434 
435  $("#methodParams tbody").html(methodParams);
436  $("#methodWrapper").show(); 
437 
438  adaptHeight();
439 
440  // trigger field modification
441  $("input.methodParameterValue").change(function() {
442    $("input.methodParameterSend[data-id='"+ $(this).data('id') +"']").attr('checked', 'checked');
443  });
444 
445  // tiptip
446  $(".methodInfo").tipTip({
447    activation:"click",
448    maxWidth:"300px",
449    defaultPosition:"right",
450    delay:0
451  });
452}
453
454// invoke method
455function invokeMethod(methodName, newWindow) {
456        var method = cachedMethods[ methodName ];
457
458  var reqUrl = ws_url +"?format="+ $("#responseFormat").val();
459 
460  // GET
461  if ($("#requestFormat").val() == 'get') {
462    reqUrl+= "&method="+ methodName;
463   
464    for (var i=0; i<method.params.length; i++) {
465      if (! $("input.methodParameterSend[data-id='"+ i +"']").is(":checked")) {
466        continue;
467      }
468
469      var paramValue = $("input.methodParameterValue[data-id='"+ i +"']").val();
470     
471      var paramSplitted = paramValue.split('|');
472      if (method.params[i].acceptArray &&  paramSplitted.length > 1) {
473        $.each(paramSplitted, function(v) {
474          reqUrl+= '&'+ method.params[i].name +'[]='+ paramSplitted[v];
475        });
476      }
477      else {
478        reqUrl+= '&'+ method.params[i].name +'='+ paramValue;
479      }
480    }
481   
482    if (newWindow) {
483      window.open(reqUrl);
484    }
485    else {
486      $("#invokeFrame").attr('src', reqUrl);
487    }
488  }
489  // POST
490  else {
491    var form = $("#invokeForm");
492    form.attr('action', reqUrl);
493   
494    var t = '<input type="hidden" name="method" value="'+ methodName +'">';
495   
496    for (var i=0; i<method.params.length; i++) {
497      if (! $("input.methodParameterSend[data-id='"+ i +"']").is(":checked")) {
498        continue;
499      }
500
501      var paramValue = $("input.methodParameterValue[data-id='"+ i +"']").val();
502
503      var paramSplitted = paramValue.split('|');
504      if (method.params[i].acceptArray &&  paramSplitted.length > 1) {
505        $.each(paramSplitted, function(v) {
506          t+= '<input type="hidden" name="'+ method.params[i].name +'[]" value="'+ paramSplitted[v] +'">';
507        });
508      }
509      else {
510        t+= '<input type="hidden" name="'+ method.params[i].name +'" value="'+ paramValue +'">';
511      }
512    }
513   
514    form.html(t);
515    form.attr('target', newWindow ? "_blank" : "invokeFrame");
516    form.submit();
517  }
518 
519  return false;
520}
521</script>
522
523</body>
524</html>
Note: See TracBrowser for help on using the repository browser.