uwa 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/bin/uwa CHANGED
@@ -8,15 +8,13 @@ CONFIG = {
8
8
  :port => '42080',
9
9
  :dynamic => false,
10
10
  :debug => false,
11
- :path => '.'
12
11
  }
13
12
 
14
13
  OPTIONS = [
15
14
  [ '--help', '-h', GetoptLong::NO_ARGUMENT, 'Display this help' ],
16
15
  [ '--host', '-b', GetoptLong::REQUIRED_ARGUMENT, 'Set host/ip' ],
17
16
  [ '--port', '-p', GetoptLong::REQUIRED_ARGUMENT, 'Set port' ],
18
- [ '--path', '-i', GetoptLong::REQUIRED_ARGUMENT, 'Set path to scan for widget' ],
19
- [ '--dynamic', '-r', GetoptLong::NO_ARGUMENT, 'Enable dynamic mode (auto reload)' ],
17
+ [ '--dynamic', '-r', GetoptLong::NO_ARGUMENT, 'Enable dynamic mode (auto reload ressources only)' ],
20
18
  [ '--debug', '-d', GetoptLong::NO_ARGUMENT, 'Enable debug mode' ],
21
19
  ]
22
20
 
@@ -35,29 +33,26 @@ opts.each do |opt, arg|
35
33
  CONFIG[:host] = arg
36
34
  when '--port'
37
35
  CONFIG[:port] = arg
38
- when '--path'
39
- CONFIG[:path] = arg
40
36
  when '--dynamic'
41
37
  CONFIG[:dynamic] = true
42
38
  when '--debug'
43
39
  CONFIG[:debug] = true
40
+ $mongrel_debug_client = true
44
41
  end
45
42
  end
46
43
 
47
44
  begin
48
45
  m = Mongrel::HttpServer.new(CONFIG[:host], CONFIG[:port])
49
- Dir[File.join(CONFIG[:path], '*')].each do |d|
50
- if File.directory?(d)
51
- name = File.basename(d)
52
- require File.join(d, 'widget.rb')
53
- klass = self.class.const_get(name.capitalize + 'Widget')
54
- widget = klass.new
55
- widget.script = File.join(d, 'script.js')
56
- widget.css = File.join(d, 'style.css')
57
- m.register('/' + name.downcase, widget)
58
- end
46
+ UWA::Plugin.load.each do |name, config|
47
+ widget = config[:class].new
48
+ widget.script = config[:script]
49
+ widget.css = config[:css]
50
+ m.register('/' + name, widget)
59
51
  end
52
+ m.register('/proxy', UWA::Proxy.new)
60
53
  m.run.join
61
54
  rescue
62
- puts "Error: #{$!.message}"
55
+ STDERR.puts "Error: #{$!.message}"
56
+ STDERR.puts "Retrying..."
57
+ retry
63
58
  end
data/lib/uwa/config.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module UWA
2
2
  NAME = 'UWA'
3
- VERSION = '0.1'
4
- DESC = 'Widget server that implements UWA specs (http://dev.netvibes.com/doc/universal_widget_api)'
3
+ VERSION = '0.2'
4
+ DESC = 'Widget server for UWA specs by Netvibes (http://dev.netvibes.com/doc/universal_widget_api)'
5
5
  AUTHOR = 'Florent Solt'
6
6
  EMAIL = 'florent@solt.biz'
7
7
  HOMEPAGE = 'http://gnetvibes.rubyforge.org'
