transmission-rss 0.1.0 → 0.1.1

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.
@@ -36,8 +36,9 @@ It should at least contain a list of feeds:
36
36
  === All available options
37
37
 
38
38
  The following configuration file example contains every existing option
39
- (although +rss_check_interval+, +paused+ and +server+ are default values
40
- and coult be omitted). The default +log_target+ is STDERR.
39
+ (although +rss_check_interval+, +paused+ and +server+ are default values and
40
+ could be omitted). The default +log_target+ is STDERR. +privileges+ is not
41
+ defined by default, so the script runs as current user/group.
41
42
 
42
43
  feeds:
43
44
  - http://example.com/feed1
@@ -45,7 +46,7 @@ and coult be omitted). The default +log_target+ is STDERR.
45
46
 
46
47
  update_interval: 600
47
48
 
48
- start_paused: false
49
+ add_paused: false
49
50
 
50
51
  server:
51
52
  host: localhost
@@ -53,8 +54,13 @@ and coult be omitted). The default +log_target+ is STDERR.
53
54
 
54
55
  log_target: /var/log/transmissiond-rss.log
55
56
 
57
+ privileges:
58
+ user: nobody
59
+ group: nobody
60
+
56
61
  == TODO
57
62
 
58
63
  * Timeout and error handling in +Aggregator+ and +Client+
59
- * Drop privileges
60
64
  * Option to stop seeding after full download
65
+ * Privileges configurable by GUI
66
+ * Log level
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require( 'getoptlong' )
4
+ require( 'etc' )
4
5
 
5
6
  $:.unshift( File.join( File.dirname( __FILE__ ), '../lib' ) )
6
7
  require( 'transmission-rss' )
@@ -67,12 +68,13 @@ config = TransmissionRSS::Config.instance
67
68
  config.load( {
68
69
  'feeds' => [],
69
70
  'update_interval' => 600,
70
- 'start_paused' => false,
71
+ 'add_paused' => false,
71
72
  'server' => {
72
73
  'host' => 'localhost',
73
74
  'port' => 9091
74
75
  },
75
- 'log_target' => $stderr
76
+ 'log_target' => $stderr,
77
+ 'privileges' => {}
76
78
  } )
77
79
 
78
80
  # Initialize a log instance, configure it and run the consumer in a subthread.
@@ -89,6 +91,26 @@ rescue Errno::ENOENT
89
91
  end
90
92
  log.add( config )
91
93
 
94
+ # Drop privileges, if section is given in config file.
95
+ if( not config.privileges.empty? )
96
+ Process::Sys.setgid(
97
+ Etc.getgrnam( config.privileges.group ).gid
98
+ )
99
+
100
+ Process::Sys.setuid(
101
+ Etc.getpwnam( config.privileges.user ).uid
102
+ )
103
+
104
+ log.add(
105
+ 'dropped privileges ' +
106
+ config.privileges.user +
107
+ ':' +
108
+ config.privileges.group
109
+ )
110
+ else
111
+ log.add( 'no privilege dropping' )
112
+ end
113
+
92
114
  # Start GUI if config edit option is given.
93
115
  if( editConfig )
94
116
  require( 'transmission-rss/config-editor' )
@@ -119,7 +141,7 @@ aggregator.feeds.concat( config.feeds )
119
141
  # Callback for a new item on one of the feeds.
120
142
  aggregator.on_new_item do |torrentFile|
121
143
  Thread.start do
122
- client.addTorrent( torrentFile, config.start_paused )
144
+ client.addTorrent( torrentFile, config.add_paused )
123
145
  end
124
146
  end
125
147
 
@@ -1,7 +1,7 @@
1
1
  $:.unshift( File.dirname( __FILE__ ) )
2
2
 
3
3
  module TransmissionRSS
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
5
5
  end
6
6
 
7
7
  dir = 'transmission-rss'
@@ -45,7 +45,7 @@ class TransmissionRSS::Aggregator
45
45
 
46
46
  while( true )
47
47
  feeds.each do |url|
48
- @log.add( 'aggregate ' + url )
48
+ # @log.add( 'aggregate ' + url )
49
49
 
50
50
  begin
51
51
  content = open( url ).readlines.join( "\n" )
@@ -337,7 +337,7 @@ File</property>
337
337
  <widget class="GtkLabel" id="label10">
338
338
  <property name="visible">True</property>
339
339
  <property name="xalign">0</property>
340
- <property name="label" translatable="yes">Logging file path</property>
340
+ <property name="label" translatable="yes"> Logging file path</property>
341
341
  </widget>
342
342
  <packing>
343
343
  <property name="top_attach">2</property>
@@ -395,6 +395,106 @@ File</property>
395
395
  <property name="type">tab</property>
