transmission-rss 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +2 -2
- data/bin/transmission-rss +29 -6
- data/lib/transmission-rss.rb +13 -3
- data/lib/transmission-rss/config-editor.rb +17 -0
- data/lib/transmission-rss/config-editor/listbox-original.rb +233 -0
- data/lib/transmission-rss/config-editor/listbox.rb +93 -0
- data/lib/transmission-rss/config-editor/main.glade +426 -0
- data/lib/transmission-rss/config-editor/main.rb +254 -0
- metadata +8 -6
data/README.rdoc
CHANGED
data/bin/transmission-rss
CHANGED
@@ -10,6 +10,9 @@ include TransmissionRSS
|
|
10
10
|
# Default config file path.
|
11
11
|
configFile = '/etc/transmission-rss.conf'
|
12
12
|
|
13
|
+
# Do not edit config file in Gtk GUI by default.
|
14
|
+
editConfig = false
|
15
|
+
|
13
16
|
# Do not fork by default.
|
14
17
|
dofork = false
|
15
18
|
|
@@ -22,6 +25,7 @@ def usageMessage( configFile )
|
|
22
25
|
Adds torrents from rss feeds to transmission web frontend.
|
23
26
|
|
24
27
|
-c <file> Custom config file path. Default: #{configFile}
|
28
|
+
-e Edit config file with Gtk GUI.
|
25
29
|
-f Fork into background after startup.
|
26
30
|
-h This help.
|
27
31
|
-v Verbose mode.
|
@@ -33,6 +37,7 @@ end
|
|
33
37
|
# Define command-line options.
|
34
38
|
options = GetoptLong.new(
|
35
39
|
[ '-c', GetoptLong::REQUIRED_ARGUMENT ],
|
40
|
+
[ '-e', GetoptLong::NO_ARGUMENT ],
|
36
41
|
[ '-f', GetoptLong::NO_ARGUMENT ],
|
37
42
|
[ '-h', GetoptLong::NO_ARGUMENT ],
|
38
43
|
[ '-v', GetoptLong::NO_ARGUMENT ]
|
@@ -43,6 +48,8 @@ options.each do |option, argument|
|
|
43
48
|
case( option )
|
44
49
|
when '-c'
|
45
50
|
configFile = argument
|
51
|
+
when '-e'
|
52
|
+
editConfig = true
|
46
53
|
when '-f'
|
47
54
|
dofork = true
|
48
55
|
when '-h'
|
@@ -59,8 +66,8 @@ config = TransmissionRSS::Config.instance
|
|
59
66
|
# Default configuration.
|
60
67
|
config.load( {
|
61
68
|
'feeds' => [],
|
62
|
-
'
|
63
|
-
'
|
69
|
+
'update_interval' => 600,
|
70
|
+
'start_paused' => false,
|
64
71
|
'server' => {
|
65
72
|
'host' => 'localhost',
|
66
73
|
'port' => 9091
|
@@ -75,9 +82,25 @@ log.target = config.log_target
|
|
75
82
|
tLog = Thread.start do log.run end
|
76
83
|
|
77
84
|
# Load config file (default or given by argument).
|
78
|
-
|
85
|
+
begin
|
86
|
+
config.load( configFile )
|
87
|
+
rescue Errno::ENOENT
|
88
|
+
log.add( configFile + ' not found' )
|
89
|
+
end
|
79
90
|
log.add( config )
|
80
91
|
|
92
|
+
# Start GUI if config edit option is given.
|
93
|
+
if( editConfig )
|
94
|
+
require( 'transmission-rss/config-editor' )
|
95
|
+
|
96
|
+
Gtk.init
|
97
|
+
|
98
|
+
ConfigEditor.new( configFile, config )
|
99
|
+
Gtk.main
|
100
|
+
|
101
|
+
exit( 0 )
|
102
|
+
end
|
103
|
+
|
81
104
|
# Connect reload of config file to SIGHUP.
|
82
105
|
trap( 'HUP' ) do
|
83
106
|
config.load( configFile )
|
@@ -96,7 +119,7 @@ aggregator.feeds.concat( config.feeds )
|
|
96
119
|
# Callback for a new item on one of the feeds.
|
97
120
|
aggregator.on_new_item do |torrentFile|
|
98
121
|
Thread.start do
|
99
|
-
client.addTorrent( torrentFile, config.
|
122
|
+
client.addTorrent( torrentFile, config.start_paused )
|
100
123
|
end
|
101
124
|
end
|
102
125
|
|
@@ -104,12 +127,12 @@ end
|
|
104
127
|
begin
|
105
128
|
if( dofork )
|
106
129
|
pid = fork do
|
107
|
-
aggregator.run( config.
|
130
|
+
aggregator.run( config.update_interval )
|
108
131
|
end
|
109
132
|
|
110
133
|
puts( 'forked ' + pid.to_s )
|
111
134
|
else
|
112
|
-
aggregator.run( config.
|
135
|
+
aggregator.run( config.update_interval )
|
113
136
|
end
|
114
137
|
rescue Interrupt
|
115
138
|
end
|
data/lib/transmission-rss.rb
CHANGED
@@ -1,9 +1,19 @@
|
|
1
1
|
$:.unshift( File.dirname( __FILE__ ) )
|
2
2
|
|
3
3
|
module TransmissionRSS
|
4
|
-
VERSION = '0.0
|
4
|
+
VERSION = '0.1.0'
|
5
5
|
end
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
dir = 'transmission-rss'
|
8
|
+
|
9
|
+
blacklist = %w(
|
10
|
+
config-editor
|
11
|
+
)
|
12
|
+
|
13
|
+
blacklist.map! do |name|
|
14
|
+
$:.first + '/' + dir + '/' + name + '.rb'
|
15
|
+
end
|
16
|
+
|
17
|
+
( Dir.glob( $:.first + '/' + dir + '/*.rb' ) - blacklist ).each do |lib|
|
18
|
+
require( lib )
|
9
19
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
$:.unshift( File.dirname( __FILE__ ) )
|
2
|
+
|
3
|
+
require( 'libglade2' )
|
4
|
+
|
5
|
+
dir = 'config-editor'
|
6
|
+
|
7
|
+
blacklist = %w(
|
8
|
+
listbox-original
|
9
|
+
)
|
10
|
+
|
11
|
+
blacklist.map! do |name|
|
12
|
+
$:.first + '/' + dir + '/' + name + '.rb'
|
13
|
+
end
|
14
|
+
|
15
|
+
( Dir.glob( $:.first + '/' + dir + '/*.rb' ) - blacklist ).each do |lib|
|
16
|
+
require( lib )
|
17
|
+
end
|
@@ -0,0 +1,233 @@
|
|
1
|
+
# ListBox - A GTK Listbox
|
2
|
+
#--
|
3
|
+
###################################################################################
|
4
|
+
#
|
5
|
+
# ListBox - A GTK Listbox
|
6
|
+
# Copyright (C) 2007 Lake Information Works
|
7
|
+
#
|
8
|
+
# This program is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#
|
21
|
+
# Contact: alan.lake AT lakeinfoworks DOT com
|
22
|
+
# Lake Information Works
|
23
|
+
# Kalervonkatu 13 A 2
|
24
|
+
# 20400 Jyväskylä
|
25
|
+
# Finland
|
26
|
+
#
|
27
|
+
###################################################################################
|
28
|
+
#++
|
29
|
+
=begin rdoc
|
30
|
+
Sample usage
|
31
|
+
Gtk.init
|
32
|
+
@main_window = Gtk::Window.new
|
33
|
+
@main_window.set_default_size 500,300
|
34
|
+
lb_left = ListBox.new
|
35
|
+
lb_left.header = 'Ad Groups'
|
36
|
+
lb_left.append('ulkomaanpuhelut')
|
37
|
+
lb_left.append('kaukopuhelut')
|
38
|
+
lb_left.append('suuntanumerot')
|
39
|
+
lb_right = ListBox.new
|
40
|
+
lb_right.header = 'State Nicknames'
|
41
|
+
lb_right.fill(['Empire','Golden','Silver','Sooner','Hoosier','Razorback','Buckeye','Lone Star'])
|
42
|
+
box = Gtk::HBox.new
|
43
|
+
@main_window.add(box)
|
44
|
+
box.pack_start(lb_left,true)
|
45
|
+
box.pack_start(lb_right,true)
|
46
|
+
@main_window.show_all
|
47
|
+
@main_window.signal_connect("destroy") { Gtk.main_quit }
|
48
|
+
lb_left.signal_connect('button_release_event') do |widget,event|
|
49
|
+
puts lb_left.button_release(widget,event)
|
50
|
+
end
|
51
|
+
lb_left.signal_connect('key-release-event') do |widget,event|
|
52
|
+
selection = lb_left.key_release(widget,event)
|
53
|
+
puts "#{selection}" if selection.class == String
|
54
|
+
end
|
55
|
+
# Note that no signal_connect code has been written for lb_right, so a selection cannot be made.
|
56
|
+
Gtk.main
|
57
|
+
=end
|
58
|
+
=begin rdoc
|
59
|
+
Purpose:
|
60
|
+
1. Document how to create a GTK widget in Ruby.
|
61
|
+
2. Create a general purpose listbox.
|
62
|
+
Credit:
|
63
|
+
Mathieu Blondel responded to my post on the Ruby Forum to teach me how to
|
64
|
+
create a valid widget. http://www.ruby-forum.com/topic/126951
|
65
|
+
Assumptions:
|
66
|
+
This document doesn't attempt to teach Ruby or GTK programming (or the
|
67
|
+
combination. Therefore, we assume that the reader knows how to create a
|
68
|
+
Ruby Class.
|
69
|
+
What's a widget?
|
70
|
+
http://www.webopedia.com/TERM/W/widget.html defines a widget. The listbox shown
|
71
|
+
here provides a way for the user to interface with an application by using the
|
72
|
+
mouse or keyboard to select an item in the list, whereupon the listbox
|
73
|
+
communicates the selection to the application.
|
74
|
+
What is provided here:
|
75
|
+
The following is in two parts: The class that creates the listbox widget and a
|
76
|
+
piece of code that illustrates the use of it. I will include comments in the
|
77
|
+
code that shows what needs to be done to make a class into a widget, but will
|
78
|
+
not completely comment the code. I am commenting the parts involved with
|
79
|
+
inheritance because it is the inheritance that makes ListBox a widget.
|
80
|
+
|
81
|
+
This listbox is extremely basic. The minimalistic design meets my need for a
|
82
|
+
listbox and makes it easier to highlight what it is that makes it a widget.
|
83
|
+
Furthermore, the fact that it is basic will allow me or another programmer to
|
84
|
+
easily modify it to include more sophisticated features.
|
85
|
+
=end
|
86
|
+
=begin rdoc
|
87
|
+
ListBox inherits Gtk::ScrolledWindow. ScrolledWindow was chosen because
|
88
|
+
(1) ScrolledWindow is a widget. This fact can be shown with interactive ruby
|
89
|
+
(irb) by doing (a) or (b):
|
90
|
+
(a)
|
91
|
+
[alan@erie ~]$ irb
|
92
|
+
irb(main):001:0> require 'gtk2'
|
93
|
+
=> true
|
94
|
+
irb(main):002:0> sw = Gtk::ScrolledWindow.new
|
95
|
+
=> #<Gtk::ScrolledWindow:0x2aaab008d088 ptr=0xac4bd0>
|
96
|
+
irb(main):003:0> sw.is_a? Gtk::Widget
|
97
|
+
=> true
|
98
|
+
(b)
|
99
|
+
[alan@erie ~]$ irb
|
100
|
+
irb(main):001:0> require 'gtk2'
|
101
|
+
=> true
|
102
|
+
irb(main):002:0> Gtk::ScrolledWindow.ancestors
|
103
|
+
=> [Gtk::ScrolledWindow, Gtk::Bin, Gtk::Container, Gtk::Widget, Atk::Implementor, GLib::Interface, GLib::MetaInterface, Gtk::Object, GLib::InitiallyUnowned, GLib::Object, GLib::Instantiatable, Object, Kernel]
|
104
|
+
Note that Gtk::Widget is among ScrolledWindow's ancestors.
|
105
|
+
(2) the scrolled window part of this widget is the part that the user adds
|
106
|
+
to the GUI application.
|
107
|
+
=end
|
108
|
+
class ListBox < Gtk::ScrolledWindow
|
109
|
+
=begin rdoc
|
110
|
+
"super()" is needed because the Listbox class is inherited.
|
111
|
+
"self" refers to the ListBox, but because ListBox inherits ScrolledWindow, references to this scrolled window are also made with "self".
|
112
|
+
=end
|
113
|
+
def initialize
|
114
|
+
super()
|
115
|
+
|
116
|
+
tbl = Gtk::Table.new(2,2,false) # 2 rows, 2 columns, not homogeneous
|
117
|
+
self.hscrollbar_policy = Gtk::PolicyType::AUTOMATIC
|
118
|
+
self.vscrollbar_policy = Gtk::PolicyType::AUTOMATIC
|
119
|
+
self.shadow_type = Gtk::ShadowType::NONE
|
120
|
+
self.window_placement= Gtk::CornerType::TOP_LEFT
|
121
|
+
|
122
|
+
@renderer=Gtk::CellRendererText.new
|
123
|
+
@renderer.set_property( 'background', 'lavender' )
|
124
|
+
@renderer.set_property( 'foreground', 'black' )
|
125
|
+
|
126
|
+
@list_store = Gtk::ListStore.new(String)
|
127
|
+
@tree_view = Gtk::TreeView.new(@list_store)
|
128
|
+
|
129
|
+
col_hdr = ''
|
130
|
+
@tree_view_col1 = Gtk::TreeViewColumn.new(col_hdr, @renderer, {:text => 0})
|
131
|
+
@tree_view_col1.sizing = Gtk::TreeViewColumn::AUTOSIZE
|
132
|
+
@text_col = 0
|
133
|
+
@tree_view.append_column(@tree_view_col1)
|
134
|
+
@tree_view.headers_visible = false
|
135
|
+
@tree_view.selection.mode = Gtk::SELECTION_SINGLE
|
136
|
+
|
137
|
+
tbl.attach_defaults(@tree_view,0,2,0,2) # widget, left, right, top, bottom
|
138
|
+
self.add_with_viewport(tbl)
|
139
|
+
end # def initialize
|
140
|
+
|
141
|
+
=begin rdoc
|
142
|
+
Appends a string to ListBox's list.
|
143
|
+
=end
|
144
|
+
def append(str)
|
145
|
+
iter = @list_store.append
|
146
|
+
iter.set_value(0, str)
|
147
|
+
end
|
148
|
+
|
149
|
+
=begin rdoc
|
150
|
+
This is a significant part of the widget, providing communication from it to the application.
|
151
|
+
Called by a signal connect mouse button_release_event:
|
152
|
+
lb_left.signal_connect('button_release_event') do |widget,event|
|
153
|
+
puts lb_left.button_release(widget,event)
|
154
|
+
end
|
155
|
+
Returns: The string that is selected.
|
156
|
+
=end
|
157
|
+
def button_release(widget,event,type='text')
|
158
|
+
path, column, cell_x, cell_y = @tree_view.get_path_at_pos(event.x, event.y)
|
159
|
+
return path if type == 'line_nbr'
|
160
|
+
@tree_view.selection.selected[@tree_view.columns.index(column)] if type == 'text'
|
161
|
+
end
|
162
|
+
|
163
|
+
=begin rdoc
|
164
|
+
Clears the ListBox's list
|
165
|
+
=end
|
166
|
+
def clear
|
167
|
+
@list_store.clear
|
168
|
+
end
|
169
|
+
|
170
|
+
=begin rdoc
|
171
|
+
Fills the ListBox's list from the array of "items".
|
172
|
+
=end
|
173
|
+
def fill(items)
|
174
|
+
items.each { |item| self.append(item) }
|
175
|
+
end
|
176
|
+
|
177
|
+
=begin rdoc
|
178
|
+
Provides a header for the list.
|
179
|
+
=end
|
180
|
+
def header=(hdr)
|
181
|
+
@tree_view.headers_visible = true unless @tree_view.headers_visible?
|
182
|
+
@tree_view_col1.title = hdr
|
183
|
+
end
|
184
|
+
|
185
|
+
=begin rdoc
|
186
|
+
This is a significant part of the widget, providing communication from it to the application.
|
187
|
+
Called by a signal connect key_release_event, which occurs when the user uses keys to navigate:
|
188
|
+
lb_left.signal_connect('key-release-event') do |widget,event|
|
189
|
+
selection = lb_left.key_release(widget,event)
|
190
|
+
puts "#{selection}" if selection.class == String
|
191
|
+
end
|
192
|
+
Returns: Selected string if the Enter or Return key is pressed; nil if any other key is pressed. The up and down keys navigate the list.
|
193
|
+
=end
|
194
|
+
def key_release(widget,event)
|
195
|
+
return nil unless event.keyval == 65293 # Enter
|
196
|
+
column = @tree_view.get_column(0)
|
197
|
+
@tree_view.selection.selected[@tree_view.columns.index(column)]
|
198
|
+
end
|
199
|
+
|
200
|
+
=begin rdoc
|
201
|
+
Select the item in the list that is equal to text
|
202
|
+
=end
|
203
|
+
def select(text)
|
204
|
+
iter = @list_store.iter_first
|
205
|
+
begin
|
206
|
+
if iter[@text_col] == text
|
207
|
+
@tree_view.selection.select_iter(iter)
|
208
|
+
return true
|
209
|
+
end
|
210
|
+
end while iter.next!
|
211
|
+
return false
|
212
|
+
end
|
213
|
+
|
214
|
+
=begin rdoc
|
215
|
+
Synonym for the header=(hdr) method.
|
216
|
+
=end
|
217
|
+
def set_header(hdr)
|
218
|
+
self.header = hdr
|
219
|
+
end
|
220
|
+
|
221
|
+
=begin rdoc
|
222
|
+
Returns the text of line <nbr>.
|
223
|
+
=end
|
224
|
+
def text_at_line(nbr)
|
225
|
+
iter = @list_store.iter_first
|
226
|
+
line_nbr = 0
|
227
|
+
begin
|
228
|
+
return iter.get_value(@text_col) if line_nbr == nbr
|
229
|
+
line_nbr += 1
|
230
|
+
end while iter.next!
|
231
|
+
return []
|
232
|
+
end
|
233
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# http://www.lakeinfoworks.com/blog/wp-content/listbox.rb
|
2
|
+
class TransmissionRSS::ListBox < Gtk::ScrolledWindow
|
3
|
+
def initialize
|
4
|
+
super
|
5
|
+
|
6
|
+
tbl = Gtk::Table.new( 2, 2, false )
|
7
|
+
|
8
|
+
self.hscrollbar_policy = Gtk::PolicyType::AUTOMATIC
|
9
|
+
self.vscrollbar_policy = Gtk::PolicyType::AUTOMATIC
|
10
|
+
self.shadow_type = Gtk::ShadowType::NONE
|
11
|
+
self.window_placement= Gtk::CornerType::TOP_LEFT
|
12
|
+
|
13
|
+
@renderer = Gtk::CellRendererText.new
|
14
|
+
|
15
|
+
# @renderer.set_property( 'background', 'lavender' )
|
16
|
+
@renderer.set_property( 'background', 'white' )
|
17
|
+
@renderer.set_property( 'foreground', 'black' )
|
18
|
+
|
19
|
+
@list_store = Gtk::ListStore.new( String )
|
20
|
+
@tree_view = Gtk::TreeView.new( @list_store )
|
21
|
+
|
22
|
+
@tree_view_col1 = Gtk::TreeViewColumn.new( '', @renderer, { :text => 0 } )
|
23
|
+
@tree_view_col1.sizing = Gtk::TreeViewColumn::AUTOSIZE
|
24
|
+
|
25
|
+
@text_col = 0
|
26
|
+
|
27
|
+
@tree_view.append_column( @tree_view_col1 )
|
28
|
+
@tree_view.headers_visible = false
|
29
|
+
@tree_view.selection.mode = Gtk::SELECTION_SINGLE
|
30
|
+
|
31
|
+
tbl.attach_defaults( @tree_view, 0, 2, 0, 2 )
|
32
|
+
|
33
|
+
self.add_with_viewport(tbl)
|
34
|
+
end
|
35
|
+
|
36
|
+
def add( *args )
|
37
|
+
args.flatten.each do |arg|
|
38
|
+
iter = @list_store.append
|
39
|
+
iter.set_value( 0, arg.to_s )
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def button_release( widget, event, type = 'text' )
|
44
|
+
path, column, cell_x, cell_y = @tree_view.get_path_at_pos( event.x, event.y )
|
45
|
+
|
46
|
+
return( '' ) if( column.nil? )
|
47
|
+
|
48
|
+
entry = case( type )
|
49
|
+
when 'line_nbr'
|
50
|
+
path
|
51
|
+
when 'text'
|
52
|
+
@tree_view.selection.selected[@tree_view.columns.index( column )]
|
53
|
+
end
|
54
|
+
|
55
|
+
return( entry )
|
56
|
+
end
|
57
|
+
|
58
|
+
def clear
|
59
|
+
@list_store.clear
|
60
|
+
end
|
61
|
+
|
62
|
+
def header=( string )
|
63
|
+
@tree_view.headers_visible = true
|
64
|
+
@tree_view_col1.title = string
|
65
|
+
end
|
66
|
+
|
67
|
+
# TODO produces Gtk-CRITICAL
|
68
|
+
def remove( *args )
|
69
|
+
args.each do |arg|
|
70
|
+
iter = @list_store.iter_first
|
71
|
+
|
72
|
+
begin
|
73
|
+
if( iter.get_value( 0 ) == arg )
|
74
|
+
@list_store.remove( iter )
|
75
|
+
end
|
76
|
+
end while( iter.next! )
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def items
|
81
|
+
array = []
|
82
|
+
|
83
|
+
iter = @list_store.iter_first
|
84
|
+
|
85
|
+
if( not iter.nil? )
|
86
|
+
begin
|
87
|
+
array << iter.get_value( 0 )
|
88
|
+
end while( iter.next! )
|
89
|
+
end
|
90
|
+
|
91
|
+
array
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,426 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<glade-interface>
|
3
|
+
<!-- interface-requires gtk+ 2.16 -->
|
4
|
+
<!-- interface-naming-policy project-wide -->
|
5
|
+
<widget class="GtkWindow" id="window1">
|
6
|
+
<property name="width_request">550</property>
|
7
|
+
<property name="height_request">250</property>
|
8
|
+
<property name="visible">True</property>
|
9
|
+
<child>
|
10
|
+
<widget class="GtkVBox" id="vbox1">
|
11
|
+
<property name="visible">True</property>
|
12
|
+
<property name="orientation">vertical</property>
|
13
|
+
<child>
|
14
|
+
<widget class="GtkMenuBar" id="menubar1">
|
15
|
+
<property name="visible">True</property>
|
16
|
+
<child>
|
17
|
+
<widget class="GtkMenuItem" id="menuitem1">
|
18
|
+
<property name="visible">True</property>
|
19
|
+
<property name="label" translatable="yes">_Datei</property>
|
20
|
+
<property name="use_underline">True</property>
|
21
|
+
<child>
|
22
|
+
<widget class="GtkMenu" id="menu1">
|
23
|
+
<property name="visible">True</property>
|
24
|
+
<child>
|
25
|
+
<widget class="GtkImageMenuItem" id="imagemenuitem1">
|
26
|
+
<property name="label">gtk-new</property>
|
27
|
+
<property name="visible">True</property>
|
28
|
+
<property name="use_underline">True</property>
|
29
|
+
<property name="use_stock">True</property>
|
30
|
+
<signal name="activate" handler="on_menu_new"/>
|
31
|
+
</widget>
|
32
|
+
</child>
|
33
|
+
<child>
|
34
|
+
<widget class="GtkImageMenuItem" id="imagemenuitem2">
|
35
|
+
<property name="label">gtk-open</property>
|
36
|
+
<property name="visible">True</property>
|
37
|
+
<property name="use_underline">True</property>
|
38
|
+
<property name="use_stock">True</property>
|
39
|
+
<signal name="activate" handler="on_menu_open"/>
|
40
|
+
</widget>
|
41
|
+
</child>
|
42
|
+
<child>
|
43
|
+
<widget class="GtkImageMenuItem" id="imagemenuitem3">
|
44
|
+
<property name="label">gtk-save</property>
|
45
|
+
<property name="visible">True</property>
|
46
|
+
<property name="use_underline">True</property>
|
47
|
+
<property name="use_stock">True</property>
|
48
|
+
<signal name="activate" handler="on_menu_save"/>
|
49
|
+
</widget>
|
50
|
+
</child>
|
51
|
+
<child>
|
52
|
+
<widget class="GtkImageMenuItem" id="imagemenuitem4">
|
53
|
+
<property name="label">gtk-save-as</property>
|
54
|
+
<property name="visible">True</property>
|
55
|
+
<property name="use_underline">True</property>
|
56
|
+
<property name="use_stock">True</property>
|
57
|
+
<signal name="activate" handler="on_menu_save_as"/>
|
58
|
+
</widget>
|
59
|
+
</child>
|
60
|
+
<child>
|
61
|
+
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
|
62
|
+
<property name="visible">True</property>
|
63
|
+
</widget>
|
64
|
+
</child>
|
65
|
+
<child>
|
66
|
+
<widget class="GtkImageMenuItem" id="imagemenuitem5">
|
67
|
+
<property name="label">gtk-quit</property>
|
68
|
+
<property name="visible">True</property>
|
69
|
+
<property name="use_underline">True</property>
|
70
|
+
<property name="use_stock">True</property>
|
71
|
+
<signal name="activate" handler="on_menu_quit"/>
|
72
|
+
</widget>
|
73
|
+
</child>
|
74
|
+
</widget>
|
75
|
+
</child>
|
76
|
+
</widget>
|
77
|
+
</child>
|
78
|
+
<child>
|
79
|
+
<widget class="GtkMenuItem" id="menuitem3">
|
80
|
+
<property name="visible">True</property>
|
81
|
+
<property name="label" translatable="yes">_Hilfe</property>
|
82
|
+
<property name="use_underline">True</property>
|
83
|
+
<child>
|
84
|
+
<widget class="GtkMenu" id="menu3">
|
85
|
+
<property name="visible">True</property>
|
86
|
+
<child>
|
87
|
+
<widget class="GtkImageMenuItem" id="imagemenuitem10">
|
88
|
+
<property name="label">gtk-about</property>
|
89
|
+
<property name="visible">True</property>
|
90
|
+
<property name="use_underline">True</property>
|
91
|
+
<property name="use_stock">True</property>
|
92
|
+
<signal name="activate" handler="on_menu_about"/>
|
93
|
+
</widget>
|
94
|
+
</child>
|
95
|
+
</widget>
|
96
|
+
</child>
|
97
|
+
</widget>
|
98
|
+
</child>
|
99
|
+
</widget>
|
100
|
+
<packing>
|
101
|
+
<property name="expand">False</property>
|
102
|
+
<property name="position">0</property>
|
103
|
+
</packing>
|
104
|
+
</child>
|
105
|
+
<child>
|
106
|
+
<widget class="GtkNotebook" id="notebook1">
|
107
|
+
<property name="visible">True</property>
|
108
|
+
<property name="can_focus">True</property>
|
109
|
+
<property name="tab_pos">left</property>
|
110
|
+
<child>
|
111
|
+
<widget class="GtkAlignment" id="alignment1">
|
112
|
+
<property name="visible">True</property>
|
113
|
+
<property name="top_padding">5</property>
|
114
|
+
<property name="bottom_padding">5</property>
|
115
|
+
<property name="left_padding">5</property>
|
116
|
+
<property name="right_padding">5</property>
|
117
|
+
<child>
|
118
|
+
<widget class="GtkTable" id="table1">
|
119
|
+
<property name="visible">True</property>
|
120
|
+
<property name="n_rows">2</property>
|
121
|
+
<property name="n_columns">2</property>
|
122
|
+
<property name="row_spacing">5</property>
|
123
|
+
<child>
|
124
|
+
<widget class="GtkLabel" id="label4">
|
125
|
+
<property name="visible">True</property>
|
126
|
+
<property name="xalign">0</property>
|
127
|
+
<property name="label" translatable="yes">Host</property>
|
128
|
+
</widget>
|
129
|
+
<packing>
|
130
|
+
<property name="y_options">GTK_FILL</property>
|
131
|
+
</packing>
|
132
|
+
</child>
|
133
|
+
<child>
|
134
|
+
<widget class="GtkLabel" id="label5">
|
135
|
+
<property name="visible">True</property>
|
136
|
+
<property name="xalign">0</property>
|
137
|
+
<property name="label" translatable="yes">Port</property>
|
138
|
+
</widget>
|
139
|
+
<packing>
|
140
|
+
<property name="top_attach">1</property>
|
141
|
+
<property name="bottom_attach">2</property>
|
142
|
+
<property name="y_options">GTK_FILL</property>
|
143
|
+
</packing>
|
144
|
+
</child>
|
145
|
+
<child>
|
146
|
+
<widget class="GtkEntry" id="entry_server_host">
|
147
|
+
<property name="visible">True</property>
|
148
|
+
<property name="can_focus">True</property>
|
149
|
+
<property name="invisible_char">●</property>
|
150
|
+
</widget>
|
151
|
+
<packing>
|
152
|
+
<property name="left_attach">1</property>
|
153
|
+
<property name="right_attach">2</property>
|
154
|
+
<property name="y_options">GTK_FILL</property>
|
155
|
+
</packing>
|
156
|
+
</child>
|
157
|
+
<child>
|
158
|
+
<widget class="GtkEntry" id="entry_server_port">
|
159
|
+
<property name="visible">True</property>
|
160
|
+
<property name="can_focus">True</property>
|
161
|
+
<property name="invisible_char">●</property>
|
162
|
+
</widget>
|
163
|
+
<packing>
|
164
|
+
<property name="left_attach">1</property>
|
165
|
+
<property name="right_attach">2</property>
|
166
|
+
<property name="top_attach">1</property>
|
167
|
+
<property name="bottom_attach">2</property>
|
168
|
+
<property name="y_options">GTK_FILL</property>
|
169
|
+
</packing>
|
170
|
+
</child>
|
171
|
+
</widget>
|
172
|
+
</child>
|
173
|
+
</widget>
|
174
|
+
</child>
|
175
|
+
<child>
|
176
|
+
<widget class="GtkLabel" id="label1">
|
177
|
+
<property name="visible">True</property>
|
178
|
+
<property name="label" translatable="yes">_Server</property>
|
179
|
+
<property name="use_underline">True</property>
|
180
|
+
</widget>
|
181
|
+
<packing>
|
182
|
+
<property name="tab_fill">False</property>
|
183
|
+
<property name="type">tab</property>
|
184
|
+
</packing>
|
185
|
+
</child>
|
186
|
+
<child>
|
187
|
+
<widget class="GtkAlignment" id="alignment2">
|
188
|
+
<property name="visible">True</property>
|
189
|
+
<property name="top_padding">5</property>
|
190
|
+
<property name="bottom_padding">5</property>
|
191
|
+
<property name="left_padding">5</property>
|
192
|
+
<property name="right_padding">5</property>
|
193
|
+
<child>
|
194
|
+
<widget class="GtkVBox" id="vbox2">
|
195
|
+
<property name="visible">True</property>
|
196
|
+
<property name="orientation">vertical</property>
|
197
|
+
<property name="spacing">5</property>
|
198
|
+
<child>
|
199
|
+
<placeholder/>
|
200
|
+
</child>
|
201
|
+
<child>
|
202
|
+
<widget class="GtkHBox" id="hbox2">
|
203
|
+
<property name="visible">True</property>
|
204
|
+
<child>
|
205
|
+
<widget class="GtkEntry" id="entry_feed_url">
|
206
|
+
<property name="visible">True</property>
|
207
|
+
<property name="can_focus">True</property>
|
208
|
+
<property name="invisible_char">●</property>
|
209
|
+
</widget>
|
210
|
+
<packing>
|
211
|
+
<property name="padding">5</property>
|
212
|
+
<property name="position">0</property>
|
213
|
+
</packing>
|
214
|
+
</child>
|
215
|
+
<child>
|
216
|
+
<widget class="GtkButton" id="button1">
|
217
|
+
<property name="label" translatable="yes">+</property>
|
218
|
+
<property name="width_request">25</property>
|
219
|
+
<property name="visible">True</property>
|
220
|
+
<property name="can_focus">True</property>
|
221
|
+
<property name="can_default">True</property>
|
222
|
+
<property name="has_default">True</property>
|
223
|
+
<property name="receives_default">True</property>
|
224
|
+
<property name="use_underline">True</property>
|
225
|
+
<signal name="clicked" handler="on_button_add_feed"/>
|
226
|
+
</widget>
|
227
|
+
<packing>
|
228
|
+
<property name="expand">False</property>
|
229
|
+
<property name="position">1</property>
|
230
|
+
</packing>
|
231
|
+
</child>
|
232
|
+
<child>
|
233
|
+
<widget class="GtkButton" id="button2">
|
234
|
+
<property name="label" translatable="yes">-</property>
|
235
|
+
<property name="width_request">25</property>
|
236
|
+
<property name="visible">True</property>
|
237
|
+
<property name="can_focus">True</property>
|
238
|
+
<property name="can_default">True</property>
|
239
|
+
<property name="receives_default">True</property>
|
240
|
+
<signal name="clicked" handler="on_button_remove_feed"/>
|
241
|
+
</widget>
|
242
|
+
<packing>
|
243
|
+
<property name="expand">False</property>
|
244
|
+
<property name="fill">False</property>
|
245
|
+
<property name="position">2</property>
|
246
|
+
</packing>
|
247
|
+
</child>
|
248
|
+
</widget>
|
249
|
+
<packing>
|
250
|
+
<property name="expand">False</property>
|
251
|
+
<property name="pack_type">end</property>
|
252
|
+
<property name="position">1</property>
|
253
|
+
</packing>
|
254
|
+
</child>
|
255
|
+
</widget>
|
256
|
+
</child>
|
257
|
+
</widget>
|
258
|
+
<packing>
|
259
|
+
<property name="position">1</property>
|
260
|
+
</packing>
|
261
|
+
</child>
|
262
|
+
<child>
|
263
|
+
<widget class="GtkLabel" id="label2">
|
264
|
+
<property name="visible">True</property>
|
265
|
+
<property name="label" translatable="yes">_Feeds</property>
|
266
|
+
<property name="use_underline">True</property>
|
267
|
+
</widget>
|
268
|
+
<packing>
|
269
|
+
<property name="position">1</property>
|
270
|
+
<property name="tab_fill">False</property>
|
271
|
+
<property name="type">tab</property>
|
272
|
+
</packing>
|
273
|
+
</child>
|
274
|
+
<child>
|
275
|
+
<widget class="GtkAlignment" id="alignment3">
|
276
|
+
<property name="visible">True</property>
|
277
|
+
<property name="top_padding">5</property>
|
278
|
+
<property name="bottom_padding">5</property>
|
279
|
+
<property name="left_padding">5</property>
|
280
|
+
<property name="right_padding">5</property>
|
281
|
+
<child>
|
282
|
+
<widget class="GtkVBox" id="vbox5">
|
283
|
+
<property name="visible">True</property>
|
284
|
+
<property name="orientation">vertical</property>
|
285
|
+
<property name="spacing">15</property>
|
286
|
+
<child>
|
287
|
+
<widget class="GtkTable" id="table2">
|
288
|
+
<property name="visible">True</property>
|
289
|
+
<property name="n_rows">3</property>
|
290
|
+
<property name="n_columns">2</property>
|
291
|
+
<property name="row_spacing">15</property>
|
292
|
+
<child>
|
293
|
+
<widget class="GtkLabel" id="label7">
|
294
|
+
<property name="visible">True</property>
|
295
|
+
<property name="xalign">0</property>
|
296
|
+
<property name="label" translatable="yes">Update interval (s)</property>
|
297
|
+
</widget>
|
298
|
+
</child>
|
299
|
+
<child>
|
300
|
+
<widget class="GtkEntry" id="entry_update_interval">
|
301
|
+
<property name="visible">True</property>
|
302
|
+
<property name="can_focus">True</property>
|
303
|
+
<property name="invisible_char">●</property>
|
304
|
+
<property name="width_chars">5</property>
|
305
|
+
</widget>
|
306
|
+
<packing>
|
307
|
+
<property name="left_attach">1</property>
|
308
|
+
<property name="right_attach">2</property>
|
309
|
+
</packing>
|
310
|
+
</child>
|
311
|
+
<child>
|
312
|
+
<widget class="GtkLabel" id="label6">
|
313
|
+
<property name="visible">True</property>
|
314
|
+
<property name="xalign">0</property>
|
315
|
+
<property name="label" translatable="yes">Logging mode</property>
|
316
|
+
</widget>
|
317
|
+
<packing>
|
318
|
+
<property name="top_attach">1</property>
|
319
|
+
<property name="bottom_attach">2</property>
|
320
|
+
</packing>
|
321
|
+
</child>
|
322
|
+
<child>
|
323
|
+
<widget class="GtkComboBox" id="combobox_logtype">
|
324
|
+
<property name="visible">True</property>
|
325
|
+
<property name="items" translatable="yes">STDERR
|
326
|
+
File</property>
|
327
|
+
<signal name="changed" handler="on_combobox_logtype_changed"/>
|
328
|
+
</widget>
|
329
|
+
<packing>
|
330
|
+
<property name="left_attach">1</property>
|
331
|
+
<property name="right_attach">2</property>
|
332
|
+
<property name="top_attach">1</property>
|
333
|
+
<property name="bottom_attach">2</property>
|
334
|
+
</packing>
|
335
|
+
</child>
|
336
|
+
<child>
|
337
|
+
<widget class="GtkLabel" id="label10">
|
338
|
+
<property name="visible">True</property>
|
339
|
+
<property name="xalign">0</property>
|
340
|
+
<property name="label" translatable="yes">Logging file path</property>
|
341
|
+
</widget>
|
342
|
+
<packing>
|
343
|
+
<property name="top_attach">2</property>
|
344
|
+
<property name="bottom_attach">3</property>
|
345
|
+
</packing>
|
346
|
+
</child>
|
347
|
+
<child>
|
348
|
+
<widget class="GtkEntry" id="entry_log_filepath">
|
349
|
+
<property name="visible">True</property>
|
350
|
+
<property name="can_focus">True</property>
|
351
|
+
<property name="invisible_char">●</property>
|
352
|
+
</widget>
|
353
|
+
<packing>
|
354
|
+
<property name="left_attach">1</property>
|
355
|
+
<property name="right_attach">2</property>
|
356
|
+
<property name="top_attach">2</property>
|
357
|
+
<property name="bottom_attach">3</property>
|
358
|
+
</packing>
|
359
|
+
</child>
|
360
|
+
</widget>
|
361
|
+
<packing>
|
362
|
+
<property name="expand">False</property>
|
363
|
+
<property name="position">0</property>
|
364
|
+
</packing>
|
365
|
+
</child>
|
366
|
+
<child>
|
367
|
+
<widget class="GtkCheckButton" id="checkbutton_add_paused">
|
368
|
+
<property name="label" translatable="yes">Do not start torrents when added</property>
|
369
|
+
<property name="visible">True</property>
|
370
|
+
<property name="can_focus">True</property>
|
371
|
+
<property name="receives_default">False</property>
|
372
|
+
<property name="draw_indicator">True</property>
|
373
|
+
</widget>
|
374
|
+
<packing>
|
375
|
+
<property name="expand">False</property>
|
376
|
+
<property name="position">1</property>
|
377
|
+
</packing>
|
378
|
+
</child>
|
379
|
+
</widget>
|
380
|
+
</child>
|
381
|
+
</widget>
|
382
|
+
<packing>
|
383
|
+
<property name="position">2</property>
|
384
|
+
</packing>
|
385
|
+
</child>
|
386
|
+
<child>
|
387
|
+
<widget class="GtkLabel" id="label3">
|
388
|
+
<property name="visible">True</property>
|
389
|
+
<property name="label" translatable="yes">_Options</property>
|
390
|
+
<property name="use_underline">True</property>
|
391
|
+
</widget>
|
392
|
+
<packing>
|
393
|
+
<property name="position">2</property>
|
394
|
+
<property name="tab_fill">False</property>
|
395
|
+
<property name="type">tab</property>
|
396
|
+
</packing>
|
397
|
+
</child>
|
398
|
+
</widget>
|
399
|
+
<packing>
|
400
|
+
<property name="position">1</property>
|
401
|
+
</packing>
|
402
|
+
</child>
|
403
|
+
<child>
|
404
|
+
<widget class="GtkStatusbar" id="statusbar1">
|
405
|
+
<property name="visible">True</property>
|
406
|
+
<property name="spacing">2</property>
|
407
|
+
</widget>
|
408
|
+
<packing>
|
409
|
+
<property name="expand">False</property>
|
410
|
+
<property name="position">2</property>
|
411
|
+
</packing>
|
412
|
+
</child>
|
413
|
+
</widget>
|
414
|
+
</child>
|
415
|
+
</widget>
|
416
|
+
<widget class="GtkWindow" id="window2">
|
417
|
+
<child>
|
418
|
+
<widget class="GtkLabel" id="label8">
|
419
|
+
<property name="width_request">320</property>
|
420
|
+
<property name="height_request">240</property>
|
421
|
+
<property name="visible">True</property>
|
422
|
+
<property name="label" translatable="yes">devoted to ann</property>
|
423
|
+
</widget>
|
424
|
+
</child>
|
425
|
+
</widget>
|
426
|
+
</glade-interface>
|
@@ -0,0 +1,254 @@
|
|
1
|
+
# Represents the config editor window.
|
2
|
+
class TransmissionRSS::ConfigEditor
|
3
|
+
TITLE = 'transmission-rss config editor'
|
4
|
+
NAME = 'config-editor'
|
5
|
+
|
6
|
+
DEFAULT_CONFIG = {
|
7
|
+
'feeds' => [],
|
8
|
+
'update_interval' => 600,
|
9
|
+
'start_paused' => false,
|
10
|
+
'server' => {
|
11
|
+
'host' => 'localhost',
|
12
|
+
'port' => 9091
|
13
|
+
},
|
14
|
+
'log_target' => $stderr
|
15
|
+
}
|
16
|
+
|
17
|
+
# Loads glade file and initializes dynamic GUI elements.
|
18
|
+
def initialize( configFile, config )
|
19
|
+
@configFile = configFile
|
20
|
+
@config = config
|
21
|
+
|
22
|
+
path = File.join( File.dirname( __FILE__ ), 'main.glade' )
|
23
|
+
|
24
|
+
# Load glade file and connect to handler method. Dubious.
|
25
|
+
@glade = GladeXML.new( path ) do |handler|
|
26
|
+
method( handler )
|
27
|
+
end
|
28
|
+
|
29
|
+
# Connect every widget to an instance variable.
|
30
|
+
@glade.widget_names.each do |name|
|
31
|
+
name.gsub!( /-/, '_' )
|
32
|
+
instance_variable_set( "@#{name}".intern, @glade[name] )
|
33
|
+
end
|
34
|
+
|
35
|
+
# Quit program, when it is closed by the WM.
|
36
|
+
@window1.signal_connect( 'destroy' ) do
|
37
|
+
Gtk.main_quit
|
38
|
+
end
|
39
|
+
|
40
|
+
# Initialize the ListBox widget.
|
41
|
+
initialize_listbox
|
42
|
+
|
43
|
+
# Reflect the current config on the GUI.
|
44
|
+
initialize_config
|
45
|
+
end
|
46
|
+
|
47
|
+
# Reflects the current config on the GUI.
|
48
|
+
def initialize_config
|
49
|
+
@entry_server_host.text = @config.server.host
|
50
|
+
@entry_server_port.text = @config.server.port.to_s
|
51
|
+
|
52
|
+
@entry_update_interval.text = @config.update_interval.to_s
|
53
|
+
|
54
|
+
@checkbutton_add_paused.active = @config.start_paused
|
55
|
+
|
56
|
+
@listbox.clear
|
57
|
+
@listbox.add( @config.feeds )
|
58
|
+
|
59
|
+
# If log target is STDERR.
|
60
|
+
if( @config.log_target.class == IO )
|
61
|
+
# Deactivate log path entry.
|
62
|
+
@label10.sensitive = false
|
63
|
+
@entry_log_filepath.sensitive = false
|
64
|
+
|
65
|
+
@combobox_logtype.active = 0
|
66
|
+
else
|
67
|
+
# Activate log path entry.
|
68
|
+
@label10.sensitive = true
|
69
|
+
@entry_log_filepath.sensitive = true
|
70
|
+
|
71
|
+
# Set entry text accordingly.
|
72
|
+
@entry_log_filepath.text = @config.log_target
|
73
|
+
|
74
|
+
@combobox_logtype.active = 1
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Initializes the ListBox widget.
|
79
|
+
def initialize_listbox
|
80
|
+
@listbox = ListBox.new
|
81
|
+
@listbox.header = 'Feeds'
|
82
|
+
|
83
|
+
@vbox2.pack_start( @listbox )
|
84
|
+
|
85
|
+
@window1.show_all
|
86
|
+
|
87
|
+
@listbox.signal_connect( 'button_release_event' ) do |widget, event|
|
88
|
+
@entry_feed_url.text = @listbox.button_release( widget, event )
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Add a feed to the ListBox if the Add-feed-button is pressed.
|
93
|
+
def on_button_add_feed( widget )
|
94
|
+
if( not @entry_feed_url.text.empty? )
|
95
|
+
@listbox.add( @entry_feed_url.text )
|
96
|
+
@entry_feed_url.text = ''
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Remove a feed from the ListBox if the Remove-feed-button is pressed.
|
101
|
+
def on_button_remove_feed( widget )
|
102
|
+
@listbox.remove( @entry_feed_url.text )
|
103
|
+
end
|
104
|
+
|
105
|
+
# Is called when a value in the log type ComboBox is selected.
|
106
|
+
def on_combobox_logtype_changed( widget )
|
107
|
+
# If STDERR is selected.
|
108
|
+
if( @combobox_logtype.active == 0 )
|
109
|
+
# Deactivate the log file path entry.
|
110
|
+
@label10.sensitive = false
|
111
|
+
@entry_log_filepath.sensitive = false
|
112
|
+
|
113
|
+
@entry_log_filepath.text = ''
|
114
|
+
else
|
115
|
+
# Activate the log file path entry.
|
116
|
+
@label10.sensitive = true
|
117
|
+
@entry_log_filepath.sensitive = true
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Is called when the Help-About menu is selected.
|
122
|
+
def on_menu_about( widget )
|
123
|
+
Gnome::About.new(
|
124
|
+
TITLE,
|
125
|
+
VERSION,
|
126
|
+
'Copyright (C) 2010 henning mueller',
|
127
|
+
'Easy transmission-rss config editing. Devoted to Ann.',
|
128
|
+
['henning mueller'],
|
129
|
+
['henning mueller'],
|
130
|
+
nil
|
131
|
+
).show
|
132
|
+
end
|
133
|
+
|
134
|
+
# Is called when the File-New menu is selected.
|
135
|
+
def on_menu_new( widget )
|
136
|
+
dialog = Gtk::MessageDialog.new(
|
137
|
+
@window1,
|
138
|
+
Gtk::Dialog::DESTROY_WITH_PARENT,
|
139
|
+
Gtk::MessageDialog::WARNING,
|
140
|
+
Gtk::MessageDialog::BUTTONS_YES_NO,
|
141
|
+
"Unsaved configuration will be lost!\nProceed?"
|
142
|
+
)
|
143
|
+
|
144
|
+
if( dialog.run == Gtk::Dialog::RESPONSE_YES )
|
145
|
+
@configFile = nil
|
146
|
+
|
147
|
+
@config.clear
|
148
|
+
@config.load( DEFAULT_CONFIG )
|
149
|
+
|
150
|
+
initialize_config
|
151
|
+
end
|
152
|
+
|
153
|
+
dialog.destroy
|
154
|
+
end
|
155
|
+
|
156
|
+
# Is called when the File-Open menu is selected.
|
157
|
+
def on_menu_open( widget )
|
158
|
+
dialog = Gtk::FileChooserDialog.new(
|
159
|
+
'Open',
|
160
|
+
@window1,
|
161
|
+
Gtk::FileChooser::ACTION_OPEN,
|
162
|
+
nil,
|
163
|
+
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
|
164
|
+
[Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT]
|
165
|
+
)
|
166
|
+
|
167
|
+
if( dialog.run == Gtk::Dialog::RESPONSE_ACCEPT )
|
168
|
+
@configFile = dialog.filename
|
169
|
+
|
170
|
+
@config.clear
|
171
|
+
@config.load( DEFAULT_CONFIG )
|
172
|
+
@config.load( @configFile )
|
173
|
+
|
174
|
+
initialize_config
|
175
|
+
end
|
176
|
+
|
177
|
+
dialog.destroy
|
178
|
+
end
|
179
|
+
|
180
|
+
# Is called when the File-Save menu is selected.
|
181
|
+
def on_menu_save( widget )
|
182
|
+
if( not @configFile.nil? )
|
183
|
+
save!
|
184
|
+
else
|
185
|
+
on_menu_save_as( nil )
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# Is called when the File-SaveAs menu is selected.
|
190
|
+
def on_menu_save_as( widget )
|
191
|
+
dialog = Gtk::FileChooserDialog.new(
|
192
|
+
'Save As..',
|
193
|
+
@window1,
|
194
|
+
Gtk::FileChooser::ACTION_SAVE,
|
195
|
+
nil,
|
196
|
+
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
|
197
|
+
[Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT]
|
198
|
+
)
|
199
|
+
|
200
|
+
if( dialog.run == Gtk::Dialog::RESPONSE_ACCEPT )
|
201
|
+
@configFile = dialog.filename
|
202
|
+
save!
|
203
|
+
end
|
204
|
+
|
205
|
+
dialog.destroy
|
206
|
+
end
|
207
|
+
|
208
|
+
# Is called when the File-Quit menu is selected.
|
209
|
+
def on_menu_quit( widget )
|
210
|
+
Gtk.main_quit
|
211
|
+
end
|
212
|
+
|
213
|
+
# Convert GUI config to +Config+, open the config file and write a YAML
|
214
|
+
# version of the Hash.
|
215
|
+
def save!
|
216
|
+
@config.server.host = @entry_server_host.text
|
217
|
+
@config.server.port = @entry_server_port.text.to_i
|
218
|
+
|
219
|
+
@config.update_interval = @entry_update_interval.text.to_i
|
220
|
+
|
221
|
+
@config.start_paused = @checkbutton_add_paused.active?
|
222
|
+
|
223
|
+
@config.feeds = @listbox.items
|
224
|
+
|
225
|
+
# If STDERR is selected.
|
226
|
+
if( @combobox_logtype.active == 0 )
|
227
|
+
# Delete log_target from config hash, so $stderr is chosen on load.
|
228
|
+
@config.delete( 'log_target' )
|
229
|
+
else
|
230
|
+
# Set log_target to entry text.
|
231
|
+
@config.log_target = @entry_log_filepath.text
|
232
|
+
end
|
233
|
+
|
234
|
+
# Try writing to file; dialog on permission error.
|
235
|
+
begin
|
236
|
+
File.open( @configFile, 'w' ) do |f|
|
237
|
+
f.write( @config.to_yaml )
|
238
|
+
end
|
239
|
+
rescue Errno::EACCES
|
240
|
+
dialog = Gtk::MessageDialog.new(
|
241
|
+
@window1,
|
242
|
+
Gtk::Dialog::DESTROY_WITH_PARENT,
|
243
|
+
Gtk::MessageDialog::ERROR,
|
244
|
+
Gtk::MessageDialog::BUTTONS_CLOSE,
|
245
|
+
"Permission denied:\n" + @configFile
|
246
|
+
)
|
247
|
+
|
248
|
+
dialog.run
|
249
|
+
dialog.destroy
|
250
|
+
|
251
|
+
on_menu_save_as( nil )
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: transmission-rss
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 13
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
7
|
+
- 1
|
8
8
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.9
|
9
|
+
version: 0.1.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- henning mueller
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2010-
|
17
|
+
date: 2010-09-11 00:00:00 +02:00
|
19
18
|
default_executable:
|
20
19
|
dependencies: []
|
21
20
|
|
@@ -33,7 +32,12 @@ extra_rdoc_files: []
|
|
33
32
|
files:
|
34
33
|
- bin/transmission-rss
|
35
34
|
- lib/transmission-rss.rb
|
35
|
+
- lib/transmission-rss/config-editor/listbox.rb
|
36
|
+
- lib/transmission-rss/config-editor/listbox-original.rb
|
37
|
+
- lib/transmission-rss/config-editor/main.rb
|
38
|
+
- lib/transmission-rss/config-editor/main.glade
|
36
39
|
- lib/transmission-rss/log.rb
|
40
|
+
- lib/transmission-rss/config-editor.rb
|
37
41
|
- lib/transmission-rss/aggregator.rb
|
38
42
|
- lib/transmission-rss/config.rb
|
39
43
|
- lib/transmission-rss/hash.rb
|
@@ -53,7 +57,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
57
|
requirements:
|
54
58
|
- - ">="
|
55
59
|
- !ruby/object:Gem::Version
|
56
|
-
hash: 3
|
57
60
|
segments:
|
58
61
|
- 0
|
59
62
|
version: "0"
|
@@ -62,7 +65,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
62
65
|
requirements:
|
63
66
|
- - ">="
|
64
67
|
- !ruby/object:Gem::Version
|
65
|
-
hash: 3
|
66
68
|
segments:
|
67
69
|
- 0
|
68
70
|
version: "0"
|