@@ -0,0 +1,124 @@
1
+ require 'rubygems'
2
+
3
+ module UWA
4
+ class Handler < Mongrel::HttpHandler
5
+ attr_accessor :css, :script
6
+
7
+ def initialize
8
+ super
9
+ @author = 'No author'
10
+ @description = 'No description'
11
+ @title = 'Widget'
12
+ @icon = 'http://www.netvibes.com/favicon.ico'
13
+ @apiVersion = '1.0'
14
+ @inline = true
15
+ @debugMode = false
16
+ @preferences = []
17
+ @keywords = self.class.name.downcase
18
+ @css = []
19
+ @script = []
20
+ @cache = {:css => nil, :script => nil}
21
+ end
22
+
23
+ def log(title, msg)
24
+ return if not CONFIG[:debug]
25
+ if msg.is_a? Array
26
+ msg.each { |l| STDERR.puts " " + l }
27
+ else
28
+ STDERR.puts "#{Time.now}: #{title.to_s.upcase}: #{msg}"
29
+ end
30
+ STDERR.flush
31
+ end
32
+
33
+ def process(req,res)
34
+ log(req.params['REQUEST_METHOD'], req.params['REQUEST_URI'])
35
+ query = query_string(req.params['QUERY_STRING'])
36
+ log(:QUERY, query.inspect)
37
+ if req.params['REQUEST_PATH'].split('/', 3)[2].nil? and query['url'].nil?
38
+ res.start(200) do |head, out|
39
+ head["Content-Type"] = "text/html"
40
+ xml = Builder::XmlMarkup.new(:indent => 4, :target => out)
41
+ xml.instruct!
42
+ xml.declare! :DOCTYPE, :html, :PUBLIC, '-//W3C//DTD XHTML 1.0 Strict//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'
43
+ xml.html(:xmlns => 'http://www.w3.org/1999/xhtml', 'xmlns:widget' => 'http://www.netvibes.com/ns/') do |xml|
44
+ xml.head do |xml|
45
+ xml.meta(:name => 'author', :content => @author)
46
+ xml.meta(:name => 'description', :content => @description)
47
+ xml.meta(:name => 'apiVersion', :content => @apiVersion)
48
+ xml.meta(:name => 'inline', :content => @inline.to_s)
49
+ xml.meta(:name => 'debugMode', :content => @debugMode.to_s)
50
+ xml.meta(:name => 'keywords', :content => @keywords)
51
+ xml.link(:rel => :stylesheet, :type => 'text/css', :href => 'http://www.netvibes.com/themes/uwa/style.css')
52
+ xml.script("", :type => 'text/javascript', :src => 'http://www.netvibes.com/js/UWA/load.js.php?env=Standalone')
53
+ xml.tag!('widget:preferences') do |xml|
54
+ @preferences.each do |pref|
55
+ xml.preference(pref)
56
+ end
57
+ end
58
+ xml.title(@title)
59
+ xml.link(:rel => :icon, :type => 'image/png', :href => @icon)
60
+ css.each { |c| xml.style("\n" + c, :type => 'text/css') }
61
+ xml.script(:type => 'text/javascript') do |xml|
62
+ url = 'http://' + req.params['HTTP_HOST'] + req.params['REQUEST_PATH'] + '/'
63
+ xml << "widget.remoteUrl = '#{url}'\n"
64
+ ['Text', 'Json', 'Xml', 'Feed'].each do |m|
65
+ xml << "widget.remote#{m} = function(uri, cb) { UWA.Data.get#{m}('#{url}' + uri, cb); };\n"
66
+ end
67
+ script.each do |s|
68
+ xml << "\n#{s}\n"
69
+ end
70
+ xml << "if (document.location && document.location.hostname == 'localhost') { UWA.proxies.ajax = '/proxy'; }\n"
71
+ end
72
+ end
73
+ xml.body do |xml|
74
+ body xml
75
+ end
76
+ end
77
+ xml.target!
78
+ end
79
+ else
80
+ method = req.params['REQUEST_PATH'].split('/', 3)[2].to_sym
81
+ if self.respond_to?(method)
82
+ res.start(200) do |head, out|
83
+ begin
84
+ self.send(method, query, head, out)
85
+ rescue Exception
86
+ log(:error, "#{$!.message} <#{$!.class.name}>")
87
+ log(:error, $!.backtrace)
88
+ end
89
+ end
90
+ else
91
+ res.start(404) do |head, out|
92
+ out.write("Method \"#{method}\" not found")
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ def script
99
+ if @cache[:script].to_a.empty? or CONFIG[:dynamic]
100
+ @cache[:script] = @script.collect { |s| File.read(s) }
101
+ end
102
+ @cache[:script].to_a
103
+ end
104
+
105
+ def css
106
+ if @cache[:css].to_a.empty? or CONFIG[:dynamic]
107
+ @cache[:css] = @css.collect { |s| File.read(s) }
108
+ end
109
+ @cache[:css].to_a
110
+ end
111
+
112
+ def body(xml)
113
+ xml << 'Loading...'
114
+ end
115
+
116
+ def query_string(req)
117
+ query = {}
118
+ CGI::parse(req.to_s).each do |k,v|
119
+ query[k] = v.first if v.size <= 1
120
+ end
121
+ query
122
+ end
123
+ end
124
+ end
data/lib/uwa/plugin.rb ADDED
@@ -0,0 +1,46 @@
1
+ require 'singleton'
2
+
3
+ # Plugin Manager inspired by GemPlugin
4
+ module UWA
5
+ class Plugin
6
+ include Singleton
7
+ def self.method_missing(name, *args)
8
+ self.instance.send(name, *args)
9
+ end
10
+
11
+ attr_reader :list
12
+
13
+ def initialize
14
+ @list = {}
15
+ end
16
+
17
+ def load
18
+ sdir = File.join(Gem.dir, "specifications")
19
+ gems = Gem::SourceIndex.from_installed_gems(sdir)
20
+ needs = {"uwa" => false}
21
+ gems.each do |path, gem|
22
+ next if @list.has_key? gem.name
23
+ check = needs.dup
24
+ gem.dependencies.each do |dep|
25
+ if check.has_key? dep.name
26
+ check[dep.name] = !check[dep.name]
27
+ end
28
+ end
29
+ if (check.select {|name,test| !test}).length == 0
30
+ gem_dir = File.join(Gem.dir, "gems", path)
31
+ file = File.join(gem_dir, "lib", gem.name, "widget.rb")
32
+ before = UWA::Widget.constants rescue []
33
+ require file
34
+ after = UWA::Widget.constants
35
+ @list[gem.name] = {
36
+ :base => gem_dir,
37
+ :class => UWA::Widget.const_get((after - before).first.to_sym),
38
+ :script => Dir[File.join(gem_dir, 'ressources', '*.js')],
39
+ :css => Dir[File.join(gem_dir, 'ressources', '*.css')]
40
+ }
41
+ end
42
+ end
43
+ @list
44
+ end
45
+ end
46
+ end
data/lib/uwa/proxy.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ # http://dev.netvibes.com/doc/uwa_faq
5
+ module UWA
6
+ class Proxy < Mongrel::HttpHandler
7
+
8
+ def process(req,res)
9
+ query = CGI::parse(req.params['QUERY_STRING'])
10
+ url = URI.parse(query['url'].to_a.first)
11
+ if req.params['REMOTE_ADDR'] == '127.0.0.1'
12
+ res.start(200) do |head, out|
13
+ head["Content-Type"] = "text/html"
14
+ unless url.nil?
15
+ STDERR.puts "#{Time.now}: PROXY: #{url}" if CONFIG[:debug]
16
+ res = Net::HTTP.start(url.host, url.port) do |http|
17
+ http.get(url.path)
18
+ end
19
+ out.write(res.body)
20
+ end
21
+ end
22
+ else
23
+ STDERR.puts "#{Time.now}: DENIED: #{url} from #{req.params['REMOTE_ADDR']}" if CONFIG[:debug]
24
+ end
25
+ end
26
+ end
27
+ end
data/lib/uwa.rb CHANGED
@@ -1,3 +1,5 @@
1
1
  require 'mongrel'
