shh 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE CHANGED
@@ -1,20 +1,20 @@
1
- Copyright (c) 2009 Mark Ryall
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2009 Mark Ryall
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc CHANGED
@@ -1,96 +1,96 @@
1
- = SHH
2
-
3
- Secret Squirrel
4
-
5
- This is a command line utility for managing secure information such as accounts, passwords as individual files so that they can be easily managed in a version control repository.
6
-
7
- You won't be hiding anything from the NSA with this level of encryption so it isn't recommended that you make your repository publicly accessible.
8
-
9
- Now with more tab completion!
10
-
11
- = Usage
12
-
13
- Here you sit expectantly in front of a computer at the command line.
14
-
15
- == Install
16
-
17
- gem install shh
18
-
19
- (you may need to install gemcutter first)
20
-
21
- == Launch
22
-
23
- Open all 'secrets' stored in ~/.secret
24
-
25
- > shh
26
-
27
- Opens all 'secrets' stored in foo/.secret
28
-
29
- > shh foo
30
-
31
- == Authenticate
32
-
33
- Enter your passphrase
34
-
35
- This passphrase will be used to encrypt and decrypt all of your secrets so don't make it too obvious.
36
-
37
- == Listing mode
38
-
39
- This mode allows you to view and edit 'entries' (which are encrypted hashes stored in files)
40
-
41
- > list
42
-
43
- bitbucket (260f34de-6779-4367-af2a-44184dec1cc1)
44
- amazon (291a3e6c-2c7b-4960-a146-1f6635d9a74e)
45
- yahoo (2fe408e7-7f2b-4dc0-854a-c92c21f131ae)
46
- evernote (41ad0a21-eafc-4f70-9b0d-0251be207b9e)
47
- gmail (8b35c1f2-851d-40fc-bd12-c2aad12c370a)
48
- rememberthemilk (a499f612-d034-4e49-82a8-6967d29653a1)
49
-
50
- * list - show entries
51
- * edit <name> - edit or create entry
52
- * view <name> - view entry
53
- * quit
54
-
55
- == Viewing mode
56
-
57
- This mode allows you to view (but not edit) an existing entry
58
-
59
- > view bitbucket
60
- (bitbucket) > list
61
- id,name,password,username
62
- (bitbucket) > show username
63
- markryall
64
-
65
- list keys, show key, copy key or quit? c password
66
-
67
- * list - show entry keys
68
- * show <key> - show entry value on screen
69
- * copy <key> - copy entry value to clipboard
70
- * quit
71
-
72
- == Editing mode
73
-
74
- This mode is viewing mode plus some editing commands
75
-
76
- > edit bitbucket
77
- (bitbucket) > edit foo
78
- Enter new value for foo
79
- bar
80
- (bitbucket) > delete foo
81
-
82
- * edit <key> - edit or create key
83
- * delete <key> - remove a key
84
-
85
- == Quitting mode
86
-
87
- You don't want to be a quitter
88
-
89
- = Future plans for world domination
90
-
91
- * Add some color
92
- * Add help
93
- * Launch applications for urls
94
- * Add multi line values (edit with default text editor)
95
- * Include uuid as part of encryption key (and upgrade encryption on existing entries)
1
+ = SHH
2
+
3
+ Secret Squirrel
4
+
5
+ This is a command line utility for managing secure information such as accounts, passwords as individual files so that they can be easily managed in a version control repository.
6
+
7
+ You won't be hiding anything from the NSA with this level of encryption so it isn't recommended that you make your repository publicly accessible.
8
+
9
+ Now with more tab completion!
10
+
11
+ = Usage
12
+
13
+ Here you sit expectantly in front of a computer at the command line.
14
+
15
+ == Install
16
+
17
+ gem install shh
18
+
19
+ (you may need to install gemcutter first)
20
+
21
+ == Launch
22
+
23
+ Open all 'secrets' stored in ~/.secret
24
+
25
+ > shh
26
+
27
+ Opens all 'secrets' stored in foo/.secret
28
+
29
+ > shh foo
30
+
31
+ == Authenticate
32
+
33
+ Enter your passphrase
34
+
35
+ This passphrase will be used to encrypt and decrypt all of your secrets so don't make it too obvious.
36
+
37
+ == Listing mode
38
+
39
+ This mode allows you to view and edit 'entries' (which are encrypted hashes stored in files)
40
+
41
+ > list
42
+
43
+ bitbucket (260f34de-6779-4367-af2a-44184dec1cc1)
44
+ amazon (291a3e6c-2c7b-4960-a146-1f6635d9a74e)
45
+ yahoo (2fe408e7-7f2b-4dc0-854a-c92c21f131ae)
46
+ evernote (41ad0a21-eafc-4f70-9b0d-0251be207b9e)
47
+ gmail (8b35c1f2-851d-40fc-bd12-c2aad12c370a)
48
+ rememberthemilk (a499f612-d034-4e49-82a8-6967d29653a1)
49
+
50
+ * list - list entries
51
+ * edit,<name> - edit or create entry
52
+ * view,<name> - view entry
53
+ * quit
54
+
55
+ == Viewing mode
56
+
57
+ This mode allows you to view (but not edit) an existing entry
58
+
59
+ > view,bitbucket
60
+ (bitbucket) > list
61
+ id,name,password,username
62
+ (bitbucket) > view,username
63
+ markryall
64
+
65
+ list keys, show key, copy key or quit? c password
66
+
67
+ * list - show entry keys
68
+ * view,<key> - view entry value on screen
69
+ * copy,<key> - copy entry value to clipboard
70
+ * launch,<key> - launch entry value in default browser (available if it starts with http)
71
+ * quit
72
+
73
+ == Editing mode
74
+
75
+ This mode is viewing mode plus some editing commands
76
+
77
+ > edit,bitbucket
78
+ (bitbucket) > edit,foo
79
+ Enter new value for foo
80
+ bar
81
+ (bitbucket) > delete,foo
82
+
83
+ * edit,<key> - edit or create key
84
+ * delete,<key> - remove a key
85
+
86
+ == Quitting mode
87
+
88
+ You don't want to be a quitter
89
+
90
+ = Future plans for world domination
91
+
92
+ * Add some color
93
+ * Add help
94
+ * Add multi line values (edit with default text editor)
95
+ * Include uuid as part of encryption key (and upgrade encryption on existing entries)
96
96
  * add some source control (hg/git) commands
