gnetvibes 0.4 → 0.5

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/bin/gnetvibes CHANGED
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/ruby
2
-
3
2
  $KCODE = "U"
4
3
  require 'rubygems'
4
+ require 'netvibes'
5
+ require 'gnetvibes'
5
6
 
6
- require 'fileutils'
7
- require 'gtk2'
8
-
9
- require 'gnetvibes/config'
10
- require 'gnetvibes/gui'
7
+ api = Netvibes.new
8
+ icon = GNetvibes::Icon.new(api)
11
9
 
12
- FileUtils.mkdir_p(GNetvibes::CACHE) if not File.exists?(GNetvibes::CACHE)
13
- FileUtils.mkdir_p(GNetvibes::DATA) if not File.exists?(GNetvibes::DATA)
10
+ if not api.load_credentials
11
+ login = GNetvibes::LoginDialog.new(api)
12
+ begin
13
+ login.run
14
+ rescue Exception
15
+ retry
16
+ end
17
+ end
14
18
 
15
- api = GNetvibes::API.new
16
- icon = GNetvibes::GUI::Icon.new(api)
17
- login = GNetvibes::GUI::LoginDialog.new(api).run
18
19
  icon.refresh
19
-
20
20
  Gtk.main
data/lib/gnetvibes.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'gtk2'
2
+ require 'gnetvibes/config'
3
+ require 'gnetvibes/icon'
4
+ require 'gnetvibes/edit'
5
+ require 'gnetvibes/login'
@@ -1,28 +1,21 @@
1
+ require 'digest/sha1'
1
2
  module GNetvibes
2
3
  NAME = 'gNetvibes'
3
- VERSION = '0.4'
4
+ VERSION = '0.5'
4
5
  COPYRIGHT = 'Copyright (C) 2007 Florent Solt'
5
6
  DESC = 'Netvibes integration with the Gnome Desktop'
6
7
  AUTHOR = 'Florent Solt'
7
8
  EMAIL = 'florent@solt.biz'
8
- HOMEPAGE = 'http://rubyforge.org/projects/gnetvibes/'
9
+ HOMEPAGE = 'http://gnetvibes.rubyforge.org'
10
+ LICENSE = 'BSD'
9
11
 
10
- if RUBY_PLATFORM =~ /win32/
11
- HOME = File.join(ENV['APPDATA'], GNetvibes::NAME)
12
- else
13
- HOME = File.join(ENV['HOME'], ".#{GNetvibes::NAME.downcase}")
12
+ if defined? Gdk
13
+ # Icons
14
+ ICON = Gdk::Pixbuf.new(File.join(File.dirname(__FILE__), "gfx", "netvibes.png"))
15
+ ICON_POSTIT = Gdk::Pixbuf.new(File.join(File.dirname(__FILE__), "gfx", "webnote.gif"))
16
+ ICON_TODOLIST = Gdk::Pixbuf.new(File.join(File.dirname(__FILE__), "gfx", "todolist.gif"))
17
+ ICON_FEED = Gdk::Pixbuf.new(File.join(File.dirname(__FILE__), "gfx", "feed.gif"))
14
18
  end
15
19
 
16
- CACHE = File.join(HOME, "cache")
17
- DATA = File.join(HOME, "data")
18
-
19
- EXPIRE = 5 * 60
20
-
21
- MODULES = {
22
- :postit => 'PostIt',
23
- :todolist => 'TodoList',
24
- :feed => 'RssReader'
25
- }
26
20
  end
27
21
 
