gnetvibes 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/gnetvibes ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $KCODE = "U"
4
+ require 'rubygems'
5
+
6
+ require 'fileutils'
7
+ require 'gtk2'
8
+
9
+ require 'gnetvibes/config'
10
+ require 'gnetvibes/gui'
11
+
12
+ FileUtils.mkdir_p(GNetvibes::CACHE) if not File.exists?(GNetvibes::CACHE)
13
+
14
+ gui = GNetvibes::GUI.new
15
+ gui.login_dialog.show_all
16
+ gui.login_dialog.run
17
+
18
+ Gtk.main
@@ -0,0 +1,117 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'cgi'
4
+ require 'digest/sha1'
5
+
6
+ module GNetvibes
7
+ class API
8
+
9
+ URL = {
10
+ :base => URI.parse('http://www.netvibes.com'),
11
+ :login => URI.parse('http://www.netvibes.com/user/signIn.php'),
12
+ :data => URI.parse('http://www.netvibes.com/get/userData.php'),
13
+ :save => URI.parse('http://www.netvibes.com/save/userData.php')
14
+ }
15
+
16
+ attr_reader :tabs, :modules
17
+
18
+ def initialize
19
+ @active_user_id = nil
20
+ @active_session_id = nil
21
+ @data = nil
22
+ @key = nil
23
+ end
24
+
25
+ def login(email, password)
26
+ res = Net::HTTP.post_form(URL[:login], {'email'=> email.strip, 'password' => password.strip})
27
+ if res.body.strip == 'success'
28
+ @key = Digest::SHA1.new(email + password).hexdigest
29
+ cookies = CGI::Cookie::parse(res['set-cookie'])
30
+ @active_user_id = cookies['activeUserID'].value
31
+ @active_session_id = cookies['activeSessionID'].value
32
+ refresh
33
+ true
34
+ else
35
+ false
36
+ end
37
+ end
38
+
39
+ def refresh(force = false)
40
+ if not force and File.exists?(DATA) and File.mtime(DATA) > Time.now - EXPIRE
41
+ @data = eval(crypt(File.read(DATA), @key))
42
+ else
43
+ res = Net::HTTP.start(URL[:data].host, URL[:data].port) do |http|
44
+ headers = {'Cookie' => "activeUserID=#{@active_user_id}; activeSessionID=#{@active_session_id}"}
45
+ http.request(Net::HTTP::Get.new(URL[:data].path, headers))
46
+ end
47
+ @data = json2ruby(unicode(res.body))
48
+ dump
49
+ end
50
+ @tabs = {}
51
+ @modules = {}
52
+ @data['tabs'].each { |t| @tabs[t['id'].to_i] = t }
53
+ @data['modules'].each { |m| @modules[m['id'].to_i] = m }
54
+ true
55
+ end
56
+
57
+ def each_modules_in_tab(tab)
58
+ @data['modules'].select{|m| m['tab'].to_i == tab.to_i}.each do |m|
59
+ yield m
60
+ end
61
+ end
62
+
63
+ def each_todo_list_item(mod)
64
+ raise "Module is not a TodoList" if @modules[mod.to_i]['name'] != 'TodoList'
65
+ list = []
66
+ data = @modules[mod.to_i]['data']
67
+ data.select{|k,v| k =~ /^tdval/}.each do |k,v|
68
+ id = k[/\d+$/].to_i
69
+ list[id] = { 'title' => v, 'checked' => data["tdchk_#{id}"].to_i == 1 }
70
+ end
71
+ list.each do |i|
72
+ yield i
73
+ end
74
+ end
75
+
76
+ def dump
77
+ File.open(DATA, 'w') do |fd|
78
+ fd.write crypt(@data.inspect, @key)
79
+ end
80
+ end
81
+
82
+ def download(uri)
83
+ if uri =~ /^\//
84
+ url = URL[:base] + uri
85
+ else
86
+ url = URI.parse(uri)
87
+ end
88
+ req = Net::HTTP::Get.new(url.path)
89
+ res = Net::HTTP.start(url.host, url.port) {|http| http.request(req) }
90
+ res.body
91
+ end
92
+
93
+ private
94
+
95
+ UNICODE_TABLE = {
96
+ 'u00b0' => '°', 'u00e0' => 'à', 'u00e2' => 'â', 'u00e7' => 'ç',
97
+ 'u00e8' => 'è', 'u00e9' => 'é', 'u00ea' => 'ê', 'u00ee' => 'î',
98
+ 'u00f4' => 'ô', 'u2019' => '\''
99
+ }
100
+
101
+ def unicode(s)
102
+ s.gsub(/u[a-f\d]{4}/) { |c| UNICODE_TABLE[c] }
103
+ end
104
+
105
+ def json2ruby(s)
106
+ eval(s.gsub(/":/, '"=>'))
107
+ end
108
+
109
+ def crypt(buf, key)
110
+ buf = buf.unpack("c*")
111
+ key = key.unpack("c*")
112
+ key *= buf.size / key.size + 1
113
+ buf.zip(key).collect{|c1,c2| c1^c2}.pack("c*")
114
+ end
115
+
116
+ end
117
+ end
@@ -0,0 +1,72 @@
1
+ require 'gnetvibes/api'
2
+ require 'digest/sha1'
3
+
4
+ module GNetvibes
5
+ class GUI
6
+
7
+ def edit(obj, mod)
8
+ mod = @api.modules[mod.to_i]
9
+ @title.text = mod['title']
10
+ @buf.text = mod['data']['text'].strip
11
+ @txt.grab_focus
12
+ @edit_dialog.show_all
13
+ @edit_dialog.run
14
+ end
15
+
16
+ def save(obj, ev)
17
+ if ev == Gtk::Dialog::RESPONSE_ACCEPT
18
+ puts "save"
19
+ end
20
+ @edit_dialog.hide_on_delete
21
+ end
22
+
23
+ def login(obj, ev)
24
+ if (ev.is_a? Gdk::EventKey and (ev.keyval == Gdk::Keyval::GDK_KP_Enter or ev.keyval == Gdk::Keyval::GDK_Return)) or
25
+ (ev.is_a? Fixnum and ev == Gtk::Dialog::RESPONSE_ACCEPT)
26
+ if @api.login(@login.text, @password.text)
27
+ refresh
28
+ @login_dialog.destroy
29
+ else
30
+ raise "Login failed"
31
+ end
32
+ end
33
+
34
+ if (ev.is_a? Fixnum and ev == Gtk::Dialog::RESPONSE_REJECT)
35
+ exit!
36
+ end
37
+ end
38
+
39
+ def refresh
40
+ @tray.tooltip = "#{GNetvibes::NAME} refreshing...";
41
+
42
+ @api.tabs.each do |id, tab|
43
+ icon = File.join(CACHE, Digest::SHA1.new(tab['icon']).hexdigest)
44
+ if not File.exists?(icon)
45
+ File.open(icon, 'w') do |fd|
46
+ fd.puts @api.download(tab['icon'])
47
+ end
48
+ end
49
+
50
+ submenutitle = Gtk::ImageMenuItem.new(tab['title'])
51
+ submenutitle.image = Gtk::Image.new(icon)
52
+
53
+ submenu = Gtk::Menu.new
54
+ @api.each_modules_in_tab(id) do |mod|
55
+ case mod['name']
56
+ when 'PostIt'
57
+ item = Gtk::ImageMenuItem.new(mod['title'])
58
+ item.image = Gtk::Image.new(@icon_webnote)
59
+ item.signal_connect("activate", mod['id'], &method(:edit))
60
+ submenu.append(item)
61
+ end
62
+ end
63
+ submenutitle.submenu = submenu
64
+ @menu.prepend(submenutitle)
65
+ end
66
+
67
+ @menu.show_all
68
+ @tray.tooltip = GNetvibes::NAME;
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,15 @@
1
+ module GNetvibes
2
+ NAME = 'gNetvibes'
3
+ VERSION = '0.1'
4
+ COPYRIGHT = 'Copyright (C) 2007 Florent Solt'
5
+ DESC = 'Netvibes integration with the Gnome Desktop'
6
+ AUTHOR = 'Florent Solt'
7
+ EMAIL = 'florent@solt.biz'
8
+ HOMEPAGE = 'http://rubyforge.org/projects/gnetvibes/'
9
+
10
+ CACHE = File.join(ENV['HOME'], ".#{GNetvibes::NAME.downcase}", "cache")
11
+ DATA = File.join(ENV['HOME'], ".#{GNetvibes::NAME.downcase}", "data")
12
+ EXPIRE = 5 * 60
13
+ end
14
+
15
+
@@ -0,0 +1,109 @@
1
+ require 'gnetvibes/callback'
2
+
3
+ module GNetvibes
4
+ class GUI
5
+
6
+ attr_reader :login_dialog, :edit_dialog
7
+
8
+ def initialize
9
+ # API
10
+ @api = GNetvibes::API.new
11
+
12
+ # Icons
13
+ @icon = Gdk::Pixbuf.new(File.join(File.dirname(__FILE__), "ico.png"))
14
+ @icon_webnote = Gdk::Pixbuf.new(File.join(File.dirname(__FILE__), "webnote.gif"))
15
+
16
+ # Login Dialog
17
+ @login_dialog = Gtk::Dialog.new("#{GNetvibes::NAME} Authentification", nil, Gtk::Dialog::MODAL,
18
+ [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT],
19
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT])
20
+ @login_dialog.icon = @icon
21
+ @login_dialog.resizable = false
22
+
23
+ @login = Gtk::Entry.new
24
+ @password = Gtk::Entry.new
25
+
26
+ table = Gtk::Table.new(2, 3)
27
+ table.border_width = 5
28
+ image = Gtk::Image.new(Gtk::Stock::DIALOG_AUTHENTICATION, Gtk::IconSize::DIALOG)
29
+ table.attach(image, 0, 1, 0, 2, nil, nil, 10, 10)
30
+
31
+ table.attach_defaults(Gtk::Label.new("Login:"), 1, 2, 0, 1)
32
+ table.attach_defaults(@login, 2, 3, 0, 1)
33
+
34
+ table.attach_defaults(Gtk::Label.new("Password:"), 1, 2, 1, 2)
35
+ @password.visibility = false
36
+ @password.invisible_char = 0
37
+ table.attach_defaults(@password, 2, 3, 1, 2)
38
+ @login_dialog.vbox.pack_start(table)
39
+ @password.signal_connect("key_release_event", &method(:login))
40
+
41
+ if not ARGV.empty?
42
+ @login.editable = false
43
+ @login.text = ARGV.first
44
+ @password.grab_focus
45
+ else
46
+ @login.grab_focus
47
+ end
48
+
49
+ @login_dialog.signal_connect('response', &method(:login))
50
+
51
+ # Status Tray Icon
52
+ @tray = Gtk::StatusIcon.new
53
+ @tray.pixbuf = @icon
54
+
55
+ @menu = Gtk::Menu.new
56
+ @menu.append(Gtk::SeparatorMenuItem.new)
57
+
58
+ item = Gtk::ImageMenuItem.new(Gtk::Stock::REFRESH)
59
+ item.signal_connect("activate", &method(:refresh))
60
+ @menu.append(item)
61
+
62
+ item = Gtk::ImageMenuItem.new(Gtk::Stock::QUIT)
63
+ item.signal_connect("activate") do
64
+ Gtk.main_quit
65
+ end
66
+ @menu.append(item)
67
+ @menu.show_all
68
+
69
+ @tray.signal_connect('popup-menu') do |w, button, time|
70
+ @menu.popup(nil, nil, button, time) do
71
+ @tray.position_menu(@menu)
72
+ end
73
+ end
74
+
75
+ # Text
76
+ @buf = Gtk::TextBuffer.new
77
+ @txt = Gtk::TextView.new(@buf)
78
+
79
+ @title = Gtk::Entry.new
80
+
81
+ # Edit Dialog
82
+ @edit_dialog = Gtk::Dialog.new(GNetvibes::NAME, nil, Gtk::Dialog::MODAL,
83
+ [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT],
84
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT])
85
+
86
+ scroll = Gtk::ScrolledWindow.new
87
+ scroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
88
+ scroll.add(@txt)
89
+ scroll.border_width = 1
90
+
91
+ frame = Gtk::Frame.new
92
+ frame.add(scroll)
93
+
94
+ @edit_dialog.set_default_size(300, 300)
95
+ @edit_dialog.signal_connect("delete-event") do
96
+ @edit_dialog.hide_on_delete
97
+ end
98
+
99
+ @edit_dialog.title = GNetvibes::NAME
100
+ @edit_dialog.modal = true
101
+ @edit_dialog.border_width = 10
102
+ @edit_dialog.icon = @icon
103
+ @edit_dialog.vbox.pack_start(@title, false, false)
104
+ @edit_dialog.vbox.pack_start(frame, true, true, 10)
105
+ @edit_dialog.signal_connect('response', &method(:save))
106
+ end
107
+
108
+ end
109
+ end
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: gnetvibes
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.1"
7
+ date: 2007-03-17 00:00:00 +01:00
8
+ summary: Netvibes integration with the Gnome Desktop
9
+ require_paths:
10
+ - lib
11
+ email: florent@solt.biz
12
+ homepage: http://rubyforge.org/projects/gnetvibes/
13
+ rubyforge_project:
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Florent Solt
31
+ files:
32
+ - lib/gnetvibes/callback.rb
33
+ - lib/gnetvibes/api.rb
34
+ - lib/gnetvibes/config.rb
35
+ - lib/gnetvibes/gui.rb
36
+ - lib/gnetvibes/ico.png
37
+ - lib/gnetvibes/webnote.gif
38
+ test_files: []
39
+
40
+ rdoc_options: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ executables:
45
+ - gnetvibes
46
+ extensions: []
47
+
48
+ requirements: []
49
+
50
+ dependencies: []
51
+