darkext 0.12.0

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.
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