28
-
@@ -0,0 +1,103 @@
1
+ module GNetvibes
2
+ class EditDialog < Gtk::Dialog
3
+
4
+ attr_reader :buf
5
+
6
+ def initialize(id)
7
+ super(NAME, nil, nil,
8
+ [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT],
9
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT])
10
+
11
+ # TODO: implementer une methode @api.is_a_postit?(Hash)
12
+ if id == :postit
13
+ build_postit("Webnote", "Type your text here")
14
+ elsif id.is_a? Hash and id['name'] == Netvibes::MODULES[:postit]
15
+ build_postit(id['title'], id['data']['text'])
16
+ @delete = self.add_button(Gtk::Stock::DELETE, Gtk::Dialog::RESPONSE_APPLY)
17
+ elsif id.is_a? Hash and id['name'] == Netvibes::MODULES[:todolist]
18
+ build_todolist(id)
19
+ end
20
+
21
+ self.has_separator = false
22
+ self.set_default_size(400, 300)
23
+
24
+ self.border_width = 10
25
+ self.icon = ICON
26
+ self.modal = false
27
+
28
+ self.show_all
29
+ end
30
+
31
+ def update_tag(*args)
32
+ @buf.apply_tag(@tag_title, @buf.get_iter_at_line(0), @buf.get_iter_at_line(1))
33
+ @buf.apply_tag(@tag_normal, @buf.get_iter_at_line(1), @buf.get_iter_at_line(2))
34
+ end
35
+
36
+ def build_postit(title, text)
37
+ # Text
38
+ @buf = Gtk::TextBuffer.new
39
+ @buf.signal_connect("changed", self, &method(:update_tag))
40
+ @txt = Gtk::TextView.new(@buf)
41
+ @txt.wrap_mode = Gtk::TextTag::WRAP_WORD
42
+ @txt.accepts_tab = false
43
+ @tag_title = @buf.create_tag('title', :font => "Sans Bold 12",
44
+ :pixels_below_lines => 7, :pixels_above_lines => 10,
45
+ :left_margin => 5)
46
+ @tag_normal = @buf.create_tag('normal', :font => "Sans 9",
47
+ :pixels_below_lines => 2, :pixels_above_lines => 0,
48
+ :left_margin => 10)
49
+
50
+ scroll = Gtk::ScrolledWindow.new
51
+ scroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
52
+ scroll.add(@txt)
53
+ scroll.border_width = 1
54
+ frame = Gtk::Frame.new
55
+ frame.add(scroll)
56
+ self.vbox.pack_start(frame, true, true)
57
+
58
+ @buf.text = ''
59
+ iter = @buf.get_iter_at_offset(0)
60
+ @buf.insert(iter, title.strip + "\n", @tag_title)
61
+ @buf.insert(iter, text.strip + "\n", @tag_normal)
62
+ @txt.grab_focus
63
+ end
64
+
65
+ def build_todolist(id)
66
+ list = []
67
+ id['data'].select{|k,v| k =~ /^tdval/}.each do |k,v|
68
+ i = k[/\d+$/].to_i
69
+ list[i] = { :title => v, :checked => id['data']["tdchk_#{i}"].to_i }
70
+ end
71
+ @treeview = Gtk::TreeView.new(Gtk::ListStore.new(Fixnum, String))
72
+ @treeview.headers_visible = false
73
+
74
+ render = Gtk::CellRendererToggle.new
75
+ render.mode = Gtk::CellRenderer::MODE_ACTIVATABLE
76
+ @column = Gtk::TreeViewColumn.new('Done?', render)
77
+ @column.set_cell_data_func(render) do |column, cell, model, iter|
78
+ cell.active = iter.get_value(0) != 0
79
+ end
80
+ render.signal_connect("toggled") do |cell, row|
81
+ @treeview.model.get_iter(row).set_value(0, cell.active? ? 0 : 1)
82
+ end
83
+
84
+ @treeview.append_column(@column)
85
+ @treeview.append_column(Gtk::TreeViewColumn.new('Title', Gtk::CellRendererText.new, :text => 1))
86
+
87
+ list.each do |item|
88
+ iter = @treeview.model.append
89
+ iter[0] = item[:checked]
90
+ iter[1] = item[:title]
91
+ end
92
+
93
+ scroll = Gtk::ScrolledWindow.new
94
+ scroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
95
+ scroll.add(@treeview)
96
+ scroll.border_width = 1
97
+ frame = Gtk::Frame.new
98
+ frame.add(scroll)
99
+ self.vbox.pack_start(frame, true, true)
100
+ end
101
+
102
+ end
103
+ end
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,166 @@
1
+ module GNetvibes
2
+ class Icon < Gtk::StatusIcon
3
+
4
+ attr_reader :buf
5
+
6
+ def initialize(api)
7
+ @api = api
8
+
9
+ super()
10
+ self.pixbuf = ICON
11
+
12
+ self.signal_connect('popup-menu') do |w, button, time|
13
+ unless @menu.nil?
14
+ @menu.popup(nil, nil, button, time) do
15
+ self.position_menu(@menu)
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ def build_menu
22
+ if @menu
23
+ @menu_items.to_a.each {|i| i.destroy}
24
+ @menu.destroy
25
+ end
26
+ @menu_items = []
27
+ @menu = Gtk::Menu.new
28
+ @menu_items << Gtk::SeparatorMenuItem.new
29
+ @menu.append(@menu_items.last)
30
+
31
+ @menu_items << Gtk::ImageMenuItem.new(Gtk::Stock::REFRESH)
32
+ @menu_items.last.signal_connect("activate", true, &method(:refresh))
33
+ @menu.append(@menu_items.last)
34
+
35
+ @menu_items << Gtk::ImageMenuItem.new(Gtk::Stock::QUIT)
36
+ @menu_items.last.signal_connect("activate") do
37
+ Gtk.main_quit
38
+ end
39
+ @menu.append(@menu_items.last)
40
+ @menu.show_all
41
+ end
42
+
43
+ def refresh(*args)
44
+ self.tooltip = "#{NAME} refreshing...";
45
+ build_menu
46
+ @api.refresh
47
+
48
+ @api.tabs.each do |id, tab|
49
+
50
+ # Title
51
+ submenutitle = Gtk::ImageMenuItem.new(tab['title'])
52
+
53
+ if not tab['icon'].strip.empty?
54
+ submenutitle.image = Gtk::Image.new(@api.download(tab['icon']))
55
+ end
56
+ submenu = Gtk::Menu.new
57
+
58
+ # Add item
59
+ @menu_items << Gtk::ImageMenuItem.new(Gtk::Stock::ADD)
60
+ @menu_items.last.signal_connect("activate", id, &method(:add))
61
+ submenu.append(@menu_items.last)
62
+
63
+ # Separator
64
+ if @api.tab_has?(id, :postit)
65
+ @menu_items << Gtk::SeparatorMenuItem.new
66
+ submenu.append(@menu_items.last)
67
+ end
68
+
69
+ # Postit
70
+ @api.each_postit_in_tab(id) do |postit|
71
+ @menu_items << Gtk::ImageMenuItem.new(postit['title'])
72
+ @menu_items.last.image = Gtk::Image.new(ICON_POSTIT)
73
+ @menu_items.last.signal_connect("activate", postit['id'], &method(:edit))
74
+ submenu.append(@menu_items.last)
75
+ end
76
+
77
+ # TodoLists
78
+ @api.each_todo_list_in_tab(id) do |todolist|
79
+ title = todolist['data']['title'] || todolist['title']
80
+ @menu_items << Gtk::ImageMenuItem.new(title)
81
+ @menu_items.last.image = Gtk::Image.new(ICON_TODOLIST)
82
+ @menu_items.last.signal_connect("activate", todolist['id'], &method(:edit))
83
+ submenu.append(@menu_items.last)
84
+ end
85
+
86
+ # Feeds
87
+ items = []
88
+ @api.each_feed_in_tab(id) do |feed|
89
+ next if feed['unread'].zero?
90
+ if feed['unread'] > 0
91
+ items << feed['title'] + " (#{feed['unread']})"
92
+ else
93
+ items << feed['title']
94
+ end
95
+ end
96
+
97
+ if not items.empty?
98
+ # Separator
99
+ if @api.tab_has?(id, :feed)
100
+ @menu_items << Gtk::SeparatorMenuItem.new
101
+ submenu.append(@menu_items.last)
102
+ end
103
+
104
+ items.each do |title|
105
+ @menu_items << Gtk::ImageMenuItem.new(title)
106
+ @menu_items.last.image = Gtk::Image.new(ICON_FEED)
107
+ submenu.append(@menu_items.last)
108
+ end
109
+ end
110
+
111
+ submenutitle.submenu = submenu
112
+ @menu_items << submenu
113
+ @menu_items << submenutitle
114
+ @menu.prepend(submenutitle)
115
+ end
116
+
117
+ @menu.show_all
118
+ self.tooltip = NAME;
119
+ GC.start
120
+ end
121
+
122
+ def edit(obj, mod)
123
+ mod = @api.modules[mod.to_i]
124
+ dlg = EditDialog.new(mod)
125
+ begin
126
+ res = dlg.run
127
+ if res == Gtk::Dialog::RESPONSE_ACCEPT
128
+ @api.save(mod['id'], :title => dlg.buf.text[/^[^\n]*/],
129
+ :text => dlg.buf.text[/\n.*$/m].strip)
130
+ refresh
131
+ dlg.destroy
132
+ elsif res == Gtk::Dialog::RESPONSE_APPLY
133
+ confirm = Gtk::MessageDialog.new(dlg, Gtk::Dialog::MODAL,
134
+ Gtk::MessageDialog::QUESTION, Gtk::MessageDialog::BUTTONS_YES_NO,
135
+ "Are you sure ?")
136
+ if confirm.run == Gtk::Dialog::RESPONSE_YES
137
+ @api.delete(mod['id'])
138
+ refresh
139
+ dlg.destroy
140
+ confirm.destroy
141
+ else
142
+ confirm.destroy
143
+ raise 'Retry'
144
+ end
145
+ else
146
+ dlg.destroy
147
+ end
148
+ rescue RuntimeError
149
+ retry
150
+ end
151
+ end
152
+
153
+ def add(obj, tab)
154
+ dlg = EditDialog.new(:postit)
155
+ res = dlg.run
156
+ if res == Gtk::Dialog::RESPONSE_ACCEPT
157
+ @api.add(tab, :postit, :title => dlg.buf.text[/^[^\n]*/],
158
+ :text => dlg.buf.text[/\n.*$/m].strip)
159
+ refresh
160
+ end
161
+ dlg.destroy
162
+ end
163
+
164
+ end
165
+ end
166
+
@@ -0,0 +1,73 @@
1
+ module GNetvibes
2
+ class LoginDialog < Gtk::Dialog
3
+
4
+ attr_reader :login, :password
5
+
6
+ def initialize(api)
7
+ @api = api
8
+
9
+ # Login Dialog
10
+ super("#{NAME} Authentification", nil, Gtk::Dialog::MODAL,
11
+ [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT],
12
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT])
13
+ self.icon = ICON
14
+ self.has_separator = false
15
+ self.resizable = false
16
+
17
+ @login = Gtk::Entry.new
18
+ @password = Gtk::Entry.new
19
+ @remember = Gtk::CheckButton.new('Remember me')
20
+
21
+ table = Gtk::Table.new(2, 3)
22
+ table.border_width = 5
23
+ image = Gtk::Image.new(Gtk::Stock::DIALOG_AUTHENTICATION, Gtk::IconSize::DIALOG)
24
+ table.attach(image, 0, 1, 0, 2, nil, nil, 10, 10)
25
+
26
+ table.attach_defaults(Gtk::Label.new("Login:"), 1, 2, 0, 1)
27
+ table.attach_defaults(@login, 2, 3, 0, 1)
28
+
29
+ table.attach_defaults(Gtk::Label.new("Password:"), 1, 2, 1, 2)
30
+ @password.visibility = false
31
+ table.attach_defaults(@password, 2, 3, 1, 2)
32
+ self.vbox.pack_start(table)
33
+ self.signal_connect("key_release_event", &method(:login))
34
+
35
+ table.attach_defaults(@remember, 2, 3, 2, 3)
36
+
37
+ if not ARGV.empty?
38
+ @login.editable = false
39
+ @login.text = ARGV.shift
40
+ @password.text = ARGV.shift if not ARGV.empty?
41
+ @password.grab_focus
42
+ else
43
+ @login.grab_focus
44
+ end
45
+
46
+ self.signal_connect('response', &method(:login))
47
+ self.show_all
48
+ end
49
+
50
+ def login(obj, ev)
51
+ if (ev.is_a? Gdk::EventKey and (ev.keyval == Gdk::Keyval::GDK_KP_Enter or ev.keyval == Gdk::Keyval::GDK_Return)) or
52
+ (ev.is_a? Fixnum and ev == Gtk::Dialog::RESPONSE_ACCEPT)
53
+
54
+ if @api.login(@login.text, @password.text)
55
+ @api.save_credentials if @remember.active?
56
+ self.destroy
57
+ else
58
+ dlg = Gtk::MessageDialog.new(nil, Gtk::Dialog::MODAL,
59
+ Gtk::MessageDialog::ERROR, Gtk::MessageDialog::BUTTONS_OK,
60
+ "\nBad email or password\nLogin failed")
61
+ dlg.run
62
+ dlg.destroy
63
+ raise "Login Failed"
64
+ end
65
+ end
66
+
67
+ if (ev.is_a? Fixnum and ev == Gtk::Dialog::RESPONSE_REJECT)
68
+ exit!
69
+ end
70
+ end
71
+ end
72
+
73
+ end
metadata CHANGED
@@ -3,13 +3,13 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: gnetvibes
5
5
  version: !ruby/object:Gem::Version
