darkext 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gitignore +4 -0
  2. data/History.txt +140 -0
  3. data/LICENSE +21 -0
  4. data/README.md +45 -0
  5. data/Rakefile +45 -0
  6. data/TODO +4 -0
  7. data/VERSION.yml +4 -0
  8. data/app_generators/sinatra_app_generator.rb +57 -0
  9. data/app_generators/templates/app.rb +16 -0
  10. data/app_generators/templates/config.ru +2 -0
  11. data/app_generators/templates/error.rb +8 -0
  12. data/app_generators/templates/gitignore +0 -0
  13. data/app_generators/templates/helpers.rb +12 -0
  14. data/app_generators/templates/http_method.rb +8 -0
  15. data/app_generators/templates/options.rb +9 -0
  16. data/bin/sinatra-app +14 -0
  17. data/darkext.gemspec +105 -0
  18. data/lib/darkext.rb +13 -0
  19. data/lib/darkext/array.rb +52 -0
  20. data/lib/darkext/beagle.rb +88 -0
  21. data/lib/darkext/boolean.rb +17 -0
  22. data/lib/darkext/fiber.rb +48 -0
  23. data/lib/darkext/float.rb +6 -0
  24. data/lib/darkext/hash.rb +38 -0
  25. data/lib/darkext/integer.rb +10 -0
  26. data/lib/darkext/io.rb +37 -0
  27. data/lib/darkext/net.rb +28 -0
  28. data/lib/darkext/numeric.rb +35 -0
  29. data/lib/darkext/object.rb +11 -0
  30. data/lib/darkext/sinatra.rb +70 -0
  31. data/lib/darkext/sitemap_generator.rb +90 -0
  32. data/lib/darkext/statistics.rb +197 -0
  33. data/lib/darkext/string.rb +63 -0
  34. data/lib/darkext/symbol.rb +7 -0
  35. data/spec/array_spec.rb +112 -0
  36. data/spec/beagle_spec.rb +42 -0
  37. data/spec/boolean_spec.rb +53 -0
  38. data/spec/fiber_spec.rb +35 -0
  39. data/spec/float_spec.rb +18 -0
  40. data/spec/hash_spec.rb +26 -0
  41. data/spec/integer_spec.rb +22 -0
  42. data/spec/io_spec.rb +44 -0
  43. data/spec/net_spec.rb +23 -0
  44. data/spec/numeric_spec.rb +52 -0
  45. data/spec/object_spec.rb +28 -0
  46. data/spec/spec.opts +3 -0
  47. data/spec/spec_helper.rb +13 -0
  48. data/spec/statistics_spec.rb +162 -0
  49. data/spec/string_spec.rb +54 -0
  50. data/spec/symbol_spec.rb +16 -0
  51. metadata +119 -0
