giggly 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,23 @@
1
+ = Giggly
2
+
3
+ Giggly is an attempt to create a gem for accessing Gigya Socialize
4
+ (http://www.gigya.com/site/partners/wfsocapi.aspx) via idiomatic ruby.
5
+
6
+ Consult the rdoc for detailed information.
7
+
8
+ == Example
9
+
10
+ For examples of usage, visit http://giggly.inheretic.com
11
+
12
+ == Authors
13
+
14
+ * Ben Vandgrift (http://neovore.com)
15
+ * Adam Hunter (http://adamhunter.me)
16
+
17
+ == Copyright
18
+
19
+ Copyright (c) 2009
20
+
21
+ == Credits
22
+
23
+ Sponsored by FlowMingle.com and Charlotte.com
@@ -0,0 +1,88 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'fileutils'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "giggly"
9
+ gem.summary = "wrapper for the gigya rest and javascript apis"
10
+ gem.description = "breaks the gigya web api down into idiomatic ruby for your coding pleasure."
11
+ gem.email = "somethingfamiliar@gmail.com"
12
+ gem.homepage = "http://github.com/sfamiliar/giggly"
13
+ gem.authors = ["Ben Vandgrift", "Adam Hunter"]
14
+ gem.files = FileList["[A-Z]*", "{examples,lib,test,javascripts}/**/*"]
15
+ #gem.rubyforge_project = "giggly"
16
+
17
+ gem.add_dependency('httparty', '0.4.5')
18
+
19
+ gem.add_development_dependency('thoughtbot-shoulda', '>= 2.10.1')
20
+ gem.add_development_dependency('jnunemaker-matchy', '0.4.0')
21
+ gem.add_development_dependency('mocha', '0.9.4')
22
+ gem.add_development_dependency('fakeweb', '>= 1.2.5')
23
+ gem.add_development_dependency('redgreen', '>= 1.0.0')
24
+ end
25
+
26
+ Jeweler::RubyforgeTasks.new do |rubyforge|
27
+ rubyforge.doc_task = "rdoc"
28
+ end
29
+ rescue LoadError
30
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
31
+ end
32
+
33
+ require 'rake/testtask'
34
+ Rake::TestTask.new(:test) do |test|
35
+ test.libs << 'lib' << 'test'
36
+ test.pattern = 'test/**/*_test.rb'
37
+ test.verbose = false
38
+ end
39
+
40
+ begin
41
+ require 'rcov/rcovtask'
42
+ Rcov::RcovTask.new do |test|
43
+ test.libs << 'test'
44
+ test.pattern = 'test/**/*_test.rb'
45
+ test.verbose = true
46
+ end
47
+ rescue LoadError
48
+ task :rcov do
49
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
50
+ end
51
+ end
52
+
53
+
54
+ task :default => :test
55
+
56
+ require 'rake/rdoctask'
57
+ Rake::RDocTask.new do |rdoc|
58
+ if File.exist?('VERSION.yml')
59
+ config = YAML.load(File.read('VERSION.yml'))
60
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
61
+ else
62
+ version = ""
63
+ end
64
+
65
+ rdoc.rdoc_dir = 'rdoc'
66
+ rdoc.title = "giggly #{version}"
67
+ rdoc.rdoc_files.include('README*')
68
+ rdoc.rdoc_files.include('lib/**/*.rb')
69
+ end
70
+
71
+ def copy_js(source, destination)
72
+ destination ||= '.'
73
+ FileUtils.cp File.join(File.dirname(__FILE__), 'javascripts', source), destination
74
+ puts "wrote #{source} to #{destination}"
75
+ end
76
+
77
+ namespace :giggly do
78
+ desc "writes out the giggly-socialize.js api wrapper in the given directory. ex) rake giggly:js IN=path/to/write (IN defaults to the current directory)"
79
+ task :js do
80
+ copy_js 'giggly-socialize.js', ENV['IN']
81
+ end
82
+
83
+ desc "writes out the minified version of giggly-socialize"
84
+ task :"js:min" do
85
+ copy_js 'giggly-socialize-min.js', ENV['IN']
86
+ end
87
+ end
88
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,8 @@
1
+ /*
2
+ * Wrapper for Gigya's Javascript Socialize API
3
+ * http://
4
+ * http://gigya.com
5
+ *
6
+ * Dual licensed under the MIT and GPL licenses.
7
+ */
8
+ eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('B=1(h){0.4=h;0.q=1(a,b,c,d,e){2 f={\'m\':a,\'6\':i(b,c),\'7\':e,\'r\':d};5 8.9.j.q(0.4,f)};0.n=1(a,b,c,d,e,f){2 g={\'m\':a,\'7\':f,\'r\':e};3(o!=b&&o!=c){p.C(\'D E F G H I J K 3 L M N s.\')}3(o==b){g[\'6\']=i(c,d)}l{g[\'s\']=b}5 8.9.j.n(0.4,g)};0.t=1(a,b,c){2 d={\'7\':c,\'6\':i(a,b)};5 8.9.j.t(0.4,d)};0.u=1(a,b,c){2 d={\'7\':c,\'6\':i(a,b)};5 8.9.j.u(0.4,d)};0.v=1(a,b,c){2 d={\'7\':c,\'6\':i(a,b)};5 8.9.j.v(0.4,d)};0.w=1(a,b,c,d,e,f){2 g={\'7\':f,\'6\':i(d,e)};3(\'1\'==k a){g[\'O\']=a}3(\'1\'==k b){g[\'P\']=b}3(\'1\'==k c){g[\'Q\']=c}5 8.9.j.w(0.4,g)};0.x=1(a,b,c,d){2 e={\'m\':a,\'7\':d,\'6\':i(b,c)};5 8.9.j.x(0.4,e)};0.y=1(a,b,c,d){3(\'R\'!=k a){a=\'n,S,T,U,z\'}2 e={\'6\':i(b,c),\'7\':d,\'V\':a};5 8.9.j.y(0.4,e)};2 i=1(b,c){2 d=1(a){3(\'W\'==a.z){3(\'1\'==k b){b(a)}l{p.X(a)}}l{3(\'1\'==k c){c(a)}l{p.A("Y A Z 10! 11 12: ("+a.13+") 14 15: "+a.16)}}};5 d}}',62,69,'this|function|var|if|config|return|callback|context|gigya|services||||||||||socialize|typeof|else|provider|login|null|console|connect|useFacebookConnect|redirect|isLoggedIn|logout|getUserInfo|addEventHandlers|disconnect|getAvailableProviders|status|error|Giggly|warn|The|onSuccess|and|onFailure|params|will|be|ignored|passed|in|with|onLogin|onConnect|onDisconnect|string|notifications|actions|friends|requiredCapabilities|OK|log|An|has|occurred|Error|details|statusMessage|In|method|operation'.split('|'),0,{}))
@@ -0,0 +1,109 @@
1
+
2
+ Giggly = function(gigyaConfig) {
3
+
4
+ this.config = gigyaConfig;
5
+
6
+ this.connect = function(provider, onSuccess, onFailure, useFacebookConnect, context) {
7
+ var params = {
8
+ 'provider': provider,
9
+ 'callback': _onSuccessOrFailure(onSuccess, onFailure),
10
+ 'context' : context,
11
+ 'useFacebookConnect' : useFacebookConnect
12
+ };
13
+ return gigya.services.socialize.connect(this.config, params);
14
+ };
15
+
16
+ this.login = function(provider, redirect, onSuccess, onFailure, useFacebookConnect, context) {
17
+ var params = {
18
+ 'provider': provider,
19
+ 'context' : context,
20
+ 'useFacebookConnect' : useFacebookConnect
21
+ };
22
+ if (null != redirect && null != onSuccess) {
23
+ console.warn('The onSuccess and onFailure params will be ignored if passed in with redirect.');
24
+ }
25
+ if (null == redirect) {
26
+ params['callback'] = _onSuccessOrFailure(onSuccess, onFailure);
27
+ } else {
28
+ params['redirect'] = redirect;
29
+ }
30
+ return gigya.services.socialize.login(this.config, params);
31
+ };
32
+
33
+ this.isLoggedIn = function(onSuccess, onFailure, context) {
34
+ var params = {
35
+ 'context' : context,
36
+ 'callback': _onSuccessOrFailure(onSuccess, onFailure)
37
+ };
38
+ return gigya.services.socialize.isLoggedIn(this.config, params);
39
+ };
40
+
41
+ this.logout = function(onSuccess, onFailure, context) {
42
+ var params = {
43
+ 'context' : context,
44
+ 'callback': _onSuccessOrFailure(onSuccess, onFailure)
45
+ };
46
+ return gigya.services.socialize.logout(this.config, params);
47
+ };
48
+
49
+ this.getUserInfo = function(onSuccess, onFailure, context) {
50
+ var params = {
51
+ 'context' : context,
52
+ 'callback': _onSuccessOrFailure(onSuccess, onFailure)
53
+ };
54
+ return gigya.services.socialize.getUserInfo(this.config, params);
55
+ };
56
+
57
+ this.addEventHandlers = function(onLogin, onConnect, onDisconnect, onSuccess, onFailure, context) {
58
+ var params = {
59
+ 'context' : context,
60
+ 'callback': _onSuccessOrFailure(onSuccess, onFailure)
61
+ };
62
+ if ('function' == typeof onLogin) { params['onLogin'] = onLogin; }
63
+ if ('function' == typeof onConnect) { params['onConnect'] = onConnect; }
64
+ if ('function' == typeof onDisconnect) { params['onDisconnect'] = onDisconnect; }
65
+ return gigya.services.socialize.addEventHandlers(this.config, params);
66
+ };
67
+
68
+ this.disconnect = function(provider, onSuccess, onFailure, context) {
69
+ var params = {
70
+ 'provider': provider,
71
+ 'context' : context,
72
+ 'callback': _onSuccessOrFailure(onSuccess, onFailure)
73
+ };
74
+ return gigya.services.socialize.disconnect(this.config, params);
75
+ };
76
+
77
+ // currently supported capabilities are: login, notifications, actions, friends, status
78
+ this.getAvailableProviders = function(requiredCapabilities, onSuccess, onFailure, context) {
79
+ if ('string' != typeof requiredCapabilities) {
80
+ requiredCapabilities = 'login,notifications,actions,friends,status';
81
+ }
82
+ var params = {
83
+ 'callback': _onSuccessOrFailure(onSuccess, onFailure),
84
+ 'context' : context,
85
+ 'requiredCapabilities' : requiredCapabilities
86
+ };
87
+ return gigya.services.socialize.getAvailableProviders(this.config, params);
88
+ };
89
+
90
+ var _onSuccessOrFailure = function(success, failure) {
91
+ var onSuccessOrFailure = function(response) {
92
+ if ('OK' == response.status) {
93
+ if ('function' == typeof success) {
94
+ success(response);
95
+ } else {
96
+ console.log(response);
97
+ }
98
+ } else {
99
+ if ('function' == typeof failure) {
100
+ failure(response);
101
+ } else {
102
+ console.error("An error has occurred! Error details: (" + response.statusMessage + ") In method: " + response.operation);
103
+ }
104
+ }
105
+ };
106
+ return onSuccessOrFailure;
107
+ };
108
+
109
+ }
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+
3
+ gem 'httparty', '0.4.5'
4
+ require 'httparty'
5
+
6
+ # breaks the gigya web api down into idiomatic ruby for your coding pleasure.
7
+ module Giggly
8
+
9
+ end
10
+
11
+ directory = File.expand_path(File.dirname(__FILE__))
12
+
13
+ require File.join(directory, 'giggly', 'rest')
14
+ require File.join(directory, 'giggly', 'javascript')
15
+ require File.join(directory, 'giggly', 'user')
16
+ require File.join(directory, 'giggly', 'friend')
17
+ require File.join(directory, 'giggly', 'session_info')
18
+
@@ -0,0 +1,4 @@
1
+ module Giggly
2
+ class Friend < Giggly::User
3
+ end
4
+ end
@@ -0,0 +1,10 @@
1
+ module Giggly
2
+ module Javascript
3
+
4
+ end
5
+ end
6
+
7
+ directory = File.expand_path(File.dirname(__FILE__))
8
+
9
+ require File.join(directory, 'javascript', 'helper')
10
+ require File.join(directory, 'javascript', 'socialize')
@@ -0,0 +1,45 @@
1
+ module Giggly
2
+ module Javascript
3
+ module Helper
4
+
5
+ # The Javascript helper should be totally generic to the api that is being used
6
+ # So that if there is a future api it can be wrapped in a class and include this
7
+
8
+ def include_gigya_api(service)
9
+ '<script type="text/javascript" src="http://cdn.gigya.com/JS/gigya.js?services=' + service.to_s + '"></script>'
10
+ end
11
+
12
+ def javascript(&block)
13
+ out = '<script type="text/javascript">' + "\n"
14
+ out += yield.to_s
15
+ out += "\n" + '</script>'
16
+ out
17
+ end
18
+
19
+ def to_var(name, object, scope_to_window = false)
20
+ "#{scope_to_window ? '' : 'var '}#{name.to_s} = #{javascriptify_object object};"
21
+ end
22
+
23
+ # borrowed mainly from the ym4r_gm plugin
24
+ def javascriptify_object(object)
25
+ if object.is_a? String
26
+ "'#{escape_javascript object}'"
27
+ elsif object.is_a? Array
28
+ '[' + object.collect{ |o| javascriptify_variable(o) }.join(', ') + ']'
29
+ elsif object.is_a? Hash
30
+ '{' + object.to_a.collect{ |o| "#{o[0].to_s} : #{javascriptify_object(o[1])}" }.join(', ') + '}'
31
+ elsif object.nil?
32
+ 'undefined'
33
+ else
34
+ object.to_s
35
+ end
36
+ end
37
+
38
+ # from rails
39
+ def escape_javascript(javascript)
40
+ javascript.gsub(/\r\n|\n|\r/, "\\n").gsub("\"") { |m| "\\#{m}" }
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,46 @@
1
+ module Giggly
2
+ module Javascript
3
+ class Socialize
4
+ include Giggly::Javascript::Helper
5
+
6
+ attr_accessor :api_key, :enabled_providers, :disabled_providers, :config
7
+
8
+ def initialize(config)
9
+ @api_key = config[:api_key]
10
+ @enabled_providers = array_to_string(config[:enabled_providers])
11
+ @disabled_providers = array_to_string(config[:disabled_providers])
12
+
13
+ @config = to_config
14
+ end
15
+
16
+ def to_config
17
+ {
18
+ 'APIKey' => @api_key,
19
+ 'enabledProviders' => @enabled_providers,
20
+ 'disabledProviders' => @disabled_providers
21
+ }.reject { |k,v| v.nil? }
22
+ end
23
+
24
+ # Socialize specific JS methods
25
+
26
+ def config_to_js(config_var_name = :gigyaConfig)
27
+ to_var(config_var_name, to_config)
28
+ end
29
+
30
+ def include_gigya_socialize(js_path = '/javascripts', min = true)
31
+ include_gigya_api(:socialize) + "\n<script type=\"text/javascript\" src=\"#{js_path}/giggly-socialize#{'-min' if min}.js\"></script>"
32
+ end
33
+
34
+ protected
35
+
36
+ def array_to_string(array)
37
+ if array.is_a? String
38
+ array
39
+ elsif array.is_a? Array
40
+ array.join(',')
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ require 'digest'
2
+ require 'hmac-sha1'
3
+ require 'base64'
4
+ require 'cgi'
5
+
6
+ module Giggly
7
+ module Rest
8
+
9
+ class SocializeError < StandardError
10
+ attr_reader :error_code
11
+
12
+ def initialize(error_data)
13
+ @error_code = error_data["errorCode"]
14
+ super(error_data["errorMessage"])
15
+ end
16
+ end
17
+
18
+ class BadRequest < SocializeError; end
19
+ class Unauthorized < SocializeError; end
20
+ class Forbidden < SocializeError; end
21
+ class NotFound < SocializeError; end
22
+ class RequestEntityTooLarge < SocializeError; end
23
+ class InternalServerError < SocializeError; end
24
+ class NotImplemented < SocializeError; end
25
+
26
+ end
27
+ end
28
+
29
+ directory = File.expand_path(File.dirname(__FILE__))
30
+
31
+ require File.join(directory, 'rest', 'request')
32
+ require File.join(directory, 'rest', 'socialize')
@@ -0,0 +1,85 @@
1
+ module Giggly
2
+ module Rest
3
+ class Request
4
+ include HTTParty
5
+ attr_accessor :api_key, :secret_key, :uid
6
+ format :xml
7
+
8
+ # Accepts a hash of connection parameters that will be used to authenticate requests with gigya
9
+ # and specify the user that the request is specific to. The keys for the has are all symbols.
10
+ # The connection parameter hash requires :api_key, :secret_key, and :uid
11
+ # These are the same parameters that can be passed to the constructor for +Giggly::Rest::Socialize+
12
+ # example:
13
+ # @connection = Giggly::Rest::Request.new(
14
+ # :api_key => 'api key provided from Gigya',
15
+ # :secret_key => 'secret key provided from Gigya',
16
+ # :user_id => 'the Gigya User ID',
17
+ # )
18
+ def initialize(conn_params)
19
+ @api_key = conn_params[:api_key]
20
+ @secret_key = conn_params[:secret_key]
21
+ @uid = conn_params[:user_id]
22
+ @gigya_secret = Base64.decode64(@secret_key)
23
+ end
24
+
25
+ # Wraps around HTTParty's post method to make API calls.
26
+ # Responsible for raising errors if they are returned from the API.
27
+ # Returns response data from the post request.
28
+ def post(url, params = {})
29
+ response = self.class.post(url, :query => sign('POST', url, params))
30
+ response_key, response_data = response.shift
31
+ raise_errors(response_data)
32
+ response_data
33
+ end
34
+
35
+ def sign(http_method, api_url, params)
36
+ params.merge! "apiKey" => @api_key, "uid" => @uid
37
+ params.merge "sig" => signature(api_url, http_method, params)
38
+ end
39
+
40
+ def signature(http_method, api_url, params)
41
+ timestamp = Time.now.to_i.to_s
42
+ params.merge!("nonce" => "#{@uid}#{timestamp}", "timestamp" => timestamp) ####
43
+ base_string = build_base_string(http_method, api_url, params)
44
+ hmacsha1 = HMAC::SHA1.digest(@gigya_secret, base_string)
45
+ sig = Base64.encode64(hmacsha1).chomp.to_s.gsub(/\n/,'')
46
+ end
47
+
48
+ private
49
+
50
+ # what is this supposed to do? or when is it supposed to be used?
51
+ def validate_signature(api_url, params, sig)
52
+ sig === signature(api_url, params)
53
+ end
54
+
55
+ def params_to_string(params)
56
+ params.sort {|a,b| a[0].to_s <=> b[0].to_s}.collect {|a| "#{a[0]}=#{CGI.escape a[1].to_s}"}.join('&').gsub('+', '%20')
57
+ end
58
+
59
+ def build_base_string(http_method, api_url, params)
60
+ [http_method, api_url, params_to_string(params)].collect! {|a| CGI.escape a}.join('&')
61
+ end
62
+
63
+ def raise_errors(data)
64
+ return if '200' == data["statusCode"]
65
+ case data["statusCode"].to_i
66
+ when 400
67
+ raise Giggly::Rest::BadRequest.new(data)
68
+ when 401
69
+ raise Giggly::Rest::Unauthorized.new(data)
70
+ when 403
71
+ raise Giggly::Rest::Forbidden.new(data)
72
+ when 404
73
+ raise Giggly::Rest::NotFound.new(data)
74
+ when 413
75
+ raise Giggly::Rest::RequestEntityTooLarge.new(data)
76
+ when 500
77
+ raise Giggly::Rest::InternalServerError.new(data)
78
+ when 503
79
+ raise Giggly::Rest::NotImplemented.new(data)
80
+ end
81
+ end
82
+
83
+ end
84
+ end
85
+ end