6
- version: "0.4"
7
- date: 2007-03-20 00:00:00 +01:00
6
+ version: "0.5"
7
+ date: 2007-03-23 00:00:00 +01:00
8
8
  summary: Netvibes integration with the Gnome Desktop
9
9
  require_paths:
10
10
  - lib
11
11
  email: florent@solt.biz
12
- homepage: http://rubyforge.org/projects/gnetvibes/
12
+ homepage: http://gnetvibes.rubyforge.org
13
13
  rubyforge_project:
14
14
  description:
15
15
  autorequire:
@@ -29,10 +29,15 @@ post_install_message:
29
29
  authors:
30
30
  - Florent Solt
31
31
  files:
32
- - lib/gnetvibes/api.rb
33
- - lib/gnetvibes/gui.rb
34
32
  - lib/gnetvibes/config.rb
35
- - lib/gnetvibes/gui
33
+ - lib/gnetvibes/edit.rb
34
+ - lib/gnetvibes/icon.rb
35
+ - lib/gnetvibes/login.rb
36
+ - lib/gnetvibes/gfx/netvibes.png
37
+ - lib/gnetvibes/gfx/todolist.gif
38
+ - lib/gnetvibes/gfx/feed.gif
39
+ - lib/gnetvibes/gfx/webnote.gif
40
+ - lib/gnetvibes.rb
36
41
  test_files: []
