gnetvibes 0.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/gnetvibes +4 -3
- data/lib/gnetvibes/api.rb +61 -7
- data/lib/gnetvibes/config.rb +7 -1
- data/lib/gnetvibes/gui.rb +10 -130
- metadata +4 -6
- data/lib/gnetvibes/callback.rb +0 -93
- data/lib/gnetvibes/ico.png +0 -0
- data/lib/gnetvibes/webnote.gif +0 -0
data/bin/gnetvibes
CHANGED
@@ -12,8 +12,9 @@ require 'gnetvibes/gui'
|
|
12
12
|
FileUtils.mkdir_p(GNetvibes::CACHE) if not File.exists?(GNetvibes::CACHE)
|
13
13
|
FileUtils.mkdir_p(GNetvibes::DATA) if not File.exists?(GNetvibes::DATA)
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
api = GNetvibes::API.new
|
16
|
+
icon = GNetvibes::GUI::Icon.new(api)
|
17
|
+
login = GNetvibes::GUI::LoginDialog.new(api).run
|
18
|
+
icon.refresh
|
18
19
|
|
19
20
|
Gtk.main
|
data/lib/gnetvibes/api.rb
CHANGED
@@ -21,6 +21,8 @@ class API
|
|
21
21
|
@data = nil
|
22
22
|
@key = nil
|
23
23
|
@email = nil
|
24
|
+
@tabs = nil
|
25
|
+
@modules == nil
|
24
26
|
end
|
25
27
|
|
26
28
|
def login(email, password)
|
@@ -40,13 +42,13 @@ class API
|
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
43
|
-
|
44
45
|
def save(id, options)
|
45
|
-
mod = @modules[id]
|
46
|
+
mod = @modules[id.to_i]
|
46
47
|
case mod['name']
|
47
|
-
when
|
48
|
+
when /PostIt/i
|
48
49
|
mod['title'] = options[:title]
|
49
50
|
mod['data']['text'] = options[:text]
|
51
|
+
mod['mode'] = 'module'
|
50
52
|
else
|
51
53
|
raise 'Not implemented'
|
52
54
|
end
|
@@ -59,6 +61,33 @@ class API
|
|
59
61
|
dump
|
60
62
|
end
|
61
63
|
|
64
|
+
def add(tab_id, type, options)
|
65
|
+
case type
|
66
|
+
when /PostIt/i
|
67
|
+
mod = { 'history' => nil, 'mode' => 'new', 'moduleRndld' => rand,
|
68
|
+
'name' => 'PostIt', 'share' => 0, 'status' => 1, 'tab' => tab_id.to_i,
|
69
|
+
'title' => options[:title], 'data' => { 'color' => 'yellow', 'text' => options[:text]}}
|
70
|
+
else
|
71
|
+
raise 'Not implemented'
|
72
|
+
end
|
73
|
+
Net::HTTP.start(URL[:data].host, URL[:data].port) do |http|
|
74
|
+
headers = {'Cookie' => "activeUserID=#{@active_user_id}; activeSessionID=#{@active_session_id}"}
|
75
|
+
post = Net::HTTP::Post.new(URL[:save].path, headers)
|
76
|
+
post.set_form_data(module2post(mod))
|
77
|
+
http.request(post)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def delete(mod)
|
82
|
+
mod = mod.to_i
|
83
|
+
Net::HTTP.start(URL[:data].host, URL[:data].port) do |http|
|
84
|
+
headers = {'Cookie' => "activeUserID=#{@active_user_id}; activeSessionID=#{@active_session_id}"}
|
85
|
+
post = Net::HTTP::Post.new(URL[:save].path, headers)
|
86
|
+
post.set_form_data({'id' => mod, 'mode' => 'close'})
|
87
|
+
http.request(post)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
62
91
|
def refresh(force = false)
|
63
92
|
if force or not load
|
64
93
|
res = Net::HTTP.start(URL[:data].host, URL[:data].port) do |http|
|
@@ -75,14 +104,40 @@ class API
|
|
75
104
|
true
|
76
105
|
end
|
77
106
|
|
78
|
-
def
|
107
|
+
def tab_has?(tab, kind)
|
108
|
+
raise "Unknown module : #{kind}" if not MODULES.keys.include?(kind)
|
109
|
+
@data['modules'].select{|m| m['tab'].to_i == tab.to_i}.each do |m|
|
110
|
+
return true if MODULES[kind] == m['name']
|
111
|
+
end
|
112
|
+
false
|
113
|
+
end
|
114
|
+
|
115
|
+
def each_modules_in_tab(tab, kind = nil)
|
116
|
+
raise "Unknown module : #{kind}" if not MODULES.keys.include?(kind)
|
79
117
|
@data['modules'].select{|m| m['tab'].to_i == tab.to_i}.each do |m|
|
80
|
-
yield m
|
118
|
+
yield m if kind.nil? or MODULES[kind] == m['name']
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def each_webnote_in_tab(tab)
|
123
|
+
each_modules_in_tab(tab, :postit) { |m| yield m }
|
124
|
+
end
|
125
|
+
|
126
|
+
def each_todo_list_in_tab(tab)
|
127
|
+
each_modules_in_tab(tab, :todolist) { |m| yield m }
|
128
|
+
end
|
129
|
+
|
130
|
+
def each_feed_in_tab(tab)
|
131
|
+
each_modules_in_tab(tab, :feed) do |feed|
|
132
|
+
history = feed['data']['history']
|
133
|
+
feed['unread'] = history.split(':')[1..-1].select { |e| e == "0" }.size rescue feed['data']['nbTitles'].to_i
|
134
|
+
p feed
|
135
|
+
yield feed
|
81
136
|
end
|
82
137
|
end
|
83
138
|
|
84
139
|
def each_todo_list_item(mod)
|
85
|
-
raise "Module is not a TodoList" if @modules[mod.to_i]['name'] !=
|
140
|
+
raise "Module is not a TodoList" if @modules[mod.to_i]['name'] != MODULES[:todolist]
|
86
141
|
list = []
|
87
142
|
data = @modules[mod.to_i]['data']
|
88
143
|
data.select{|k,v| k =~ /^tdval/}.each do |k,v|
|
@@ -155,7 +210,6 @@ class API
|
|
155
210
|
post[k] = v
|
156
211
|
end
|
157
212
|
end
|
158
|
-
post['mode'] = 'module'
|
159
213
|
post
|
160
214
|
end
|
161
215
|
|
data/lib/gnetvibes/config.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module GNetvibes
|
2
2
|
NAME = 'gNetvibes'
|
3
|
-
VERSION = '0.
|
3
|
+
VERSION = '0.4'
|
4
4
|
COPYRIGHT = 'Copyright (C) 2007 Florent Solt'
|
5
5
|
DESC = 'Netvibes integration with the Gnome Desktop'
|
6
6
|
AUTHOR = 'Florent Solt'
|
@@ -17,6 +17,12 @@ module GNetvibes
|
|
17
17
|
DATA = File.join(HOME, "data")
|
18
18
|
|
19
19
|
EXPIRE = 5 * 60
|
20
|
+
|
21
|
+
MODULES = {
|
22
|
+
:postit => 'PostIt',
|
23
|
+
:todolist => 'TodoList',
|
24
|
+
:feed => 'RssReader'
|
25
|
+
}
|
20
26
|
end
|
21
27
|
|
22
28
|
|
data/lib/gnetvibes/gui.rb
CHANGED
@@ -1,136 +1,16 @@
|
|
1
|
-
require '
|
1
|
+
require 'digest/sha1'
|
2
|
+
require 'gnetvibes/api'
|
3
|
+
require 'gnetvibes/gui/icon'
|
4
|
+
require 'gnetvibes/gui/dlg_edit'
|
5
|
+
require 'gnetvibes/gui/dlg_login'
|
2
6
|
|
3
7
|
module GNetvibes
|
4
|
-
|
8
|
+
module GUI
|
5
9
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
gui_login
|
17
|
-
gui_edit
|
18
|
-
gui_tray
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def gui_login
|
24
|
-
# Login Dialog
|
25
|
-
@login_dialog = Gtk::Dialog.new("#{GNetvibes::NAME} Authentification", nil, Gtk::Dialog::MODAL,
|
26
|
-
[Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT],
|
27
|
-
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT])
|
28
|
-
@login_dialog.icon = @icon
|
29
|
-
@login_dialog.resizable = false
|
30
|
-
|
31
|
-
@login = Gtk::Entry.new
|
32
|
-
@password = Gtk::Entry.new
|
33
|
-
|
34
|
-
table = Gtk::Table.new(2, 3)
|
35
|
-
table.border_width = 5
|
36
|
-
image = Gtk::Image.new(Gtk::Stock::DIALOG_AUTHENTICATION, Gtk::IconSize::DIALOG)
|
37
|
-
table.attach(image, 0, 1, 0, 2, nil, nil, 10, 10)
|
38
|
-
|
39
|
-
table.attach_defaults(Gtk::Label.new("Login:"), 1, 2, 0, 1)
|
40
|
-
table.attach_defaults(@login, 2, 3, 0, 1)
|
41
|
-
|
42
|
-
table.attach_defaults(Gtk::Label.new("Password:"), 1, 2, 1, 2)
|
43
|
-
@password.visibility = false
|
44
|
-
table.attach_defaults(@password, 2, 3, 1, 2)
|
45
|
-
@login_dialog.vbox.pack_start(table)
|
46
|
-
@password.signal_connect("key_release_event", &method(:login))
|
47
|
-
|
48
|
-
if not ARGV.empty?
|
49
|
-
@login.editable = false
|
50
|
-
@login.text = ARGV.shift
|
51
|
-
@password.text = ARGV.shift if not ARGV.empty?
|
52
|
-
@password.grab_focus
|
53
|
-
else
|
54
|
-
@login.grab_focus
|
55
|
-
end
|
56
|
-
|
57
|
-
@login_dialog.signal_connect('response', &method(:login))
|
58
|
-
end
|
59
|
-
|
60
|
-
def gui_tray
|
61
|
-
# Status Tray Icon
|
62
|
-
@tray = Gtk::StatusIcon.new
|
63
|
-
@tray.pixbuf = @icon
|
64
|
-
|
65
|
-
@tray.signal_connect('popup-menu') do |w, button, time|
|
66
|
-
unless @menu.nil?
|
67
|
-
@menu.popup(nil, nil, button, time) do
|
68
|
-
@tray.position_menu(@menu)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def gui_menu
|
75
|
-
if @menu
|
76
|
-
@menu_items.to_a.each {|i| i.destroy}
|
77
|
-
@menu.destroy
|
78
|
-
end
|
79
|
-
@menu_items = []
|
80
|
-
@menu = Gtk::Menu.new
|
81
|
-
@menu_items << Gtk::SeparatorMenuItem.new
|
82
|
-
@menu.append(@menu_items.last)
|
83
|
-
|
84
|
-
@menu_items << Gtk::ImageMenuItem.new(Gtk::Stock::REFRESH)
|
85
|
-
@menu_items.last.signal_connect("activate", true, &method(:refresh))
|
86
|
-
@menu.append(@menu_items.last)
|
87
|
-
|
88
|
-
@menu_items << Gtk::ImageMenuItem.new(Gtk::Stock::QUIT)
|
89
|
-
@menu_items.last.signal_connect("activate") do
|
90
|
-
Gtk.main_quit
|
91
|
-
end
|
92
|
-
@menu.append(@menu_items.last)
|
93
|
-
@menu.show_all
|
94
|
-
end
|
95
|
-
|
96
|
-
def gui_edit
|
97
|
-
# Edit Dialog
|
98
|
-
@edit_dialog = Gtk::Dialog.new(GNetvibes::NAME, nil, Gtk::Dialog::MODAL,
|
99
|
-
[Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT],
|
100
|
-
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT])
|
101
|
-
|
102
|
-
# Text
|
103
|
-
@buf = Gtk::TextBuffer.new
|
104
|
-
@buf.signal_connect("changed", &method(:update_tag))
|
105
|
-
@txt = Gtk::TextView.new(@buf)
|
106
|
-
@txt.wrap_mode = Gtk::TextTag::WRAP_WORD
|
107
|
-
@txt.accepts_tab = false
|
108
|
-
@tag_title = @buf.create_tag('title', :font => "Sans Bold 13",
|
109
|
-
:pixels_below_lines => 10, :pixels_above_lines => 10,
|
110
|
-
:left_margin => 5)
|
111
|
-
@tag_normal = @buf.create_tag('normal', :font => "Sans 10",
|
112
|
-
:pixels_below_lines => 2, :pixels_above_lines => 0,
|
113
|
-
:left_margin => 10)
|
114
|
-
|
115
|
-
scroll = Gtk::ScrolledWindow.new
|
116
|
-
scroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
|
117
|
-
scroll.add(@txt)
|
118
|
-
scroll.border_width = 1
|
119
|
-
frame = Gtk::Frame.new
|
120
|
-
frame.add(scroll)
|
121
|
-
@edit_dialog.vbox.pack_start(frame, true, true, 10)
|
122
|
-
|
123
|
-
@edit_dialog.set_default_size(600, 400)
|
124
|
-
@edit_dialog.signal_connect("delete-event") do
|
125
|
-
@edit_dialog.hide_on_delete
|
126
|
-
end
|
127
|
-
|
128
|
-
@edit_dialog.title = GNetvibes::NAME
|
129
|
-
@edit_dialog.modal = true
|
130
|
-
@edit_dialog.border_width = 10
|
131
|
-
@edit_dialog.icon = @icon
|
132
|
-
@edit_dialog.signal_connect('response', &method(:save))
|
133
|
-
end
|
10
|
+
# Icons
|
11
|
+
ICON = Gdk::Pixbuf.new(File.join(File.dirname(__FILE__), "gui", "netvibes.png"))
|
12
|
+
ICON_WEBNOTE = Gdk::Pixbuf.new(File.join(File.dirname(__FILE__), "gui", "webnote.gif"))
|
13
|
+
ICON_FEED = Gdk::Pixbuf.new(File.join(File.dirname(__FILE__), "gui", "feed.gif"))
|
134
14
|
|
135
15
|
end
|
136
16
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: gnetvibes
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: "0.
|
7
|
-
date: 2007-03-
|
6
|
+
version: "0.4"
|
7
|
+
date: 2007-03-20 00:00:00 +01:00
|
8
8
|
summary: Netvibes integration with the Gnome Desktop
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -29,12 +29,10 @@ post_install_message:
|
|
29
29
|
authors:
|
30
30
|
- Florent Solt
|
31
31
|
files:
|
32
|
+
- lib/gnetvibes/api.rb
|
32
33
|
- lib/gnetvibes/gui.rb
|
33
34
|
- lib/gnetvibes/config.rb
|
34
|
-
- lib/gnetvibes/
|
35
|
-
- lib/gnetvibes/api.rb
|
36
|
-
- lib/gnetvibes/ico.png
|
37
|
-
- lib/gnetvibes/callback.rb
|
35
|
+
- lib/gnetvibes/gui
|
38
36
|
test_files: []
|
39
37
|
|
40
38
|
rdoc_options: []
|
data/lib/gnetvibes/callback.rb
DELETED
@@ -1,93 +0,0 @@
|
|
1
|
-
require 'gnetvibes/api'
|
2
|
-
require 'digest/sha1'
|
3
|
-
|
4
|
-
module GNetvibes
|
5
|
-
class GUI
|
6
|
-
|
7
|
-
def edit(obj, mod)
|
8
|
-
@edit_current = mod.to_i
|
9
|
-
mod = @api.modules[mod.to_i]
|
10
|
-
@buf.text = ''
|
11
|
-
iter = @buf.get_iter_at_offset(0)
|
12
|
-
@buf.insert(iter, mod['title'] + "\n", @tag_title)
|
13
|
-
@buf.insert(iter, mod['data']['text'].strip + "\n", @tag_normal)
|
14
|
-
@txt.grab_focus
|
15
|
-
@edit_dialog.show_all
|
16
|
-
@edit_dialog.run
|
17
|
-
end
|
18
|
-
|
19
|
-
def update_tag(*args)
|
20
|
-
@buf.apply_tag(@tag_title, @buf.get_iter_at_line(0), @buf.get_iter_at_line(1))
|
21
|
-
@buf.apply_tag(@tag_normal, @buf.get_iter_at_line(1), @buf.get_iter_at_line(2))
|
22
|
-
end
|
23
|
-
|
24
|
-
def save(obj, ev)
|
25
|
-
if ev == Gtk::Dialog::RESPONSE_ACCEPT
|
26
|
-
@api.save(@edit_current, :title => @buf.text[/^[^\n]*/], :text => @buf.text[/\n.*$/m].strip)
|
27
|
-
end
|
28
|
-
@edit_current = nil
|
29
|
-
@edit_dialog.hide_on_delete
|
30
|
-
refresh
|
31
|
-
end
|
32
|
-
|
33
|
-
def login(obj, ev)
|
34
|
-
if (ev.is_a? Gdk::EventKey and (ev.keyval == Gdk::Keyval::GDK_KP_Enter or ev.keyval == Gdk::Keyval::GDK_Return)) or
|
35
|
-
(ev.is_a? Fixnum and ev == Gtk::Dialog::RESPONSE_ACCEPT)
|
36
|
-
if @api.login(@login.text, @password.text)
|
37
|
-
refresh
|
38
|
-
@login_dialog.destroy
|
39
|
-
else
|
40
|
-
raise "Login failed"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
if (ev.is_a? Fixnum and ev == Gtk::Dialog::RESPONSE_REJECT)
|
45
|
-
exit!
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def refresh(*args)
|
50
|
-
@tray.tooltip = "#{GNetvibes::NAME} refreshing...";
|
51
|
-
gui_menu
|
52
|
-
if args.empty?
|
53
|
-
@api.refresh
|
54
|
-
elsif args.last == true
|
55
|
-
@api.refresh(true)
|
56
|
-
end
|
57
|
-
|
58
|
-
@api.tabs.each do |id, tab|
|
59
|
-
submenutitle = Gtk::ImageMenuItem.new(tab['title'])
|
60
|
-
|
61
|
-
if not tab['icon'].strip.empty?
|
62
|
-
icon = File.join(CACHE, Digest::SHA1.new(tab['icon']).hexdigest)
|
63
|
-
if not File.exists?(icon)
|
64
|
-
File.open(icon, 'w') do |fd|
|
65
|
-
fd.puts @api.download(tab['icon'])
|
66
|
-
end
|
67
|
-
end
|
68
|
-
submenutitle.image = Gtk::Image.new(icon)
|
69
|
-
end
|
70
|
-
|
71
|
-
submenu = Gtk::Menu.new
|
72
|
-
@api.each_modules_in_tab(id) do |mod|
|
73
|
-
case mod['name']
|
74
|
-
when 'PostIt'
|
75
|
-
@menu_items << Gtk::ImageMenuItem.new(mod['title'])
|
76
|
-
@menu_items.last.image = Gtk::Image.new(@icon_webnote)
|
77
|
-
@menu_items.last.signal_connect("activate", mod['id'], &method(:edit))
|
78
|
-
submenu.append(@menu_items.last)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
submenutitle.submenu = submenu
|
82
|
-
@menu_items << submenu
|
83
|
-
@menu_items << submenutitle
|
84
|
-
@menu.prepend(submenutitle)
|
85
|
-
end
|
86
|
-
|
87
|
-
@menu.show_all
|
88
|
-
@tray.tooltip = GNetvibes::NAME;
|
89
|
-
GC.start
|
90
|
-
end
|
91
|
-
|
92
|
-
end
|
93
|
-
end
|
data/lib/gnetvibes/ico.png
DELETED
Binary file
|
data/lib/gnetvibes/webnote.gif
DELETED
Binary file
|