396
396
  </packing>
397
397
  </child>
398
+ <child>
399
+ <widget class="GtkAlignment" id="alignment4">
400
+ <property name="visible">True</property>
401
+ <property name="top_padding">5</property>
402
+ <property name="bottom_padding">5</property>
403
+ <property name="left_padding">5</property>
404
+ <property name="right_padding">5</property>
405
+ <child>
406
+ <widget class="GtkVBox" id="vbox3">
407
+ <property name="visible">True</property>
408
+ <property name="orientation">vertical</property>
409
+ <property name="spacing">15</property>
410
+ <child>
411
+ <widget class="GtkCheckButton" id="checkbutton_drop_privileges">
412
+ <property name="label" translatable="yes">Drop privileges after startup</property>
413
+ <property name="visible">True</property>
414
+ <property name="can_focus">True</property>
415
+ <property name="receives_default">False</property>
416
+ <property name="draw_indicator">True</property>
417
+ <signal name="toggled" handler="on_checkbutton_drop_privileges_toggled"/>
418
+ </widget>
419
+ <packing>
420
+ <property name="expand">False</property>
421
+ <property name="position">0</property>
422
+ </packing>
423
+ </child>
424
+ <child>
425
+ <widget class="GtkTable" id="table5">
426
+ <property name="visible">True</property>
427
+ <property name="n_rows">2</property>
428
+ <property name="n_columns">2</property>
429
+ <property name="row_spacing">15</property>
430
+ <child>
431
+ <widget class="GtkLabel" id="label15">
432
+ <property name="visible">True</property>
433
+ <property name="xalign">0</property>
434
+ <property name="label" translatable="yes"> User</property>
435
+ </widget>
436
+ </child>
437
+ <child>
438
+ <widget class="GtkEntry" id="entry_drop_privileges_user">
439
+ <property name="visible">True</property>
440
+ <property name="can_focus">True</property>
441
+ <property name="invisible_char">&#x25CF;</property>
442
+ <property name="width_chars">5</property>
443
+ </widget>
444
+ <packing>
445
+ <property name="left_attach">1</property>
446
+ <property name="right_attach">2</property>
447
+ </packing>
448
+ </child>
449
+ <child>
450
+ <widget class="GtkLabel" id="label16">
451
+ <property name="visible">True</property>
452
+ <property name="xalign">0</property>
453
+ <property name="label" translatable="yes"> Group</property>
454
+ </widget>
455
+ <packing>
456
+ <property name="top_attach">1</property>
457
+ <property name="bottom_attach">2</property>
458
+ </packing>
459
+ </child>
460
+ <child>
461
+ <widget class="GtkEntry" id="entry_drop_privileges_group">
462
+ <property name="visible">True</property>
463
+ <property name="can_focus">True</property>
464
+ <property name="invisible_char">&#x25CF;</property>
465
+ </widget>
466
+ <packing>
467
+ <property name="left_attach">1</property>
468
+ <property name="right_attach">2</property>
469
+ <property name="top_attach">1</property>
470
+ <property name="bottom_attach">2</property>
471
+ </packing>
472
+ </child>
473
+ </widget>
474
+ <packing>
475
+ <property name="expand">False</property>
476
+ <property name="position">1</property>
477
+ </packing>
478
+ </child>
479
+ </widget>
480
+ </child>
481
+ </widget>
482
+ <packing>
483
+ <property name="position">3</property>
484
+ </packing>
485
+ </child>
486
+ <child>
487
+ <widget class="GtkLabel" id="label9">
488
+ <property name="visible">True</property>
489
+ <property name="label" translatable="yes">_Privileges</property>
490
+ <property name="use_underline">True</property>
491
+ </widget>
492
+ <packing>
493
+ <property name="position">3</property>
494
+ <property name="tab_fill">False</property>
495
+ <property name="type">tab</property>
496
+ </packing>
497
+ </child>
398
498
  </widget>
399
499
  <packing>
400
500
  <property name="position">1</property>
@@ -413,14 +513,4 @@ File</property>
413
513
  </widget>
414
514
  </child>
415
515
  </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
516
  </glade-interface>
@@ -6,12 +6,13 @@ class TransmissionRSS::ConfigEditor
6
6
  DEFAULT_CONFIG = {
7
7
  'feeds' => [],
8
8
  'update_interval' => 600,
9
- 'start_paused' => false,
9
+ 'add_paused' => false,
10
10
  'server' => {
11
11
  'host' => 'localhost',
12
12
  'port' => 9091
13
13
  },
14
- 'log_target' => $stderr
14
+ 'log_target' => $stderr,
15
+ 'privileges' => {}
15
16
  }
16
17
 
17
18
  # Loads glade file and initializes dynamic GUI elements.
