fanforce 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
19
+ .DS_Store
20
+ .idea/
21
+ .idea/*
data/.rbenv-gemsets ADDED
@@ -0,0 +1 @@
1
+ gemset-fanforce-ruby
data/.rbenv-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p194
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "http://rubygems.org"
2
+ gemspec
3
+
4
+ gem 'multi_json'
5
+ gem 'rest-client'
6
+
7
+ group :development, :test do
8
+ gem 'rake'
9
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ fanforce (0.1.1)
5
+ multi_json
6
+ rest-client
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ mime-types (1.19)
12
+ multi_json (1.3.6)
13
+ rake (0.9.2.2)
14
+ rest-client (1.6.7)
15
+ mime-types (>= 1.16)
16
+
17
+ PLATFORMS
18
+ ruby
19
+
20
+ DEPENDENCIES
21
+ fanforce!
22
+ multi_json
23
+ rake
24
+ rest-client
data/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Caleb Clark
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,17 @@
1
+ ## Install
2
+
3
+ Via rubygems.org:
4
+
5
+ ```
6
+ $ gem install fanforce
7
+ ```
8
+
9
+ To build and install the development branch yourself from the latest source:
10
+
11
+ ```
12
+ $ git clone git@github.com:mlabs/fanforce-ruby.git
13
+ $ cd fanforce-ruby
14
+ $ git checkout master
15
+ $ rake gem
16
+ $ gem install pkg/fanforce-ruby-{version}
17
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/ext/extconf.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'mkmf'
2
+
3
+ #$CFLAGS = "-Wall -Werror -Wextra"
4
+
5
+ extension_name = 'pr_query_parser'
6
+ dir_config(extension_name)
7
+
8
+ have_library('curl', 'curl_easy_unescape')
9
+ create_makefile(extension_name)
@@ -0,0 +1,137 @@
1
+ #include "ruby.h"
2
+
3
+ #include <stdio.h>
4
+ #include <ctype.h>
5
+ #include <curl/curl.h>
6
+
7
+ static void
8
+ pr_set_param(VALUE params, char *key, char *value)
9
+ {
10
+ VALUE rkey, rvalue, cur;
11
+ char *v;
12
+
13
+ /* no key do nothing */
14
+ if (key == NULL || *key == 0) return;
15
+
16
+ /* strip [] from the key name */
17
+ v = curl_easy_unescape(NULL, key, 0, NULL);
18
+ if (strlen(v) > 2)
19
+ {
20
+ char *t = v;
21
+ char *open_bracket = NULL;
22
+
23
+ while (*(t + 1) != 0)
24
+ {
25
+ if (*t == '[') open_bracket = t;
26
+ t++;
27
+ }
28
+
29
+ if ((*t == ']') && (open_bracket != NULL))
30
+ {
31
+ char *pos = (open_bracket + 1);
32
+ int is_digit = 1;
33
+
34
+ while (pos != t)
35
+ {
36
+ if (!isdigit(*pos))
37
+ {
38
+ is_digit = 0;
39
+ break;
40
+ }
41
+ pos ++;
42
+ }
43
+
44
+ if ((*t == ']') && (*(t - 1) == '['))
45
+ {
46
+ *(t - 1) = 0;
47
+ }
48
+ else if ((*t == ']') && (*open_bracket == '[') && is_digit)
49
+ {
50
+ *open_bracket = 0;
51
+ }
52
+ }
53
+ }
54
+
55
+ /* key was only [], do nothing */
56
+ if (v == NULL || *v == 0) return;
57
+
58
+ rkey = rb_str_new2(v);
59
+ free(v);
60
+
61
+ v = curl_easy_unescape(NULL, value, 0, NULL);
62
+ rvalue = rb_str_new2(v);
63
+ free(v);
64
+
65
+ cur = rb_hash_aref(params, rkey);
66
+ if (NIL_P(cur))
67
+ {
68
+ rb_hash_aset(params, rkey, rvalue);
69
+ }
70
+ else
71
+ {
72
+ VALUE arry;
73
+ if (rb_obj_is_kind_of(cur, rb_cArray) == Qtrue)
74
+ {
75
+ arry = cur;
76
+ }
77
+ else
78
+ {
79
+ arry = rb_ary_new();
80
+ rb_ary_push(arry, cur);
81
+ rb_hash_aset(params, rkey, arry);
82
+ }
83
+ rb_ary_push(arry, rvalue);
84
+ }
85
+ }
86
+
87
+ VALUE
88
+ pr_query_parser(VALUE self, VALUE query_string, VALUE delim)
89
+ {
90
+ VALUE params = Qnil;
91
+ char *qs, *p, *s, *key = NULL;
92
+ char delimiter = RSTRING_PTR(delim)[0];
93
+
94
+ params = rb_hash_new();
95
+ qs = strdup(RSTRING_PTR(query_string));
96
+ for (s = qs, p = qs; *p != 0; p++)
97
+ {
98
+ if (*p == delimiter)
99
+ {
100
+ *p = 0;
101
+ if (key != NULL)
102
+ {
103
+ pr_set_param(params, key, s);
104
+ key = NULL;
105
+ }
106
+ else
107
+ {
108
+ pr_set_param(params, s, s);
109
+ }
110
+ s = (p + 1);
111
+ }
112
+ else if ((*p == '=') && (key == NULL))
113
+ {
114
+ *p = 0;
115
+ key = s;
116
+ s = (p + 1);
117
+ }
118
+ }
119
+
120
+ if (s != NULL)
121
+ {
122
+ if (key != NULL) pr_set_param(params, key, s);
123
+ else pr_set_param(params, s, s);
124
+ }
125
+ free(qs);
126
+
127
+ return params;
128
+ self = self;
129
+ }
130
+
131
+ void
132
+ Init_pr_query_parser(void)
133
+ {
134
+ VALUE QueryStringParser = rb_define_module("QueryStringParser");
135
+
136
+ rb_define_module_function(QueryStringParser, "pr_query_parser", pr_query_parser, 2);
137
+ }
data/fanforce.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "fanforce/version"
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "fanforce"
8
+ gem.version = Fanforce::VERSION
9
+ gem.date = '2012-10-19'
10
+ gem.summary = %q{Ruby API wrapper for Fanforce}
11
+ gem.description = %q{Ruby API wrapper that interfaces with all six Fanforce APIs.}
12
+ gem.authors = ["Caleb Clark"]
13
+ gem.email = ["cclark@fanforce.com"]
14
+ gem.homepage = "http://github.com/mlabs/fanforce-ruby"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.extensions = ["ext/extconf.rb", "ext/extconf.rb"]
20
+ gem.require_paths = ["lib"]
21
+
22
+ gem.add_development_dependency 'rake'
23
+ gem.add_runtime_dependency 'rest-client'
24
+ gem.add_runtime_dependency 'multi_json'
25
+ end
@@ -0,0 +1,14 @@
1
+ class Fanforce
2
+ SERVERS = {
3
+ dev: 'api.fanforce.gg',
4
+ qa: 'api.fanforce.us',
5
+ prod: 'api.fanforce.com'
6
+ }
7
+
8
+ TEST_ACCOUNT = {
9
+ _id: '',
10
+ _slug: '',
11
+ _password: '',
12
+ _api_key: ''
13
+ }
14
+ end
@@ -0,0 +1,39 @@
1
+ class Fanforce
2
+ class Error < StandardError;
3
+ def initialize(response, request, path, query_params)
4
+ @query_params = query_params
5
+ @path = path
6
+ @request = request
7
+ begin
8
+ @response = MultiJson.load(response, :symbolize_keys => symbolize_keys)
9
+ rescue
10
+ @response = response
11
+ end
12
+ @request_url = "#{@path}?#{@query_params.to_param}"
13
+ super(@response.is_a?(Hash) ? @response[:message] : @response)
14
+ end
15
+ attr :path, :query_params, :request, :response, :request_url
16
+
17
+ def curl_command
18
+ case @request.method
19
+ when :get
20
+ "curl \"#{@path}?#{@query_params.to_param}\""
21
+ when :post
22
+ "curl -X POST -d \"#{@query_params.to_param}\" #{@path}"
23
+ when :put
24
+ "curl -X PUT -d \"#{@query_params.to_param}\" #{@path.to_json}"
25
+ when :delete
26
+ "curl --request DELETE \"#{@path}?#{@query_params.to_param}\""
27
+ else
28
+ "Could not create curl command because request method was unknown: #{@request.method}"
29
+ end
30
+ end
31
+ def code() end
32
+ end
33
+
34
+ class BadRequestError < Error; def code() 400 end end
35
+ class ForbiddenError < Error; def code() 403 end end
36
+ class NotFoundError < Error; def code() 404 end end
37
+ class UnprocessableEntityError < Error; def code() 422 end end
38
+ class UnknownError < Error; def code() 500 end end
39
+ end
@@ -0,0 +1,117 @@
1
+ require 'fanforce/errors'
2
+ require 'fanforce/utils'
3
+
4
+ class Fanforce
5
+
6
+ ########################################################################
7
+ def initialize(auth_key_or_hash=nil)
8
+ auth(auth_key_or_hash) if auth_key_or_hash.present?
9
+ end
10
+
11
+ def get(path, requestParams={})
12
+ path = complete_path(path)
13
+ query = apply_auth(requestParams)
14
+ RestClient.get(path, {:params => query, :accept => :json}) do |response, request, result, &block|
15
+ handle_response(response, request, path, query)
16
+ end
17
+ end
18
+
19
+ def post(path, requestParams={})
20
+ path = complete_path(path)
21
+ query = apply_auth(requestParams)
22
+ RestClient.post(path, query, {:accept => :json}) do |response, request, result, &block|
23
+ handle_response(response, request, path, query)
24
+ end
25
+ end
26
+
27
+ def put(path, requestParams={})
28
+ path = complete_path(path)
29
+ query = apply_auth(requestParams)
30
+ RestClient.put(path, query, {:accept => :json}) do |response, request, result, &block|
31
+ handle_response(response, request, path, query)
32
+ end
33
+ end
34
+
35
+ def delete(path, requestParams={})
36
+ path = complete_path(path)
37
+ query = apply_auth(requestParams)
38
+ RestClient.delete(path, {:query => query, :accept => :json}) do |response, request, result, &block|
39
+ handle_response(response, request, path, query)
40
+ end
41
+ end
42
+
43
+ def handle_response(response, request, path, query)
44
+ case response.code
45
+ when 200, 201
46
+ begin
47
+ response = MultiJson.load(response, :symbolize_keys => symbolize_keys)
48
+ rescue
49
+ raise UnknownError.new(response, request, path, query)
50
+ end
51
+ when 400
52
+ raise BadRequestError.new(response, request, path, query)
53
+ when 403
54
+ raise ForbiddenError.new(response, request, path, query)
55
+ when 404
56
+ raise NotFoundError.new(response, request, path, query)
57
+ when 422
58
+ raise UnprocessableEntityError.new(response, request, path, query)
59
+ else
60
+ raise UnknownError.new(response, request, path, query)
61
+ end
62
+ response
63
+ end
64
+
65
+ def auth(auth_key_or_hash=nil)
66
+ if auth_key_or_hash.present?
67
+ key = auth_key_or_hash.is_a?(Hash) ? auth_key_or_hash.symbolize_keys[:key] : auth_key_or_hash
68
+ @auth_hash = {key: key} if key.present?
69
+ end
70
+ @auth_hash
71
+ end
72
+
73
+ def valid_auth?
74
+ @auth_hash.present? and @auth_hash[:key].present?
75
+ end
76
+
77
+ def apply_auth(params)
78
+ params.merge(@auth_hash || {})
79
+ end
80
+
81
+ def complete_path(path)
82
+ 'http://' + $API_DOMAIN + path
83
+ end
84
+
85
+ def is_valid_install_request(params)
86
+ Utils.is_valid_install_request(params)
87
+ end
88
+
89
+ def is_invalid_install_request(params)
90
+ !is_valid_install_request(params)
91
+ end
92
+
93
+ def is_valid_uninstall_request(params)
94
+ Utils.is_valid_uninstall_request(params)
95
+ end
96
+
97
+ def is_invalid_uninstall_request(params)
98
+ !is_valid_uninstall_request(params)
99
+ end
100
+
101
+ def is_valid_request(params)
102
+ Utils.is_valid_request(params)
103
+ end
104
+
105
+ def is_invalid_request(params)
106
+ !is_valid_request(params)
107
+ end
108
+
109
+ def parse_params(params)
110
+ Utils.parse_params(params)
111
+ end
112
+
113
+ def parse_url(raw_url)
114
+ Utils.parse_url(raw_url)
115
+ end
116
+
117
+ end
@@ -0,0 +1,85 @@
1
+ require 'uri'
2
+ require 'query_string_parser'
3
+
4
+ module Fanforce::Utils
5
+
6
+ def self.blank?(obj)
7
+ obj.respond_to?(:empty?) ? obj.empty? : !obj
8
+ end
9
+
10
+ def self.present?(obj)
11
+ !blank?(obj)
12
+ end
13
+
14
+ def self.valid_request?(params)
15
+ return false if !params.is_a?(Hash)
16
+ return false if blank?(params[:fanforce_id])
17
+ return false if blank?(params[:app_id]) and blank?(params[:behavior_id]) and blank?(params[:module_id]) and blank?(params[:widget_id])
18
+ return true
19
+ end
20
+
21
+ def self.valid_install_request?(params)
22
+ return false if !params.is_a?(Hash)
23
+ return false if blank?(params[:fanforce_id])
24
+ return false if blank?(params[:app_id]) and blank?(params[:behavior_id]) and blank?(params[:module_id]) and blank?(params[:widget_id])
25
+ return false if blank?(params[:key])
26
+ return true
27
+ end
28
+
29
+ def self.valid_uninstall_request?(params)
30
+ return false if !params.is_a?(Hash)
31
+ return false if blank?(params[:fanforce_id])
32
+ return false if blank?(params[:app_id]) and blank?(params[:behavior_id]) and blank?(params[:module_id]) and blank?(params[:widget_id])
33
+ return false if blank?(params[:key])
34
+ return true
35
+ end
36
+
37
+ def self.parse_params(params)
38
+ if present?(params[:app_id])
39
+ plugin_type = :app
40
+ plugin_id = params[:app_id]
41
+ elsif present?(params[:behavior_id])
42
+ plugin_type = :behavior
43
+ plugin_id = params[:behavior_id]
44
+ elsif present?(params[:module_id])
45
+ plugin_type = :module
46
+ plugin_id = params[:module_id]
47
+ elsif present?(params[:widget_id])
48
+ plugin_type = :widget
49
+ plugin_id = params[:widget_id]
50
+ end
51
+ {:"#{plugin_type}_id" => params["#{plugin_type}_id"], plugin_type: plugin_type, plugin_id: plugin_id, fanforce_id: params[:fanforce_id], key: params[:key]}
52
+ end
53
+
54
+ def self.parse_url(raw_url)
55
+ return if blank?(raw_url)
56
+ url = URI::parse(raw_url)
57
+ query_params = QueryStringParser.qs_parse(url.query).inject({}) do |result, (k,v)|
58
+ result[k] = v if k !~ /^ff_.+/
59
+ result
60
+ end
61
+ query_string = to_query_string(Hash[query_params.sort]) if present?(query_params)
62
+ _external_id = url.host + url.path
63
+ clean_url = "#{url.scheme}://#{url.host}#{(if ![80,443].include?(url.port) then ":#{url.port}" end)}#{url.path}#{(if present?(query_string) then "?#{query_string}" end)}"
64
+
65
+ { _external_id: _external_id, clean_url: clean_url, raw_url: raw_url, query_params: query_params, query_string: query_string, scheme: url.scheme, host: url.host, port: url.port, path: url.path, fragment: url.fragment }
66
+ end
67
+
68
+ def self.to_query_string(params, namespace = nil)
69
+ if params.is_a?(String)
70
+ params
71
+ elsif params.is_a?(Array)
72
+ params.collect { |value| to_query_chunk(value, "#{namespace}[]") }.join '&'
73
+ elsif params.is_a?(Hash)
74
+ params.collect { |key, value| to_query_chunk(value, namespace ? "#{namespace}[#{key}]" : key) }.sort * '&'
75
+ else
76
+ raise "params must be an Object, Hash, or Array"
77
+ end
78
+ end
79
+
80
+ def self.to_query_chunk(value,key)
81
+ require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
82
+ "#{CGI.escape(to_query_string(key))}=#{CGI.escape(to_query_string(value).to_s)}"
83
+ end
84
+
85
+ end
@@ -0,0 +1,3 @@
1
+ class Fanforce
2
+ VERSION = "0.1.1"
3
+ end
data/lib/fanforce.rb ADDED
@@ -0,0 +1,5 @@
1
+ class Fanforce
2
+ end
3
+ require 'fanforce/version'
4
+ require 'fanforce/config'
5
+ require 'fanforce/main'
@@ -0,0 +1,13 @@
1
+ require 'pr_query_parser'
2
+
3
+ module QueryStringParser
4
+ module_function
5
+
6
+ def qs_parse(query_string, delim = '&')
7
+ return {} if query_string.nil? || query_string == ""
8
+
9
+ ret = (query_string + "\x20").force_encoding('UTF-8').encode('UTF-16', :invalid => :replace, :replace => '').encode('UTF-8')[0..-2]
10
+ pr_query_parser(ret, delim)
11
+ end
12
+
13
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fanforce
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Caleb Clark
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rest-client
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: multi_json
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Ruby API wrapper that interfaces with all six Fanforce APIs.
63
+ email:
64
+ - cclark@fanforce.com
65
+ executables: []
66
+ extensions:
67
+ - ext/extconf.rb
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - .rbenv-gemsets
72
+ - .rbenv-version
73
+ - Gemfile
74
+ - Gemfile.lock
75
+ - LICENSE.md
76
+ - README.md
77
+ - Rakefile
78
+ - ext/extconf.rb
79
+ - ext/pr_query_parser.c
80
+ - fanforce.gemspec
81
+ - lib/fanforce.rb
82
+ - lib/fanforce/config.rb
83
+ - lib/fanforce/errors.rb
84
+ - lib/fanforce/main.rb
85
+ - lib/fanforce/utils.rb
86
+ - lib/fanforce/version.rb
87
+ - lib/query_string_parser.rb
88
+ homepage: http://github.com/mlabs/fanforce-ruby
89
+ licenses: []
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 1.8.23
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: Ruby API wrapper for Fanforce
112
+ test_files: []