gembox 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ == 0.1.3 2009-04-06
2
+
3
+ * Support/linking to local RDoc files in Gem pages
4
+ * Added JS so that clippy only loads on mouseover (fixes load issues)
5
+ * Tests now rely on rack-test instead of sintra/test
6
+
7
+ == 0.1.1 2009-03-04
8
+
9
+ * 1 minor fix:
10
+ * Fixed paths so that the binary works correctly
11
+
12
+ == 0.1.0 2009-02-27
13
+
14
+ * 1 major enhancement:
15
+ * Initial release
@@ -0,0 +1,41 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.rdoc
5
+ Rakefile
6
+ bin/gembox
7
+ gembox.gemspec
8
+ lib/extensions.rb
9
+ lib/gembox.rb
10
+ lib/gembox/app.rb
11
+ lib/gembox/config.ru
12
+ lib/gembox/gem_list.rb
13
+ lib/gembox/gems.rb
14
+ lib/gembox/view_helpers.rb
15
+ public/images/edit.png
16
+ public/images/folder.png
17
+ public/images/git.gif
18
+ public/images/page.png
19
+ public/images/page_white_text.png
20
+ public/images/rubygems-125x125t.png
21
+ public/javascripts/base.js
22
+ public/javascripts/gembox.js
23
+ public/javascripts/jquery.form.js
24
+ public/javascripts/jquery.js
25
+ public/javascripts/jquery.metadata.js
26
+ public/javascripts/jquery.ui.js
27
+ public/swf/clippy.swf
28
+ test/.bacon
29
+ test/test_gembox_app.rb
30
+ test/test_gembox_gems.rb
31
+ test/test_helper.rb
32
+ views/doc.haml
33
+ views/file_tree.haml
34
+ views/gem.haml
35
+ views/gembox.sass
36
+ views/gems_columns.haml
37
+ views/gems_header.haml
38
+ views/gems_table.haml
39
+ views/index.haml
40
+ views/layout.haml
41
+ views/no_results.haml
@@ -0,0 +1,4 @@
1
+ For more information on gembox, see http://code.quirkey.com/gembox
2
+
3
+
4
+
@@ -0,0 +1,35 @@
1
+ = gembox
2
+
3
+ == DESCRIPTION:
4
+
5
+ Gembox is a little sinatra app that ties in with your local ruby gems to let you browse and learn more about them.
6
+
7
+ Please see the project home page for a full description:
8
+
9
+ http://code.quirkey.com/gembox
10
+
11
+
12
+ == LICENSE:
13
+
14
+ (The MIT License)
15
+
16
+ Copyright (c) 2009 Aaron Quint, Quirkey NYC, LLC
17
+
18
+ Permission is hereby granted, free of charge, to any person obtaining
19
+ a copy of this software and associated documentation files (the
20
+ 'Software'), to deal in the Software without restriction, including
21
+ without limitation the rights to use, copy, modify, merge, publish,
22
+ distribute, sublicense, and/or sell copies of the Software, and to
23
+ permit persons to whom the Software is furnished to do so, subject to
24
+ the following conditions:
25
+
26
+ The above copyright notice and this permission notice shall be
27
+ included in all copies or substantial portions of the Software.
28
+
29
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
30
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
32
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
33
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
34
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
35
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,35 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen jeweler].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/gembox'
3
+
4
+ require 'jeweler'
5
+
6
+ # Generate all the Rake tasks
7
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
8
+
9
+ $hoe = Hoe.new('gembox', Jeweler::Version.new(File.expand_path(File.dirname(__FILE__))).to_s) do |p|
10
+ p.developer('Aaron Quint', 'aaron@quirkey.com')
11
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
12
+ p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
13
+ p.rubyforge_name = 'quirkey'
14
+ p.summary = p.description = "A sinatra based interface for browsing and admiring your gems."
15
+ p.url = ['http://code.quirkey.com/gembox', 'http://github.com/quirkey/gembox']
16
+ p.extra_deps = [
17
+ ['sinatra', '>=0.9.1'],
18
+ ['haml', '>=2.0.9'],
19
+ ['activesupport', '>=2.2.2'],
20
+ ['mislav-will_paginate', '>=2.3.7']
21
+ ]
22
+
23
+ p.extra_dev_deps = [
24
+ ['newgem', ">= #{::Newgem::VERSION}"],
25
+ ['rack-test', '>=0.1.0']
26
+ ]
27
+
28
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
29
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
30
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
31
+ p.rsync_args = '-av --delete --ignore-errors'
32
+ end
33
+
34
+ require 'newgem/tasks' # load /tasks/*.rake
35
+ Dir['tasks/**/*.rake'].each { |t| load t }
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created on 2009-2-27.
4
+ # Copyright (c) 2009. All rights reserved.
5
+
6
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/gembox")
7
+
8
+ Gembox::App.set :app_file, File.expand_path(File.dirname(__FILE__) + "/../lib/gembox/app.rb")
9
+ Gembox::App.set :environment, :production
10
+ Gembox::App.set :port, 5678
11
+ Gembox::App.run!
@@ -0,0 +1,56 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{gembox}
5
+ s.version = "0.1.3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Aaron Quint"]
9
+ s.date = %q{2009-04-06}
10
+ s.default_executable = %q{gembox}
11
+ s.description = %q{A sinatra based interface for browsing and admiring your gems.}
12
+ s.email = ["aaron@quirkey.com"]
13
+ s.executables = ["gembox"]
14
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "PostInstall.txt", "README.rdoc"]
15
+ s.files = ["History.txt", "Manifest.txt", "PostInstall.txt", "README.rdoc", "Rakefile", "bin/gembox", "gembox.gemspec", "lib/extensions.rb", "lib/gembox.rb", "lib/gembox/app.rb", "lib/gembox/config.ru", "lib/gembox/gem_list.rb", "lib/gembox/gems.rb", "lib/gembox/view_helpers.rb", "public/images/edit.png", "public/images/folder.png", "public/images/git.gif", "public/images/page.png", "public/images/page_white_text.png", "public/images/rubygems-125x125t.png", "public/javascripts/base.js", "public/javascripts/gembox.js", "public/javascripts/jquery.form.js", "public/javascripts/jquery.js", "public/javascripts/jquery.metadata.js", "public/javascripts/jquery.ui.js", "public/swf/clippy.swf", "test/.bacon", "test/test_gembox_app.rb", "test/test_gembox_gems.rb", "test/test_helper.rb", "views/doc.haml", "views/file_tree.haml", "views/gem.haml", "views/gembox.sass", "views/gems_columns.haml", "views/gems_header.haml", "views/gems_table.haml", "views/index.haml", "views/layout.haml", "views/no_results.haml"]
16
+ s.has_rdoc = true
17
+ s.homepage = %q{http://code.quirkey.com/gembox}
18
+ s.post_install_message = %q{PostInstall.txt}
19
+ s.rdoc_options = ["--main", "README.rdoc"]
20
+ s.require_paths = ["lib"]
21
+ s.rubyforge_project = %q{quirkey}
22
+ s.rubygems_version = %q{1.3.1}
23
+ s.summary = %q{A sinatra based interface for browsing and admiring your gems.}
24
+ s.test_files = ["test/test_gembox_app.rb", "test/test_gembox_gems.rb", "test/test_helper.rb"]
25
+
26
+ if s.respond_to? :specification_version then
27
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
28
+ s.specification_version = 2
29
+
30
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
31
+ s.add_runtime_dependency(%q<sinatra>, [">= 0.9.1"])
32
+ s.add_runtime_dependency(%q<haml>, [">= 2.0.9"])
33
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.2.2"])
34
+ s.add_runtime_dependency(%q<mislav-will_paginate>, [">= 2.3.7"])
35
+ s.add_development_dependency(%q<newgem>, [">= 1.2.3"])
36
+ s.add_development_dependency(%q<rack-test>, [">= 0.1.0"])
37
+ s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
38
+ else
39
+ s.add_dependency(%q<sinatra>, [">= 0.9.1"])
40
+ s.add_dependency(%q<haml>, [">= 2.0.9"])
41
+ s.add_dependency(%q<activesupport>, [">= 2.2.2"])
42
+ s.add_dependency(%q<mislav-will_paginate>, [">= 2.3.7"])
43
+ s.add_dependency(%q<newgem>, [">= 1.2.3"])
44
+ s.add_dependency(%q<rack-test>, [">= 0.1.0"])
45
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
46
+ end
47
+ else
48
+ s.add_dependency(%q<sinatra>, [">= 0.9.1"])
49
+ s.add_dependency(%q<haml>, [">= 2.0.9"])
50
+ s.add_dependency(%q<activesupport>, [">= 2.2.2"])
51
+ s.add_dependency(%q<mislav-will_paginate>, [">= 2.3.7"])
52
+ s.add_dependency(%q<newgem>, [">= 1.2.3"])
53
+ s.add_dependency(%q<rack-test>, [">= 0.1.0"])
54
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
55
+ end
56
+ end
@@ -0,0 +1,21 @@
1
+ module Gem
2
+ class Specification
3
+
4
+ def files_tree
5
+ tree = {}
6
+ files.each do |file|
7
+ split_dirs = file.split(/\//)
8
+ keyed_hash = {}
9
+ split_dirs.reverse.each do |key|
10
+ keyed_hash = {key => keyed_hash}
11
+ end
12
+ tree.deep_merge!(keyed_hash)
13
+ end
14
+ tree
15
+ end
16
+
17
+ def on_github?
18
+ homepage =~ /github\.com\/([\w\d\-\_]+)\/([\w\d\-\_]+)\/tree/
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'rubygems'
5
+ require 'active_support'
6
+ require 'will_paginate/array'
7
+ require 'will_paginate/view_helpers'
8
+
9
+ require 'extensions'
10
+ require 'gembox/gem_list'
11
+ require 'gembox/gems'
12
+ require 'gembox/view_helpers'
13
+ require 'gembox/app'
@@ -0,0 +1,87 @@
1
+ require 'sinatra'
2
+
3
+ module Gembox
4
+ class App < ::Sinatra::Default
5
+ include Gembox::ViewHelpers
6
+ include WillPaginate::ViewHelpers
7
+
8
+ @@root = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
9
+
10
+ set :root, @@root
11
+
12
+ before do
13
+ Gembox::Gems.load
14
+ @gems = Gembox::Gems.local_gems.paginate :page => params[:page], :per_page => 30
15
+ @stats = Gembox::Gems.stats
16
+ end
17
+
18
+ get '/stylesheets/:stylesheet.css' do
19
+ sass params[:stylesheet].to_sym
20
+ end
21
+
22
+ get '/' do
23
+ redirect '/gems'
24
+ end
25
+
26
+ get %r{/gems/doc/([\w\-\_]+)/?([\d\.]+)?/?(.*)?} do
27
+ if params[:captures].length == 3 && !params[:captures][2].blank?
28
+ # we have a path
29
+ load_gem_by_version
30
+ @rdoc_path = File.join(@gem.installation_path, "doc", @gem.full_name, 'rdoc')
31
+ full_path = File.join(@rdoc_path, params[:captures].pop)
32
+ content_type File.extname(full_path)
33
+ File.read(full_path)
34
+ else
35
+ load_gem_by_version
36
+ @rdoc_path = File.join(@gem.installation_path, "doc", @gem.full_name, 'rdoc')
37
+ haml :doc, :layout => false
38
+ end
39
+ end
40
+
41
+ get %r{/gems/([\w\-\_]+)/?([\d\.]+)?/?} do
42
+ show_layout = params[:layout] != 'false'
43
+ load_gem_by_version
44
+ if params[:file]
45
+ action = params[:action] || 'view'
46
+ file_path = File.join(@gem.full_gem_path, params[:file])
47
+ if File.readable?(file_path)
48
+ if action == 'edit'
49
+ `$EDITOR #{file_path}`
50
+ else
51
+ content_type 'text/plain'
52
+ return File.read(file_path)
53
+ end
54
+ end
55
+ end
56
+ haml :gem, :layout => show_layout
57
+ end
58
+
59
+ get '/gems/?' do
60
+ show_layout = params[:layout] != 'false'
61
+ @show_as = params[:as] || 'columns'
62
+ if @search = params[:search]
63
+ @gems = Gembox::Gems.search(@search).paginate :page => params[:page]
64
+ end
65
+ haml "gems_#{@show_as}".to_sym, :layout => show_layout
66
+ end
67
+
68
+ private
69
+
70
+ def load_gem_by_version
71
+ name, version = params[:captures]
72
+ @gems = Gembox::Gems.search(name, nil, true)
73
+ raise @gems.inspect if @gems.empty?
74
+ @gem_versions = @gems[0][1]
75
+ if version
76
+ @gems = Gembox::Gems.search(name, version)
77
+ @gem = @gems.shift[1].first if @gems
78
+ end
79
+ if !@gem
80
+ @gem = @gem_versions.shift
81
+ redirect "/gems/#{@gem.name}/#{@gem.version}"
82
+ end
83
+ end
84
+
85
+
86
+ end
87
+ end
@@ -0,0 +1,8 @@
1
+ # To use with thin
2
+ # thin start -p PORT -R config.ru
3
+
4
+ require File.join(File.dirname(__FILE__), 'gembox')
5
+
6
+ disable :run
7
+ set :env, :production
8
+ run Gembox::App
@@ -0,0 +1,41 @@
1
+ module Gembox
2
+
3
+ class GemList < Array
4
+
5
+ def [](*args)
6
+ if args.first.is_a?(String)
7
+ search(args.first)
8
+ else
9
+ super
10
+ end
11
+ end
12
+
13
+ def []=(key, value)
14
+ if key.is_a?(String)
15
+ if versions = search(key)
16
+ versions.replace([key, value])
17
+ else
18
+ self << [key, value]
19
+ end
20
+ else
21
+ super
22
+ end
23
+ end
24
+
25
+ def search(key)
26
+ i = find {|v|
27
+ if v.is_a?(Array)
28
+ v[0] == key
29
+ else
30
+ v == key
31
+ end
32
+ }
33
+ i.is_a?(Array) ? i[1] : i
34
+ end
35
+
36
+ def has_key?(key)
37
+ !search(key).nil?
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,44 @@
1
+ module Gembox
2
+ class Gems
3
+ class << self
4
+ attr_accessor :source_index
5
+
6
+ def load
7
+ @source_index ||= ::Gem.source_index
8
+ local_gems
9
+ end
10
+
11
+ def local_gems
12
+ @local_gems ||= group_gems(source_index.gems)
13
+ end
14
+
15
+ def search(search_term, version = nil, strict = false)
16
+ version = version ? Gem::Requirement.create(version) : Gem::Requirement.default
17
+ escaped = Regexp.escape(search_term)
18
+ regexp = strict ? /^#{escaped}$/ : /#{escaped}/
19
+ gems = source_index.search Gem::Dependency.new(regexp, version)
20
+ group_gems(gems)
21
+ end
22
+
23
+ def stats
24
+ num_versions = source_index.length
25
+ num_gems = local_gems.length
26
+ oldest_gem = source_index.min {|a,b| a[1].date <=> b[1].date }.last
27
+ {:num_versions => num_versions, :num_gems => num_gems, :oldest_gem => oldest_gem}
28
+ end
29
+
30
+ protected
31
+ def group_gems(gem_collection)
32
+ gem_hash = GemList.new
33
+ gem_collection = gem_collection.values if gem_collection.is_a?(Hash)
34
+ gem_collection.each do |spec|
35
+ gem_hash[spec.name] ||= []
36
+ gem_hash[spec.name] << spec
37
+ gem_hash[spec.name].sort! {|a,b| (b.version || 0) <=> (a.version || 0) }
38
+ end
39
+ gem_hash.sort {|a, b| a[0].downcase <=> b[0].downcase }
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,69 @@
1
+ module Gembox
2
+ module ViewHelpers
3
+
4
+ def tag_options(options, escape = true)
5
+ option_string = options.collect {|k,v| %{#{k}="#{v}"}}.join(' ')
6
+ option_string = " " + option_string unless option_string.blank?
7
+ end
8
+
9
+ def content_tag(name, content, options, escape = true)
10
+ tag_options = tag_options(options, escape) if options
11
+ "<#{name}#{tag_options}>#{content}</#{name}>"
12
+ end
13
+
14
+ def link_to(text, link = nil, options = {})
15
+ link ||= text
16
+ link = url_for(link)
17
+ "<a href=\"#{link}\">#{text}</a>"
18
+ end
19
+
20
+ def link_to_gem(gem, options = {})
21
+ text = options[:text] || gem.name
22
+ version = gem.version if options[:show_version]
23
+ link_to(text, "/gems/#{gem.name}/#{gem.version}")
24
+ end
25
+
26
+ def url_for(link_options)
27
+ case link_options
28
+ when Hash
29
+ path = link_options.delete(:path) || request.path_info
30
+ params.delete('captures')
31
+ path + '?' + build_query(params.merge(link_options))
32
+ else
33
+ link_options
34
+ end
35
+ end
36
+
37
+ def ts(time)
38
+ time.strftime('%b %d, %Y') if time
39
+ end
40
+
41
+ def clippy(text, bgcolor='#FFFFFF')
42
+ html = <<-EOF
43
+ <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
44
+ width="110"
45
+ height="14"
46
+ id="clippy" >
47
+ <param name="movie" value="/swf/clippy.swf"/>
48
+ <param name="allowScriptAccess" value="always" />
49
+ <param name="quality" value="high" />
50
+ <param name="scale" value="noscale" />
51
+ <param NAME="FlashVars" value="text=#{text}">
52
+ <param name="bgcolor" value="#{bgcolor}">
53
+ <embed src="/swf/clippy.swf"
54
+ width="110"
55
+ height="14"
56
+ name="clippy"
57
+ quality="high"
58
+ allowScriptAccess="always"
59
+ type="application/x-shockwave-flash"
60
+ pluginspage="http://www.macromedia.com/go/getflashplayer"
61
+ FlashVars="text=#{text}"
62
+ bgcolor="#{bgcolor}"
63
+ />
64
+ </object>
65
+ EOF
66
+ end
67
+
68
+ end
69
+ end