1 //
  2 // The Antville Project
  3 // http://code.google.com/p/antville
  4 //
  5 // Copyright 2001-2007 by The Antville People
  6 //
  7 // Licensed under the Apache License, Version 2.0 (the ``License'');
  8 // you may not use this file except in compliance with the License.
  9 // You may obtain a copy of the License at
 10 //
 11 //    http://www.apache.org/licenses/LICENSE-2.0
 12 //
 13 // Unless required by applicable law or agreed to in writing, software
 14 // distributed under the License is distributed on an ``AS IS'' BASIS,
 15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 16 // See the License for the specific language governing permissions and
 17 // limitations under the License.
 18 //
 19 // $Revision$
 20 // $LastChangedBy$
 21 // $LastChangedDate$
 22 // $URL$
 23 //
 24 
 25 /**
 26  * @fileOverview Defines the Api prototype.
 27  */
 28 
 29 /**
 30  * 
 31  * @param {Site} site
 32  * @param {User} user
 33  */
 34 Api.constrain = function(site, user) {
 35    res.handlers.site = site;
 36    res.handlers.membership = Membership.getByName(user.name);
 37    return;
 38 }
 39 
 40 /** @ignore */
 41 Api.dispatch = function() {
 42 }
 43 
 44 /**
 45  * 
 46  * @param {String} name
 47  * @param {String} password
 48  * @throws {Error}
 49  * @returns {User} 
 50  */
 51 Api.getUser = function(name, password) {
 52    var user = User.getByName(name);
 53    if (!user) {
 54       throw Error("User " + name + " does not exist on this server");
 55    } else if (user.hash !== String(password + user.salt).md5()) {
 56       throw Error("Authentication failed for user " + name);
 57    } else if (user.status === User.BLOCKED) {
 58       throw Error("The user account " + name + " is currently blocked");
 59    }
 60    // FIXME: This was commented out after Story.add() et al. were added
 61    //session.login(user);
 62    return user;
 63 }
 64 
 65 /**
 66  * 
 67  * @param {String} name
 68  * @throws {Error}
 69  * @returns {Site}
 70  */
 71 Api.getSite = function(name) {
 72    var site = Site.getByName(String(name));
 73    if (!site) {
 74       throw Error("Site " + name + " does not exist on this server");
 75    } else if (site.status === Site.BLOCKED) {
 76       throw Error("The site " + name + " is blocked");
 77    }
 78    return site;
 79 }
 80 
 81 /**
 82  * 
 83  * @param {Number} id
 84  * @throws {Error}
 85  * @returns {Story}
 86  */
 87 Api.getStory = function(id) {
 88    var story = Story.getById(id);
 89    if (!story) {
 90       throw Error("Story #" + id + " does not exist on this server");
 91    }
 92    return story;
 93 }
 94 
 95 /**
 96  * @name Api
 97  * @constructor
 98  * @extends HopObject
 99  */
100 
101 /**
102  * @returns {Boolean}
103  */
104 Api.prototype.getPermission = function(){
105    return true;
106 }
107 
108 Api.prototype.main_action = function() {
109    res.data.title = gettext("Application Programming Interfaces");
110    res.data.body = this.renderSkinAsString("$Api#main");
111    res.handlers.site.renderSkin("Site#page");
112    return;
113 }
114 
115 Api.prototype.callback_action = function() {
116    var ping = function(data) {
117       if (data.type !== "Story" && data.type !== "Comment") {
118          return;
119       }
120       var remote = new Remote("http://rpc.weblogs.com/RPC2");
121       var call = remote.weblogUpdates.ping(data.site, data.origin);
122       if (call.error || call.result.flerror) {
123          app.debug("Error invoking weblogs.com ping() method for " + 
124                data.site + ": " + call.error || call.result.message);
125       } else {
126          app.debug(call.result);
127       }
128       return;
129    };
130 
131    if (req.isGet()) {
132       res.data.title = gettext("Default Callback Url");
133       res.data.body = this.renderSkinAsString("$Api#callback", 
134             {name: req.action, code: ping.toString()});
135       res.handlers.site.renderSkin("Site#page");
136    } else if (req.isPost()) {
137       app.debug("Invoked default callback with POST params: " + req.postParams);
138       app.invokeAsync(this, ping, [req.postParams], 1000);
139    }
140    return;
141 }
142 
143 /**
144  * 
145  * @param {String} methodName
146  * @throws {Error}
147  */
148 Api.prototype.main_action_xmlrpc = function(methodName) {
149    if (!methodName) {
150       return false;
151    } 
152    var parts = methodName.split(".");
153    var method = parts[1];
154    if (method && !method.startsWith("_")) {
155       var handler = Api[parts[0]];
156       if (handler && handler[method]) {
157          var args = Array.prototype.splice.call(arguments, 1);
158          return handler[method].apply(null, args);
159       }
160    }
161    throw Error("Method " + methodName + "() is not implemented");
162    return;
163 }
164 
165 /**
166  *
167  * @param {String} name
168  */
169 Api.prototype.getChildElement = function(name) {
170    if (name === "json") {
171       var flexiPath = new FlexiPath(name, this);
172       
173       flexiPath.addUrlPattern("/1/users/show/(.+).json$", function(path, name) {
174          var id = parseInt(name, 10);
175          var user = User.getById(id);
176          res.write({
177             id: id,
178             name: user.name
179          }.toJSON());
180          return;
181       });
182 
183       flexiPath.addUrlPattern("/1/users/update/$", function() {
184          app.log(res.cookies);
185          var user = User.getByName(req.data.name);
186          if (!user) {
187             user = User.register(req.data);
188          }
189          res.write({
190             id: user._id,
191             name: user.name
192          }.toJSON());
193          return;
194       });
195 
196       return flexiPath;
197       //: "updateUser"
198    }
199    return this.get(name);
200 }
201