gimdb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/LICENSE +674 -0
- data/README.rdoc +81 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/bin/gimdb +9 -0
- data/data/gimdb.glade +1122 -0
- data/data/icons/favourites.png +0 -0
- data/data/icons/imdb.png +0 -0
- data/data/icons/imdb_icon.png +0 -0
- data/data/icons/no_poster.png +0 -0
- data/data/icons/seen.png +0 -0
- data/data/icons/spinner16x16.gif +0 -0
- data/data/icons/to_see.png +0 -0
- data/data/icons/users.png +0 -0
- data/data/icons/users_edit.png +0 -0
- data/data/locale/it/LC_MESSAGES/gimdb.mo +0 -0
- data/gimdb.gemspec +73 -0
- data/lib/imdb.rb +104 -0
- data/po/gimdb.pot +217 -0
- data/po/it/gimdb.po +233 -0
- data/src/controller.rb +50 -0
- data/src/gimdb.rb +379 -0
- data/src/model.rb +135 -0
- data/src/movie_box.rb +110 -0
- metadata +109 -0
data/src/gimdb.rb
ADDED
@@ -0,0 +1,379 @@
|
|
1
|
+
begin
|
2
|
+
require 'gtk2'
|
3
|
+
rescue LoadError => e
|
4
|
+
puts "Error: #{e.to_s}"
|
5
|
+
puts ""
|
6
|
+
puts "You must install 'gtk2' to run this program."
|
7
|
+
puts "If you are using Debian/GNU Linux you can install it with:"
|
8
|
+
puts ""
|
9
|
+
puts " apt-get install libgnome2-ruby"
|
10
|
+
puts ""
|
11
|
+
exit -1
|
12
|
+
end
|
13
|
+
begin
|
14
|
+
require 'libglade2'
|
15
|
+
rescue LoadError => e
|
16
|
+
puts "Error: #{e.to_s}"
|
17
|
+
puts ""
|
18
|
+
puts "You must install 'libglade2' to run this program."
|
19
|
+
puts "If you are using Debian/GNU Linux you can install it with:"
|
20
|
+
puts ""
|
21
|
+
puts " apt-get install libglade2-ruby"
|
22
|
+
puts ""
|
23
|
+
exit -1
|
24
|
+
end
|
25
|
+
require 'lib/imdb'
|
26
|
+
require 'src/controller'
|
27
|
+
require 'src/movie_box'
|
28
|
+
|
29
|
+
|
30
|
+
class GimdbGlade
|
31
|
+
include GetText
|
32
|
+
|
33
|
+
attr :glade
|
34
|
+
|
35
|
+
def initialize(path_or_data, root = nil, domain = $DOMAIN, localedir = $LOCALEDIR, flag = GladeXML::FILE)
|
36
|
+
bindtextdomain(domain, localedir, nil, 'UTF-8')
|
37
|
+
@glade = GladeXML.new(path_or_data, root, domain, localedir, flag) { |handler| method(handler) }
|
38
|
+
@searcher = IMDB.new
|
39
|
+
@movies = []
|
40
|
+
setting_up
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
|
47
|
+
def setting_up
|
48
|
+
# Get widgets from glade xml file
|
49
|
+
@window = @glade.get_widget('window')
|
50
|
+
@sidebar = @glade.get_widget('sidebar')
|
51
|
+
@users_menu_item = @glade.get_widget('users_menu_item')
|
52
|
+
@entry_title = @glade.get_widget('entry_title')
|
53
|
+
@spin_year_from = @glade.get_widget('spin_year_from')
|
54
|
+
@spin_year_to = @glade.get_widget('spin_year_to')
|
55
|
+
@combo_rating_from = @glade.get_widget('combo_rating_from')
|
56
|
+
@combo_rating_to = @glade.get_widget('combo_rating_to')
|
57
|
+
@b_search = @glade.get_widget('b_search')
|
58
|
+
@combo_sort = @glade.get_widget('combo_sort')
|
59
|
+
@toggle_sort = @glade.get_widget('toggle_sort')
|
60
|
+
@check_hide_seen = @glade.get_widget('check_hide_seen')
|
61
|
+
@check_only_see = @glade.get_widget('check_only_see')
|
62
|
+
@label_status = @glade.get_widget('label_status')
|
63
|
+
@progress = @glade.get_widget('progress')
|
64
|
+
@image_connection = @glade.get_widget('image_connection')
|
65
|
+
@image_spinner = @glade.get_widget('image_spinner')
|
66
|
+
@scrolled = @glade.get_widget('scrolled')
|
67
|
+
@vbox_movies = Gtk::VBox.new
|
68
|
+
@dialog_users = @glade.get_widget('dialog_users')
|
69
|
+
@entry_user = @glade.get_widget('entry_user')
|
70
|
+
@combo_del_users = @glade.get_widget('combo_del_users')
|
71
|
+
@table_combo = @glade.get_widget('table_combo')
|
72
|
+
@check_genres_all = @glade.get_widget('check_genres_all')
|
73
|
+
|
74
|
+
@genres = [
|
75
|
+
:action,:adventure,:animation,:biography,:comedy,
|
76
|
+
:crime,:documentary,:drama,:family,:fantasy,:film_noir,
|
77
|
+
:game_show,:history,:horror,:music,:musical,:mystery,:news,
|
78
|
+
:romance,:sci_fi,:sport,:thriller,:war,:western
|
79
|
+
]
|
80
|
+
@genres.each do |genre|
|
81
|
+
instance_variable_set("@check_genres_#{genre}", @glade.get_widget("check_genres_#{genre}")).signal_connect('clicked') do
|
82
|
+
@check_genres_all.active = false
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Some stuffs
|
87
|
+
@users = User.find(:all, :conditions => 'selected = 1')
|
88
|
+
@all_users = User.all
|
89
|
+
build_users_menu
|
90
|
+
@spin_year_to.value = Time.now.year.to_i
|
91
|
+
@combo_rating_from.active = 0
|
92
|
+
@combo_rating_to.active = 9
|
93
|
+
@combo_sort.active = 0
|
94
|
+
@image_spinner.pixbuf_animation = Gdk::PixbufAnimation.new('data/icons/spinner16x16.gif')
|
95
|
+
@scrolled.add_with_viewport(@vbox_movies)
|
96
|
+
@scrolled.vscrollbar.signal_connect('value-changed') do |s|
|
97
|
+
x = (s.adjustment.upper * 90.0)/100.0
|
98
|
+
vadj = s.value + s.adjustment.page_size
|
99
|
+
if (vadj > x && vadj > @vadj && @b_search.sensitive?)
|
100
|
+
Thread.new{get_more_movies} if @b_search.sensitive?
|
101
|
+
#get_more_movies if @b_search.sensitive?
|
102
|
+
end
|
103
|
+
@vadj = vadj
|
104
|
+
end
|
105
|
+
@vbox_movies.border_width = 10
|
106
|
+
@vbox_movies.spacing = 10
|
107
|
+
|
108
|
+
# Window startup
|
109
|
+
@window.signal_connect('delete_event') { Gtk.main_quit }
|
110
|
+
@window.show_all
|
111
|
+
@progress.hide
|
112
|
+
@label_status.hide
|
113
|
+
@image_spinner.hide
|
114
|
+
@image_connection.hide
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
def build_options
|
119
|
+
options = {}
|
120
|
+
options[:offline] = @offline
|
121
|
+
options[:title] = @entry_title.text unless @entry_title.text.blank?
|
122
|
+
options[:release_date] = "#{@spin_year_from.value.to_i},#{@spin_year_to.value.to_i}"
|
123
|
+
rating_from = @combo_rating_from.active_text
|
124
|
+
rating_to = @combo_rating_to.active_text
|
125
|
+
if rating_from != '1' && rating_to != '10'
|
126
|
+
options[:user_rating] = "#{rating_from},#{rating_to}"
|
127
|
+
end
|
128
|
+
unless @check_genres_all.active?
|
129
|
+
options[:genres] = ''
|
130
|
+
@genres.each do |genre|
|
131
|
+
options[:genres] += "#{genre}," if instance_variable_get("@check_genres_#{genre}").active?
|
132
|
+
end
|
133
|
+
options[:genres].chop!
|
134
|
+
end
|
135
|
+
case @combo_sort.active
|
136
|
+
when 0
|
137
|
+
sort = 'moviemeter'
|
138
|
+
when 1
|
139
|
+
sort = 'alpha'
|
140
|
+
when 2
|
141
|
+
sort = 'user_rating'
|
142
|
+
when 3
|
143
|
+
sort = 'num_votes'
|
144
|
+
when 4
|
145
|
+
sort = 'runtime'
|
146
|
+
when 5
|
147
|
+
sort = 'year'
|
148
|
+
end
|
149
|
+
options[:sort] = sort + (@toggle_sort.active? ? ',DESC' : '')
|
150
|
+
return options
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
def searching(state)
|
155
|
+
if state
|
156
|
+
@b_search.sensitive = false
|
157
|
+
update_progress_bar(0.0, 0.0, _('Searching'))
|
158
|
+
@progress.show
|
159
|
+
@label_status.show
|
160
|
+
@image_spinner.show
|
161
|
+
else
|
162
|
+
@b_search.sensitive = true
|
163
|
+
@progress.hide
|
164
|
+
@label_status.hide
|
165
|
+
@image_spinner.hide
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
def update_progress_bar(step, max, text = nil)
|
171
|
+
max = 80000 if max.nil? || max == 0
|
172
|
+
fraction = step.to_f / max.to_f
|
173
|
+
fraction = 1.0 if fraction > 1.0
|
174
|
+
@progress.fraction = fraction
|
175
|
+
@label_status.text = _(text) + '...' unless text.nil?
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
def get_movies(kind = nil)
|
180
|
+
if @b_search.sensitive?
|
181
|
+
clear_movies_list
|
182
|
+
searching(true)
|
183
|
+
if kind.nil?
|
184
|
+
@movies = Controller::process_info(@searcher, build_options) do |step, max, text|
|
185
|
+
update_progress_bar(step, max, text)
|
186
|
+
end
|
187
|
+
else
|
188
|
+
@movies = Movie.get_kind(@users, kind)
|
189
|
+
end
|
190
|
+
@index = 0
|
191
|
+
update_movies_list
|
192
|
+
searching(false)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
def get_more_movies
|
198
|
+
if @b_search.sensitive?
|
199
|
+
searching(true)
|
200
|
+
@movies += Controller::process_info(@searcher, :next => true, :offline => @offline) do |step, max, text|
|
201
|
+
update_progress_bar(step, max, text)
|
202
|
+
end
|
203
|
+
update_movies_list
|
204
|
+
searching(false)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
def clear_movies_list
|
210
|
+
@scrolled.each { |child| @scrolled.remove(child) }
|
211
|
+
@vbox_movies = Gtk::VBox.new
|
212
|
+
@vbox_movies.border_width = 10
|
213
|
+
@vbox_movies.spacing = 10
|
214
|
+
@scrolled.add_with_viewport(@vbox_movies)
|
215
|
+
@scrolled.vscrollbar.adjustment.value = 0
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
def update_movies_list
|
220
|
+
@progress.fraction = 0
|
221
|
+
unless @index.nil?
|
222
|
+
display_movies = @movies[@index..-1]
|
223
|
+
display_movies.each_with_index do |m, i|
|
224
|
+
if ((!@check_hide_seen.active? || (m.get_users(:seen) & @users).empty?) &&
|
225
|
+
(!@check_only_see.active? || !(m.get_users(:to_see) & @users).empty?))
|
226
|
+
@vbox_movies.pack_start(GtkGimdb::MovieBox.new(m, @users), false)
|
227
|
+
@vbox_movies.pack_start(Gtk::HSeparator.new, false)
|
228
|
+
end
|
229
|
+
update_progress_bar(i, display_movies.size - 1, 'Building movie boxes')
|
230
|
+
end
|
231
|
+
@index = @movies.size
|
232
|
+
@vbox_movies.show_all
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
def build_users_menu
|
238
|
+
submenu = Gtk::Menu.new
|
239
|
+
@all_users.sort{|x,y| x.name <=> y.name}.each do |u|
|
240
|
+
m = Gtk::CheckMenuItem.new(u.name)
|
241
|
+
m.active = true if @users.include?(u)
|
242
|
+
submenu.append(m)
|
243
|
+
m.signal_connect('toggled') do
|
244
|
+
if m.active?
|
245
|
+
u.selected = 1
|
246
|
+
u.save!
|
247
|
+
@users << u
|
248
|
+
else
|
249
|
+
u.selected = 0
|
250
|
+
u.save!
|
251
|
+
@users.delete(u)
|
252
|
+
end
|
253
|
+
@users.sort!{|x,y| x.name <=> y.name}
|
254
|
+
end
|
255
|
+
end
|
256
|
+
@users_menu_item.submenu = submenu
|
257
|
+
@users_menu_item.show_all
|
258
|
+
end
|
259
|
+
|
260
|
+
|
261
|
+
############
|
262
|
+
### Events ###
|
263
|
+
############
|
264
|
+
|
265
|
+
|
266
|
+
def on_search_clicked(widget, arg = nil)
|
267
|
+
Thread.new{get_movies} if @b_search.sensitive?
|
268
|
+
#get_movies if @b_search.sensitive?
|
269
|
+
end
|
270
|
+
|
271
|
+
def on_key_press(widget, arg = nil)
|
272
|
+
on_search_clicked(widget) if arg.keyval == Gdk::Keyval::GDK_Return
|
273
|
+
end
|
274
|
+
|
275
|
+
def on_get_more_movies_clicked(widget, arg = nil)
|
276
|
+
Thread.new{get_more_movies} if @b_search.sensitive?
|
277
|
+
#get_more_movies if @b_search.sensitive?
|
278
|
+
end
|
279
|
+
|
280
|
+
def on_show_to_see_clicked(widget, arg = nil)
|
281
|
+
Thread.new{get_movies(:to_see)}
|
282
|
+
end
|
283
|
+
|
284
|
+
def on_show_seen_clicked(widget, arg = nil)
|
285
|
+
Thread.new{get_movies(:seen)}
|
286
|
+
end
|
287
|
+
|
288
|
+
def on_show_favourites_clicked(widget, arg = nil)
|
289
|
+
Thread.new{get_movies(:favourites)}
|
290
|
+
end
|
291
|
+
|
292
|
+
def on_clean_clicked(widget, arg = nil)
|
293
|
+
@entry_title.text = ''
|
294
|
+
@spin_year_from.value = 1970
|
295
|
+
@spin_year_to.value = Time.now.year.to_i
|
296
|
+
@combo_rating_from.active = 0
|
297
|
+
@combo_rating_to.active = 9
|
298
|
+
@combo_sort.active = 0
|
299
|
+
@genres.each do |genre|
|
300
|
+
instance_variable_get("@check_genres_#{genre}").active = false
|
301
|
+
@check_genres_all.active = true
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
def on_work_offline_clicked(widget, arg = nil)
|
306
|
+
@offline = !widget.active?
|
307
|
+
if @offline
|
308
|
+
@window.title += ' (offline)'
|
309
|
+
@image_connection.show
|
310
|
+
else
|
311
|
+
@window.title = @window.title.gsub(' (offline)', '')
|
312
|
+
@image_connection.hide
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
def on_quit_clicked(widget, arg = nil)
|
317
|
+
Gtk.main_quit
|
318
|
+
end
|
319
|
+
|
320
|
+
def on_show_sidebar(widget, arg = nil)
|
321
|
+
widget.active? ? @sidebar.show : @sidebar.hide
|
322
|
+
end
|
323
|
+
|
324
|
+
def on_manage_users_clicked(widget, arg = nil)
|
325
|
+
@combo_del_users = Gtk::ComboBox.new
|
326
|
+
@table_combo.attach(@combo_del_users, 0,1, 1,2)
|
327
|
+
@all_users.sort{|x,y| x.name <=> y.name}.each do |u|
|
328
|
+
@combo_del_users.append_text(u.name)
|
329
|
+
end
|
330
|
+
@combo_del_users.active = 0
|
331
|
+
@dialog_users.show_all
|
332
|
+
end
|
333
|
+
|
334
|
+
def on_add_users_clicked(widget, arg = nil)
|
335
|
+
unless @entry_user.text.empty?
|
336
|
+
u = User.new(:name => @entry_user.text)
|
337
|
+
begin
|
338
|
+
u.save
|
339
|
+
@all_users << u
|
340
|
+
build_users_menu
|
341
|
+
@combo_del_users.append_text(u.name)
|
342
|
+
@combo_del_users.active = 0
|
343
|
+
@entry_user.text = ''
|
344
|
+
@label_status.text = _('New user added')
|
345
|
+
@label_status.show
|
346
|
+
# @dialog_users.hide
|
347
|
+
rescue
|
348
|
+
nil
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
def on_del_users_clicked(widget, arg = nil)
|
354
|
+
name = @combo_del_users.active_text
|
355
|
+
u = User.find_by_name(name)
|
356
|
+
unless u.nil?
|
357
|
+
u.destroy
|
358
|
+
@all_users.delete(u)
|
359
|
+
build_users_menu
|
360
|
+
@combo_del_users.remove_text(@combo_del_users.active)
|
361
|
+
@label_status.text = _('User deleted')
|
362
|
+
@label_status.show
|
363
|
+
# @combo_del_users.active = 0
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
def on_select_all_users_clicked(widget, arg = nil)
|
368
|
+
@users_menu_item.submenu.children.each do |c|
|
369
|
+
c.active = !c.active?
|
370
|
+
end
|
371
|
+
@dialog_users.hide
|
372
|
+
end
|
373
|
+
|
374
|
+
def on_close_manage_users_clicked(widget, arg = nil)
|
375
|
+
@dialog_users.hide
|
376
|
+
@label_status.hide
|
377
|
+
end
|
378
|
+
|
379
|
+
end
|
data/src/model.rb
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_record'
|
3
|
+
require 'etc'
|
4
|
+
|
5
|
+
|
6
|
+
$GIMDB_PATH = "#{Etc.getpwuid.dir}/.gimdb"
|
7
|
+
Dir.mkdir($GIMDB_PATH) unless File.exist?($GIMDB_PATH)
|
8
|
+
Dir.mkdir("#{$GIMDB_PATH}/posters") unless File.exist?("#{$GIMDB_PATH}/posters")
|
9
|
+
|
10
|
+
|
11
|
+
ActiveRecord::Base.establish_connection(
|
12
|
+
:adapter => "sqlite3",
|
13
|
+
:database => "#{$GIMDB_PATH}/db.sqlite3"
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
if(!ActiveRecord::Base.connection.tables.include?('movies') ||
|
18
|
+
!ActiveRecord::Base.connection.tables.include?('users') ||
|
19
|
+
!ActiveRecord::Base.connection.tables.include?('populars'))
|
20
|
+
ActiveRecord::Schema.define do
|
21
|
+
create_table :movies do |t|
|
22
|
+
t.string :code, :unique => true, :null => false
|
23
|
+
t.string :title, :null => false
|
24
|
+
t.string :image_url
|
25
|
+
t.string :image_path
|
26
|
+
t.integer :year, :limit => 4
|
27
|
+
t.integer :votes
|
28
|
+
t.float :rating
|
29
|
+
t.text :outline
|
30
|
+
t.string :credit
|
31
|
+
t.string :genre
|
32
|
+
t.float :runtime
|
33
|
+
t.datetime :updated_at, :null => false, :default => Time.now
|
34
|
+
end
|
35
|
+
|
36
|
+
create_table :users do |t|
|
37
|
+
t.string :name, :unique => true, :null => :false
|
38
|
+
t.integer :selected, :limit => 1, :default => 0
|
39
|
+
end
|
40
|
+
|
41
|
+
create_table :populars, :id => false do |t|
|
42
|
+
t.references :movie
|
43
|
+
t.references :user
|
44
|
+
t.integer :kind, :null => false, :limit => 3
|
45
|
+
end
|
46
|
+
|
47
|
+
add_index :movies, :id, :unique
|
48
|
+
add_index :populars, [:movie_id, :user_id, :kind], :unique
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
class Popular < ActiveRecord::Base
|
54
|
+
belongs_to :movie
|
55
|
+
belongs_to :user
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
class Movie < ActiveRecord::Base
|
60
|
+
has_many :populars, :dependent => :delete_all
|
61
|
+
has_many :users, :through => :populars
|
62
|
+
|
63
|
+
def get_users(what = :to_see)
|
64
|
+
code = Movie.get_code(what)
|
65
|
+
unless code.nil?
|
66
|
+
pops = Popular.find(:all, :conditions => "movie_id = #{self.id} AND kind = #{code}")
|
67
|
+
return [] if pops.nil?
|
68
|
+
return pops.collect{|pop| pop.user}
|
69
|
+
else
|
70
|
+
return []
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def set_user(user, what = :to_see)
|
75
|
+
code = Movie.get_code(what)
|
76
|
+
unless code.nil?
|
77
|
+
pop = Popular.new(:movie => self, :user => user, :kind => code)
|
78
|
+
self.populars << pop
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def remove_user(user, what = :to_see)
|
83
|
+
code = Movie.get_code(what)
|
84
|
+
unless code.nil?
|
85
|
+
sql = "delete from populars where movie_id = #{self.id} AND user_id = #{user.id} AND kind = #{code}"
|
86
|
+
ActiveRecord::Base.connection.execute(sql)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.get_list(options)
|
91
|
+
@start = options[:start] || 1
|
92
|
+
c = ''
|
93
|
+
c += " AND title LIKE '%#{options[:title]}%'" if options[:title]
|
94
|
+
if options[:release_data] && options[:release_data].include?(',')
|
95
|
+
c += " AND year >= #{options[:release_data].split(',')[0]}"
|
96
|
+
c += " AND year <= #{options[:release_data].split(',')[1]}"
|
97
|
+
end
|
98
|
+
if options[:user_rating] && options[:user_rating].include?(',')
|
99
|
+
c += " AND rating >= #{options[:user_rating].split(',')[0]}"
|
100
|
+
c += " AND rating <= #{options[:user_rating].split(',')[1]}"
|
101
|
+
end
|
102
|
+
c += " AND genre LIKE '%#{options[:genre]}%'" if options[:genre]
|
103
|
+
c = c[5..-1]
|
104
|
+
@movies = Movie.find(:all, :conditions => c, :order => 'title ASC')#, :limit => 50)
|
105
|
+
return @movies[@start-1..@start+48]
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.next
|
109
|
+
@start = @start + 50
|
110
|
+
return @movies[@start-1..@start+48] || []
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.get_kind(users, kind)
|
114
|
+
c = ''
|
115
|
+
users.each { |u| c += "populars.user_id = #{u.id} OR " }
|
116
|
+
c = '(' + c[0..-5] + ') AND ' unless c.empty?
|
117
|
+
c += "populars.kind = #{Movie.get_code(kind)}"
|
118
|
+
Movie.find(:all, :joins => :populars, :conditions => c, :order => 'title ASC', :group => 'movies.id')
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.get_code(what)
|
122
|
+
case what.to_sym
|
123
|
+
when :to_see: 0
|
124
|
+
when :seen: 1
|
125
|
+
when :favourites: 2
|
126
|
+
else nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
class User < ActiveRecord::Base
|
133
|
+
has_many :populars, :dependent => :delete_all
|
134
|
+
has_many :movies, :through => :populars
|
135
|
+
end
|
data/src/movie_box.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
module GtkGimdb
|
2
|
+
|
3
|
+
class MovieBox < Gtk::HBox
|
4
|
+
include GetText
|
5
|
+
|
6
|
+
|
7
|
+
def initialize(movie, users = [])
|
8
|
+
bindtextdomain($DOMAIN, $LOCALEDIR, nil, 'UTF-8')
|
9
|
+
super()
|
10
|
+
@movie = movie
|
11
|
+
@users = users
|
12
|
+
setting_up
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
|
19
|
+
def setting_up
|
20
|
+
img = Gtk::Image.new((@movie.image_path.nil? || !File.exists?(@movie.image_path)) ? 'data/icons/no_poster.png' : @movie.image_path)
|
21
|
+
img.set_tooltip_text("Code: #{@movie.code}")
|
22
|
+
self.pack_start(img, false)
|
23
|
+
|
24
|
+
vbox = Gtk::VBox.new
|
25
|
+
vbox.spacing = 10
|
26
|
+
hbox1 = Gtk::HBox.new
|
27
|
+
hbox1.spacing = 50
|
28
|
+
hbox2 = Gtk::HBox.new
|
29
|
+
hbox2.spacing = 50
|
30
|
+
|
31
|
+
title = Gtk::Label.new
|
32
|
+
year = (@movie.year.nil? || @movie.year == 0) ? '' : "(#{@movie.year})"
|
33
|
+
title.markup = "<a href='http://www.imdb.it/title/#{@movie.code}/'><span color='#000' underline='none' size='large' weight='ultrabold'>#{@movie.title}</span></a> #{year}"
|
34
|
+
hbox1.pack_start(title, false)
|
35
|
+
|
36
|
+
rating = Gtk::Label.new
|
37
|
+
rating.markup = "#{@movie.rating}/10" unless @movie.rating.nil? || @movie.rating == 0
|
38
|
+
rating.set_tooltip_text(@movie.votes.to_s + ' votes') unless @movie.votes.nil? || @movie.votes == 0
|
39
|
+
hbox1.pack_end(rating, false)
|
40
|
+
|
41
|
+
vbox.pack_start(hbox1, false)
|
42
|
+
|
43
|
+
outline = Gtk::TextView.new
|
44
|
+
outline.buffer.text = @movie.outline || ''
|
45
|
+
outline.editable = false
|
46
|
+
outline.wrap_mode = Gtk::TextTag::WRAP_WORD_CHAR
|
47
|
+
outline.cursor_visible = false
|
48
|
+
outline.modify_base(Gtk::STATE_NORMAL, Gdk::Color.parse('#edeceb'))
|
49
|
+
vbox.pack_start(outline, false)
|
50
|
+
|
51
|
+
credit = Gtk::Label.new
|
52
|
+
credit.markup = @movie.credit || ''
|
53
|
+
credit.set_alignment(0.0, 0.0)
|
54
|
+
vbox.pack_start(credit, false)
|
55
|
+
|
56
|
+
genre = Gtk::Label.new
|
57
|
+
genre.text = @movie.genre.nil? ? '' : _('Genres') + ': ' + @movie.genre.gsub('|', ' | ')
|
58
|
+
hbox2.pack_start(genre, false)
|
59
|
+
|
60
|
+
runtime = Gtk::Label.new
|
61
|
+
unless @movie.runtime.nil? || @movie.runtime == 0
|
62
|
+
runtime.text = @movie.runtime.to_i.to_s + ' mins'
|
63
|
+
time = Time.now.midnight + @movie.runtime * 60
|
64
|
+
runtime.set_tooltip_text("#{time.hour}:#{"%02d" % time.min}")
|
65
|
+
end
|
66
|
+
hbox2.pack_end(runtime, false)
|
67
|
+
|
68
|
+
vbox.pack_start(hbox2, false)
|
69
|
+
|
70
|
+
vbox.pack_start(add_users_info, false) if @users.size > 0
|
71
|
+
|
72
|
+
self.pack_start(vbox)
|
73
|
+
self.spacing = 10
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def add_users_info
|
78
|
+
table = Gtk::Table.new(@users.size + 1, 4)
|
79
|
+
table.attach(Gtk::Label.new, 0,1, 0,1, Gtk::SHRINK)
|
80
|
+
table.attach(Gtk::Label.new.set_markup(_('<b>To see</b>')), 1,2, 0,1, Gtk::SHRINK, Gtk::EXPAND|Gtk::FILL, 10)
|
81
|
+
table.attach(Gtk::Label.new.set_markup(_('<b>Seen</b>')), 2,3, 0,1, Gtk::SHRINK, Gtk::EXPAND|Gtk::FILL, 10)
|
82
|
+
table.attach(Gtk::Label.new.set_markup(_('<b>Favourites</b>')), 3,4, 0,1, Gtk::SHRINK)
|
83
|
+
@users.each_with_index do |u, i|
|
84
|
+
row = i + 1
|
85
|
+
table.attach(Gtk::Label.new(u.name), 0,1, row,row+1, Gtk::SHRINK)
|
86
|
+
table.attach(UserCheckButton.new(u, @movie, :to_see), 1,2, row,row+1, Gtk::SHRINK)
|
87
|
+
table.attach(UserCheckButton.new(u, @movie, :seen), 2,3, row,row+1, Gtk::SHRINK)
|
88
|
+
table.attach(UserCheckButton.new(u, @movie, :favourites), 3,4, row,row+1, Gtk::SHRINK)
|
89
|
+
end
|
90
|
+
return table
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
class UserCheckButton < Gtk::CheckButton
|
95
|
+
def initialize(user, movie, what)
|
96
|
+
super()
|
97
|
+
self.active = movie.get_users(what).include?(user)
|
98
|
+
self.signal_connect('toggled') do |b|
|
99
|
+
if b.active?
|
100
|
+
movie.set_user(user, what)
|
101
|
+
else
|
102
|
+
movie.remove_user(user, what)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|