2
2
  require 'builder'
3
- require 'uwa/widget'
3
+ require 'uwa/proxy'
4
+ require 'uwa/handler'
5
+ require 'uwa/plugin'
metadata CHANGED
@@ -3,9 +3,9 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: uwa
5
5
  version: !ruby/object:Gem::Version
6
- version: "0.1"
7
- date: 2007-03-25 00:00:00 +01:00
8
- summary: Widget server that implements UWA specs (http://dev.netvibes.com/doc/universal_widget_api)
6
+ version: "0.2"
7
+ date: 2007-03-28 00:00:00 +02:00
8
+ summary: Widget server for UWA specs by Netvibes (http://dev.netvibes.com/doc/universal_widget_api)
9
9
  require_paths:
10
10
  - lib
11
11
  email: florent@solt.biz
@@ -29,8 +29,10 @@ post_install_message:
29
29
  authors:
30
30
  - Florent Solt
31
31
  files:
32
+ - lib/uwa/handler.rb
32
33
  - lib/uwa/config.rb
33
- - lib/uwa/widget.rb
34
+ - lib/uwa/plugin.rb
35
+ - lib/uwa/proxy.rb
34
36
  - lib/uwa.rb
35
37
  test_files: []
36
38
 
data/lib/uwa/widget.rb DELETED
@@ -1,84 +0,0 @@
1
- require 'rubygems'
2
-
3
- module UWA
4
- class Widget < Mongrel::HttpHandler
5
- attr_accessor :title, :icon, :apiVersion, :inline, :debugMode,
6
- :preferences, :css, :script
7
-
8
- def initialize
9
- super
10
- @author = 'No author'
11
- @description = 'No description'
12
- @title = 'Widget'
13
- @icon = 'http://www.netvibes.com/favicon.ico'
14
- @apiVersion = '1.0'
15
- @inline = 'true'
16
- @debugMode = 'false'
17
- @preferences = []
18
- @css = nil
19
- @script = nil
20
- @cache = {:config => nil, :css => nil, :script => nil}
21
- end
22
-
23
- def process(req,res)
24
- res.start(200) do |head, out|
25
- head["Content-Type"] = "text/html"
26
- xml = Builder::XmlMarkup.new(:indent => 4, :target => out)
27
- xml.instruct!
28
- xml.declare! :DOCTYPE, :html, :PUBLIC, '-//W3C//DTD XHTML 1.0 Strict//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'
29
- xml.html(:xmlns => 'http://www.w3.org/1999/xhtml', 'xmlns:widget' => 'http://www.netvibes.com/ns/') do |xml|
30
- xml.head do |xml|
31
- xml.meta(:name => 'author', :content => @author)
32
- xml.meta(:name => 'description', :content => @description)
33
- xml.meta(:name => 'apiVersion', :content => @apiVersion)
34
- xml.meta(:name => 'inline', :content => @inline)
35
- xml.meta(:name => 'debugMode', :content => @debugMode)
36
- xml.link(:rel => :stylesheet, :type => 'text/css', :href => 'http://www.netvibes.com/themes/uwa/style.css')
37
- xml.script("", :type => 'text/javascript', :src => 'http://www.netvibes.com/js/UWA/load.js.php?env=Standalone')
38
- xml.tag!('widget:preferences') do |xml|
39
- @preferences.each do |pref|
40
- xml.preference(pref)
41
- end
42
- end
43
- xml.title(@title)
44
- xml.link(:rel => :icon, :type => 'image/png', :href => @icon)
45
- xml.style(css, :type => 'text/css')
46
- xml.script(script, :type => 'text/javascript')
47
- end
48
- xml.body do |xml|
49
- body xml
50
- end
51
- end
52
- xml.target!
53
- end
54
- end
55
-
56
- def script
57
- begin
58
- if CONFIG[:dynamic]
59
- File.read(@script)
60
- else
61
- @cache[:script] ||= File.read(@script)
62
- end
63
- rescue Errno::ENOENT
64
- nil
65
- end
66
- end
67
-
68
- def css
69
- begin
70
- if CONFIG[:dynamic]
71
- File.read(@css)
72
- else
73
- @cache[:css] ||= File.read(@css)
74
- end
75
- rescue Errno::ENOENT
76
- nil
77
- end
78
- end
79
-
80
- def body(xml)
81
- xml.em('Loading...')
82
- end
83
- end
84
- end