data/bin/shh CHANGED
@@ -1,5 +1,5 @@
1
- #!/usr/bin/env ruby
2
-
3
- $:.unshift File.dirname(__FILE__)+'/../lib'
4
- require 'shh/cli'
5
- Shh::Cli.execute(*ARGV)
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.dirname(__FILE__)+'/../lib'
4
+ require 'shh/cli'
5
+ Shh::Cli.execute(*ARGV)
data/lib/shh/cli.rb CHANGED
@@ -1,16 +1,16 @@
1
- require 'rubygems'
2
- require 'shh/repository'
3
- require 'shh/prompt'
4
- require 'shh/entries_menu'
5
-
6
- module Shh
7
- class Cli
8
- def self.execute *args
9
- prompt = Prompt.new
10
- passphrase = prompt.get('Enter your passphrase', :silent => true)
11
- path = args.shift || ('~')
12
-
13
- EntriesMenu.new(prompt, Repository.new(passphrase, path)).main_loop
14
- end
15
- end
16
- end
1
+ require 'rubygems'
2
+ require 'shh/repository'
3
+ require 'shh/prompt'
4
+ require 'shh/entries_menu'
5
+
6
+ module Shh
7
+ class Cli
8
+ def self.execute *args
9
+ prompt = Prompt.new
10
+ passphrase = prompt.get('Enter your passphrase', :silent => true)
11
+ path = args.shift || ('~')
12
+
13
+ EntriesMenu.new(prompt, Repository.new(passphrase, path)).main_loop
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ module Shh
2
+ def self.clipboard
3
+ if RUBY_PLATFORM =~ /mswin32/
4
+ require 'shh/win32_clipboard'
5
+ return Win32Clipboard.new
6
+ end
7
+ if RUBY_PLATFORM =~ /darwin10/
8
+ require 'shh/darwin10_clipboard'
9
+ return Darwin10Clipboard.new
10
+ end
11
+ nil
12
+ end
13
+ end
data/lib/shh/crypt.rb CHANGED
@@ -1,25 +1,25 @@
1
- require 'crypt/blowfish'
2
-
3
- module Shh
4
- class Crypt
5
- def initialize passphrase
6
- @blowfish = ::Crypt::Blowfish.new(passphrase)
7
- end
8
-
9
- def encrypt text, out_io
10
- in_io = StringIO.new(text)
11
- while l = in_io.read(8) do
12
- while l.size < 8 do l += "\0" end
13
- out_io.print @blowfish.encrypt_block(l)
14
- end
15
- end
16
-
17
- def decrypt in_io
18
- out_io = StringIO.new
19
- while l = in_io.read(8) do
20
- out_io.print @blowfish.decrypt_block(l)
21
- end
22
- out_io.string.gsub("\0",'')
23
- end
24
- end
1
+ require 'crypt/blowfish'
2
+
3
+ module Shh
4
+ class Crypt
5
+ def initialize passphrase
6
+ @blowfish = ::Crypt::Blowfish.new(passphrase)
7
+ end
8
+
9
+ def encrypt text, out_io
10
+ in_io = StringIO.new(text)
11
+ while l = in_io.read(8) do
12
+ while l.size < 8 do l += "\0" end
13
+ out_io.print @blowfish.encrypt_block(l)
14
+ end
15
+ end
16
+
17
+ def decrypt in_io
18
+ out_io = StringIO.new
19
+ while l = in_io.read(8) do
20
+ out_io.print @blowfish.decrypt_block(l)
21
+ end
22
+ out_io.string.gsub("\0",'')
23
+ end
24
+ end
25
25
  end
