gnetvibes 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/bin/gnetvibes CHANGED
@@ -10,6 +10,7 @@ require 'gnetvibes/config'
10
10
  require 'gnetvibes/gui'
11
11
 
12
12
  FileUtils.mkdir_p(GNetvibes::CACHE) if not File.exists?(GNetvibes::CACHE)
13
+ FileUtils.mkdir_p(GNetvibes::DATA) if not File.exists?(GNetvibes::DATA)
13
14
 
14
15
  gui = GNetvibes::GUI.new
15
16
  gui.login_dialog.show_all
data/lib/gnetvibes/api.rb CHANGED
@@ -20,12 +20,16 @@ class API
20
20
  @active_session_id = nil
21
21
  @data = nil
22
22
  @key = nil
23
+ @email = nil
23
24
  end
24
25
 
25
26
  def login(email, password)
26
- res = Net::HTTP.post_form(URL[:login], {'email'=> email.strip, 'password' => password.strip})
27
+ email.strip!
28
+ password.strip!
29
+ res = Net::HTTP.post_form(URL[:login], {'email'=> email, 'password' => password})
27
30
  if res.body.strip == 'success'
28
31
  @key = Digest::SHA1.new(email + password).hexdigest
32
+ @email = email
29
33
  cookies = CGI::Cookie::parse(res['set-cookie'])
30
34
  @active_user_id = cookies['activeUserID'].value
31
35
  @active_session_id = cookies['activeSessionID'].value
@@ -36,10 +40,27 @@ class API
36
40
  end
37
41
  end
38
42
 
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))
43
+
44
+ def save(id, options)
45
+ mod = @modules[id]
46
+ case mod['name']
47
+ when 'PostIt'
48
+ mod['title'] = options[:title]
49
+ mod['data']['text'] = options[:text]
42
50
  else
51
+ raise 'Not implemented'
52
+ end
53
+ Net::HTTP.start(URL[:data].host, URL[:data].port) do |http|
54
+ headers = {'Cookie' => "activeUserID=#{@active_user_id}; activeSessionID=#{@active_session_id}"}
55
+ post = Net::HTTP::Post.new(URL[:save].path, headers)
56
+ post.set_form_data(module2post(mod))
57
+ http.request(post)
58
+ end
59
+ dump
60
+ end
61
+
62
+ def refresh(force = false)
63
+ if force or not load
43
64
  res = Net::HTTP.start(URL[:data].host, URL[:data].port) do |http|
44
65
  headers = {'Cookie' => "activeUserID=#{@active_user_id}; activeSessionID=#{@active_session_id}"}
45
66
  http.request(Net::HTTP::Get.new(URL[:data].path, headers))
@@ -74,11 +95,21 @@ class API
74
95
  end
75
96
 
76
97
  def dump
77
- File.open(DATA, 'w') do |fd|
98
+ File.open(File.join(DATA, @email), 'w') do |fd|
78
99
  fd.write crypt(@data.inspect, @key)
79
100
  end
80
101
  end
81
102
 
103
+ def load
104
+ file = File.join(DATA, @email)
105
+ if File.exists?(file) and File.mtime(file) > Time.now - EXPIRE
106
+ @data = eval(crypt(File.read(file), @key))
107
+ true
108
+ else
109
+ false
110
+ end
111
+ end
112
+
82
113
  def download(uri)
83
114
  if uri =~ /^\//
84
115
  url = URL[:base] + uri
@@ -103,7 +134,7 @@ class API
103
134
  end
104
135
 
105
136
  def json2ruby(s)
