Permalink
Browse files

PhoneGap wrapper around Shopify4J to make authenticated API calls

to the Shopify API from Javascript
  • Loading branch information...
jiblits committed Oct 8, 2011
1 parent d940919 commit 94d165c3d87e7c8360e4fdc181b125a16f33df91
Showing with 279 additions and 0 deletions.
  1. +100 −0 Android/ShopGap/README.md
  2. +138 −0 Android/ShopGap/ShopGapPlugin.java
  3. +41 −0 Android/ShopGap/shopgap.js
View
@@ -0,0 +1,100 @@
+# ShopGap plugin for Android/Phonegap
+
+Chris Saunders // @csaunders
+
+## About
+
+ShopGap is a wrapper around [Shopify4J](http://github.com/shopify/Shopify4J) to allow you to make Authenticated API calls to the Shopify API.
+
+## Dependencies
+
+You will need to include Shopify4J and all of it's dependencies in your project in order for this tool to work. This should be as simple as adding Shopify4J as a Library in your Android configuration.
+
+## Using the plugin
+
+**This has been developed against PhoneGap 1.1.0**
+
+* Add java code to your projects source
+
+* Register the plugin in the plugins.xml file
+
+```xml
+<plugin name="ShopGapPlugin" value="ca.christophersaunders.shopgap.ShopGapPlugin" />
+```
+
+* Setup your authenticated session with the Shopify API
+
+```javascript
+window.plugins.shopGap.setup(
+ 'YOUR_API_KEY',
+ 'GENERATED_API_PASSWORD',
+ 'SHOP_NAME',
+ successFunctionOrNull,
+ failureFunctionOrNull
+);
+```
+
+* Make calls to the Shopify API
+
+```javascript
+var success = function(resultJson){
+ console.log(JSON.stringify(resultJson));
+}
+
+window.plugins.shopGap.read(
+ 'products', // endpoint
+ null, // query -- not supported yet
+ null, // data -- not needed for GET requests
+ function(r){success(r);}, // success callback
+ function(e){console.log}); // failure callback
+```
+
+### Endpoints
+
+The plugin takes care of most of the work for the endpoints, all you need to
+do is fill in a few missing pieces.
+
+```javascript
+// get all products,
+window.plugins.shopGap.read('products', null, null, s, f);
+
+// get product 1
+window.plugins.shopGap.read('products/1', null, null, s, f);
+
+// create product
+window.plugins.shopGap.create('products', null, JSON.stringify(newProduct), s, f);
+
+// update product 1
+window.plugins.shopGap.update('products/1', null, JSON.stringify(updateProduct), s, f);
+
+// delete product 1
+window.plugins.shopGap.destry('products/1', null, null, s, f);
+```
+
+## Release Notes
+
+0.1.0 Initial Release
+
+## License
+
+The MIT License
+
+Copyright (c) 2011 Chris Saunders
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
@@ -0,0 +1,138 @@
+package ca.christophersaunders.shopgap;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.phonegap.api.Plugin;
+import com.phonegap.api.PluginResult;
+import com.phonegap.api.PluginResult.Status;
+import com.shopify.api.client.ShopifyClient;
+import com.shopify.api.credentials.Credential;
+import com.shopify.api.endpoints.JsonPipeService;
+
+public class ShopGapPlugin extends Plugin {
+ private static final String API_KEY = "apikey";
+ private static final String PASSWORD = "password";
+ private static final String SHOPNAME = "shopname";
+ private static final String CALL = "call";
+ private static final String ENDPOINT = "endpoint";
+ private static final String QUERY = "query";
+ private static final String DATA = "data";
+
+ private ShopifyClient client;
+ private JsonPipeService service;
+
+ enum Methods { CALL_API, SETUP };
+ enum Call { READ, CREATE, UPDATE, DESTROY };
+
+ @Override
+ public PluginResult execute(String func, JSONArray arguments, String callbackId) {
+ try {
+ JSONObject argsMap = arguments.getJSONObject(0);
+ switch(determineMethod(func)) {
+ case CALL_API:
+ JSONObject results = callAPI(determineCall(argsMap.getString(CALL)), argsMap);
+ return new PluginResult(Status.OK, results);
+ case SETUP:
+ if(setupClient(argsMap)) {
+ return new PluginResult(Status.OK);
+ }
+ break;
+ default:
+ return new PluginResult(PluginResult.Status.INVALID_ACTION);
+ }
+ } catch (JSONException e) {
+ // Trololololololo
+ return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
+ }
+ return null;
+ }
+
+ private Methods determineMethod(String name){
+ if(name.equals("callapi"))
+ return Methods.CALL_API;
+ if(name.equals("setup"))
+ return Methods.SETUP;
+ return null;
+ }
+
+ private Call determineCall(String callname) {
+ if(callname.equals("read"))
+ return Call.READ;
+ if (callname.equals("update"))
+ return Call.UPDATE;
+ if (callname.equals("create"))
+ return Call.CREATE;
+ if (callname.equals("destroy"))
+ return Call.DESTROY;
+ return null;
+ }
+
+ private boolean setupClient(JSONObject args) throws JSONException {
+ if (args.has(API_KEY) && args.has(PASSWORD) && args.has(SHOPNAME)) {
+ String apiKey = args.getString(API_KEY);
+ String passwd = args.getString(PASSWORD);
+ String shop = args.getString(SHOPNAME);
+
+ Credential cred = new Credential(apiKey, "", shop, passwd);
+ client = new ShopifyClient(cred);
+ service = client.constructService(JsonPipeService.class);
+ return true;
+ }
+ return false;
+ }
+
+ private JSONObject callAPI(Call call, JSONObject args) {
+ try {
+ String endpoint = null, data = null, query = null;
+ if(args.has(ENDPOINT))
+ endpoint = args.getString(ENDPOINT);
+ if(args.has(QUERY))
+ query = args.getString(QUERY);
+ if(args.has(DATA))
+ data = args.getString(DATA);
+
+ InputStream result = null;
+
+ switch(call) {
+ case CREATE:
+ result = service.create(endpoint, data);
+ break;
+ case READ:
+ result = service.read(endpoint);
+ break;
+ case UPDATE:
+ result = service.update(endpoint, data);
+ break;
+ case DESTROY:
+ result = service.destroy(endpoint);
+ break;
+ }
+
+ if( result != null) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ BufferedInputStream bis = new BufferedInputStream(result);
+ byte[] resultData = new byte[0x4000];
+ int dataRead = 0;
+ while((dataRead = bis.read(resultData)) > 0) {
+ baos.write(resultData, 0, dataRead);
+ }
+ return new JSONObject(new String(baos.toByteArray()));
+ }
+
+ } catch (JSONException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return new JSONObject();
+ }
+
+}
View
@@ -0,0 +1,41 @@
+var ShopGap = function(){};
+
+ShopGap.prototype.setup = function(apiKey, password, shopname, onSuccessFn, onFailureFn){
+ var args = {'apikey': apiKey, 'password': password, 'shopname': shopname};
+ return PhoneGap.exec(onSuccessFn, onFailureFn, 'ShopGapPlugin', 'setup', [args]);
+};
+
+ShopGap.prototype.consArgs = function(call, endpoint, query, data){
+ return {call: call, endpoint: endpoint, query: query, data: data};
+};
+
+ShopGap.prototype.read = function(endpoint, query, data, success, failure){
+ return this.callapi(this.consArgs('read', endpoint, query, data), success, failure);
+};
+
+ShopGap.prototype.update = function(endpoint, query, data, success, failure){
+ return this.callapi(this.consArgs('update', endpoint, query, data), success, failure);
+};
+
+ShopGap.prototype.create = function(endpoint, query, data, success, failure){
+ return this.callapi(this.consArgs('create', endpoint, query, data), success, failure);
+};
+
+ShopGap.prototype.destroy = function(endpoint, query, data, success, failure){
+ return this.callapi(this.consArgs('destroy', endpoint, query, data), success, failure);
+};
+
+ShopGap.prototype.callapi = function(args, onSuccessFn, onFailureFn){
+ return PhoneGap.exec(onSuccessFn, onFailureFn, 'ShopGapPlugin', 'callapi', [args]);
+};
+
+/*
+ShopGap.prototype.callapi = function(call, endpoint, query, data, onSuccessFn, onFailureFn){
+ var args = {'endpoint': endpoint, 'data': data, 'query': query};
+ return PhoneGap.exec(onSuccessFn, onFailureFn, 'ShopGapPlugin', 'callapi', [args]);
+};
+*/
+
+PhoneGap.addConstructor(function(){
+ PhoneGap.addPlugin('shopGap', new ShopGap());
+});

0 comments on commit 94d165c

Please sign in to comment.