37
42
 
38
43
  rdoc_options: []
@@ -45,5 +50,13 @@ extensions: []
45
50
 
46
51
  requirements: []
47
52
 
48
- dependencies: []
49
-
53
+ dependencies:
54
+ - !ruby/object:Gem::Dependency
55
+ name: netvibes
56
+ version_requirement:
57
+ version_requirements: !ruby/object:Gem::Version::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0.5"
62
+ version:
data/lib/gnetvibes/api.rb DELETED
@@ -1,217 +0,0 @@
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
- @email = nil
24
- @tabs = nil
25
- @modules == nil
26
- end
27
-
28
- def login(email, password)
29
- email.strip!
30
- password.strip!
31
- res = Net::HTTP.post_form(URL[:login], {'email'=> email, 'password' => password})
32
- if res.body.strip == 'success'
33
- @key = Digest::SHA1.new(email + password).hexdigest
34
- @email = email
35
- cookies = CGI::Cookie::parse(res['set-cookie'])
36
- @active_user_id = cookies['activeUserID'].value
37
- @active_session_id = cookies['activeSessionID'].value
38
- refresh
39
- true
40
- else
41
- false
42
- end
43
- end
44
-
45
- def save(id, options)
46
- mod = @modules[id.to_i]
47
- case mod['name']
48
- when /PostIt/i
49
- mod['title'] = options[:title]
50
- mod['data']['text'] = options[:text]
51
- mod['mode'] = 'module'
52
- else
53
- raise 'Not implemented'
54
- end
55
- Net::HTTP.start(URL[:data].host, URL[:data].port) do |http|
56
- headers = {'Cookie' => "activeUserID=#{@active_user_id}; activeSessionID=#{@active_session_id}"}
57
- post = Net::HTTP::Post.new(URL[:save].path, headers)
58
- post.set_form_data(module2post(mod))
59
- http.request(post)
60
- end
61
- dump
62
- end
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
-
91
- def refresh(force = false)
92
- if force or not load
93
- res = Net::HTTP.start(URL[:data].host, URL[:data].port) do |http|
94
- headers = {'Cookie' => "activeUserID=#{@active_user_id}; activeSessionID=#{@active_session_id}"}
95
- http.request(Net::HTTP::Get.new(URL[:data].path, headers))
96
- end
97
- @data = json2ruby(unicode(res.body))
98
- dump
99
- end
100
- @tabs = {}
101
- @modules = {}
102
- @data['tabs'].each { |t| @tabs[t['id'].to_i] = t }
103
- @data['modules'].each { |m| @modules[m['id'].to_i] = m }
104
- true
105
- end
106
-
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)
117
- @data['modules'].select{|m| m['tab'].to_i == tab.to_i}.each do |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
136
- end
137
- end
138
-
139
- def each_todo_list_item(mod)
140
- raise "Module is not a TodoList" if @modules[mod.to_i]['name'] != MODULES[:todolist]
141
- list = []
142
- data = @modules[mod.to_i]['data']
143
- data.select{|k,v| k =~ /^tdval/}.each do |k,v|
144
- id = k[/\d+$/].to_i
145
- list[id] = { 'title' => v, 'checked' => data["tdchk_#{id}"].to_i == 1 }
146
- end
147
- list.each do |i|
148
- yield i
149
- end
150
- end
151
-
152
- def dump
153
- File.open(File.join(DATA, @email), 'w') do |fd|
154
- fd.write crypt(@data.inspect, @key)
155
- end
156
- end
157
-
158
- def load
159
- file = File.join(DATA, @email)
160
- if File.exists?(file) and File.mtime(file) > Time.now - EXPIRE
161
- @data = eval(crypt(File.read(file), @key))
162
- true
163
- else
164
- false
165
- end
166
- end
167
-
168
- def download(uri)
169
- if uri =~ /^\//
170
- url = URL[:base] + uri
171
- else
172
- url = URI.parse(uri)
173
- end
174
- req = Net::HTTP::Get.new(url.path)
175
- res = Net::HTTP.start(url.host, url.port) {|http| http.request(req) }
176
- res.body
177
- end
178
-
179
- private
180
-
181
- UNICODE_TABLE = {
182
- 'u00b0' => '°', 'u00e0' => 'à', 'u00e2' => 'â', 'u00e7' => 'ç',
183
- 'u00e8' => 'è', 'u00e9' => 'é', 'u00ea' => 'ê', 'u00ee' => 'î',
184
- 'u00f4' => 'ô', 'u2019' => '\''
185
- }
186
-
187
- def unicode(s)
188
- s.gsub(/u[a-f\d]{4}/) { |c| UNICODE_TABLE[c] }
189
- end
190
-
191
- def json2ruby(s)
192
- eval(s.gsub(/:null/, ':nil').gsub(/":/, '"=>'))
193
- end
194
-
195
- def crypt(buf, key)
196
- buf = buf.unpack("c*")
197
- key = key.unpack("c*")
198
- key *= buf.size / key.size + 1
199
- buf.zip(key).collect{|c1,c2| c1^c2}.pack("c*")
200
- end
201
-
202
- def module2post(mod)
203
- post = {}
204
- mod.each do |k,v|
205
- if v.is_a? Hash
206
- v.each do |subk, subv|
207
- post["arr#{k.capitalize}[#{subk}]"] = subv
208
- end
209
- else
210
- post[k] = v
211
- end
212
- end
213
- post
214
- end
215
-
216
- end
217
- end
data/lib/gnetvibes/gui.rb DELETED
@@ -1,16 +0,0 @@
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'
6
-
7
- module GNetvibes
8
- module GUI
9
-
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"))
14
-
15
- end
16
- end