transmission-rss 0.0.9 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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"
|