@@ -1,5 +1,5 @@
1
- class Darwin10Clipboard
2
- def content= text
3
- `echo "#{text}" | pbcopy`
4
- end
1
+ class Darwin10Clipboard
2
+ def content= text
3
+ `echo "#{text}" | pbcopy`
4
+ end
5
5
  end
@@ -1,5 +1,5 @@
1
- class Darwin10Launcher
2
- def launch text
3
- `open #{text}`
4
- end
5
- end
1
+ class Darwin10Launcher
2
+ def launch text
3
+ `open #{text}`
4
+ end
5
+ end
@@ -1,64 +1,63 @@
1
- require 'uuidtools'
2
- require 'readline'
3
- require 'shh/entry_menu'
4
-
5
- module Shh
6
- class EntriesMenu
7
- def initialize prompt, repository
8
- @prompt, @repository = prompt, repository
9
- refresh
10
- end
11
-
12
- def main_loop
13
- prompt_text = 'shh > '
14
-
15
- begin
16
- while line = Readline.readline(prompt_text, true)
17
- line.strip!
18
- case line
19
- when 'quit'
20
- break
21
- when 'refresh'
22
- refresh
23
- when 'list'
24
- @entries.each {|entry| say entry }
25
- when /^view (.*)/
26
- view $1
27
- when /^edit (.*)/
28
- edit $1
29
- end
30
- puts
31
- end
32
- rescue Interrupt => e
33
- exit
34
- end
35
- puts
36
- end
37
-
38
- def refresh
39
- commands = ['list', 'refresh', 'quit']
40
- @entries = []
41
- @repository.each_entry do |entry|
42
- @entries << "#{entry['name']} (#{entry['id']})"
43
- commands << "edit #{entry['name']}"
44
- commands << "view #{entry['name']}"
45
- end
46
- Readline.completion_proc = lambda do |text|
47
- commands.grep( /^#{Regexp.escape(text)}/ ).sort
48
- end
49
- Readline.completer_word_break_characters = ''
50
- end
51
-
52
- def edit name
53
- entry = @repository.find_entry(name)
54
- entry ||= {'name' => name, 'id' => UUIDTools::UUID.random_create.to_s}
55
- @repository.persist_entry EntryMenu.new(@prompt, entry).main_loop
56
- refresh
57
- end
58
-
59
- def view name
60
- EntryMenu.new(@prompt, @repository.find_entry(name), true).main_loop
61
- refresh
62
- end
63
- end
64
- end
1
+ require 'uuidtools'
2
+ require 'readline'
3
+ require 'shh/entry_menu'
4
+
5
+ module Shh
6
+ class EntriesMenu
7
+ def initialize prompt, repository
8
+ @prompt, @repository = prompt, repository
9
+ refresh
10
+ end
11
+
12
+ def main_loop
13
+ prompt_text = 'shh > '
14
+
15
+ begin
16
+ while line = Readline.readline(prompt_text, true)
17
+ line.strip!
18
+ case line
19
+ when 'quit'
20
+ return
21
+ when 'refresh'
22
+ refresh
23
+ when 'list'
24
+ @entries.sort.each {|entry| say entry }
25
+ when /^view,(.*)/
26
+ view $1
27
+ when /^edit,(.*)/
28
+ edit $1
29
+ end
30
+ puts
31
+ end
32
+ rescue Interrupt => e
33
+ exit
34
+ end
35
+ puts
36
+ end
37
+
38
+ def refresh
39
+ commands = ['list', 'refresh', 'quit']
40
+ @entries = []
41
+ @repository.each_entry do |entry|
42
+ @entries << "#{entry['name']} (#{entry['id']})"
43
+ commands << "edit,#{entry['name']}"
44
+ commands << "view,#{entry['name']}"
45
+ end
46
+ Readline.completion_proc = lambda do |text|
47
+ commands.grep( /^#{Regexp.escape(text)}/ ).sort
48
+ end
49
+ end
50
+
51
+ def edit name
52
+ entry = @repository.find_entry(name)
53
+ entry ||= {'name' => name, 'id' => UUIDTools::UUID.random_create.to_s}
54
+ @repository.persist_entry EntryMenu.new(@prompt, entry).main_loop
55
+ refresh
56
+ end
57
+
58
+ def view name
59
+ EntryMenu.new(@prompt, @repository.find_entry(name), true).main_loop
60
+ refresh
61
+ end
62
+ end
63
+ end
@@ -1,102 +1,101 @@
1
- require 'shh'
2
-
3
- module Shh
4
- class EntryMenu
5
- def initialize prompt, hash, read_only=false
6
- @prompt, @hash, @read_only = prompt, hash, read_only
7
- @clipboard = Shh.clipboard
8
- @launcher = Shh.launcher
9
- refresh
10
- end
11
-
12
- def main_loop
13
- prompt_text = "shh:#{@hash['name']} > "
14
-
15
- begin
16
- while line = Readline.readline(prompt_text, true)
17
- line.strip!
18
- case line
19
- when 'quit'
20
- break
21
- when 'list'
22
- say(@hash.keys.sort.join(','))
23
- when /^edit (.*)/
24
- edit $1
25
- when /^copy (.*)/
26
- copy $1
27
- when /^launch (.*)/
28
- launch $1
29
- when /^delete (.*)/
30
- delete $1
31
- when /^show (.*)/
32
- show $1
33
- end
34
- end
35
- rescue Interrupt => e
36
- exit
37
- end
38
-
39
- puts
40
- @hash
41
- end
42
-
43
- private
44
-
45
- def can_copy? key
46
- @clipboard and @hash[key]
47
- end
48
-
49
- def can_edit?
50
- !@read_only
51
- end
52
-
53
- def can_launch? key
54
- @launcher and @hash[key] =~ /^http\:\/\//
55
- end
56
-
57
- def show key
58
- say(@hash[key]) if @hash[key]
59
- end
60
-
61
- def copy key
62
- @clipboard.content = @hash[key] if can_copy?(key)
63
- end
64
-
65
- def edit key
66
- if can_edit?
67
- @hash[key] = new_value(key)
68
- refresh
69
- end
70
- end
71
-
72
- def delete key
73
- if can_edit?
74
- @hash.delete(key)
75
- refresh
76
- end
77
- end
78
-
79
- def launch key
80
- @launcher.launch @hash[key] if can_launch?(key)
81
- end
82
-
83
- def refresh
84
- commands = ['list', 'quit']
85
- @hash.keys.each do |key|
86
- commands << "edit #{key}" if can_edit?
87
- commands << "delete #{key}" if can_edit?
88
- commands << "show #{key}"
89
- commands << "copy #{key}" if can_copy?(key)
90
- commands << "launch #{key}" if can_launch?(key)
91
- end
92
- Readline.completion_proc = lambda do |text|
93
- commands.grep( /^#{Regexp.escape(text)}/ ).sort
94
- end
95
- Readline.completer_word_break_characters = ''
96
- end
97
-
98
- def new_value key
99
- @prompt.get "Enter new value for #{key}", :silent => (key =~ /pass/)
100
- end
101
- end
102
- end
1
+ require 'shh'
2
+
3
+ module Shh
4
+ class EntryMenu
5
+ def initialize prompt, hash, read_only=false
6
+ @prompt, @hash, @read_only = prompt, hash, read_only
7
+ @clipboard = Shh.clipboard
8
+ @launcher = Shh.launcher
9
+ refresh
10
+ end
11
+
12
+ def main_loop
13
+ prompt_text = "shh:#{@hash['name']} > "
14
+
15
+ begin
16
+ while line = Readline.readline(prompt_text, true)
17
+ line.strip!
18
+ case line
19
+ when 'quit'
20
+ return @hash
21
+ when 'list'
22
+ say(@hash.keys.sort.join(','))
23
+ when /^edit,(.*)/
24
+ edit $1
25
+ when /^copy,(.*)/
26
+ copy $1
27
+ when /^launch,(.*)/
28
+ launch $1
29
+ when /^delete,(.*)/
30
+ delete $1
31
+ when /^view,(.*)/
32
+ view $1
33
+ end
34
+ end
35
+ rescue Interrupt => e
36
+ exit
37
+ end
38
+
39
+ puts
40
+ @hash
41
+ end
42
+
43
+ private
44
+
45
+ def can_copy? key
46
+ @clipboard and @hash[key]
47
+ end
48
+
49
+ def can_edit?
50
+ !@read_only
51
+ end
52
+
53
+ def can_launch? key
54
+ @launcher and @hash[key] =~ /^http/
55
+ end
56
+
57
+ def view key
58
+ say(@hash[key]) if @hash[key]
59
+ end
60
+
61
+ def copy key
62
+ @clipboard.content = @hash[key] if can_copy?(key)
63
+ end
64
+
65
+ def edit key
66
+ if can_edit?
67
+ @hash[key] = new_value(key)
68
+ refresh
69
+ end
70
+ end
71
+
72
+ def delete key
73
+ if can_edit?
74
+ @hash.delete(key)
75
+ refresh
76
+ end
77
+ end
78
+
79
+ def launch key
80
+ @launcher.launch @hash[key] if can_launch?(key)
81
+ end
82
+
83
+ def refresh
84
+ commands = ['list', 'quit']
85
+ @hash.keys.each do |key|
86
+ commands << "edit,#{key}" if can_edit?
87
+ commands << "delete,#{key}" if can_edit?
88
+ commands << "view,#{key}"
89
+ commands << "copy,#{key}" if can_copy?(key)
90
+ commands << "launch,#{key}" if can_launch?(key)
91
+ end
92
+ Readline.completion_proc = lambda do |text|
93
+ commands.grep( /^#{Regexp.escape(text)}/ ).sort
94
+ end
95
+ end
96
+
97
+ def new_value key
98
+ @prompt.get "Enter new value for #{key}", :silent => (key =~ /pass/)
99
+ end
100
+ end
101
+ end
data/lib/shh/prompt.rb CHANGED
@@ -1,11 +1,11 @@
1
- require 'highline/import'
2
-
3
- module Shh
4
- class Prompt
5
- def get text, params={}
6
- return params[:value] if params[:value] and params[:value].size > 0
7
- echo = params[:silent] ? false : true
8
- ask(text) { |q| q.echo = echo }
9
- end
10
- end
1
+ require 'highline/import'
2
+
3
+ module Shh
4
+ class Prompt
5
+ def get text, params={}
6
+ return params[:value] if params[:value] and params[:value].size > 0
7
+ echo = params[:silent] ? false : true
8
+ ask(text) { |q| q.echo = echo }
9
+ end
10
+ end
11
11
  end
@@ -1,39 +1,39 @@
1
- require 'pathname2'
2
- require 'yaml'
3
- require 'shh/crypt'
4
-
5
- module Shh
6
- class Repository
7
- attr_reader :folder
8
-
9
- def initialize passphrase, path
10
- @folder = Pathname.new(File.expand_path(path)) + '.secret'
11
- @folder.mkdir_p
12
- @crypt = Crypt.new(passphrase)
13
- end
14
-
15
- def each_entry
16
- @folder.children.each do |child|
17
- entry = load_entry(child)
18
- yield entry if entry
19
- end
20
- end
21
-
22
- def find_entry name
23
- each_entry {|e| return e if e['name'] == name}
24
- nil
25
- end
26
-
27
- def load_entry path
28
- return nil if path.directory?
29
- yaml = path.open('rb') {|io| @crypt.decrypt(io) }
30
- entry = YAML::load(yaml)
31
- return nil unless entry
32
- path.basename.to_s == entry['id'] ? entry : nil
33
- end
34
-
35
- def persist_entry entry
36
- (@folder + entry['id']).open('wb') {|io| @crypt.encrypt(entry.to_yaml, io) }
37
- end
38
- end
39
- end
1
+ require 'pathname2'
2
+ require 'yaml'
3
+ require 'shh/crypt'
4
+
5
+ module Shh
6
+ class Repository
7
+ attr_reader :folder
8
+
9
+ def initialize passphrase, path
10
+ @folder = Pathname.new(File.expand_path(path)) + '.secret'
11
+ @folder.mkdir_p
12
+ @crypt = Crypt.new(passphrase)
13
+ end
14
+
15
+ def each_entry
16
+ @folder.children.each do |child|
17
+ entry = load_entry(child)
18
+ yield entry if entry
19
+ end
20
+ end
21
+
22
+ def find_entry name
23
+ each_entry {|e| return e if e['name'] == name}
24
+ nil
25
+ end
26
+
27
+ def load_entry path
28
+ return nil if path.directory?
29
+ yaml = path.open('rb') {|io| @crypt.decrypt(io) }
30
+ entry = YAML::load(yaml)
31
+ return nil unless entry
32
+ path.basename.to_s == entry['id'] ? entry : nil
33
+ end
34
+
35
+ def persist_entry entry
36
+ (@folder + entry['id']).open('wb') {|io| @crypt.encrypt(entry.to_yaml, io) }
37
+ end
38
+ end
39
+ end
@@ -1,7 +1,7 @@
1
- require 'win32/clipboard'
2
-
3
- class Win32Clipboard
4
- def content= text
5
- Win32::Clipboard.set_data(text)
6
- end
1
+ require 'win32/clipboard'
2
+
3
+ class Win32Clipboard
4
+ def content= text
5
+ Win32::Clipboard.set_data(text)
6
+ end
7
7
  end
@@ -1,5 +1,5 @@
1
- class Win32Launcher
2
- def launch text
3
- `start #{text}`
4
- end
5
- end
1
+ class Win32Launcher
2
+ def launch text
3
+ `start #{text}`
4
+ end
5
+ end
data/lib/shh.rb CHANGED
@@ -1,25 +1,25 @@
1
- module Shh
2
- def self.clipboard
3
- if RUBY_PLATFORM =~ /mswin32/
4
- require 'shh/win32_clipboard'
5
- return Win32Clipboard.new
6
- end
7
- if RUBY_PLATFORM =~ /darwin10/
8
- require 'shh/darwin10_clipboard'
9
- return Darwin10Clipboard.new
10
- end
11
- nil
12
- end
13
-
14
- def self.launcher
15
- if RUBY_PLATFORM =~ /mswin32/
16
- require 'shh/win32_launcher'
17
- return Win32Launcher.new
18
- end
19
- if RUBY_PLATFORM =~ /darwin10/
20
- require 'shh/darwin10_launcher'
21
- return Darwin10Launcher.new
22
- end
23
- nil
24
- end
25
- end
1
+ module Shh
2
+ def self.clipboard
3
+ if RUBY_PLATFORM =~ /mswin32/
4
+ require 'shh/win32_clipboard'
5
+ return Win32Clipboard.new
6
+ end
7
+ if RUBY_PLATFORM =~ /darwin10/
8
+ require 'shh/darwin10_clipboard'
9
+ return Darwin10Clipboard.new
10
+ end
11
+ nil
12
+ end
13
+
14
+ def self.launcher
15
+ if RUBY_PLATFORM =~ /mswin32/
16
+ require 'shh/win32_launcher'
17
+ return Win32Launcher.new
18
+ end
19
+ if RUBY_PLATFORM =~ /darwin10/
20
+ require 'shh/darwin10_launcher'
21
+ return Darwin10Launcher.new
22
+ end
23
+ nil
24
+ end
25
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Ryall
@@ -64,6 +64,7 @@ extra_rdoc_files: []
64
64
 
65
65
  files:
66
66
  - lib/shh/cli.rb
67
+ - lib/shh/clipboard.rb
67
68
  - lib/shh/crypt.rb
68
69
  - lib/shh/darwin10_clipboard.rb
69
70
  - lib/shh/darwin10_launcher.rb