106
- eval(s.gsub(/":/, '"=>'))
137
+ eval(s.gsub(/:null/, ':nil').gsub(/":/, '"=>'))
107
138
  end
108
139
 
109
140
  def crypt(buf, key)
@@ -113,5 +144,20 @@ class API
113
144
  buf.zip(key).collect{|c1,c2| c1^c2}.pack("c*")
114
145
  end
115
146
 
147
+ def module2post(mod)
148
+ post = {}
149
+ mod.each do |k,v|
150
+ if v.is_a? Hash
151
+ v.each do |subk, subv|
152
+ post["arr#{k.capitalize}[#{subk}]"] = subv
153
+ end
154
+ else
155
+ post[k] = v
156
+ end
157
+ end
158
+ post['mode'] = 'module'
159
+ post
160
+ end
161
+
116
162
  end
117
163
  end
@@ -5,19 +5,29 @@ module GNetvibes
5
5
  class GUI
6
6
 
7
7
  def edit(obj, mod)
8
+ @edit_current = mod.to_i
8
9
  mod = @api.modules[mod.to_i]
9
- @title.text = mod['title']
10
- @buf.text = mod['data']['text'].strip
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)
11
14
  @txt.grab_focus
12
15
  @edit_dialog.show_all
13
16
  @edit_dialog.run
14
17
  end
15
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
+
16
24
  def save(obj, ev)
17
25
  if ev == Gtk::Dialog::RESPONSE_ACCEPT
18
- puts "save"
26
+ @api.save(@edit_current, :title => @buf.text[/^[^\n]*/], :text => @buf.text[/\n.*$/m].strip)
19
27
  end
28
+ @edit_current = nil
20
29
  @edit_dialog.hide_on_delete
30
+ refresh
21
31
  end
22
32
 
23
33
  def login(obj, ev)
@@ -36,36 +46,47 @@ class GUI
36
46
  end
37
47
  end
38
48
 
39
- def refresh
49
+ def refresh(*args)
40
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
41
57
 
42
58
  @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'])
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
47
67
  end
68
+ submenutitle.image = Gtk::Image.new(icon)
48
69
  end
49
70
 
50
- submenutitle = Gtk::ImageMenuItem.new(tab['title'])
51
- submenutitle.image = Gtk::Image.new(icon)
52
-
53
71
  submenu = Gtk::Menu.new
54
72
  @api.each_modules_in_tab(id) do |mod|
55
73
  case mod['name']
56
74
  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)
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)
61
79
  end
62
80
  end
63
81
  submenutitle.submenu = submenu
82
+ @menu_items << submenu
83
+ @menu_items << submenutitle
64
84
  @menu.prepend(submenutitle)
65
85
  end
66
86
 
67
87
  @menu.show_all
68
88
  @tray.tooltip = GNetvibes::NAME;
89
+ GC.start
69
90
  end
70
91
 
71
92
  end
@@ -1,14 +1,21 @@
1
1
  module GNetvibes
2
2
  NAME = 'gNetvibes'
3
- VERSION = '0.1'
3
+ VERSION = '0.2'
4
4
  COPYRIGHT = 'Copyright (C) 2007 Florent Solt'
5
5
  DESC = 'Netvibes integration with the Gnome Desktop'
6
6
  AUTHOR = 'Florent Solt'
7
7
  EMAIL = 'florent@solt.biz'
8
8
  HOMEPAGE = 'http://rubyforge.org/projects/gnetvibes/'
9
9
 
10
- CACHE = File.join(ENV['HOME'], ".#{GNetvibes::NAME.downcase}", "cache")
11
- DATA = File.join(ENV['HOME'], ".#{GNetvibes::NAME.downcase}", "data")
10
+ if RUBY_PLATFORM =~ /win32/
11
+ HOME = File.join(ENV['APPDATA'], GNetvibes::NAME)
12
+ else
13
+ HOME = File.join(ENV['HOME'], ".#{GNetvibes::NAME.downcase}")
14
+ end
15
+
16
+ CACHE = File.join(HOME, "cache")
17
+ DATA = File.join(HOME, "data")
18
+
12
19
  EXPIRE = 5 * 60
13
20
  end
14
21
 
data/lib/gnetvibes/gui.rb CHANGED
@@ -13,6 +13,14 @@ class GUI
13
13
  @icon = Gdk::Pixbuf.new(File.join(File.dirname(__FILE__), "ico.png"))
14
14
  @icon_webnote = Gdk::Pixbuf.new(File.join(File.dirname(__FILE__), "webnote.gif"))
15
15
 
16
+ gui_login
17
+ gui_edit
18
+ gui_tray
19
+ end
20
+
21
+ private
22
+
23
+ def gui_login
16
24
  # Login Dialog
17
25
  @login_dialog = Gtk::Dialog.new("#{GNetvibes::NAME} Authentification", nil, Gtk::Dialog::MODAL,
18
26
  [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT],
@@ -33,65 +41,86 @@ class GUI
33
41
 
34
42
  table.attach_defaults(Gtk::Label.new("Password:"), 1, 2, 1, 2)
35
43
  @password.visibility = false
36
- @password.invisible_char = 0
37
44
  table.attach_defaults(@password, 2, 3, 1, 2)
38
45
  @login_dialog.vbox.pack_start(table)
39
46
  @password.signal_connect("key_release_event", &method(:login))
40
47
 
41
48
  if not ARGV.empty?
42
49
  @login.editable = false
43
- @login.text = ARGV.first
50
+ @login.text = ARGV.shift
51
+ @password.text = ARGV.shift if not ARGV.empty?
44
52
  @password.grab_focus
45
53
  else
46
54
  @login.grab_focus
47
55
  end
48
56
 
49
57
  @login_dialog.signal_connect('response', &method(:login))
58
+ end
50
59
 
60
+ def gui_tray
51
61
  # Status Tray Icon
52
62
  @tray = Gtk::StatusIcon.new
53
63
  @tray.pixbuf = @icon
54
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 = []
55
80
  @menu = Gtk::Menu.new
56
- @menu.append(Gtk::SeparatorMenuItem.new)
81
+ @menu_items << Gtk::SeparatorMenuItem.new
82
+ @menu.append(@menu_items.last)
57
83
 
58
- item = Gtk::ImageMenuItem.new(Gtk::Stock::REFRESH)
59
- item.signal_connect("activate", &method(:refresh))
60
- @menu.append(item)
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)
61
87
 
62
- item = Gtk::ImageMenuItem.new(Gtk::Stock::QUIT)
63
- item.signal_connect("activate") do
88
+ @menu_items << Gtk::ImageMenuItem.new(Gtk::Stock::QUIT)
89
+ @menu_items.last.signal_connect("activate") do
64
90
  Gtk.main_quit
65
91
  end
66
- @menu.append(item)
92
+ @menu.append(@menu_items.last)
67
93
  @menu.show_all
94
+ end
68
95
 
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
-
96
+ def gui_edit
81
97
  # Edit Dialog
82
98
  @edit_dialog = Gtk::Dialog.new(GNetvibes::NAME, nil, Gtk::Dialog::MODAL,
83
99
  [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT],
84
100
  [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT])
85
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
+
86
115
  scroll = Gtk::ScrolledWindow.new
87
116
  scroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
88
117
  scroll.add(@txt)
89
118
  scroll.border_width = 1
90
-
91
119
  frame = Gtk::Frame.new
92
120
  frame.add(scroll)
121
+ @edit_dialog.vbox.pack_start(frame, true, true, 10)
93
122
 
94
- @edit_dialog.set_default_size(300, 300)
123
+ @edit_dialog.set_default_size(600, 400)
95
124
  @edit_dialog.signal_connect("delete-event") do
96
125
  @edit_dialog.hide_on_delete
97
126
  end
@@ -100,8 +129,6 @@ class GUI
100
129
  @edit_dialog.modal = true
101
130
  @edit_dialog.border_width = 10
102
131
  @edit_dialog.icon = @icon
103
- @edit_dialog.vbox.pack_start(@title, false, false)
104
- @edit_dialog.vbox.pack_start(frame, true, true, 10)
105
132
  @edit_dialog.signal_connect('response', &method(:save))
106
133
  end
107
134
 
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.1"
7
- date: 2007-03-17 00:00:00 +01:00
6
+ version: "0.2"
7
+ date: 2007-03-19 00:00:00 +01:00
8
8
  summary: Netvibes integration with the Gnome Desktop
9
9
  require_paths:
10
10
  - lib
@@ -29,12 +29,12 @@ post_install_message:
29
29
  authors:
30
30
  - Florent Solt
31
31
  files:
32
- - lib/gnetvibes/callback.rb
33
- - lib/gnetvibes/api.rb
34
- - lib/gnetvibes/config.rb
35
32
  - lib/gnetvibes/gui.rb
36
- - lib/gnetvibes/ico.png
33
+ - lib/gnetvibes/config.rb
37
34
  - lib/gnetvibes/webnote.gif
35
+ - lib/gnetvibes/api.rb
36
+ - lib/gnetvibes/ico.png
37
+ - lib/gnetvibes/callback.rb
38
38
  test_files: []
39
39
 
40
40
  rdoc_options: []