darkext 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|