themactep-fliewr 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ nbproject
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ == Fliewr
2
+
3
+ Copyright (c) 2008, Paul Philippov
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without modification,
7
+ are permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice,
10
+ this list of conditions and the following disclaimer.
11
+ * Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+ * Neither the name of the PPDS.WS nor the names of its contributors may be used
15
+ to endorse or promote products derived from this software without specific
16
+ prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README ADDED
@@ -0,0 +1,52 @@
1
+ == Fliewr (Flickr Viewr) ==
2
+
3
+ Flickr friends photostream viewer.
4
+
5
+
6
+ === Licence ===
7
+
8
+ New BSD License
9
+
10
+
11
+ === Requirements: ===
12
+
13
+ * Ruby
14
+ http://www.ruby-lang.org/
15
+
16
+ * GTK+
17
+ http://www.mozilla.org/
18
+
19
+ * Gecko engine from Mozilla
20
+ http://www.mozilla.org/
21
+
22
+ * Ruby Gtk2 bindings and Ruby/GTK bindings for Mozilla
23
+ from Ruby-GNOME2 Project
24
+ http://ruby-gnome2.sourceforge.jp/
25
+
26
+ * Ruby XML library
27
+ http://libxml.rubyforge.org/
28
+
29
+ Say Gentoo Linux users could run following command:
30
+
31
+ $ sudo emerge -uva \
32
+ dev-lang/ruby \
33
+ dev-ruby/ruby-gconf2 \
34
+ dev-ruby/ruby-gtk2 \
35
+ dev-ruby/ruby-gtkmozembed \
36
+ dev-ruby/libxml
37
+
38
+
39
+ === Installation ===
40
+
41
+ $ sudo gem source -a http://gems.github.com/
42
+ $ sudo gem install themactep-fliewr
43
+
44
+
45
+ === Homepage ===
46
+
47
+ http://github.com/themactep/fliewr
48
+
49
+
50
+ === Authors ===
51
+
52
+ Paul Philippov <themactep@gmail.com>
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gemspec|
8
+ gemspec.name = "fliewr"
9
+ gemspec.summary = "Flickr Viewr for GNOME"
10
+ gemspec.description = "fliewr is a GNOME application to watch updates from Flickr contacts."
11
+ gemspec.email = "themactep@gmail.com"
12
+ gemspec.homepage = "http://github.com/themactep/fliewr"
13
+ gemspec.description = "TODO"
14
+ gemspec.authors = ["Paul Philippov"]
15
+ gemspec.add_dependency "libxml"
16
+ gemspec.add_dependency "rest-client"
17
+ end
18
+ rescue LoadError
19
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
20
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.0.0
data/bin/fliewr ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # $Id: fliewr.rb 2009/02/08 21:48:53 EET paul Exp $
3
+ #
4
+ =begin
5
+ Flickr Viewr - Flicker Friends Photostream Viewer.
6
+
7
+ Copyright (c) 2008, Paul Philippov <paul@ppds.ws>
8
+
9
+ This software is released under the BSD License.
10
+ http://creativecommons.org/licenses/BSD/
11
+ =end
12
+
13
+ app_file = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
14
+ APP_ROOT = File.expand_path(File.dirname(app_file))
15
+ Dir.glob(APP_ROOT + '/../**/').reverse.each { |d| $:.unshift d }
16
+
17
+ begin
18
+ require 'rubygems'
19
+ rescue LoadError
20
+ nil
21
+ end
22
+
23
+ require 'fliewr/core'
24
+
25
+ Fliewr::Core.new
26
+ Thread.new { Fliewr::StatusIcon.new }
27
+ $app.main
data/data/api.url ADDED
@@ -0,0 +1 @@
1
+ http://api.flickr.com/services/rest?method=flickr.photos.getContactsPublicPhotos&api_key=0282f93eb6da0425310bd5791f4c2fc0&extras=date_upload,icon_server,license&user_id=%s&count=%d&single_photo=%d&just_friends=%d&include_self=%d
@@ -0,0 +1,9 @@
1
+ [Desktop Entry]
2
+ Name=Fliewr
3
+ Comment=Flickr Viewr
4
+ Exec=fliewr
5
+ Icon=fliewr
6
+ StartupNotify=true
7
+ Terminal=false
8
+ Type=Application
9
+ Categories=Network;
data/data/fliewr.svg ADDED
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="128" height="128">
2
+ <path fill="#0063dc" stroke="none" d="M 64.504461,16.817487 C 38.168536,17.488304 16.999778,39.17825 16.999778,65.787131 C 16.999778,84.014679 26.943418,99.898404 41.666404,108.32951 C 37.617837,101.19225 35.285462,92.947102 35.285462,84.150747 C 35.285462,57.119498 57.130753,35.181103 84.047286,35.181103 C 92.813625,35.181103 101.03145,37.517116 108.14248,41.589241 C 99.748559,26.798284 83.915678,16.817487 65.761602,16.817487 C 65.341032,16.817487 64.922491,16.806836 64.504461,16.817487 z" />
3
+ <path fill="#ff0084" stroke="none" d="M 94.809723,47.321192 C 97.715396,52.419557 99.386031,58.317585 99.386031,64.60187 C 99.386031,83.90596 83.71894,99.573047 64.414849,99.573047 C 58.127778,99.573047 52.234085,97.891152 47.134167,94.98308 C 53.153275,105.54919 64.506779,112.68725 77.529041,112.68725 C 96.833137,112.68725 112.50022,97.020162 112.50022,77.716061 C 112.50022,64.699042 105.36882,53.342179 94.809723,47.321192 z" />
4
+ </svg>
@@ -0,0 +1 @@
1
+ <div class="error"> <h1>Error</h1> %s</div>
@@ -0,0 +1,10 @@
1
+ <div class="message">
2
+ <a class="image" href="%s" style="background-image:url(%s);"></a>
3
+ <div class="popup">
4
+ <div class="userpic">
5
+ <a href="%s" title="%s"><img src="%s" alt="" /></a>
6
+ </div>
7
+ <h1>%s</h1>
8
+ <p class="time">%s</p>
9
+ </div>
10
+ </div>
@@ -0,0 +1,72 @@
1
+ body {
2
+ padding : 0;
3
+ color : #999;
4
+ color : #fff;
5
+ background : #333;
6
+ line-height : 1.250;
7
+ font : 12px "NokiaSansCn", "LucidaGrande", sans-serif;
8
+ }
9
+ body, img {
10
+ margin : 0;
11
+ }
12
+ img {
13
+ border : none;
14
+ }
15
+ div, h1, p, a {
16
+ margin-bottom : 0;
17
+ }
18
+ a {
19
+ color : #fff;
20
+ text-decoration : none;
21
+ }
22
+ div.error {
23
+ padding : 10px;
24
+ }
25
+ div.message {
26
+ clear : both;
27
+ position : relative;
28
+ padding : 7px;
29
+ margin : 5px;
30
+ color : #bbb;
31
+ background-color : #444;
32
+ -moz-border-radius : 7px;
33
+ }
34
+ a.image {
35
+ display : block;
36
+ height : 130px;
37
+ background-position : center;
38
+ }
39
+ div.userpic {
40
+ width : 55px;
41
+ height : 100%;
42
+ float : left;
43
+ }
44
+ div.imgbox {
45
+ width : 48px;
46
+ height : 48px;
47
+ margin-bottom : 5px;
48
+ background-repeat : no-repeat;
49
+ }
50
+ div.popup {
51
+ position : absolute;
52
+ left : 7px;
53
+ right : 7px;
54
+ bottom : 7px;
55
+ background-color : #000;
56
+ padding : 5px;
57
+ display : none;
58
+ }
59
+ div.message:hover div.popup {
60
+ display : inherit;
61
+ }
62
+ h1 {
63
+ font : bold 11px "NokiaSans", "LucidaGrande", sans-serif;
64
+ margin-top : 0;
65
+ height : 2.500em;
66
+ overflow : hidden;
67
+ color : #ff0;
68
+ }
69
+ p.time {
70
+ font-size : 10px;
71
+ text-align : right;
72
+ }
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml" lang="en">
4
+ <head>
5
+ <title>Flickr Viewr</title>
6
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
7
+ <style type="text/css">
8
+ /*<![CDATA[*/
9
+ %s
10
+ /*]]>*/
11
+ </style>
12
+ </head>
13
+ <body>
14
+ %s
15
+ </body>
16
+ </html>
data/fliewr.gemspec ADDED
@@ -0,0 +1,60 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{fliewr}
8
+ s.version = "2.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Paul Philippov"]
12
+ s.date = %q{2009-08-22}
13
+ s.default_executable = %q{fliewr}
14
+ s.description = %q{TODO}
15
+ s.email = %q{themactep@gmail.com}
16
+ s.executables = ["fliewr"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README"
20
+ ]
21
+ s.files = [
22
+ ".gitignore",
23
+ "LICENSE",
24
+ "README",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "bin/fliewr",
28
+ "data/api.url",
29
+ "data/fliewr.desktop",
30
+ "data/fliewr.svg",
31
+ "data/themes/default/error.html",
32
+ "data/themes/default/item.html",
33
+ "data/themes/default/style.css",
34
+ "data/themes/default/theme.html",
35
+ "fliewr.gemspec",
36
+ "lib/fliewr/core.rb",
37
+ "lib/fliewr/ui.rb",
38
+ "lib/ppds/class_factory.rb",
39
+ "lib/ppds/config.rb",
40
+ "lib/ppds/flickr.rb"
41
+ ]
42
+ s.homepage = %q{http://github.com/themactep/fliewr}
43
+ s.rdoc_options = ["--charset=UTF-8"]
44
+ s.require_paths = ["lib"]
45
+ s.rubygems_version = %q{1.3.5}
46
+ s.summary = %q{Flickr Viewr for GNOME}
47
+
48
+ if s.respond_to? :specification_version then
49
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
50
+ s.specification_version = 3
51
+
52
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
53
+ s.add_runtime_dependency(%q<libxml>, [">= 0"])
54
+ else
55
+ s.add_dependency(%q<libxml>, [">= 0"])
56
+ end
57
+ else
58
+ s.add_dependency(%q<libxml>, [">= 0"])
59
+ end
60
+ end
@@ -0,0 +1,71 @@
1
+ require 'ppds/config'
2
+ require 'ppds/flickr'
3
+ require 'fliewr/ui'
4
+ require 'gtk2'
5
+
6
+ module Fliewr
7
+ class Core
8
+
9
+ def initialize
10
+ $app = self
11
+ $cfg = Ppds::Config.new 'fliewr'
12
+
13
+ $gui = Fliewr::UI.new
14
+ $gui.show_all
15
+
16
+ $api = Ppds::Flickr.new
17
+
18
+ start_timer
19
+ end
20
+
21
+ def update
22
+ Gtk.timeout_remove(@@timeout) if @@timeout
23
+ $gui.statusbar.push 0, "updating..."
24
+
25
+ Thread.new do
26
+ ask_update $cfg.get(:update_interval) * 60
27
+ photos = $api.update $cfg.get(:max_photos)
28
+ $gui.refresh_with photos
29
+ @last_updated_at = timestamp
30
+ end
31
+ start_timer
32
+ rescue Exception => e
33
+ Alert.new @nsid, e.message, e.backtrace
34
+ end
35
+
36
+ def timestamp
37
+ Time.now.to_i
38
+ end
39
+
40
+ def ask_update(time_ahead = 0)
41
+ @requires_update_at = timestamp + time_ahead
42
+ end
43
+
44
+ def start_timer
45
+ @@timeout = Gtk::timeout_add(1000) do
46
+ sec_to_next_update = @requires_update_at.to_i - timestamp
47
+ if sec_to_next_update < 0
48
+ update
49
+ else
50
+ $gui.statusbar.push 0, "%s to update" % human_time(sec_to_next_update)
51
+ end
52
+ end
53
+ end
54
+
55
+ def human_time(time)
56
+ seconds = time.modulo(SECONDS_PER_MINUTE)
57
+ minutes = (time - seconds) / SECONDS_PER_MINUTE
58
+ "%d:%02d" % [minutes, seconds]
59
+ end
60
+
61
+ def main
62
+ Gtk::main
63
+ end
64
+
65
+ def quit
66
+ Gtk::main_quit
67
+ ensure
68
+ $cfg.save
69
+ end
70
+ end
71
+ end
data/lib/fliewr/ui.rb ADDED
@@ -0,0 +1,370 @@
1
+ require 'gtk2'
2
+ require 'gtkmozembed'
3
+
4
+ Gtk::MozEmbed.set_profile_path ENV['HOME'] + '/.mozilla', 'fliewr'
5
+
6
+ module Fliewr
7
+
8
+ SECONDS_PER_MINUTE = 60
9
+ IMAGE_ROOT = File.expand_path(File.join(APP_ROOT, '..', 'data'))
10
+
11
+ class UI < Gtk::Window
12
+
13
+ attr_accessor :logo, :statusbar, :theme_base, :theme_item, :theme_error, :theme_style
14
+
15
+ def initialize
16
+ super Gtk::Window::TOPLEVEL
17
+
18
+ filename = File.join(Fliewr::IMAGE_ROOT, 'fliewr.svg')
19
+ self.logo = Gdk::Pixbuf.new filename, 128, 128
20
+
21
+ self.set_title 'Fliewr'
22
+ self.set_icon self.logo
23
+ self.set_width_request 278
24
+ self.set_height_request 400
25
+ self.set_allow_shrink false
26
+ self.set_default_width $cfg.get(:window_width).to_i
27
+ self.set_default_height $cfg.get(:window_height).to_i
28
+ self.move $cfg.get(:window_x_pos).to_i, $cfg.get(:window_y_pos).to_i
29
+
30
+ theme = $cfg.get(:theme) || 'default'
31
+ self.theme_base = File.open(File.join('../data/themes/',theme,'theme.html'), "r") { |f| f.read }
32
+ self.theme_item = File.open(File.join('../data/themes/',theme,'item.html'), "r") { |f| f.read }
33
+ self.theme_error = File.open(File.join('../data/themes/',theme,'error.html'), "r") { |f| f.read }
34
+ self.theme_style = File.open(File.join('../data/themes/',theme,'style.css'), "r") { |f| f.read }
35
+
36
+ self.signal_connect(:destroy) { quit }
37
+ self.signal_connect(:delete_event) { minimize }
38
+ self.signal_connect(:check_resize) { remember_size_position }
39
+ self.signal_connect(:window_state_event) do |widget, event|
40
+ case event.event_type
41
+ when Gdk::Event::WINDOW_STATE
42
+ minimize if event.changed_mask.iconified? and event.new_window_state.iconified?
43
+ end
44
+ end
45
+
46
+ self.statusbar = Gtk::Statusbar.new
47
+ self.statusbar.set_has_resize_grip false
48
+
49
+ toolbar = Gtk::Toolbar.new
50
+ toolbar.icon_size = Gtk::IconSize::MENU
51
+
52
+ icon = Gtk::Image.new Gtk::Stock::HOME, Gtk::IconSize::MENU
53
+ button = Gtk::ToolButton.new icon, 'Flickr'
54
+ button.set_important true
55
+ button.signal_connect(:clicked) do |widget|
56
+ visit_user_profile
57
+ end
58
+ toolbar.insert 0, button
59
+
60
+ icon = Gtk::Image.new Gtk::Stock::REFRESH, Gtk::IconSize::MENU
61
+ button = Gtk::ToolButton.new icon, 'Refresh'
62
+ button.set_important true
63
+ button.set_can_default true
64
+ button.set_can_focus true
65
+ button.signal_connect(:clicked) do |widget|
66
+ $app.ask_update
67
+ end
68
+ toolbar.insert 1, button
69
+ self.set_default button
70
+ self.set_focus button
71
+
72
+ icon = Gtk::Image.new Gtk::Stock::PREFERENCES, Gtk::IconSize::MENU
73
+ button = Gtk::ToolButton.new icon, 'Settings'
74
+ button.signal_connect(:clicked) do |widget|
75
+ Fliewr::SettingsDialog.new
76
+ end
77
+ toolbar.insert 2, button
78
+
79
+ separator = Gtk::SeparatorToolItem.new
80
+ separator.set_draw false
81
+ separator.set_expand true
82
+ toolbar.insert 3, separator
83
+
84
+ icon = Gtk::Image.new Gtk::Stock::QUIT, Gtk::IconSize::MENU
85
+ button = Gtk::ToolButton.new icon, 'Quit'
86
+ button.signal_connect(:clicked) do |widget|
87
+ $app.quit
88
+ end
89
+ toolbar.insert 4, button
90
+
91
+ @browser = Gtk::MozEmbed.new
92
+ @browser.signal_connect(:open_uri) do |widget, uri|
93
+ open_in_external_browser(uri)
94
+ end
95
+
96
+ vbox = Gtk::VBox.new false, 4
97
+ vbox.pack_start toolbar, false
98
+ vbox.pack_start @browser
99
+ vbox.pack_start self.statusbar, false
100
+ self.add vbox
101
+ end
102
+
103
+ def remember_size_position
104
+ x, y = self.position
105
+ w, h = self.size
106
+ $cfg.set :window_x_pos, x
107
+ $cfg.set :window_y_pos, y
108
+ $cfg.set :window_width, w
109
+ $cfg.set :window_height, h
110
+ end
111
+
112
+ def minimize
113
+ remember_size_position
114
+ hide
115
+ end
116
+
117
+ def maximize
118
+ self.show
119
+ self.present
120
+ end
121
+
122
+ def open_in_gecko(html)
123
+ @browser.open_stream "file:///", "text/html"
124
+ @browser.append_data self.theme_base % [ self.theme_style, html ]
125
+ @browser.close_stream
126
+ end
127
+
128
+ def refresh_with(data)
129
+ html = data.map { |d| templatize(d) }.join
130
+ open_in_gecko html
131
+ end
132
+
133
+ def templatize(data)
134
+ self.theme_item % [
135
+ photolink(data.owner, data.id),
136
+ photopreview(data.farm, data.server, data.id, data.secret),
137
+ user_profile_link(data.owner),
138
+ data.username,
139
+ userpic(data.iconfarm, data.iconserver, data.owner),
140
+ data.title,
141
+ dateupload(data.dateupload)
142
+ ]
143
+ end
144
+
145
+ def photopreview(*args)
146
+ 'http://farm%s.static.flickr.com/%s/%s_%s_m.jpg' % args
147
+ end
148
+
149
+ def photolink(*args)
150
+ 'http://www.flickr.com/photos/%s/%s' % args
151
+ end
152
+
153
+ def user_profile_link(id = @nsid)
154
+ 'http://www.flickr.com/people/%s' % id
155
+ end
156
+
157
+ def userpic(farm, server, owner)
158
+ return 'http://www.flickr.com/images/buddyicon.jpg' if farm.to_i == 0
159
+ 'http://farm%s.static.flickr.com/%s/buddyicons/%s.jpg' % [ farm, server, owner ]
160
+ end
161
+
162
+ def dateupload(date_and_time)
163
+ Time.at(date_and_time.to_i)
164
+ end
165
+
166
+ def visit_user_profile
167
+ open_in_external_browser user_profile_link
168
+ end
169
+
170
+ def open_in_external_browser(uri)
171
+ Thread.new { system('xdg-open "%s"' % uri) }
172
+ end
173
+
174
+ def quit
175
+ $app.quit
176
+ end
177
+ end
178
+
179
+
180
+ class StatusIcon < Gtk::StatusIcon
181
+ def initialize
182
+ super
183
+ self.file = File.join(Fliewr::IMAGE_ROOT, 'fliewr.svg')
184
+ self.set_tooltip 'Flickr Viewr'
185
+ self.signal_connect(:activate) do
186
+ if $gui.visible?
187
+ $gui.minimize
188
+ else
189
+ $gui.move $cfg.get(:window_x_pos), $cfg.get(:window_y_pos)
190
+ $gui.show.present
191
+ end
192
+ end
193
+
194
+ self.signal_connect(:popup_menu) do |icon, button, time|
195
+ menu.popup nil, nil, button, time
196
+ end
197
+
198
+ separator = Gtk::SeparatorMenuItem.new
199
+
200
+ menu = Gtk::Menu.new
201
+
202
+ item = Gtk::ImageMenuItem.new Gtk::Stock::HOME
203
+ item.signal_connect(:activate) do
204
+ $app.visit_user_profile
205
+ end
206
+ menu.append item
207
+
208
+ item = Gtk::ImageMenuItem.new Gtk::Stock::REFRESH
209
+ item.signal_connect(:activate) do
210
+ $app.update
211
+ end
212
+ menu.append item
213
+
214
+ item = Gtk::CheckMenuItem.new 'Always on top'
215
+ item.signal_connect(:toggled) do |widget|
216
+ $gui.keep_above = widget.active?
217
+ end
218
+ menu.append item
219
+
220
+ item = Gtk::ImageMenuItem.new Gtk::Stock::PREFERENCES
221
+ item.signal_connect(:activate) do
222
+ Fliewr::SettingsDialog.new
223
+ end
224
+ menu.append item
225
+
226
+ item = Gtk::ImageMenuItem.new Gtk::Stock::ABOUT
227
+ item.signal_connect(:activate) do
228
+ AboutDialog.new
229
+ end
230
+ menu.append item
231
+ menu.append separator
232
+
233
+ item = Gtk::ImageMenuItem.new Gtk::Stock::QUIT
234
+ item.signal_connect(:activate) do
235
+ $app.quit
236
+ end
237
+ menu.append item
238
+ menu.show_all
239
+ end
240
+ end
241
+
242
+ class AboutDialog < Gtk::AboutDialog
243
+ def initialize
244
+ Gtk::AboutDialog.set_email_hook do |widget, email|
245
+ system("xdg-email #{email}")
246
+ end
247
+ Gtk::AboutDialog.set_url_hook do |widget, link|
248
+ system("xdg-open #{link}")
249
+ end
250
+ super
251
+ self.name = 'Flickr Viewr'
252
+ self.program_name = 'Flickr Viewr'
253
+ self.comments = "Flickr photostream viewer"
254
+ self.version = '2.0'
255
+ self.copyright = "Copyright (c)2008 Paul Philippov"
256
+ self.license = "This software is released under the BSD License.\nhttp://creativecommons.org/licenses/BSD/"
257
+ self.authors = ['Paul Philippov <paul@ppds.ws>']
258
+ self.documenters = ['Paul Philippov <paul@ppds.ws>']
259
+ self.website = "http://fliewr.googlecode.com/"
260
+ self.logo = $gui.logo
261
+ self.run
262
+ self.destroy
263
+ end
264
+ end
265
+
266
+ class SettingsDialog < Gtk::Dialog
267
+ def initialize
268
+ super "Settings", nil, Gtk::Dialog::MODAL,
269
+ [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT],
270
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
271
+
272
+ self.set_default_response Gtk::Dialog::RESPONSE_ACCEPT
273
+ self.signal_connect :response do |dialog, response|
274
+ case response
275
+ when Gtk::Dialog::RESPONSE_ACCEPT
276
+ if /\d\d\d\d\d\d\d\d@N\d\d/ =~ @nsid_entry.text
277
+ $cfg.set :nsid, @nsid_entry.text
278
+ $cfg.set :update_interval, @update_interval_spin.value
279
+ $cfg.set :max_photos, @max_photos_spin.value
280
+ $cfg.set :one_per_contact, @one_per_contact_toggle.active?
281
+ $cfg.set :only_from_friends, @only_from_friends_toggle.active?
282
+ $cfg.set :include_self, @include_self_toggle.active?
283
+ $app.update
284
+ else
285
+ Alert.new "User ID has incorrect format"
286
+ end
287
+ when Gtk::Dialog::RESPONSE_CANCEL
288
+ true
289
+ end
290
+ end
291
+ hbox = Gtk::HBox.new false, 8
292
+ hbox.set_border_width 8
293
+ self.vbox.pack_start hbox, false, false, 0
294
+
295
+ stock = Gtk::Image.new Gtk::Stock::PREFERENCES, Gtk::IconSize::DIALOG
296
+ hbox.pack_start stock, false, false, 0
297
+
298
+ table = Gtk::Table.new 3, 6
299
+ table.set_row_spacings 4
300
+ table.set_column_spacings 8
301
+ hbox.pack_start table, true, true, 0
302
+
303
+ @nsid_entry = Gtk::Entry.new
304
+ @nsid_entry.width_chars = 13
305
+ @nsid_entry.max_length = 12
306
+ @nsid_entry.text = $cfg.get(:nsid)
307
+ table.attach_defaults label('Your Flickr user ID'), 0, 1, 0, 1
308
+ table.attach_defaults @nsid_entry, 1, 2, 0, 1
309
+ table.attach_defaults button_with_click(:find, :find_nsid), 2, 3, 0, 1
310
+
311
+ @update_interval_spin = Gtk::SpinButton.new(1, 100, 1)
312
+ @update_interval_spin.value = $cfg.get(:update_interval).to_i
313
+ table.attach_defaults label('Check new photos every'), 0, 1, 1, 2
314
+ table.attach_defaults @update_interval_spin, 1, 2, 1, 2
315
+ table.attach_defaults label('minutes'), 2, 3, 1, 2
316
+
317
+ @max_photos_spin = Gtk::SpinButton.new(1, 50, 1)
318
+ @max_photos_spin.value = $cfg.get(:max_photos).to_i
319
+ table.attach_defaults label('Maximum photos to display'), 0, 1, 2, 3
320
+ table.attach_defaults @max_photos_spin, 1, 2, 2, 3
321
+
322
+ @one_per_contact_toggle = Gtk::CheckButton.new
323
+ @one_per_contact_toggle.active = $cfg.get(:one_per_contact)
324
+ table.attach_defaults label('Only one photo per contact'), 0, 1, 3, 4
325
+ table.attach_defaults @one_per_contact_toggle, 1, 2, 3, 4
326
+
327
+ @only_from_friends_toggle = Gtk::CheckButton.new
328
+ @only_from_friends_toggle.active = $cfg.get(:only_from_friend)
329
+ table.attach_defaults label('Only from friends and family'), 0, 1, 4, 5
330
+ table.attach_defaults @only_from_friends_toggle, 1, 2, 4, 5
331
+
332
+ @include_self_toggle = Gtk::CheckButton.new
333
+ @include_self_toggle.active = $cfg.get(:include_self)
334
+ table.attach_defaults label('Include your own photos'), 0, 1, 5, 6
335
+ table.attach_defaults @include_self_toggle, 1, 2, 5, 6
336
+
337
+ self.show_all
338
+ self.run
339
+ self.destroy
340
+ end
341
+
342
+ def button_with_click(stock_id, method_name)
343
+ button = Gtk::Button.new icon(stock_id)
344
+ button.signal_connect(:clicked) do |widget|
345
+ self.method(method_name).call
346
+ end
347
+ button.show_all
348
+ end
349
+
350
+ def find_nsid
351
+ $gui.open_in_external_browser 'http://www.flickr.com/services/api/explore/?method=flickr.people.getInfo'
352
+ end
353
+
354
+ def icon(stock_id)
355
+ Gtk::Stock.const_get stock_id.to_s.upcase
356
+ end
357
+
358
+ def label(text)
359
+ Gtk::Label.new(text).set_alignment(0, 0.5)
360
+ end
361
+ end
362
+
363
+ class Alert
364
+ def initialize(*args)
365
+ html = $gui.theme_error % [args].flatten.map { |e| "<li>#{e}</li>" }.join
366
+ $gui.open_in_gecko(html)
367
+ false
368
+ end
369
+ end
370
+ end
@@ -0,0 +1,17 @@
1
+ module Ppds
2
+ class ClassFactory
3
+ def initialize(data=[])
4
+ for att in data
5
+ set(att.name.gsub(/-/,'_'), att.value)
6
+ end
7
+ end
8
+
9
+ def get(name)
10
+ instance_variable_get("@#{name}")
11
+ end
12
+
13
+ def set(name, value)
14
+ instance_variable_set("@#{name}", value)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,47 @@
1
+ require 'gconf2'
2
+
3
+ module Ppds
4
+ class Config
5
+ @@gconf = GConf::Client.default
6
+
7
+ def gconf
8
+ @@gconf
9
+ end
10
+
11
+ def initialize(app)
12
+ @root = '/apps/%s' % app
13
+ gconf.add_dir(@root)
14
+ end
15
+
16
+ def name_from_key(key)
17
+ key.split('/').last
18
+ end
19
+
20
+ def key_from_name(name)
21
+ [ @root, name ].join("/")
22
+ end
23
+
24
+ def all
25
+ gconf.all_entries(@root)
26
+ end
27
+
28
+ def get(name)
29
+ gconf[key_from_name(name)]
30
+ end
31
+
32
+ def set(name, value)
33
+ gconf[key_from_name(name)] = value
34
+ end
35
+
36
+ def save
37
+ gconf.suggest_sync
38
+ end
39
+
40
+ def destroy
41
+ for one in all
42
+ gconf.unset(one.key)
43
+ end
44
+ save
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,51 @@
1
+ require 'ppds/class_factory'
2
+ require 'rest_client'
3
+ require 'xml'
4
+
5
+ module Ppds
6
+ class Photo < ClassFactory
7
+ attr_accessor :id, :secret, :server, :farm, :title, :owner, :username,
8
+ :ispublic, :isfriend, :isfamily, :dateupload, :iconserver,
9
+ :iconfarm, :license
10
+ end
11
+
12
+ class Flickr
13
+ API_URL = 'http://api.flickr.com/services/rest'
14
+ API_KEY = '0282f93eb6da0425310bd5791f4c2fc0'
15
+
16
+ attr_accessor :photos
17
+
18
+ def initialize
19
+ end
20
+
21
+ def query(action, data)
22
+ data.update({
23
+ :api_key => API_KEY,
24
+ :method => action
25
+ })
26
+ RestClient.post(API_URL, data)
27
+ rescue RestClient::RequestFailed
28
+ raise 'Query failed: %s' % $!
29
+ rescue RestClient::RequestTimeout
30
+ raise 'Timeout occured'
31
+ rescue Exception
32
+ raise $!
33
+ end
34
+
35
+ def update(qty)
36
+ data = {
37
+ :extras => 'date_upload,icon_server,license',
38
+ :count => qty,
39
+ :user_id => $cfg.get(:nsid).to_s,
40
+ :single_photo => $cfg.get(:one_per_contact) ? 1 : 0,
41
+ :just_friends => $cfg.get(:only_from_friends) ? 1 : 0,
42
+ :include_self => $cfg.get(:include_self) ? 1 : 0
43
+ }
44
+ xml = query('flickr.photos.getContactsPublicPhotos', data)
45
+ @xml = XML::Parser.string(xml).parse
46
+ self.photos = @xml.find('//photos/photo').map do |node|
47
+ Photo.new(node.attributes)
48
+ end
49
+ end
50
+ end
51
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: themactep-fliewr
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Paul Philippov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-08-22 00:00:00 -07:00
13
+ default_executable: fliewr
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: libxml
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: TODO
26
+ email: themactep@gmail.com
27
+ executables:
28
+ - fliewr
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README
34
+ files:
35
+ - .gitignore
36
+ - LICENSE
37
+ - README
38
+ - Rakefile
39
+ - VERSION
40
+ - bin/fliewr
41
+ - data/api.url
42
+ - data/fliewr.desktop
43
+ - data/fliewr.svg
44
+ - data/themes/default/error.html
45
+ - data/themes/default/item.html
46
+ - data/themes/default/style.css
47
+ - data/themes/default/theme.html
48
+ - fliewr.gemspec
49
+ - lib/fliewr/core.rb
50
+ - lib/fliewr/ui.rb
51
+ - lib/ppds/class_factory.rb
52
+ - lib/ppds/config.rb
53
+ - lib/ppds/flickr.rb
54
+ has_rdoc: false
55
+ homepage: http://github.com/themactep/fliewr
56
+ licenses:
57
+ post_install_message:
58
+ rdoc_options:
59
+ - --charset=UTF-8
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: "0"
73
+ version:
74
+ requirements: []
75
+
76
+ rubyforge_project:
77
+ rubygems_version: 1.3.5
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: Flickr Viewr for GNOME
81
+ test_files: []
82
+