data/lib/darkext.rb ADDED
@@ -0,0 +1,13 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ libs = Dir[File.join(File.join(File.dirname(__FILE__), 'darkext'), '*.rb')]
5
+
6
+ # Don't load these by default
7
+ other_libs = libs.reject! { |lib| lib.include?('sinatra') || lib.include?('sitemap') }
8
+
9
+ libs.reject! { |lib| lib.include?('beagle') }.first
10
+ libs.each { |lib| require lib }
11
+
12
+ # autoload beagle
13
+ autoload(:Beagle, 'darkext/beagle')
@@ -0,0 +1,52 @@
1
+ require 'darkext/numeric'
2
+ require 'darkext/symbol'
3
+
4
+ class Array
5
+ # Rotates the array left by n elements
6
+ def rotate(n = 1)
7
+ return if self.size.zero?
8
+ n.times { self.push(self.shift) }
9
+ end
10
+
11
+ # Rotates the array right by n elements
12
+ def rotate_reverse(n = 1)
13
+ return if self.size.zero?
14
+ n.times { self.unshift(self.pop) }
15
+ end
16
+
17
+ # Sums the array
18
+ def sum
19
+ self.inject(&:+)
20
+ end
21
+
22
+ # Finds the product of the array
23
+ def product
24
+ self.inject(&:*)
25
+ end
26
+
27
+ # Collects the squares of each value in the array
28
+ def squares
29
+ self.map(&:square)
30
+ end
31
+
32
+ # Destructively collects the squares
33
+ def squares!
34
+ self.map!(&:square)
35
+ end
36
+
37
+ # Picks a random value from the array
38
+ def random
39
+ self[rand(self.size)]
40
+ end
41
+ alias :pick :random
42
+
43
+ # Randomizes the array
44
+ def randomize
45
+ self.sort_by { rand }
46
+ end
47
+
48
+ # Destructively randomizes
49
+ def randomize!
50
+ self.replace(self.randomize)
51
+ end
52
+ end
@@ -0,0 +1,88 @@
1
+ require 'darkext/fiber'
2
+ require 'darkext/string'
3
+ require 'darkext/symbol'
4
+
5
+ "Beagle.query is not secure! Use with caution".printn
6
+
7
+ module Beagle
8
+ class BeagleError < RuntimeError; end
9
+
10
+ class BeagleResultsHelper
11
+ def initialize(io)
12
+ @io = io
13
+ @fiber = Fiber.new do
14
+ while !@io.eof?
15
+ result = Hash.new
16
+ loop do
17
+ line = @io.gets
18
+ break if line.nil?
19
+ line.chomp!
20
+ break if line.empty? && 0 < result.keys.size
21
+ if !line.include?('=') || line.starts_with?(' Snip')
22
+ parts = line.split(':')
23
+ k = parts.shift.strip
24
+ v = parts.join(':').strip
25
+ result[k] = v unless k.empty? || v.empty?
26
+ elsif line.include?('=')
27
+ k,v = line.split('=')
28
+ k = k.split(':').last.strip
29
+ v = v.gsub("'",'').strip
30
+ result[k] = v unless k.empty? || v.empty?
31
+ end
32
+ end
33
+ Fiber.yield(result)
34
+ end
35
+ @io.close
36
+ end
37
+ end
38
+
39
+ def next
40
+ begin
41
+ return @fiber.resume
42
+ rescue FiberError
43
+ return nil
44
+ end
45
+ end
46
+ end
47
+
48
+ def self.home
49
+ ENV['BEAGLE_HOME']
50
+ end
51
+
52
+ def self.home=(home)
53
+ ENV['BEAGLE_HOME'] = home
54
+ end
55
+
56
+ def self.start
57
+ raise BeagleError, "Beagle.home (BEAGLE_HOME) not set!" if home.nil?
58
+ system('beagled --backend Files')
59
+ end
60
+
61
+ def self.stop
62
+ raise BeagleError, "Beagle.home (BEAGLE_HOME) not set!" if home.nil?
63
+ system('beagle-shutdown')
64
+ end
65
+
66
+ def self.query(query, max_hits = 100)
67
+ raise BeagleError, "Beagle.home (BEAGLE_HOME) not set!" if home.nil?
68
+ args = Array.new
69
+ args << 'beagle-query'
70
+ args << '--verbose'
71
+ args << '--max-hits'
72
+ args << max_hits.to_s
73
+ args << "\"#{query.gsub('"','\"')}\""
74
+ return BeagleResultsHelper.new(IO.popen(args.join(' ')))
75
+ end
76
+
77
+ def self.running?
78
+ raise BeagleError, "Beagle.home (BEAGLE_HOME) not set!" if home.nil?
79
+ s = status
80
+ return false if s.include?("Could not connect") || s.empty?
81
+ return true
82
+ end
83
+
84
+ def self.status
85
+ raise BeagleError, "Beagle.home (BEAGLE_HOME) not set!" if home.nil?
86
+ DarkIO.capture_output(:stderr => false) { system('beagle-info','--status') }.strip
87
+ end
88
+ end
@@ -0,0 +1,17 @@
1
+ class Object
2
+ def is_boolean?
3
+ self.is_a?(TrueClass) || self.is_a?(FalseClass)
4
+ end
5
+ end
6
+
7
+ class TrueClass
8
+ def intern
9
+ return :true
10
+ end
11
+ end
12
+
13
+ class FalseClass
14
+ def intern
15
+ return :false
16
+ end
17
+ end
@@ -0,0 +1,48 @@
1
+ # Poor Man's Fiber (API compatible Thread based Fiber implementation for Ruby 1.8)
2
+ # (c) 2008 Aman Gupta (tmm1)
3
+
4
+ unless defined? Fiber
5
+ require 'thread'
6
+
7
+ class FiberError < StandardError; end
8
+
9
+ class Fiber
10
+ def initialize
11
+ raise ArgumentError, 'new Fiber requires a block' unless block_given?
12
+
13
+ @yield = Queue.new
14
+ @resume = Queue.new
15
+
16
+ @thread = Thread.new{ @yield.push [ *yield(*@resume.pop) ] }
17
+ @thread.abort_on_exception = true
18
+ @thread[:fiber] = self
19
+ end
20
+ attr_reader :thread
21
+
22
+ def resume *args
23
+ raise FiberError, 'dead fiber called' unless @thread.alive?
24
+ @resume.push(args)
25
+ result = @yield.pop
26
+ result.size > 1 ? result : result.first
27
+ end
28
+
29
+ def yield *args
30
+ @yield.push(args)
31
+ result = @resume.pop
32
+ result.size > 1 ? result : result.first
33
+ end
34
+
35
+ def self.yield *args
36
+ raise FiberError, "can't yield from root fiber" unless fiber = Thread.current[:fiber]
37
+ fiber.yield(*args)
38
+ end
39
+
40
+ def self.current
41
+ Thread.current[:fiber] or raise FiberError, 'not inside a fiber'
42
+ end
43
+
44
+ def inspect
45
+ "#<#{self.class}:0x#{self.object_id.to_s(16)}>"
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,6 @@
1
+ class Float
2
+ # Equals for floats with tolerance
3
+ def equals?(x, tolerance = 1e-6)
4
+ (self - x).abs < tolerance
5
+ end
6
+ end
@@ -0,0 +1,38 @@
1
+ class Hash
2
+ def nested_find(*keys)
3
+ v = self
4
+ keys.each do |key|
5
+ v = v[key]
6
+ return nil if v.nil?
7
+ end
8
+ return v
9
+ end
10
+
11
+ # http://snippets.dzone.com/posts/show/4146
12
+ def deep_merge!(second)
13
+ # From: http://www.ruby-forum.com/topic/142809
14
+ # Author: Stefan Rusterholz
15
+ merger = proc { |key,v1,v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
16
+ self.merge!(second, &merger)
17
+ end
18
+
19
+ def method_missing(m,*a)
20
+ if m.to_s =~ /=$/
21
+ self[$`] = a[0]
22
+ elsif a.empty?
23
+ self[m]
24
+ else
25
+ raise NoMethodError, "#{ m}"
26
+ end
27
+ end
28
+
29
+ # http://noobkit.com/show/ruby/gems/development/merb/hash/symbolize_keys-21.html
30
+ def symbolize_keys!
31
+ each do |k,v|
32
+ sym = k.respond_to?(:to_sym) ? k.to_sym : k
33
+ self[sym] = Hash === v ? v.symbolize_keys! : v
34
+ delete(k) unless k == sym
35
+ end
36
+ self
37
+ end
38
+ end
@@ -0,0 +1,10 @@
1
+ require 'darkext/array'
2
+
3
+ class Integer
4
+ # Computes the factorial of the Integer
5
+ def fact
6
+ raise ArgumentError.new('Cannot compute factorial of negative number') if 0 > self
7
+ return 1 if self.zero?
8
+ return (1..self).to_a.product
9
+ end
10
+ end
data/lib/darkext/io.rb ADDED
@@ -0,0 +1,37 @@
1
+ require 'darkext/hash'
2
+
3
+ module DarkIO
4
+ # Runs a block and captures the output it generates
5
+ def self.capture_output(opts = { }) # yield e
6
+ opts = { :stdout => true, :stderr => false }.merge(opts)
7
+ cout,cerr = opts[:stdout],opts[:stderr]
8
+
9
+ yield and return if !cout && !cerr
10
+
11
+ old_stdout = STDOUT.dup if cout
12
+ old_stderr = STDERR.dup if cerr
13
+
14
+ r_stdout,w_stdout = IO.pipe if cout
15
+ r_stderr,w_stderr = IO.pipe if cerr
16
+
17
+ STDOUT.reopen(w_stdout) if cout
18
+ STDERR.reopen(w_stderr) if cerr
19
+
20
+ begin
21
+ yield
22
+ ensure
23
+ STDOUT.reopen(old_stdout) if cout
24
+ STDERR.reopen(old_stderr) if cerr
25
+ w_stdout.close if cout
26
+ w_stderr.close if cerr
27
+ end
28
+
29
+ ret_stdout = r_stdout.read if cout
30
+ ret_stderr = r_stderr.read if cerr
31
+ r_stdout.close if cout
32
+ r_stderr.close if cerr
33
+ return ret_stdout,ret_stderr if cout && cerr
34
+ return ret_stdout if cout
35
+ return ret_stderr if cerr
36
+ end
37
+ end
@@ -0,0 +1,28 @@
1
+ require 'net/http'
2
+
3
+ module Net
4
+ def self.download(url,limit = 10)
5
+ raise ArgumentError, 'HTTP redirect too deep' if limit == 0
6
+ #url = URI.parse(url)
7
+ #req = Net::HTTP::Get.new(url.path)
8
+ #req['User-Agent'] = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.7) Gecko/2009030422 Ubuntu/8.10 (intrepid) Firefox/3.0.7"
9
+ #resp = Net::HTTP.new(url.host, url.port).start { |http| http.request(req) }
10
+ resp = Net::HTTP.get_response(URI.parse(url))
11
+ case resp
12
+ when Net::HTTPSuccess then resp
13
+ when Net::HTTPRedirection then download(resp['location'], limit - 1)
14
+ else resp.error!
15
+ end
16
+ end
17
+
18
+ def self.download_and_save(url,path = nil)
19
+ if path.nil?
20
+ path = File.expand_path(url.split('/').last)
21
+ else
22
+ path = File.expand_path(path)
23
+ end
24
+ raise ArgumentError.new('Save path is a directory') if File.directory?(path)
25
+ resp = download(url)
26
+ open(path,'w') { |file| file.write(resp.body) } if resp.is_a?(Net::HTTPSuccess)
27
+ end
28
+ end
@@ -0,0 +1,35 @@
1
+ require 'mathn'
2
+
3
+ class Numeric
4
+ # Squares the number
5
+ def square
6
+ self * self
7
+ end
8
+
9
+ # Cube the number
10
+ def cube
11
+ self.square * self
12
+ end
13
+
14
+ # Finds the square root of the number
15
+ def sqrt
16
+ Math.sqrt(self)
17
+ end
18
+
19
+ # Do some other roots
20
+ def root(n = 2)
21
+ return self if 1 == n
22
+ return self.sqrt if 2 == n
23
+ self ** (1 / n.to_f)
24
+ end
25
+
26
+ # Finds the log base e of the number
27
+ def ln
28
+ Math::log(self)
29
+ end
30
+
31
+ # Finds the log base 10 of the number
32
+ def log
33
+ Math::log10(self)
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ class Object
2
+ def try(*args, &block)
3
+ return nil if self.nil?
4
+ block_given? ? yield(self) : self.__send__(args.shift, *args)
5
+ end
6
+
7
+ def tap
8
+ yield(self)
9
+ return self
10
+ end
11
+ end
@@ -0,0 +1,70 @@
1
+ module Sinatra
2
+ module DarkHelpers
3
+ module HelperMethods
4
+ def view(view, options = {})
5
+ html = haml(view,options)
6
+ flash.clear
7
+ html
8
+ end
9
+
10
+ def partial(view, options = {})
11
+ haml(view,options.merge(:layout => false))
12
+ end
13
+
14
+ def css_link_tag(sheet, media = 'screen,projection')
15
+ partial("%link{ :type => 'text/css', :href => '#{options.slash ? '/' : ''}stylesheets/#{sheet}.css', :rel => 'stylesheet', :media => '#{media}' }")
16
+ end
17
+
18
+ def js_script_tag(script)
19
+ partial("%script{ :type => 'text/javascript', :src => '#{options.slash ? '/' : ''}javascripts/#{script}.js' }")
20
+ end
21
+
22
+ def js_tag(script)
23
+ @dsh_script = script
24
+ temp = ["%script{ :type => 'text/javascript' }",
25
+ " //<![CDATA[",
26
+ " = @dsh_script",
27
+ " //]]>"].join("\n")
28
+ partial(temp)
29
+ end
30
+
31
+ def flash
32
+ session[:flash] = {} if session[:flash] && session[:flash].class != Hash
33
+ session[:flash] ||= {}
34
+ end
35
+
36
+ def host
37
+ "#{protocol}://#{request.env['HTTP_HOST']}"
38
+ end
39
+
40
+ def protocol
41
+ request.env['rack.url_scheme']
42
+ end
43
+
44
+ def server_name
45
+ request.env['SERVER_NAME']
46
+ end
47
+
48
+ def set_title(extra)
49
+ @title = "#{options.site_name} - #{extra}"
50
+ end
51
+
52
+ def base
53
+ host + options.site_base
54
+ end
55
+
56
+ def redirect_back
57
+ redirect(request.env['HTTP_REFERER'])
58
+ end
59
+ end
60
+
61
+ def self.registered(app)
62
+ app.helpers(HelperMethods)
63
+ app.disable(:slash)
64
+ app.set(:site_base, '/')
65
+ app.enable(:sessions)
66
+ end
67
+ end
68
+
69
+ register DarkHelpers
70
+ end