@@ -51,7 +52,7 @@ class TransmissionRSS::ConfigEditor
51
52
 
52
53
  @entry_update_interval.text = @config.update_interval.to_s
53
54
 
54
- @checkbutton_add_paused.active = @config.start_paused
55
+ @checkbutton_add_paused.active = @config.add_paused
55
56
 
56
57
  @listbox.clear
57
58
  @listbox.add( @config.feeds )
@@ -73,6 +74,33 @@ class TransmissionRSS::ConfigEditor
73
74
 
74
75
  @combobox_logtype.active = 1
75
76
  end
77
+
78
+ # If privilege section is given in config.
79
+ if( @config.privileges.empty? )
80
+ # Deactivate user entry.
81
+ @label15.sensitive = false
82
+ @entry_drop_privileges_user.sensitive = false
83
+
84
+ # Deactivate group entry.
85
+ @label16.sensitive = false
86
+ @entry_drop_privileges_group.sensitive = false
87
+
88
+ @checkbutton_drop_privileges.active = false
89
+ else
90
+ # Activate user entry.
91
+ @label15.sensitive = true
92
+ @entry_drop_privileges_user.sensitive = true
93
+
94
+ # Activate group entry.
95
+ @label16.sensitive = true
96
+ @entry_drop_privileges_group.sensitive = true
97
+
98
+ # Set entry texts accordingly.
99
+ @entry_drop_privileges_user.text = @config.privileges.user
100
+ @entry_drop_privileges_group.text = @config.privileges.group
101
+
102
+ @checkbutton_drop_privileges.active = true
103
+ end
76
104
  end
77
105
 
78
106
  # Initializes the ListBox widget.
@@ -102,6 +130,32 @@ class TransmissionRSS::ConfigEditor
102
130
  @listbox.remove( @entry_feed_url.text )
103
131
  end
104
132
 
133
+ # Activate or deactivate entry widgets if drop privileges checkbutton is
134
+ # toggled.
135
+ def on_checkbutton_drop_privileges_toggled( widget )
136
+ if( @checkbutton_drop_privileges.active? )
137
+ # Activate user entry.
138
+ @label15.sensitive = true
139
+ @entry_drop_privileges_user.sensitive = true
140
+
141
+ # Activate group entry.
142
+ @label16.sensitive = true
143
+ @entry_drop_privileges_group.sensitive = true
144
+ else
145
+ # Deactivate user entry.
146
+ @label15.sensitive = false
147
+ @entry_drop_privileges_user.sensitive = false
148
+
149
+ # Deactivate group entry.
150
+ @label16.sensitive = false
151
+ @entry_drop_privileges_group.sensitive = false
152
+
153
+ # Delete entry texts.
154
+ @entry_drop_privileges_user.text = ''
155
+ @entry_drop_privileges_group.text = ''
156
+ end
157
+ end
158
+
105
159
  # Is called when a value in the log type ComboBox is selected.
106
160
  def on_combobox_logtype_changed( widget )
107
161
  # If STDERR is selected.
@@ -110,6 +164,7 @@ class TransmissionRSS::ConfigEditor
110
164
  @label10.sensitive = false
111
165
  @entry_log_filepath.sensitive = false
112
166
 
167
+ # Delete entry text.
113
168
  @entry_log_filepath.text = ''
114
169
  else
115
170
  # Activate the log file path entry.
@@ -218,7 +273,7 @@ class TransmissionRSS::ConfigEditor
218
273
 
219
274
  @config.update_interval = @entry_update_interval.text.to_i
220
275
 
221
- @config.start_paused = @checkbutton_add_paused.active?
276
+ @config.add_paused = @checkbutton_add_paused.active?
222
277
 
223
278
  @config.feeds = @listbox.items
224
279
 
@@ -231,6 +286,16 @@ class TransmissionRSS::ConfigEditor
231
286
  @config.log_target = @entry_log_filepath.text
232
287
  end
233
288
 
289
+ # If checkbutton drop privileges is activated.
290
+ if( @checkbutton_drop_privileges.active? )
291
+ # Set user and group to entry texts.
292
+ @config.privileges.user = @entry_drop_privileges_user.text
293
+ @config.privileges.group = @entry_drop_privileges_group.text
294
+ else
295
+ # Delete privilege section from config hash.
296
+ @config.delete( 'privileges' )
297
+ end
298
+
234
299
  # Try writing to file; dialog on permission error.
235
300
  begin
236
301
  File.open( @configFile, 'w' ) do |f|
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 0
9
- version: 0.1.0
8
+ - 1
9
+ version: 0.1.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - henning mueller
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-09-11 00:00:00 +02:00
17
+ date: 2010-09-28 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies: []
20
20