sapis 0.1.0 → 0.3.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.
- checksums.yaml +4 -4
- data/README.md +1 -177
- data/lib/sapis/bash_helper.rb +17 -20
- data/lib/sapis/computations_helper.rb +15 -18
- data/lib/sapis/concurrency_helper.rb +17 -21
- data/lib/sapis/configuration_helper.rb +30 -32
- data/lib/sapis/desktop_helper.rb +6 -8
- data/lib/sapis/generic_helper.rb +7 -7
- data/lib/sapis/gnome_helper.rb +1 -4
- data/lib/sapis/graphing_helper.rb +48 -51
- data/lib/sapis/interactions_helper.rb +27 -30
- data/lib/sapis/multimedia_helper.rb +71 -74
- data/lib/sapis/sqlite_layer.rb +38 -39
- data/lib/sapis/system_helper.rb +27 -30
- data/lib/sapis/version.rb +1 -1
- metadata +21 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 52b3ca66bfcde6713ac1c84026d2a92b65d3438581f549c740ec61551c849778
|
|
4
|
+
data.tar.gz: 52777650753a8d17c9bd82afd557f3bc2ca98477beb26dad28cb262fd2694342
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2176d3ac1427fd9a9db7e0df494ba4d66af2f795b75743d87ce03467e5570fcb00a0716be2b7bcb28f59755c54f6a5ef7522af2d033a7ad381cf849aeb067540
|
|
7
|
+
data.tar.gz: 32fd64559a032787ca5154673ee4b7d866a61e1110bbf2b131da75bc367d9c2004b8f73ac69a36b4adc98667c5e68951d4fb7de37cc05ec4796a4e05743f5d04
|
data/README.md
CHANGED
|
@@ -1,179 +1,3 @@
|
|
|
1
1
|
# Sapis
|
|
2
2
|
|
|
3
|
-
Sav's APIs - A collection of Ruby utility helpers
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
Add this line to your application's Gemfile:
|
|
8
|
-
|
|
9
|
-
```ruby
|
|
10
|
-
gem 'sapis'
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
And then execute:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
bundle install
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Or install it yourself as:
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
gem install sapis
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## Usage
|
|
26
|
-
|
|
27
|
-
Require the gem in your Ruby code:
|
|
28
|
-
|
|
29
|
-
```ruby
|
|
30
|
-
require 'sapis'
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Available Modules
|
|
34
|
-
|
|
35
|
-
#### GraphingHelper
|
|
36
|
-
|
|
37
|
-
Provides functionality for creating and formatting graphs using Gruff.
|
|
38
|
-
|
|
39
|
-
```ruby
|
|
40
|
-
# Transpose data and create line graphs
|
|
41
|
-
data, days = GraphingHelper.transpose_data_top_headers( source_data )
|
|
42
|
-
GraphingHelper.format_as_line_graph( data, days, out_file: 'graph.png' )
|
|
43
|
-
|
|
44
|
-
# Format data as tables
|
|
45
|
-
table = GraphingHelper.format_as_table( rows, separator: '|', align: { 'Header' => :left } )
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
#### ConfigurationHelper
|
|
49
|
-
|
|
50
|
-
Load configuration from files with optional encryption support.
|
|
51
|
-
|
|
52
|
-
```ruby
|
|
53
|
-
config = ConfigurationHelper.load_configuration( group: 'myapp', sym_keys: true )
|
|
54
|
-
value = config[ :some_key ]
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
#### ConcurrencyHelper
|
|
58
|
-
|
|
59
|
-
Parallel processing with thread pooling.
|
|
60
|
-
|
|
61
|
-
```ruby
|
|
62
|
-
ConcurrencyHelper.with_parallel_queue( 4 ) do | queue, semaphore |
|
|
63
|
-
queue.push { task_1 }
|
|
64
|
-
queue.push { task_2 }
|
|
65
|
-
end
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
#### GenericHelper
|
|
69
|
-
|
|
70
|
-
General utility functions including date decoding and retry logic.
|
|
71
|
-
|
|
72
|
-
```ruby
|
|
73
|
-
date = GenericHelper.decode_date( 'today' )
|
|
74
|
-
GenericHelper.do_retry( max_retries: 3, sleep: 1 ) { risky_operation }
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
#### BashHelper
|
|
78
|
-
|
|
79
|
-
Safe execution of bash commands.
|
|
80
|
-
|
|
81
|
-
```ruby
|
|
82
|
-
result = BashHelper.safe_execute( 'ls -la' )
|
|
83
|
-
BashHelper.simple_bash_execute( 'rm', file1, file2, file3 )
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
#### ComputationsHelper
|
|
87
|
-
|
|
88
|
-
Data manipulation and smoothing functions.
|
|
89
|
-
|
|
90
|
-
```ruby
|
|
91
|
-
ComputationsHelper.convert_to_incremental_values!( values )
|
|
92
|
-
ComputationsHelper.smooth_line!( values, 5 )
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
#### DesktopHelper
|
|
96
|
-
|
|
97
|
-
Desktop integration utilities.
|
|
98
|
-
|
|
99
|
-
```ruby
|
|
100
|
-
DesktopHelper.set_clipboard_text( 'Hello, World!' )
|
|
101
|
-
result = DesktopHelper.display_dialog( 'Are you sure?' )
|
|
102
|
-
DesktopHelper.desktop_notification( 'Task completed' )
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
#### InteractionsHelper
|
|
106
|
-
|
|
107
|
-
Command-line user interaction helpers.
|
|
108
|
-
|
|
109
|
-
```ruby
|
|
110
|
-
password = InteractionsHelper.secure_ask( 'Enter password: ' )
|
|
111
|
-
answer = InteractionsHelper.ask_entry( 'Name', 'default_name' )
|
|
112
|
-
choice = InteractionsHelper.ask_entries_with_points( 'Select option', options )
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
#### MultimediaHelper
|
|
116
|
-
|
|
117
|
-
Audio and multimedia file operations.
|
|
118
|
-
|
|
119
|
-
```ruby
|
|
120
|
-
MultimediaHelper.play_audio_file( 'song.mp3' )
|
|
121
|
-
MultimediaHelper.normalize_songs( file1, file2 )
|
|
122
|
-
MultimediaHelper.create_m3u_playlist( files, basedir, 'playlist.m3u' )
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
#### GnomeHelper
|
|
126
|
-
|
|
127
|
-
GNOME desktop environment helpers.
|
|
128
|
-
|
|
129
|
-
```ruby
|
|
130
|
-
GnomeHelper.set_gnome_background( '/path/to/image.jpg' )
|
|
131
|
-
current = GnomeHelper.get_gnome_background_filename
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
#### SystemHelper
|
|
135
|
-
|
|
136
|
-
System-level utilities.
|
|
137
|
-
|
|
138
|
-
```ruby
|
|
139
|
-
cores = SystemHelper.system_cores_number
|
|
140
|
-
files = SystemHelper.find_files( '*.rb', [ '/path' ], file_type: SystemHelper::SEARCH_FILES )
|
|
141
|
-
SystemHelper.open_file( 'document.pdf' )
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
#### SQLiteLayer
|
|
145
|
-
|
|
146
|
-
Simplified SQLite database operations.
|
|
147
|
-
|
|
148
|
-
```ruby
|
|
149
|
-
db = SQLiteLayer.new( 'database.db' )
|
|
150
|
-
id = db.insert_values( 'users', { name: 'John', email: 'john@example.com' } )
|
|
151
|
-
results = db.select_all( 'SELECT * FROM users WHERE active = ?', true )
|
|
152
|
-
db.transaction do
|
|
153
|
-
# database operations
|
|
154
|
-
end
|
|
155
|
-
db.close
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
## Dependencies
|
|
159
|
-
|
|
160
|
-
- gruff (~> 0.7) - For graphing functionality
|
|
161
|
-
- parseconfig (~> 1.0) - For configuration file parsing
|
|
162
|
-
- highline (~> 2.0) - For secure command-line input
|
|
163
|
-
- sqlite3 (~> 1.4) - For SQLite database operations
|
|
164
|
-
|
|
165
|
-
## Development
|
|
166
|
-
|
|
167
|
-
After checking out the repo, run `bundle install` to install dependencies.
|
|
168
|
-
|
|
169
|
-
## License
|
|
170
|
-
|
|
171
|
-
This project is licensed under the GNU General Public License v3.0. See the source files for full license text.
|
|
172
|
-
|
|
173
|
-
## Author
|
|
174
|
-
|
|
175
|
-
Saverio Miroddi
|
|
176
|
-
|
|
177
|
-
## Contributing
|
|
178
|
-
|
|
179
|
-
Bug reports and pull requests are welcome on GitHub.
|
|
3
|
+
Sav's APIs - A collection of Ruby utility helpers I wrote for myself.
|
data/lib/sapis/bash_helper.rb
CHANGED
|
@@ -19,16 +19,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
19
19
|
=end
|
|
20
20
|
|
|
21
21
|
module BashHelper
|
|
22
|
-
|
|
23
22
|
require 'open3'
|
|
24
23
|
require 'shellwords'
|
|
25
24
|
|
|
26
25
|
# REFACTOR: default :out to STDOUT
|
|
27
26
|
#
|
|
28
|
-
def self.safe_execute(
|
|
29
|
-
out = options[
|
|
27
|
+
def self.safe_execute(cmd, options={})
|
|
28
|
+
out = options[:out]
|
|
30
29
|
|
|
31
|
-
Open3.popen3(
|
|
30
|
+
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
|
|
32
31
|
exit_status = wait_thr.value.exitstatus
|
|
33
32
|
|
|
34
33
|
output = stdout.read
|
|
@@ -43,38 +42,36 @@ module BashHelper
|
|
|
43
42
|
end
|
|
44
43
|
end
|
|
45
44
|
|
|
46
|
-
def safe_execute(
|
|
47
|
-
BashHelper.safe_execute(
|
|
45
|
+
def safe_execute(cmd, options={})
|
|
46
|
+
BashHelper.safe_execute(cmd, options)
|
|
48
47
|
end
|
|
49
48
|
|
|
50
49
|
# Encode as single-quoted, space-separated series of filenames.
|
|
51
50
|
# Encoding a slash apparently requires four slashes.
|
|
52
51
|
#
|
|
53
52
|
|
|
54
|
-
def simple_bash_execute(
|
|
55
|
-
BashHelper.simple_bash_execute(
|
|
53
|
+
def simple_bash_execute(command, *files_and_options)
|
|
54
|
+
BashHelper.simple_bash_execute(command, *files_and_options)
|
|
56
55
|
end
|
|
57
56
|
|
|
58
|
-
def BashHelper.simple_bash_execute(
|
|
59
|
-
options = files_and_options.last.is_a?(
|
|
57
|
+
def BashHelper.simple_bash_execute(command, *files_and_options)
|
|
58
|
+
options = files_and_options.last.is_a?(Hash) ? files_and_options.pop : {}
|
|
60
59
|
files = files_and_options
|
|
61
60
|
|
|
62
|
-
output = options.has_key?(
|
|
61
|
+
output = options.has_key?(:out) ? options[:out] : STDOUT
|
|
63
62
|
|
|
64
63
|
files = files.flatten
|
|
65
|
-
command = "#{
|
|
64
|
+
command = "#{command} #{encode_bash_filenames(*files)}"
|
|
66
65
|
|
|
67
|
-
safe_execute(
|
|
66
|
+
safe_execute(command, out: output)
|
|
68
67
|
end
|
|
69
68
|
|
|
70
|
-
def encode_bash_filenames(
|
|
71
|
-
BashHelper.encode_bash_filenames(
|
|
69
|
+
def encode_bash_filenames(*files)
|
|
70
|
+
BashHelper.encode_bash_filenames(*files)
|
|
72
71
|
end
|
|
73
72
|
|
|
74
|
-
def BashHelper.encode_bash_filenames(
|
|
75
|
-
quoted_filenames = files.map { |
|
|
76
|
-
quoted_filenames.join(
|
|
73
|
+
def BashHelper.encode_bash_filenames(*files)
|
|
74
|
+
quoted_filenames = files.map { |file| file.shellescape }
|
|
75
|
+
quoted_filenames.join(' ')
|
|
77
76
|
end
|
|
78
|
-
|
|
79
77
|
end
|
|
80
|
-
|
|
@@ -19,7 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
19
19
|
=end
|
|
20
20
|
|
|
21
21
|
module ComputationsHelper
|
|
22
|
-
|
|
23
22
|
# Covnerts to incremental values.
|
|
24
23
|
#
|
|
25
24
|
# Modifies the original data.
|
|
@@ -29,10 +28,10 @@ module ComputationsHelper
|
|
|
29
28
|
# becomes:
|
|
30
29
|
# [ 1, 1, 0, 1 ]
|
|
31
30
|
#
|
|
32
|
-
def self.convert_to_incremental_values!(
|
|
31
|
+
def self.convert_to_incremental_values!(source_values)
|
|
33
32
|
current_sum = 0
|
|
34
33
|
|
|
35
|
-
source_values.map! do |
|
|
34
|
+
source_values.map! do |value|
|
|
36
35
|
if value
|
|
37
36
|
current_sum += value
|
|
38
37
|
current_sum
|
|
@@ -41,21 +40,21 @@ module ComputationsHelper
|
|
|
41
40
|
end
|
|
42
41
|
|
|
43
42
|
SMOOTHING_DATA = {
|
|
44
|
-
5 => [
|
|
45
|
-
7 => [
|
|
46
|
-
9 => [
|
|
43
|
+
5 => [35.0, [-3, 12, 17, 12, -3]],
|
|
44
|
+
7 => [21.0, [-2, 3, 6, 7, 6, 3, -2]],
|
|
45
|
+
9 => [231.0, [-21, 14, 39, 54, 59, 54, 39, 14, -21]],
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
# Reference: http://stackoverflow.com/questions/4388911/how-can-i-draw-smoothed-rounded-curved-line-graphs-c
|
|
50
49
|
#
|
|
51
50
|
# Optimized for readability :-)
|
|
52
51
|
#
|
|
53
|
-
def self.smooth_line!(
|
|
54
|
-
h, coefficients = SMOOTHING_DATA[
|
|
52
|
+
def self.smooth_line!(values, coefficients_number)
|
|
53
|
+
h, coefficients = SMOOTHING_DATA[coefficients_number] || raise('Wrong number of coefficients')
|
|
55
54
|
|
|
56
|
-
raise "Smoothing needs at least #{
|
|
55
|
+
raise "Smoothing needs at least #{coefficients.size} values" if values.compact.size < coefficients.size
|
|
57
56
|
|
|
58
|
-
buffer_middle_position = (
|
|
57
|
+
buffer_middle_position = (coefficients.size + 1) / 2 - 1 # 0-based
|
|
59
58
|
|
|
60
59
|
non_empty_positions = []
|
|
61
60
|
original_values = values.clone
|
|
@@ -65,15 +64,15 @@ module ComputationsHelper
|
|
|
65
64
|
# When the buffer is ready, we compute the smoothed value and set it, and remove the first entry
|
|
66
65
|
# from the buffer.
|
|
67
66
|
#
|
|
68
|
-
values.each_with_index do |
|
|
67
|
+
values.each_with_index do |value, current_position|
|
|
69
68
|
non_empty_positions << current_position if value
|
|
70
69
|
|
|
71
70
|
next if non_empty_positions.size < coefficients.size
|
|
72
71
|
|
|
73
|
-
buffer = non_empty_positions.map { |
|
|
74
|
-
modifying_position = non_empty_positions[
|
|
72
|
+
buffer = non_empty_positions.map { |non_empty_position| original_values[non_empty_position] }
|
|
73
|
+
modifying_position = non_empty_positions[buffer_middle_position]
|
|
75
74
|
|
|
76
|
-
values[
|
|
75
|
+
values[modifying_position] = compute_smoothed_point(buffer, coefficients, h)
|
|
77
76
|
|
|
78
77
|
non_empty_positions.shift
|
|
79
78
|
end
|
|
@@ -83,13 +82,11 @@ module ComputationsHelper
|
|
|
83
82
|
|
|
84
83
|
private
|
|
85
84
|
|
|
86
|
-
def self.compute_smoothed_point(
|
|
87
|
-
sum = buffer.zip(
|
|
85
|
+
def self.compute_smoothed_point(buffer, coefficients, h)
|
|
86
|
+
sum = buffer.zip(coefficients).inject(0) do |current_sum, (value, coefficient)|
|
|
88
87
|
current_sum + value * coefficient
|
|
89
88
|
end
|
|
90
89
|
|
|
91
90
|
sum / h
|
|
92
91
|
end
|
|
93
|
-
|
|
94
92
|
end
|
|
95
|
-
|
|
@@ -19,7 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
19
19
|
=end
|
|
20
20
|
|
|
21
21
|
module ConcurrencyHelper
|
|
22
|
-
|
|
23
22
|
require 'thread'
|
|
24
23
|
|
|
25
24
|
# Parallel working, constrained on the number of threads.
|
|
@@ -48,15 +47,14 @@ module ConcurrencyHelper
|
|
|
48
47
|
# The semaphore is a generic semaphore; it can be used for example to lock when printing information to stdout.
|
|
49
48
|
#
|
|
50
49
|
class ParallelWorkersQueue
|
|
50
|
+
def initialize(slots, options={})
|
|
51
|
+
abort_on_exception = !options.has_key?(:abort_on_exception) || options[:abort_on_exception]
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
abort_on_exception = ! options.has_key?( :abort_on_exception ) || options[ :abort_on_exception ]
|
|
54
|
-
|
|
55
|
-
@queue = SizedQueue.new( slots )
|
|
53
|
+
@queue = SizedQueue.new(slots)
|
|
56
54
|
|
|
57
55
|
@threads = slots.times.map do
|
|
58
56
|
Thread.new do
|
|
59
|
-
while (
|
|
57
|
+
while (data = @queue.pop) != :stop
|
|
60
58
|
data[]
|
|
61
59
|
end
|
|
62
60
|
end
|
|
@@ -65,40 +63,38 @@ module ConcurrencyHelper
|
|
|
65
63
|
Thread.abort_on_exception = abort_on_exception
|
|
66
64
|
end
|
|
67
65
|
|
|
68
|
-
def push(
|
|
69
|
-
@queue.push(
|
|
66
|
+
def push(&task)
|
|
67
|
+
@queue.push(task)
|
|
70
68
|
end
|
|
71
69
|
|
|
72
70
|
def join
|
|
73
71
|
@threads.each do
|
|
74
|
-
@queue.push(
|
|
72
|
+
@queue.push(:stop)
|
|
75
73
|
end
|
|
76
74
|
|
|
77
|
-
@threads.each(
|
|
75
|
+
@threads.each(&:join)
|
|
78
76
|
end
|
|
79
|
-
|
|
80
77
|
end
|
|
81
78
|
|
|
82
|
-
def self.with_parallel_queue(
|
|
83
|
-
instances = options[
|
|
84
|
-
abort_on_exception = options[
|
|
79
|
+
def self.with_parallel_queue(slots, options={})
|
|
80
|
+
instances = options[:instances]
|
|
81
|
+
abort_on_exception = options[:abort_on_exception]
|
|
85
82
|
|
|
86
|
-
queue = ParallelWorkersQueue.new(
|
|
83
|
+
queue = ParallelWorkersQueue.new(slots, :abort_on_exception => abort_on_exception)
|
|
87
84
|
semaphore = Mutex.new
|
|
88
85
|
|
|
89
86
|
if instances
|
|
90
|
-
instances.each do |
|
|
91
|
-
proc = yield(
|
|
87
|
+
instances.each do |instance|
|
|
88
|
+
proc = yield(instance, semaphore)
|
|
92
89
|
|
|
93
|
-
raise "The value returned is not a Proc!" unless proc.is_a?(
|
|
90
|
+
raise "The value returned is not a Proc!" unless proc.is_a?(Proc)
|
|
94
91
|
|
|
95
|
-
queue.push(
|
|
92
|
+
queue.push(&proc)
|
|
96
93
|
end
|
|
97
94
|
else
|
|
98
|
-
yield(
|
|
95
|
+
yield(queue, semaphore)
|
|
99
96
|
end
|
|
100
97
|
|
|
101
98
|
queue.join
|
|
102
99
|
end
|
|
103
|
-
|
|
104
100
|
end
|
|
@@ -19,19 +19,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
19
19
|
=end
|
|
20
20
|
|
|
21
21
|
module ConfigurationHelper
|
|
22
|
-
|
|
23
22
|
require 'rubygems'
|
|
24
23
|
require 'parseconfig'
|
|
25
24
|
require 'openssl'
|
|
26
25
|
require 'base64'
|
|
27
26
|
|
|
28
|
-
CONFIGURATION_FILE = File.expand_path(
|
|
29
|
-
PASSWORD_KEY_FILE = File.expand_path(
|
|
27
|
+
CONFIGURATION_FILE = File.expand_path('.sav_scripts', '~')
|
|
28
|
+
PASSWORD_KEY_FILE = File.expand_path('.sav_scripts_key', '~')
|
|
30
29
|
|
|
31
30
|
# The encryption is intentionally weak.
|
|
32
31
|
#
|
|
33
32
|
PASSWORD_CIPHER = 'des'
|
|
34
|
-
PASSWORD_KEY = IO.read(
|
|
33
|
+
PASSWORD_KEY = IO.read(PASSWORD_KEY_FILE).chomp
|
|
35
34
|
|
|
36
35
|
# Loads the configuration from a file, for a given group.
|
|
37
36
|
#
|
|
@@ -43,29 +42,29 @@ module ConfigurationHelper
|
|
|
43
42
|
# :sym_keys keys as symbols
|
|
44
43
|
# :file configuration filename
|
|
45
44
|
#
|
|
46
|
-
def self.load_configuration(
|
|
45
|
+
def self.load_configuration(options={})
|
|
47
46
|
$stderr.puts ">>> MIGRATE TO SIMPLE_SCRIPTING::CONFIG!"
|
|
48
47
|
|
|
49
|
-
raise "Change argument to :group if needed (when the filename is different from the group)" if options.is_a?(
|
|
48
|
+
raise "Change argument to :group if needed (when the filename is different from the group)" if options.is_a?(String)
|
|
50
49
|
|
|
51
|
-
group = options[
|
|
52
|
-
sym_keys = options[
|
|
53
|
-
configuration_file = options[
|
|
50
|
+
group = options[:group] || File.basename($0).chomp('.rb')
|
|
51
|
+
sym_keys = options[:sym_keys]
|
|
52
|
+
configuration_file = options[:file] || CONFIGURATION_FILE
|
|
54
53
|
|
|
55
|
-
configuration = ParseConfig.new(
|
|
54
|
+
configuration = ParseConfig.new(configuration_file)[group]
|
|
56
55
|
|
|
57
|
-
raise "Group not found in configuration: #{
|
|
56
|
+
raise "Group not found in configuration: #{group}" if configuration.nil?
|
|
58
57
|
|
|
59
|
-
if configuration[
|
|
60
|
-
configuration[
|
|
58
|
+
if configuration['password']
|
|
59
|
+
configuration['password'] = decrypt(configuration['password'], PASSWORD_KEY, PASSWORD_CIPHER, :base_64_decoding => true)
|
|
61
60
|
end
|
|
62
61
|
|
|
63
62
|
|
|
64
|
-
configuration = Hash[
|
|
63
|
+
configuration = Hash[configuration.map{ |key, value| [key.to_sym, value] }] if sym_keys
|
|
65
64
|
|
|
66
|
-
def configuration.path(
|
|
67
|
-
raw_value = self[
|
|
68
|
-
raw_value.start_with?(
|
|
65
|
+
def configuration.path(key)
|
|
66
|
+
raw_value = self[key]
|
|
67
|
+
raw_value.start_with?('/') ? raw_value : File.expand_path(raw_value, '~')
|
|
69
68
|
end
|
|
70
69
|
|
|
71
70
|
configuration
|
|
@@ -75,11 +74,11 @@ module ConfigurationHelper
|
|
|
75
74
|
#
|
|
76
75
|
# Returns a String when querying only one key, otherwise an Array.
|
|
77
76
|
#
|
|
78
|
-
def self.load_configuration_values(
|
|
77
|
+
def self.load_configuration_values(*keys)
|
|
79
78
|
configuration = load_configuration
|
|
80
79
|
|
|
81
|
-
values = keys.inject(
|
|
82
|
-
current_values << configuration[
|
|
80
|
+
values = keys.inject([]) do |current_values, key|
|
|
81
|
+
current_values << configuration[key]
|
|
83
82
|
end
|
|
84
83
|
|
|
85
84
|
if values.size == 1
|
|
@@ -89,10 +88,10 @@ module ConfigurationHelper
|
|
|
89
88
|
end
|
|
90
89
|
end
|
|
91
90
|
|
|
92
|
-
def self.encrypt(
|
|
93
|
-
base_64_encoding = !!
|
|
91
|
+
def self.encrypt(plaintext, key, algo, options={})
|
|
92
|
+
base_64_encoding = !!options[:base_64_encoding]
|
|
94
93
|
|
|
95
|
-
cipher = OpenSSL::Cipher::Cipher.new(
|
|
94
|
+
cipher = OpenSSL::Cipher::Cipher.new(algo)
|
|
96
95
|
cipher.encrypt
|
|
97
96
|
|
|
98
97
|
iv = cipher.random_iv
|
|
@@ -100,29 +99,28 @@ module ConfigurationHelper
|
|
|
100
99
|
cipher.key = key
|
|
101
100
|
cipher.iv = iv
|
|
102
101
|
|
|
103
|
-
ciphertext = iv + cipher.update(
|
|
102
|
+
ciphertext = iv + cipher.update(plaintext) + cipher.final
|
|
104
103
|
|
|
105
|
-
ciphertext = Base64.encode64(
|
|
104
|
+
ciphertext = Base64.encode64(ciphertext) if base_64_encoding
|
|
106
105
|
|
|
107
106
|
ciphertext
|
|
108
107
|
end
|
|
109
108
|
|
|
110
|
-
def self.decrypt(
|
|
109
|
+
def self.decrypt(ciphertext, key, algo, options={})
|
|
111
110
|
puts ">>> ConfigurationHelper.decrypt should have key and algo as options"
|
|
112
111
|
|
|
113
|
-
base_64_decoding = !!
|
|
112
|
+
base_64_decoding = !!options[:base_64_decoding]
|
|
114
113
|
|
|
115
|
-
ciphertext = Base64.decode64(
|
|
114
|
+
ciphertext = Base64.decode64(ciphertext) if base_64_decoding
|
|
116
115
|
|
|
117
|
-
cipher = OpenSSL::Cipher::Cipher.new(
|
|
116
|
+
cipher = OpenSSL::Cipher::Cipher.new(algo)
|
|
118
117
|
cipher.decrypt
|
|
119
118
|
|
|
120
119
|
cipher.key = key
|
|
121
120
|
|
|
122
|
-
cipher.iv = ciphertext.slice!(
|
|
123
|
-
plaintext = cipher.update(
|
|
121
|
+
cipher.iv = ciphertext.slice!(0, cipher.iv_len)
|
|
122
|
+
plaintext = cipher.update(ciphertext) + cipher.final
|
|
124
123
|
|
|
125
124
|
plaintext
|
|
126
125
|
end
|
|
127
|
-
|
|
128
126
|
end
|
data/lib/sapis/desktop_helper.rb
CHANGED
|
@@ -24,27 +24,25 @@ require 'shellwords'
|
|
|
24
24
|
module DesktopHelper
|
|
25
25
|
CLIPBOARD_COMMAND = "xi"
|
|
26
26
|
|
|
27
|
-
def set_clipboard_text(
|
|
28
|
-
IO.popen(CLIPBOARD_COMMAND, 'w'
|
|
27
|
+
def set_clipboard_text(text)
|
|
28
|
+
IO.popen(CLIPBOARD_COMMAND, 'w') { |io| io << text }
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# Displays an OK/Cancel dialog.
|
|
32
32
|
#
|
|
33
33
|
# Returns true for OK, false for Cancel/Esc.
|
|
34
34
|
#
|
|
35
|
-
def display_dialog(
|
|
36
|
-
quoted_text = '"' + text.gsub(
|
|
35
|
+
def display_dialog(text)
|
|
36
|
+
quoted_text = '"' + text.gsub('"', '\"').gsub("'", "'\\\\''") + '"'
|
|
37
37
|
|
|
38
38
|
if SystemHelper.mac?
|
|
39
|
-
`osascript -e 'tell app "System Events" to display dialog #{
|
|
39
|
+
`osascript -e 'tell app "System Events" to display dialog #{quoted_text}'`.strip == 'button returned:OK'
|
|
40
40
|
else
|
|
41
|
-
system(
|
|
41
|
+
system("zenity --question --text=#{quoted_text}")
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def desktop_notification(text)
|
|
46
46
|
`notify-send #{text.shellescape}`
|
|
47
47
|
end
|
|
48
|
-
|
|
49
48
|
end
|
|
50
|
-
|
data/lib/sapis/generic_helper.rb
CHANGED
|
@@ -23,7 +23,7 @@ require 'date'
|
|
|
23
23
|
module GenericHelper
|
|
24
24
|
def self.do_retry(options={}, &block)
|
|
25
25
|
max_retries = options[:max_retries] || 3
|
|
26
|
-
sleep_interval = options[:sleep
|
|
26
|
+
sleep_interval = options[:sleep] || 0
|
|
27
27
|
|
|
28
28
|
current_retries = 0
|
|
29
29
|
|
|
@@ -47,7 +47,7 @@ module GenericHelper
|
|
|
47
47
|
buffer = ""
|
|
48
48
|
capitalize_next = true
|
|
49
49
|
|
|
50
|
-
string.chars.each do |
|
|
50
|
+
string.chars.each do |char|
|
|
51
51
|
if char == '_'
|
|
52
52
|
capitalize_next = true
|
|
53
53
|
elsif capitalize_next
|
|
@@ -118,7 +118,7 @@ module GenericHelper
|
|
|
118
118
|
when /^-(\d+)$/
|
|
119
119
|
Date.today - $1.to_i
|
|
120
120
|
else
|
|
121
|
-
raise "Unrecognized date: #{
|
|
121
|
+
raise "Unrecognized date: #{encoded_date}"
|
|
122
122
|
end
|
|
123
123
|
end
|
|
124
124
|
|
|
@@ -162,7 +162,7 @@ module GenericHelper
|
|
|
162
162
|
daytime.unshift(current_token)
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
-
raise "Wrong start year format. Non-consumed tokens: #{
|
|
165
|
+
raise "Wrong start year format. Non-consumed tokens: #{daytime}" if base_day.nil?
|
|
166
166
|
|
|
167
167
|
current_token = daytime.shift
|
|
168
168
|
|
|
@@ -187,7 +187,7 @@ module GenericHelper
|
|
|
187
187
|
daytime.unshift(current_token)
|
|
188
188
|
end
|
|
189
189
|
|
|
190
|
-
raise "Wrong start daytime format. Non-consumed tokens: #{
|
|
190
|
+
raise "Wrong start daytime format. Non-consumed tokens: #{daytime}" if start_daytime.nil?
|
|
191
191
|
|
|
192
192
|
current_token = daytime.shift
|
|
193
193
|
|
|
@@ -223,9 +223,9 @@ module GenericHelper
|
|
|
223
223
|
end_daytime = add_days(start_daytime, 1)
|
|
224
224
|
end
|
|
225
225
|
|
|
226
|
-
raise "Wrong end daytime format. Non-consumed tokens: #{
|
|
226
|
+
raise "Wrong end daytime format. Non-consumed tokens: #{daytime}" if end_daytime.nil?
|
|
227
227
|
|
|
228
|
-
raise "Non-consumed tokens found: #{
|
|
228
|
+
raise "Non-consumed tokens found: #{daytime}" if daytime.size > 0
|
|
229
229
|
|
|
230
230
|
[start_daytime, end_daytime, all_day]
|
|
231
231
|
end
|
data/lib/sapis/gnome_helper.rb
CHANGED
|
@@ -21,16 +21,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
21
21
|
require_relative 'bash_helper'
|
|
22
22
|
|
|
23
23
|
module GnomeHelper
|
|
24
|
-
|
|
25
24
|
include BashHelper
|
|
26
25
|
|
|
27
|
-
def set_gnome_background(
|
|
26
|
+
def set_gnome_background(pic_path)
|
|
28
27
|
simple_bash_execute "gconftool -t string -s /desktop/gnome/background/picture_filename", pic_path
|
|
29
28
|
end
|
|
30
29
|
|
|
31
30
|
def get_gnome_background_filename
|
|
32
31
|
simple_bash_execute "gconftool -g /desktop/gnome/background/picture_filename"
|
|
33
32
|
end
|
|
34
|
-
|
|
35
33
|
end
|
|
36
|
-
|