allgems 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ });