jiveapps 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ === 0.0.1 2010-09-29
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,30 @@
1
+ .rspec
2
+ History.txt
3
+ Manifest.txt
4
+ PostInstall.txt
5
+ README.rdoc
6
+ Rakefile
7
+ app_generators/create/USAGE
8
+ app_generators/create/create_generator.rb
9
+ app_generators/create/templates/app.xml
10
+ app_generators/create/templates/canvas.html
11
+ app_generators/create/templates/hello.html
12
+ app_generators/create/templates/home.html
13
+ app_generators/create/templates/images/j-icon-jaf-48.png
14
+ app_generators/create/templates/javascripts/main.js
15
+ app_generators/create/templates/stylesheets/main.css
16
+ autotest/discover.rb
17
+ bin/jiveapps
18
+ lib/jiveapps.rb
19
+ lib/jiveapps/client.rb
20
+ lib/jiveapps/command.rb
21
+ lib/jiveapps/commands/app.rb
22
+ lib/jiveapps/commands/auth.rb
23
+ lib/jiveapps/commands/base.rb
24
+ lib/jiveapps/commands/help.rb
25
+ lib/jiveapps/commands/keys.rb
26
+ lib/jiveapps/helpers.rb
27
+ spec/client_spec.rb
28
+ spec/commands/app_spec.rb
29
+ spec/commands/keys_spec.rb
30
+ spec/spec_helper.rb
data/PostInstall.txt ADDED
@@ -0,0 +1,7 @@
1
+
2
+ For more information on jiveapps, see http://jiveapps.rubyforge.org
3
+
4
+ NOTE: Change this information in PostInstall.txt
5
+ You can also delete it if you don't want it.
6
+
7
+
data/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = jiveapps
2
+
3
+ * http://github.com/#{github_username}/#{project_name}
4
+
5
+ == DESCRIPTION:
6
+
7
+ FIX (describe your package)
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * FIX (list of features or problems)
12
+
13
+ == SYNOPSIS:
14
+
15
+ FIX (code sample of usage)
16
+
17
+ == REQUIREMENTS:
18
+
19
+ * FIX (list of requirements)
20
+
21
+ == INSTALL:
22
+
23
+ * FIX (sudo gem install, anything else)
24
+
25
+ == LICENSE:
26
+
27
+ (The MIT License)
28
+
29
+ Copyright (c) 2010 FIXME full name
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining
32
+ a copy of this software and associated documentation files (the
33
+ 'Software'), to deal in the Software without restriction, including
34
+ without limitation the rights to use, copy, modify, merge, publish,
35
+ distribute, sublicense, and/or sell copies of the Software, and to
36
+ permit persons to whom the Software is furnished to do so, subject to
37
+ the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be
40
+ included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
43
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
45
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
46
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
47
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
48
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,68 @@
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+ require './lib/jiveapps'
6
+
7
+ Hoe.plugin :newgem
8
+ # Hoe.plugin :website
9
+ # Hoe.plugin :cucumberfeatures
10
+
11
+ # Generate all the Rake tasks
12
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
13
+ $hoe = Hoe.spec 'jiveapps' do
14
+ self.developer 'Scott Becker', 'becker.scott@gmail.com'
15
+ self.description = "A set of command line tools for creating Jive Apps."
16
+ self.summary = self.description
17
+ self.version = "0.0.3"
18
+ self.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
19
+ self.rubyforge_name = self.name # TODO this is default value
20
+ self.extra_deps = [
21
+ ['rest-client'],
22
+ ['json'],
23
+ ['rubigen']
24
+ ]
25
+ end
26
+
27
+ require 'newgem/tasks'
28
+ Dir['tasks/**/*.rake'].each { |t| load t }
29
+
30
+ # TODO - want other tests/tasks run by default? Add them to the list
31
+ # remove_task :default
32
+ # task :default => [:spec, :features]
33
+
34
+
35
+
36
+ ### gems this gem depends on
37
+ # rest_client
38
+ # json_pure (or json)
39
+ # rubigen
40
+ # rspec (2.0.0.rc)
41
+ # webmock 1.4.0 (for development/testing)
42
+
43
+ ################
44
+
45
+ require 'rake'
46
+ require 'rspec'
47
+ require 'rspec/core/rake_task'
48
+
49
+ desc "Run all specs"
50
+ RSpec::Core::RakeTask.new('spec') do |t|
51
+ t.rspec_opts = ['--colour --format progress']
52
+ # t.spec_files = FileList['spec/**/*_spec.rb']
53
+ end
54
+
55
+ desc "Print specdocs"
56
+ RSpec::Core::RakeTask.new(:doc) do |t|
57
+ t.rspec_opts = ["--format", "specdoc", "--dry-run"]
58
+ # t.spec_files = FileList['spec/*_spec.rb']
59
+ end
60
+
61
+ desc "Generate RCov code coverage report"
62
+ RSpec::Core::RakeTask.new('rcov') do |t|
63
+ # t.spec_files = FileList['spec/*_spec.rb']
64
+ t.rcov = true
65
+ t.rcov_opts = ['--exclude', 'examples']
66
+ end
67
+
68
+ task :default => :spec
@@ -0,0 +1,5 @@
1
+ Description:
2
+
3
+
4
+ Usage:
5
+
@@ -0,0 +1,77 @@
1
+ class CreateGenerator < RubiGen::Base
2
+
3
+ DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
4
+ Config::CONFIG['ruby_install_name'])
5
+
6
+ default_options :author => nil
7
+
8
+ attr_reader :name
9
+
10
+ def initialize(runtime_args, runtime_options = {})
11
+ super
12
+ usage if args.empty?
13
+ @destination_root = File.expand_path(args.first)
14
+ @name = base_name
15
+ extract_options
16
+ end
17
+
18
+ def manifest
19
+ record do |m|
20
+ # Ensure appropriate folder(s) exists
21
+ m.directory ''
22
+ BASEDIRS.each { |path| m.directory path }
23
+
24
+ # Create stubs
25
+ m.template "app.xml", "app.xml"
26
+ m.template "canvas.html", "canvas.html"
27
+ m.template "home.html", "home.html"
28
+ m.template "hello.html", "hello.html"
29
+ m.template "stylesheets/main.css", "stylesheets/main.css"
30
+ m.template "javascripts/main.js", "javascripts/main.js"
31
+ m.file "images/j-icon-jaf-48.png", "images/j-icon-jaf-48.png"
32
+
33
+ # Samples
34
+ # m.template_copy_each ["template.rb", "template2.rb"]
35
+ # m.file "file", "some_file_copied"
36
+ # m.file_copy_each ["path/to/file", "path/to/file2"]
37
+
38
+ # m.dependency "install_rubigen_scripts", [destination_root, 'create'],
39
+ # :shebang => options[:shebang], :collision => :force
40
+ end
41
+ end
42
+
43
+ protected
44
+ def banner
45
+ <<-EOS
46
+ Creates a ...
47
+
48
+ USAGE: #{spec.name} name
49
+ EOS
50
+ end
51
+
52
+ def add_options!(opts)
53
+ opts.separator ''
54
+ opts.separator 'Options:'
55
+ # For each option below, place the default
56
+ # at the top of the file next to "default_options"
57
+ # opts.on("-a", "--author=\"Your Name\"", String,
58
+ # "Some comment about this option",
59
+ # "Default: none") { |o| options[:author] = o }
60
+ opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
61
+ end
62
+
63
+ def extract_options
64
+ # for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
65
+ # Templates can access these value via the attr_reader-generated methods, but not the
66
+ # raw instance variable value.
67
+ # @author = options[:author]
68
+ end
69
+
70
+ # Installation skeleton. Intermediate directories are automatically
71
+ # created so don't sweat their absence here.
72
+ BASEDIRS = %w(
73
+ javascripts
74
+ stylesheets
75
+ images
76
+ )
77
+ end
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Module>
3
+ <ModulePrefs title="<%= name %>">
4
+ <Require feature="views" />
5
+ <Require feature="dynamic-height" />
6
+ </ModulePrefs>
7
+
8
+ <!-- To begin development, remove the hello view and uncomment the home and canvas views below -->
9
+ <Content view="home,canvas" href="hello.html">
10
+ </Content>
11
+
12
+ <!--
13
+ <Content view="home" href="home.html" />
14
+ <Content view="canvas" href="canvas.html" />
15
+ -->
16
+
17
+ </Module>
@@ -0,0 +1,4 @@
1
+ <link rel="stylesheet" href="stylesheets/main.css" type="text/css" media="screen" />
2
+ <script type="text/javascript" charset="utf-8" src="javascripts/main.js"></script>
3
+
4
+ <h2>Canvas View: <%= name %></h2>
@@ -0,0 +1,88 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
2
+ "http://www.w3.org/TR/html4/strict.dtd">
3
+
4
+ <html lang="en">
5
+ <head>
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
7
+ <title>Hello World!</title>
8
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
9
+ <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.js"></script>
10
+ <script>
11
+ $(function() {
12
+ $( "#devlinks" ).accordion( {
13
+ autoHeight: false,
14
+ navigation: true
15
+ });
16
+ gadgets.window.adjustHeight();
17
+ });
18
+ </script>
19
+ <style type="text/css" media="screen">
20
+ body {background: #fff; font-size:90%;color:#333;font-family: arial, helvetica, sans-serif;}
21
+ #wrapper {width:350px;}
22
+ #wrapper div {padding:0;margin:0;}
23
+ #wrapper p {padding:0;margin:0;}
24
+ ol {padding:0px; margin:0px 0px 0px 20px;}
25
+ ol li {font-weight:bold;margin-bottom:7px;}
26
+ ol li span {font-size:90%;font-weight:normal;}
27
+ a {color:#333;}
28
+ h1 {font-size:150%;margin-bottom:2px;}
29
+ h2 {font-size:110%;margin-bottom:5px;}
30
+ h3 {background-color:#e5e5e5;padding:3px;font-size:105%;}
31
+ h5 {font-size:105%;margin:0;}
32
+ #devlinks h3 {margin:2px;}
33
+ #devlinks div.community {padding:0;margin:0;background: url('images/j-icon-jaf-48.png') no-repeat; background-position: 10px 2px ; height:70px;}
34
+ #devlinks div.documentation {padding:0;margin:0;background: url('images/j-icon-jaf-48.png') no-repeat; background-position: 10px 2px ; height:70px;}
35
+ #devlinks div.login {padding:0;margin:0;background: url('images/j-icon-jaf-48.png') no-repeat; background-position: 10px 2px ; height:70px;}
36
+ #devlinks div.market {padding:0;margin:0;background: url('images/j-icon-jaf-48.png') no-repeat; background-position: 10px 2px ; height:70px;}
37
+ #devlinks div p {margin:10px 0px 0px 80px;}
38
+ #devlinks h3 a,a:hover {text-decoration:none;}
39
+ #devlinks ul {margin:5px 0px 0px 50px;}
40
+ #devlinks li a {font-size:95%;}
41
+ </style>
42
+ </head>
43
+ <body>
44
+ <div id="wrapper">
45
+ <h1>Congratulations!</h1>
46
+ <h5>Your Jive App "<%= name %>" has been created.</h5>
47
+ <hr />
48
+ <ol>
49
+ <li>Update your app code.<br /><span>by replacing the sample app with your own app code</span></li>
50
+ <li>Require the features you need.<br /><span>by adding them to the &#60;ModulePrefs&#62; &#60;/ModulePrefs&#62;</span></li>
51
+ <li>Modify javascripts/main.js<br /><span>by incorporating scripts that complete your app</span></li>
52
+ </ol>
53
+ <hr />
54
+ <h2>Developer Resources</h2>
55
+ <div class="content">
56
+
57
+ <div id="devlinks">
58
+ <h3><a href="#">Community</a></h3>
59
+ <div class="community">
60
+ <ul>
61
+ <li><a href="http://developers.jivesoftware.com/community/blogs">Developer Blog</a></li>
62
+ <li><a href="">Bug Tracker</a></li>
63
+ <li><a href="">IRC Channel</a></li>
64
+ <li><a href="http://www.jivesoftware.com/">Jive Software</a></li>
65
+ </ul>
66
+ </div>
67
+ <h3><a href="#">Documentation</a></h3>
68
+ <div class="documentation">
69
+ <ul>
70
+ <li><a href="">Jive Apps</a></li>
71
+ <li><a href="">Jive Core API</a></li>
72
+ <li><a href="">Jive Connects</a></li>
73
+ <li><a href="">OpenSocial</a></li>
74
+ </ul>
75
+ </div>
76
+ <h3><a href="#">Developer Login</a></h3>
77
+ <div class="login">
78
+ <p><a href="">Log in</a> to your Jive Apps Developer Account.</p>
79
+ </div>
80
+ <h3><a href="#">Apps Market</a></h3>
81
+ <div class="market">
82
+ <p>Browse the <a href="">Apps Market</a> to learn about new apps.</p>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ </div>
87
+ </body>
88
+ </html>
@@ -0,0 +1,4 @@
1
+ <link rel="stylesheet" href="stylesheets/main.css" type="text/css" media="screen" />
2
+ <script type="text/javascript" charset="utf-8" src="javascripts/main.js"></script>
3
+
4
+ <h2>Home View: <%= name %></h2>
@@ -0,0 +1 @@
1
+ Autotest.add_discovery { "rspec2" }
data/bin/jiveapps ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
6
+ require 'jiveapps'
7
+ require 'jiveapps/command'
8
+
9
+ args = ARGV.dup
10
+ ARGV.clear
11
+ command = args.shift.strip rescue 'help'
12
+
13
+ Jiveapps::Command.run(command, args)
14
+
data/lib/jiveapps.rb ADDED
@@ -0,0 +1,7 @@
1
+ module Jiveapps
2
+ VERSION = '0.0.1'
3
+ WEBHOST = 'apphosting.jivesoftware.com'
4
+ GITHOST = 'apphosting.jivesoftware.com'
5
+ end
6
+
7
+ require 'jiveapps/client'
@@ -0,0 +1,179 @@
1
+ require 'rubygems'
2
+ require 'rest_client'
3
+ require 'json'
4
+
5
+ class Jiveapps::Client
6
+
7
+ def self.version
8
+ '0.0.1'
9
+ end
10
+
11
+ def self.gem_version_string
12
+ "jiveapps-gem/#{version}"
13
+ end
14
+
15
+ attr_reader :host, :user, :password
16
+
17
+ def initialize(user, password, host=Jiveapps::WEBHOST)
18
+ @user = user
19
+ @password = password
20
+ @host = host
21
+ end
22
+
23
+ ### Apps
24
+
25
+ def list
26
+ apps = get('/apps')
27
+
28
+ if apps.class == Array
29
+ apps.map { |item| item['app'] }
30
+ else
31
+ return []
32
+ end
33
+ end
34
+
35
+ def info(name)
36
+ begin
37
+ item = get("/apps/#{name}")
38
+ item['app']
39
+ rescue RestClient::ResourceNotFound
40
+ nil
41
+ end
42
+ end
43
+
44
+ def create(name)
45
+ begin
46
+ item = post("/apps", {:app => {:name => name}})
47
+ if item.class == Hash && item['app']
48
+ item['app']
49
+ else
50
+ nil
51
+ end
52
+ rescue => e
53
+ if e.response.body =~ /^\{/ # assume this is JSON if it starts with "{"
54
+ errors = JSON.parse(e.response.body)
55
+ return {"errors" => errors}
56
+ else
57
+ nil
58
+ end
59
+ end
60
+ end
61
+
62
+ def register(name)
63
+ item = post("/apps/#{name}/register", {})
64
+
65
+ if item.class == Hash && item['app']
66
+ item['app']
67
+ else
68
+ nil
69
+ end
70
+ end
71
+
72
+ ### SSH Keys
73
+
74
+ def keys
75
+ ssh_keys = get('/ssh_keys')
76
+
77
+ if ssh_keys.class == Array
78
+ ssh_keys.map { |item| item['ssh_key'] }
79
+ else
80
+ return []
81
+ end
82
+ end
83
+
84
+ def add_key(key)
85
+ item = post("/ssh_keys", {:ssh_key => {:key => key}})
86
+
87
+ if item.class == Hash && item['ssh_key']
88
+ item['ssh_key']
89
+ else
90
+ nil
91
+ end
92
+ end
93
+
94
+ def remove_key(name)
95
+ ### Ugly hack - nginx/passenger unescapes the name before it gets to rails, causing routes to fail. double encode in production
96
+ if Jiveapps::WEBHOST =~ /^becker/ # in dev mode
97
+ delete("/ssh_keys/#{escape(name)}").to_s
98
+ else # in production mode
99
+ delete("/ssh_keys/#{escape(escape(name))}").to_s
100
+ end
101
+ end
102
+
103
+ ### General
104
+
105
+ def on_warning(&blk)
106
+ @warning_callback = blk
107
+ end
108
+
109
+ def get(uri, extra_headers={}) # :nodoc:
110
+ process(:get, uri, extra_headers)
111
+ end
112
+
113
+ def post(uri, object, extra_headers={}) # :nodoc:
114
+ process(:post, uri, extra_headers, JSON.dump(object))
115
+ end
116
+
117
+ def put(uri, object, extra_headers={}) # :nodoc:
118
+ process(:put, uri, extra_headers, JSON.dump(object))
119
+ end
120
+
121
+ def delete(uri, extra_headers={}) # :nodoc:
122
+ process(:delete, uri, extra_headers)
123
+ end
124
+
125
+ def process(method, uri, extra_headers={}, payload=nil)
126
+ headers = jiveapps_headers.merge(extra_headers)
127
+ args = [method, payload, headers].compact
128
+ response = resource(uri).send(*args)
129
+
130
+ extract_warning(response)
131
+ parse_response(response.to_s)
132
+ end
133
+
134
+ def parse_response(response)
135
+ if response == 'null' || response.strip.length == 0
136
+ return nil
137
+ else
138
+ return JSON.parse(response.strip)
139
+ end
140
+ end
141
+
142
+ def jiveapps_headers # :nodoc:
143
+ {
144
+ 'X-Jiveapps-API-Version' => '1',
145
+ 'User-Agent' => self.class.gem_version_string,
146
+ 'X-Ruby-Version' => RUBY_VERSION,
147
+ 'X-Ruby-Platform' => RUBY_PLATFORM,
148
+ 'Accept' => 'application/json',
149
+ 'Content-Type' => 'application/json'
150
+ }
151
+ end
152
+
153
+ def escape(value) # :nodoc:
154
+ escaped = URI.escape(value.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
155
+ escaped.gsub('.', '%2E') # not covered by the previous URI.escape
156
+ end
157
+
158
+ def resource(uri)
159
+ RestClient.proxy = ENV['HTTP_PROXY'] || ENV['http_proxy']
160
+ if uri =~ /^https?/
161
+ RestClient::Resource.new(uri, user, password)
162
+ else
163
+ RestClient::Resource.new("http://#{host}", user, password)[uri]
164
+ end
165
+ end
166
+
167
+ def extract_warning(response)
168
+ return unless response
169
+ if response.headers[:x_jiveapps_warning] && @warning_callback
170
+ warning = response.headers[:x_jiveapps_warning]
171
+ @displayed_warnings ||= {}
172
+ unless @displayed_warnings[warning]
173
+ @warning_callback.call(warning)
174
+ @displayed_warnings[warning] = true
175
+ end
176
+ end
177
+ end
178
+
179
+ end