allgems 0.0.1

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,17 @@
1
+ module AllGems
2
+ class IndexBuilder
3
+ def initialize(args={})
4
+ raise ArgumentError.new('Expecting a Sequel::Database to be passed') unless args[:database] && args[:database].is_a?(Sequel::Database)
5
+ @db = args[:database]
6
+ end
7
+ def build_array(filter=[])
8
+ b = []
9
+ Gem::SpecFetcher.fetcher.list(AllGems.allgems).each_pair{|uri, x| b = b | x.reject{|a|filter.include?(a)}.map{|c|{:name => c[0], :version => c[1]}}}
10
+ b
11
+ end
12
+ def local_array
13
+ la = @db[:versions].join(:gems, :id => :gem_id).join(:platforms, :id => :versions__platform_id).select(:name, :version, :platform).all.collect{|x|x.values}
14
+ la.map{|a| [a[0], Gem::Version.new(a[1]), a[2]]}
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ module AllGems
2
+ class Indexer
3
+ class << self
4
+ def index_gem(spec, format)
5
+ case format
6
+ when :hanna
7
+ self.index_hanna(spec)
8
+ when :rdoc
9
+ self.index_rdoc(spec)
10
+ when :sdoc
11
+ self.index_sdoc(spec)
12
+ end
13
+ AllGems.logger.info "Gem index is complete for #{spec.full_name}"
14
+ end
15
+ def index_hanna(spec)
16
+ end
17
+ def index_rdoc(spec)
18
+ end
19
+ def index_sdoc(spec)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,59 @@
1
+ require 'actionpool'
2
+ require 'actiontimer'
3
+ require 'allgems/IndexBuilder'
4
+ require 'allgems/GemWorker'
5
+
6
+ module AllGems
7
+ class Runner
8
+ # :db_path:: path to sqlite database
9
+ # :runners:: maximum number of threads to use
10
+ # :interval:: how often to update documents (useless if using cron)
11
+ def initialize(args={})
12
+ raise ArgumentError.new('Expecting path to database') unless args[:db_path]
13
+ @db = Sequel.connect("sqlite://#{args[:db_path]}")
14
+ AllGems.initialize_db(@db)
15
+ @pool = ActionPool::Pool.new(:max_threads => args[:runners] ? args[:runners] : 10)
16
+ GemWorker.setup
17
+ @index = IndexBuilder.new(:database => @db)
18
+ @interval = args[:interval] ? args[:interval] : nil
19
+ @timer = nil
20
+ @lock = Mutex.new
21
+ @guard = ConditionVariable.new
22
+ @stop = false
23
+ end
24
+
25
+ def do_sync
26
+ if(@interval)
27
+ @timer = ActionTimer::Timer.new(:pool => @pool)
28
+ sync
29
+ @timer.add(@interval){ sync }
30
+ else
31
+ sync
32
+ end
33
+ end
34
+ # Get the list of gems we need and load up the pool. Then take a nap
35
+ # until the pool gets bored and wakes us up
36
+ def sync
37
+ Gem.refresh
38
+ Thread.new do
39
+ @pool.add_jobs(@index.build_array(@index.local_array).collect{|x| lambda{GemWorker.process({:database => @db}.merge(x))}})
40
+ end
41
+ begin
42
+ @pool << lambda{@lock.synchronize{@guard.signal}}
43
+ @lock.synchronize{@guard.wait(@lock)}
44
+ rescue StandardError => boom
45
+ AllGems.logger.error boom.to_s
46
+ retry unless @stop
47
+ end
48
+ end
49
+ # Stop the runner
50
+ def stop(now=false)
51
+ @timer.clear if @timer
52
+ @stop = true
53
+ @lock.synchronize{@guard.broadcast}
54
+ @pool.shutdown(now)
55
+ GemWorker.pool.shutdown(now)
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,12 @@
1
+ module AllGems
2
+ class Specer
3
+ class << self
4
+ def get_spec(gem, version=nil)
5
+ spec = AllGems.db[:specs].join(:versions, :id => :version_id).join(:gems, :id => :gem_id).filter(:name => gem)
6
+ spec = spec.filter(:version => version) if version
7
+ spec = spec.order(:version.desc).limit(1).first
8
+ return spec ? Marshal.load(spec[:spec].unpack('m')[0]) : nil
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,48 @@
1
+ require 'rdoc/markup/to_html'
2
+
3
+ module AllGems
4
+ module ViewHelpers
5
+
6
+ def tag_options(options, escape = true)
7
+ option_string = options.collect {|k,v| %{#{k}="#{v}"}}.join(' ')
8
+ option_string = " " + option_string unless option_string.blank?
9
+ end
10
+
11
+ def content_tag(name, content, options, escape = true)
12
+ tag_options = tag_options(options, escape) if options
13
+ "<#{name}#{tag_options}>#{content}</#{name}>"
14
+ end
15
+
16
+ def link_to(text, link = nil, options = {})
17
+ link ||= text
18
+ link = url_for(link)
19
+ "<a href=\"#{link}\">#{text}</a>"
20
+ end
21
+
22
+ def link_to_gem(gem, options = {})
23
+ version = options[:version] ? options[:version] : ''
24
+ text = options[:text] ? options[:text] : gem
25
+ link_to(text, "/gems/#{gem}/#{version}")
26
+ end
27
+
28
+ def url_for(link_options)
29
+ case link_options
30
+ when Hash
31
+ path = link_options.delete(:path) || request.path_info
32
+ params.delete('captures')
33
+ path + '?' + build_query(params.merge(link_options))
34
+ else
35
+ link_options
36
+ end
37
+ end
38
+
39
+ def ts(time)
40
+ time.strftime('%b %d, %Y') if time
41
+ end
42
+
43
+ def rdocify(text)
44
+ @_rdoc ||= RDoc::Markup::ToHtml.new
45
+ @_rdoc.convert(text)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,82 @@
1
+ # This file is a simple hack to force hanna to use
2
+ # the 2.3.0 version of rdoc
3
+
4
+ if ARGV.size == 1 and ARGV.first == '-h'
5
+ puts <<-HELP
6
+ Hanna -- a better RDoc template
7
+ Synopsis:
8
+ hanna [options] [file names...]
9
+ [sudo] hanna --gems [gem names...]
10
+
11
+ Example usage:
12
+
13
+ hanna lib/**/*.rb
14
+
15
+ Hanna passes all arguments to RDoc. To find more about RDoc options, see
16
+ "rdoc -h". Default options are:
17
+
18
+ -o doc --inline-source --charset=UTF-8
19
+
20
+ The second form, with the "--gems" argument, serves the same purpose as
21
+ the "gem rdoc" command: it generates documentation for installed gems.
22
+ When no gem names are given, "hanna --gems" will install docs for EACH of
23
+ the gems, which can, uh, take a little while.
24
+
25
+ HELP
26
+ exit 0
27
+ end
28
+
29
+ unless RUBY_PLATFORM =~ /(:?mswin|mingw)/
30
+ require 'pathname'
31
+ hanna_dir = Pathname.new(__FILE__).realpath.dirname + '../lib'
32
+ else
33
+ # windows
34
+ hanna_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
35
+ end
36
+
37
+ $:.unshift(hanna_dir) unless $:.include?(hanna_dir)
38
+
39
+ require 'rubygems'
40
+ gem 'rdoc', '2.3.0'
41
+ require 'rdoc/rdoc'
42
+
43
+ options = []
44
+
45
+ options << '-f' << 'html' << '-T' << 'hanna'
46
+ options << '--inline-source' << '--charset=UTF-8'
47
+
48
+ if ARGV.first == '--gems'
49
+ require 'rubygems/doc_manager'
50
+ Gem::DocManager.configured_args = options
51
+
52
+ gem_names = ARGV.dup
53
+ gem_names.shift
54
+
55
+ unless gem_names.empty?
56
+ specs = gem_names.inject([]) do |arr, name|
57
+ found = Gem::SourceIndex.from_installed_gems.find_name(name)
58
+ spec = found.sort_by {|s| s.version }.last
59
+ arr << spec if spec
60
+ arr
61
+ end
62
+ else
63
+ specs = Gem::SourceIndex.from_installed_gems.inject({}) do |all, pair|
64
+ full_name, spec = pair
65
+ if spec.has_rdoc? and (!all[spec.name] or spec.version > all[spec.name].version)
66
+ all[spec.name] = spec
67
+ end
68
+ all
69
+ end
70
+ specs = specs.values
71
+ puts "Hanna is installing documentation for #{specs.size} gem#{specs.size > 1 ? 's' : ''} ..."
72
+ end
73
+
74
+ specs.each do |spec|
75
+ Gem::DocManager.new(spec).generate_rdoc
76
+ end
77
+ else
78
+ options << '-o' << 'doc' unless ARGV.include?('-o') or ARGV.include?('--op')
79
+ options.concat ARGV
80
+
81
+ RDoc::RDoc.new.document(options)
82
+ end
@@ -0,0 +1,39 @@
1
+ Class.new(Sequel::Migration) do
2
+ def up
3
+ AllGems.db << "CREATE TABLE gems (
4
+ name VARCHAR NOT NULL UNIQUE COLLATE NOCASE,
5
+ summary TEXT,
6
+ description TEXT,
7
+ id INTEGER NOT NULL PRIMARY KEY)"
8
+ # create_table(:gems) do
9
+ # String :name, :null => false, :unique => true
10
+ # String :summary
11
+ # String :description
12
+ # primary_key :id, :null => false
13
+ # end
14
+ AllGems.db.create_table(:platforms) do
15
+ String :platform, :null => false, :unique => true
16
+ primary_key :id, :null => false
17
+ end
18
+ AllGems.db.create_table(:versions) do
19
+ String :version, :null => false
20
+ Time :release, :null => false
21
+ foreign_key :gem_id, :table => :gems, :null => false
22
+ foreign_key :platform_id, :table => :platforms, :null => false
23
+ index [:gem_id, :version, :platform_id], :unique => true
24
+ primary_key :id, :null => false
25
+ end
26
+ AllGems.db.create_table(:specs) do
27
+ String :spec, :null => false
28
+ foreign_key :version_id, :table => :versions, :null => false
29
+ index [:spec, :version_id], :unique => true
30
+ primary_key :id, :null => false
31
+ end
32
+ end
33
+ def down
34
+ AllGems.db.drop_table(:specs)
35
+ AllGems.db.drop_table(:versions)
36
+ AllGems.db.drop_table(:platforms)
37
+ AllGems.db.drop_table(:gems)
38
+ end
39
+ end
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,212 @@
1
+ (function(){
2
+ var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
3
+
4
+ // The base Class implementation (does nothing)
5
+ this.Class = function(){};
6
+
7
+ // Create a new Class that inherits from this class
8
+ Class.extend = function(prop) {
9
+ var _super = this.prototype;
10
+
11
+ // Instantiate a base class (but only create the instance,
12
+ // don't run the init constructor)
13
+ initializing = true;
14
+ var prototype = new this();
15
+ initializing = false;
16
+
17
+ // Copy the properties over onto the new prototype
18
+ for (var name in prop) {
19
+ // Check if we're overwriting an existing function
20
+ prototype[name] = typeof prop[name] == "function" &&
21
+ typeof _super[name] == "function" && fnTest.test(prop[name]) ?
22
+ (function(name, fn){
23
+ return function() {
24
+ var tmp = this._super;
25
+
26
+ // Add a new ._super() method that is the same method
27
+ // but on the super-class
28
+ this._super = _super[name];
29
+
30
+ // The method only need to be bound temporarily, so we
31
+ // remove it when we're done executing
32
+ var ret = fn.apply(this, arguments);
33
+ this._super = tmp;
34
+
35
+ return ret;
36
+ };
37
+ })(name, prop[name]) :
38
+ prop[name];
39
+ }
40
+
41
+ // The dummy class constructor
42
+ function Class() {
43
+ // All construction is actually done in the init method
44
+ if ( !initializing && this.init )
45
+ this.init.apply(this, arguments);
46
+ }
47
+
48
+ // Populate our constructed prototype object
49
+ Class.prototype = prototype;
50
+
51
+ // Enforce the constructor to be what we expect
52
+ Class.constructor = Class;
53
+
54
+ // And make this class extendable
55
+ Class.extend = arguments.callee;
56
+
57
+ return Class;
58
+ };
59
+ })();
60
+
61
+
62
+ $.fn.extend({
63
+ getId: function() {
64
+ var match = $(this).attr("id").match(/\d+/)
65
+ return match ? parseInt(match[0]) : null;
66
+ },
67
+ setInputHint: function() {
68
+ el = $(this);
69
+ el.data('default', el.val());
70
+
71
+ el.focus(function() {
72
+ if(el.data('default') != el.val()) return;
73
+ el.removeClass('hint').val('');
74
+ })
75
+ .blur(function() {
76
+ if($.trim(el.val()) != '') return;
77
+ el.addClass('hint').val(el.data('default'));
78
+ })
79
+ .addClass('hint');
80
+ },
81
+ fadeUp: function(speed) {
82
+ $(this).css({'position':'relative'}).animate({top:"-150px", opacity: 0}, speed, function() { $(this).remove(); })
83
+ return $(this);
84
+ }
85
+ });
86
+
87
+ $.extend({
88
+ log: function() {
89
+ if (typeof console == 'undefined') {
90
+ // do nothing
91
+ } else {
92
+ console.log(arguments);
93
+ }
94
+ },
95
+ timestamp: function() {
96
+ return Math.floor(new Date().getTime()/1000);
97
+ }
98
+ });
99
+
100
+ // authenticity tokens
101
+ // http://www.viget.com/extend/ie-jquery-rails-and-http-oh-my
102
+ $(function() {
103
+ $(document).ajaxSend(function(event, request, settings) {
104
+ if (settings.type == 'GET' || settings.type == 'get' || typeof(AUTH_TOKEN) == "undefined") return;
105
+ // settings.data is a serialized string like "foo=bar&baz=boink" (or null)
106
+ settings.data = settings.data || "";
107
+ settings.data += (settings.data ? "&" : "") + "authenticity_token=" + encodeURIComponent(AUTH_TOKEN);
108
+ });
109
+ });
110
+
111
+ var Base = {
112
+ popup: function (link,title,width,height) {
113
+ return window.open(link,title,"height="+height+",width="+width+",status=no,toolbar=no,menubar=no,location=no");
114
+ },
115
+ urlify: function(title) {
116
+ // self.downcase.gsub(/(_|-|\/|\\|\&|,| )/,'_')[0..40]
117
+ return title.toString().strip().toLowerCase().gsub(/ /, '_').gsub(/[^a-z0-9\-_]/,'').truncate(40,'');
118
+ },
119
+ copyTextToClipboard: function(text) {
120
+ // create form element
121
+ var form_element = $('clipboard_holder') ? $('clipboard_holder') : new Element('input',{'type':'hidden','id':'clipboard_holder','name':'clipboard_holder','value':text});
122
+ if (form_element.createTextRange) {
123
+ var range = form_element.createTextRange();
124
+ if (range && BodyLoaded==1)
125
+ range.execCommand('Copy');
126
+ } else {
127
+ var flashcopier = $('flashcopier') ? $('flashcopier') : new Element('div',{id: 'flashcopier'});
128
+ $(flashcopier).innerHTML = '<embed src="/swf/_clipboard.swf" FlashVars="clipboard='+escape(form_element.value)+'" width="0" height="0" type="application/x-shockwave-flash"></embed>';
129
+ document.body.appendChild(flashcopier);
130
+ }
131
+ },
132
+ images: {
133
+ hover_suffix: '_on',
134
+ active_suffix: '_on',
135
+ deactive_suffix: '_off',
136
+ swap: function(for_el,to) {
137
+ $(for_el).attr('src', to);
138
+ },
139
+ activate: function (for_el) {
140
+ return this.swap(for_el,this.activateSrc(for_el));
141
+ },
142
+ deactivate: function (for_el) {
143
+ return this.swap(for_el,this.deactivateSrc(for_el));
144
+ },
145
+ hover: function (for_el) {
146
+ return this.swap(for_el,this.hoverSrc(for_el));
147
+ },
148
+ replaceSrc: function (for_el,search,replace_with) {
149
+ return $(for_el).attr('src').replace(search,replace_with);
150
+ },
151
+ activateSrc: function (for_el) {
152
+ return this.replaceSrc(for_el,this.deactive_suffix,this.active_suffix);
153
+ },
154
+ deactivateSrc: function (for_el) {
155
+ return this.replaceSrc(for_el,this.active_suffix,this.deactive_suffix);
156
+ },
157
+ hoverSrc: function (for_el) {
158
+ return this.replaceSrc(for_el,this.deactive_suffix,this.hover_suffix);
159
+ },
160
+ restore: function (for_el) {
161
+ MM_swapImgRestore();
162
+ }
163
+ }
164
+ };
165
+
166
+ $.extend({
167
+ param: function( a, nest_in ) {
168
+ var s = [ ];
169
+ // check for nest
170
+ if (typeof nest_in == 'undefined') nest_in = false;
171
+
172
+ function nested(key) {
173
+ if (nest_in)
174
+ return nest_in + '[' + key + ']';
175
+ else
176
+ return key;
177
+ }
178
+ function add( key, value ){
179
+ key = nested(key)
180
+ s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
181
+ };
182
+ // If an array was passed in, assume that it is an array
183
+ // of form elements
184
+ if ( jQuery.isArray(a) || a.jquery )
185
+ // Serialize the form elements
186
+ jQuery.each( a, function(){
187
+ add( this.name, this.value );
188
+ });
189
+
190
+ // Otherwise, assume that it's an object of key/value pairs
191
+ else
192
+ // Serialize the key/values
193
+ for ( var j in a )
194
+ // If the value is an array then the key names need to be repeated
195
+ if ( jQuery.isArray(a[j]) )
196
+ jQuery.each( a[j], function(){
197
+ add( j, this );
198
+ });
199
+ else if (a[j].constructor == Object)
200
+ s.push($.param(a[j], nested(j)));
201
+ else
202
+ add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
203
+
204
+ // Return the resulting serialization
205
+ return s.join("&").replace(/%20/g, "+");
206
+ },
207
+ shove: function(fn, object) {
208
+ return function() {
209
+ return fn.apply(object, arguments);
210
+ }
211
+ }
212
+ });