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.
- data/.gitignore +4 -0
- data/History.txt +140 -0
- data/LICENSE +21 -0
- data/README.md +45 -0
- data/Rakefile +45 -0
- data/TODO +4 -0
- data/VERSION.yml +4 -0
- data/app_generators/sinatra_app_generator.rb +57 -0
- data/app_generators/templates/app.rb +16 -0
- data/app_generators/templates/config.ru +2 -0
- data/app_generators/templates/error.rb +8 -0
- data/app_generators/templates/gitignore +0 -0
- data/app_generators/templates/helpers.rb +12 -0
- data/app_generators/templates/http_method.rb +8 -0
- data/app_generators/templates/options.rb +9 -0
- data/bin/sinatra-app +14 -0
- data/darkext.gemspec +105 -0
- data/lib/darkext.rb +13 -0
- data/lib/darkext/array.rb +52 -0
- data/lib/darkext/beagle.rb +88 -0
- data/lib/darkext/boolean.rb +17 -0
- data/lib/darkext/fiber.rb +48 -0
- data/lib/darkext/float.rb +6 -0
- data/lib/darkext/hash.rb +38 -0
- data/lib/darkext/integer.rb +10 -0
- data/lib/darkext/io.rb +37 -0
- data/lib/darkext/net.rb +28 -0
- data/lib/darkext/numeric.rb +35 -0
- data/lib/darkext/object.rb +11 -0
- data/lib/darkext/sinatra.rb +70 -0
- data/lib/darkext/sitemap_generator.rb +90 -0
- data/lib/darkext/statistics.rb +197 -0
- data/lib/darkext/string.rb +63 -0
- data/lib/darkext/symbol.rb +7 -0
- data/spec/array_spec.rb +112 -0
- data/spec/beagle_spec.rb +42 -0
- data/spec/boolean_spec.rb +53 -0
- data/spec/fiber_spec.rb +35 -0
- data/spec/float_spec.rb +18 -0
- data/spec/hash_spec.rb +26 -0
- data/spec/integer_spec.rb +22 -0
- data/spec/io_spec.rb +44 -0
- data/spec/net_spec.rb +23 -0
- data/spec/numeric_spec.rb +52 -0
- data/spec/object_spec.rb +28 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/statistics_spec.rb +162 -0
- data/spec/string_spec.rb +54 -0
- data/spec/symbol_spec.rb +16 -0
- 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,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
|
data/lib/darkext/hash.rb
ADDED
@@ -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
|
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
|
data/lib/darkext/net.rb
ADDED
@@ -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,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
|