serial-watcher 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,42 @@
1
+
2
+ module Gui
3
+ class MetaDialog < Gtk::Dialog
4
+
5
+ type_register
6
+ def initialize(hash)
7
+ serial = hash[:serial]
8
+ hash = nil
9
+ super
10
+
11
+
12
+ set_title "Serial Meta Edit"
13
+ add_buttons [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_OK],
14
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
15
+ has_separator = false
16
+
17
+ table = Gtk::Table.new 5, 2, true
18
+ table.border_width = 10
19
+
20
+ entry = Gtk::Entry.new
21
+ @status = Status.instance
22
+
23
+ # 1st row
24
+ label = Gtk::Label.new("Name: ")
25
+ @name_entry = Gtk::Entry.new
26
+ @name_entry.text = serial.meta.name || serial.name
27
+ table.attach label, 0, 1, 0, 1
28
+ table.attach @name_entry, 1, 2, 0, 1
29
+
30
+ # 2nd row
31
+
32
+ vbox.add(table)
33
+ show_all
34
+ end
35
+
36
+ def values
37
+ data = {
38
+ :name => @name_entry.text
39
+ }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,44 @@
1
+
2
+ module Gui
3
+ class SettingsDialog < Gtk::Dialog
4
+
5
+ type_register
6
+ def initialize()
7
+ super
8
+ set_title "Serial Watcher Settings"
9
+ add_buttons [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_OK],
10
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
11
+ has_separator = false
12
+
13
+ table = Gtk::Table.new 5, 2, true
14
+ table.border_width = 10
15
+
16
+ @status = Status.instance
17
+ @original_path = @status.data_dir
18
+
19
+ entry = Gtk::Entry.new
20
+
21
+ # 1st row
22
+ label = Gtk::Label.new("Serials directory: ")
23
+ @path_chooser = Gtk::FileChooserButton.new( "Choose a Folder", Gtk::FileChooser::ACTION_SELECT_FOLDER)
24
+ @path_chooser.current_folder = @status.data_dir
25
+ table.attach label, 0, 1, 0, 1
26
+ table.attach @path_chooser, 1, 2, 0, 1
27
+
28
+ # 2nd row
29
+
30
+ vbox.add(table)
31
+ show_all
32
+ end
33
+
34
+ def path_changed?
35
+ @original_path != @path_chooser.current_folder
36
+ end
37
+
38
+ def values
39
+ data = {
40
+ :path => @path_chooser.current_folder
41
+ }
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,73 @@
1
+
2
+ require 'serial'
3
+ require 'fs'
4
+
5
+ module Gui
6
+ class TitleBox < Gtk::VBox
7
+ type_register
8
+ attr_accessor :serials
9
+
10
+ signal_new("title_changed", GLib::Signal::RUN_FIRST, nil, nil, Serial)
11
+ signal_new("loaded", GLib::Signal::RUN_FIRST, nil, nil, false)
12
+
13
+ def initialize
14
+ @colormap = Gtk::Widget.default_colormap
15
+ @fs = Fs.instance
16
+ @status = Status.instance
17
+ super
18
+ end
19
+
20
+ def clear
21
+ self.each_forall do |e|
22
+ remove(e) if e.class.to_s == "Gtk::Button"
23
+ end
24
+ end
25
+
26
+ def load(dir = @status.data_dir)
27
+ clear
28
+
29
+ @fs.init dir
30
+ series = @fs.series || []
31
+ series.each do |serial|
32
+
33
+ # button
34
+ button = Gtk::Button.new " #{serial.name} "
35
+ button.use_stock = true
36
+ button.set_xalign 0.0
37
+ button.set_image Gtk::Image.new( serial.image || File.join($STATIC_PATH, 'images/dash.png') )
38
+ button.set_image_position Gtk::POS_LEFT
39
+
40
+ button.signal_connect "clicked" do
41
+ self.modify_current_button button
42
+ self.signal_emit( "title_changed", serial )
43
+ end
44
+
45
+ if serial.path == @status.get_last_serial
46
+ button.signal_emit "clicked"
47
+ end
48
+
49
+ pack_start button, false, false, 3
50
+ end
51
+ self.show_all
52
+ self.signal_emit( "loaded" , false)
53
+ end
54
+
55
+ def modify_current_button button
56
+ self.each_forall do |btn|
57
+ if btn.class.to_s == "Gtk::Button"
58
+ btn.modify_bg(Gtk::STATE_NORMAL, nil)
59
+ btn.modify_bg(Gtk::STATE_PRELIGHT, nil)
60
+ end
61
+ end
62
+ button.modify_bg(Gtk::STATE_NORMAL, Gdk::Color.new(45535, 45535, 65535))
63
+ button.modify_bg(Gtk::STATE_PRELIGHT, Gdk::Color.new(40535, 40535, 65535))
64
+ end
65
+
66
+ def signal_do_title_changed(arg)
67
+ end
68
+
69
+ def signal_do_loaded(arg)
70
+ end
71
+ end
72
+ end
73
+
@@ -0,0 +1,42 @@
1
+
2
+ require 'thread'
3
+
4
+ module Gui
5
+ class TorrentPanel < Gtk::VBox
6
+
7
+ type_register
8
+
9
+ def initialize()
10
+ height_request = 50
11
+ super
12
+ end
13
+
14
+ def clear
15
+ each_forall do |e| remove(e) end
16
+ end
17
+
18
+ def load(serial)
19
+ clear
20
+
21
+ Thread.new do
22
+ @torrent = ::Torrent::Torrentz.instance
23
+ @torrent.load serial.meta.name
24
+ @torrent.get_last_feeds.each do |torrent|
25
+
26
+ torrent_link = Gtk::LinkButton.new torrent[:url], "#{torrent[:date]} / #{torrent[:name]}"
27
+
28
+ torrent_link.set_alignment 0, 0.5
29
+ torrent_link.signal_connect "clicked" do |link_btn|
30
+ Thread.new do
31
+ `chromium #{link_btn.uri}`
32
+ end
33
+ end
34
+
35
+ pack_start_defaults torrent_link#, true, true #false, false
36
+
37
+ end
38
+ show_all
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,53 @@
1
+
2
+ $LOAD_PATH << '.'
3
+
4
+ require 'lockfile'
5
+ require 'gui/main'
6
+
7
+ $DATADIR = ''
8
+ $INITIAL_SERIAL = ""
9
+ $INITIAL_EPISODE = 0
10
+
11
+ $DEBUG = false
12
+ #$DEBUG = true
13
+
14
+ class SerialWatcher
15
+ def initialize
16
+ begin
17
+ Lockfile("/tmp/serial-watcher.lock", :retries => 0, :debug => $DEBUG, :poll_retries => 1) do
18
+ Gtk.init
19
+ window = Gui::Main.new
20
+ window.show_all
21
+ Gtk.main
22
+ end
23
+ rescue Lockfile::MaxTriesLockError
24
+ notify "Another instance is running"
25
+ self.raise_window
26
+ end
27
+ self.quit
28
+ end
29
+
30
+ def raise_window
31
+ begin
32
+ window_id = `xdotool search --name "Serial\ Watcher"`
33
+ `xdotool windowraise #{window_id}`
34
+ `xdotool windowfocus #{window_id}`
35
+ rescue
36
+ notify "you need to install xdotool to raise opened window"
37
+ end
38
+ end
39
+
40
+ def quit
41
+ log "Quiting .."
42
+ Kernel.exit(1)
43
+ end
44
+ end
45
+
46
+ def notify(message)
47
+ `notify-send '#{message}'`
48
+ end
49
+
50
+ def log(message)
51
+ puts message
52
+ end
53
+
@@ -0,0 +1,43 @@
1
+
2
+ class Meta
3
+ def initialize(serial)
4
+ @serial = serial
5
+ end
6
+
7
+ def name
8
+ @name ||= (@name.nil? ? @serial.name : @name)
9
+ end
10
+
11
+ def path
12
+ "#{@serial.path}/.meta"
13
+ end
14
+
15
+ def meta_data
16
+ data = {
17
+ :name => name
18
+ }
19
+ end
20
+
21
+ def create_file
22
+ begin
23
+ File.open(path, 'w') { |f| f.write( meta_data.to_yaml ) }
24
+ rescue
25
+ puts "cannot create meta-file"
26
+ end
27
+ end
28
+
29
+ def load_file
30
+ meta = File.exists?(path) ? YAML.load(File.open(path)) : meta_data
31
+ meta_data.each { |key, value|
32
+ eval("@#{key} = ?", meta.try('[]', key))
33
+ }
34
+ end
35
+
36
+ def save_file meta
37
+ meta_data.each do |key, value|
38
+ eval("@#{key} = ?", meta.try('[]', key))
39
+ end
40
+ create_file
41
+ end
42
+ end
43
+
@@ -0,0 +1,58 @@
1
+ require 'singleton'
2
+ require 'gtk2'
3
+
4
+ require 'status'
5
+
6
+ class Player < Gtk::Object
7
+
8
+ include Singleton
9
+ type_register
10
+
11
+ attr_accessor :status
12
+
13
+ signal_new("playing_ended", GLib::Signal::RUN_FIRST, nil, nil, String)
14
+
15
+ def initialize
16
+ super
17
+ @status = Status.instance
18
+ end
19
+
20
+ def play_episode episode
21
+ @status.save_status episode
22
+ begin
23
+ @thr = Thread.new do
24
+
25
+ Thread.abort_on_exception = true
26
+ #s = `mplayer -identify -fs \'#{episode.path}\' 2>&1 | tail -n 1`
27
+ `killall mplayer 2>&1 > /dev/null`
28
+ s = `mplayer -identify \'#{episode.path}\' #{"-fs" if @status.data[:fullscreen]} 2>&1 | tail -n 1`
29
+ if s == "ID_EXIT=EOF\n"
30
+ signal_emit("playing_ended", "param")
31
+ #raise "playing ended"
32
+ end
33
+
34
+ Thread.exit
35
+ end
36
+
37
+ Thread.new do
38
+ sleep 2
39
+ 4.times do
40
+ # TODO fix it all
41
+ m_id=`xwininfo -name MPlayer |grep 'Window id:' |cut -d" " -f4`.strip
42
+ cmd = "xdotool key --window #{m_id} 114"
43
+ `#{cmd}`
44
+ end
45
+ Thread.exit
46
+ end
47
+
48
+ rescue
49
+ puts "resque"
50
+ end
51
+
52
+ end
53
+
54
+ def signal_do_playing_ended param
55
+ end
56
+
57
+ end
58
+
@@ -0,0 +1,29 @@
1
+
2
+ require 'simple-rss'
3
+ require 'open-uri'
4
+ require 'singleton'
5
+
6
+ module Torrent
7
+ class Main
8
+ attr_reader :url, :rss
9
+ include Singleton
10
+
11
+ def initialize
12
+ @data = {}
13
+ end
14
+
15
+ def rss_load
16
+ @rss = @data[@name] || (@data[@name] = SimpleRSS.parse open(@url) if @url)
17
+ end
18
+
19
+ def human_format
20
+ raise "Method need to be overloaded"
21
+ end
22
+
23
+
24
+ def get_last_feeds(num = 5, trim = 40)
25
+ return [] if not @rss
26
+ human_format(@rss.channel.items.sort{|b,a| a[:pubDate] <=> b[:pubDate]}[0,5], trim)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+
2
+ require 'date'
3
+ require 'plugins/torrent/main'
4
+
5
+ module Torrent
6
+ class Torrentz < Main
7
+
8
+ def load(name)
9
+ @name = name
10
+ @url = ("http://torrentz.eu/feed?q=#{CGI.escape(name)}" if name) || nil
11
+ rss_load if @url
12
+ end
13
+
14
+ def human_format list, trim
15
+ list.map do |item|
16
+ nitem = {}
17
+ nitem[:name] = item[:title].length > trim ? "#{item[:title][0, trim]}.." : item[:title]
18
+ nitem[:date] = "#{(Date.today - item[:pubDate].to_date).to_i} days ago"
19
+ nitem[:url] = item[:link]
20
+ nitem
21
+ end
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,25 @@
1
+
2
+ require 'date'
3
+ require 'plugins/torrent/main'
4
+
5
+ module Torrent
6
+ class TPB < Main
7
+
8
+ def load(name)
9
+ @name = name
10
+ @url = ""#http://torrentz.eu/feed?q=#{CGI.escape(name)}"
11
+ rss_load
12
+ end
13
+
14
+ def human_format list, trim
15
+ list.map do |item|
16
+ nitem = {}
17
+ nitem[:name] = "#{item[:title][0, trim]}.." if item[:title].length > trim
18
+ nitem[:date] = item[:pubDate]
19
+ nitem[:url] = item[:link]
20
+ nitem
21
+ end
22
+ end
23
+ end
24
+ end
25
+