gnetvibes 0.4 → 0.5

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