bmo2 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: faea14056fbbf7aaab2e42498cd57fded00efaaa
4
+ data.tar.gz: 21dc0832fcd59ed3ad7814f3465e69cc643bf496
5
+ SHA512:
6
+ metadata.gz: a2ef8d4c3d3f21f1d494fb52815660a29f1dff44bb868a1a4310d9d34207c341ceb9666375b2e729fa6e65b43a9b283b75baf57cfc27418b3c56eec6b7252d2b
7
+ data.tar.gz: 8c82460f6f31808d97a30b23a0970a3375c93fbfbe9af57679670864d6ac6b12229305a8824d76e3f7698f173b33fcdfc0471e20b24ba0cc6d4e17ddf3d9f64f
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) Peter Boriskin, x66w@ya.ru
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # B M O 2
2
+
3
+ ## About
4
+
5
+ bmo2 manages your text snippets on your command line.
6
+
7
+ For more details about what boom is and how it works, check out
8
+ [bmo2 website](http://bmo2.com).
9
+
10
+ ## Install
11
+
12
+ gem install bmo2
13
+
14
+ ## Quick Start
15
+
16
+ $ bmo2 config
17
+ Bmo2 Created a new list called "config".
18
+
19
+ $ boom config nginx /etc/nginx/conf
20
+ Bmo2 "nginx" in "conf" is "/etc/nginx/conf". Got it.
21
+
22
+ $ boom nginx
23
+ Bmo2 Just copied /etc/nginx/conf to your clipboard.
24
+
25
+ $ boom delete conf nginx
26
+ Bmo2 nginx is gone forever.
27
+
28
+
29
+ ## Bmo2 [website](http://bmo2.com)
data/bin/bmo2 ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
5
+
6
+ require 'bmo2'
7
+
8
+ Bmo2::Command.execute(*ARGV)
data/lib/bmo2/color.rb ADDED
@@ -0,0 +1,32 @@
1
+ module Bmo2
2
+ module Color
3
+ extend self
4
+
5
+ CODES = {
6
+ :reset => "\e[0m",
7
+ :cyan => "\e[36m",
8
+ :magenta => "\e[35m",
9
+ :red => "\e[31m",
10
+ :green => "\e[32m",
11
+ :yellow => "\e[33m"
12
+ }
13
+
14
+ def self.included(other)
15
+ if RUBY_PLATFORM =~ /win32/ || RUBY_PLATFORM =~ /mingw32/
16
+ require 'Win32/Console/ANSI'
17
+ end
18
+ rescue LoadError
19
+ end
20
+
21
+ def colorize(string, color_code)
22
+ if !defined?(Win32::Console) && !!(RUBY_PLATFORM =~ /win32/ || RUBY_PLATFORM =~ /mingw32/)
23
+ return string
24
+ end
25
+ "#{CODES[color_code] || color_code}#{string}#{CODES[:reset]}"
26
+ end
27
+
28
+ self.class_eval(CODES.keys.reject {|color| color == :reset }.map do |color|
29
+ "def #{color}(string); colorize(string, :#{color}); end"
30
+ end.join("\n"))
31
+ end
32
+ end
@@ -0,0 +1,217 @@
1
+ module Bmo2
2
+ class Command
3
+ class << self
4
+ include Bmo2::Color
5
+
6
+ def storage
7
+ Bmo2.storage
8
+ end
9
+
10
+ def execute(*args)
11
+ command = args.shift
12
+ major = args.shift
13
+ minor = args.empty? ? nil : args.join(' ')
14
+
15
+ return overview unless command
16
+ delegate(command, major, minor)
17
+ end
18
+
19
+ def output(s)
20
+ puts(s)
21
+ end
22
+
23
+ def stdin
24
+ $stdin
25
+ end
26
+
27
+ def overview
28
+ storage.lists.each do |list|
29
+ output " #{list.name} (#{list.items.size})"
30
+ end
31
+ s = "\e[32mYou don't have anything yet! To start out, create a new list:\e[0m"
32
+ s << "\n$ bmo2 <list-name>"
33
+ s << "\n\e[32mAnd then add something to your list!\e[0m"
34
+ s << "\n$ bmo2 <list-name> <item-name> <item-value>"
35
+ s << "\n\e[32mYou can then grab your new item:\e[0m"
36
+ s << "\n$ bmo2 <item-name>"
37
+ output s if storage.lists.size == 0
38
+ end
39
+
40
+ def all
41
+ storage.lists.each do |list|
42
+ output " #{list.name}"
43
+ list.items.each do |item|
44
+ output " #{item.short_name}:#{item.spacer} #{item.value}"
45
+ end
46
+ end
47
+ end
48
+
49
+ def delegate(command, major, minor)
50
+ return all if command == 'all'
51
+ return edit if command == 'edit'
52
+ return version if command == "-v"
53
+ return version if command == "--version"
54
+ return help if command == 'help'
55
+ return help if command[0] == 45 || command[0] == '-' # any - dash options are pleas for help
56
+ return echo(major,minor) if command == 'echo' || command == 'e'
57
+ return copy(major,minor) if command == 'copy' || command == 'c'
58
+ return open(major,minor) if command == 'open' || command == 'o'
59
+ return random(major) if command == 'random' || command == 'rand' || command == 'r'
60
+
61
+ if command == 'delete' || command == 'd'
62
+ if minor
63
+ return delete_item(major, minor)
64
+ else
65
+ return delete_list(major)
66
+ end
67
+ end
68
+
69
+ if storage.list_exists?(command)
70
+ return detail_list(command) unless major
71
+ return add_item(command,major,minor) if minor
72
+ return add_item(command,major,stdin.read) if stdin.stat.size > 0
73
+ return search_list_for_item(command, major)
74
+ end
75
+
76
+ return search_items(command) if storage.item_exists?(command) and !major
77
+
78
+ return create_list(command, major, stdin.read) if !minor && stdin.stat.size > 0
79
+ return create_list(command, major, minor)
80
+ end
81
+
82
+ def detail_list(name)
83
+ list = List.find(name)
84
+ list.items.sort{ |x,y| x.name <=> y.name }.each do |item|
85
+ output " #{item.short_name}:#{item.spacer} #{item.value}"
86
+ end
87
+ end
88
+
89
+ def echo(major, minor)
90
+ unless minor
91
+ item = storage.items.detect do |item|
92
+ item.name == major
93
+ end
94
+ return output "#{cyan(major)} #{red("not found")}" unless item
95
+ else
96
+ list = List.find(major)
97
+ item = list.find_item(minor)
98
+ return output "#{cyan(minor)} #{red("not found in")} #{cyan(major)}" unless item
99
+ end
100
+ output item.value
101
+ end
102
+
103
+ def copy(major, minor)
104
+ unless minor
105
+ item = storage.items.detect do |item|
106
+ item.name == major
107
+ end
108
+ return output "#{cyan(major)} #{red("not found")}" unless item
109
+ else
110
+ list = List.find(major)
111
+ item = list.find_item(minor)
112
+ return output "#{cyan(minor)} #{red("not found in")} #{cyan(major)}" unless item
113
+ end
114
+ Platform.copy(item)
115
+ end
116
+
117
+ def create_list(name, item = nil, value = nil)
118
+ lists = (storage.lists << List.new(name))
119
+ storage.lists = lists
120
+ output "#{green("Bmo2")} Created a new list called #{cyan(name)}."
121
+ save
122
+ add_item(name, item, value) unless value.nil?
123
+ end
124
+
125
+ def delete_list(name)
126
+ if storage.list_exists?(name)
127
+ printf "You sure you want to delete everything in #{cyan(name)}? (y/n): "
128
+ if $stdin.gets.chomp == 'y'
129
+ List.delete(name)
130
+ output "#{green("Bmo2")} Deleted all your #{cyan(name)}."
131
+ save
132
+ else
133
+ output "Just kidding then."
134
+ end
135
+ else
136
+ output "We couldn't find that list."
137
+ end
138
+ end
139
+
140
+ def add_item(list,name,value)
141
+ list = List.find(list)
142
+ list.add_item(Item.new(name,value))
143
+ output "#{green("Bmo2")} #{cyan(name)} in #{cyan(list.name)} is #{cyan(value)}. Got it."
144
+ save
145
+ end
146
+
147
+ def delete_item(list_name,name)
148
+ if storage.list_exists?(list_name)
149
+ list = List.find(list_name)
150
+ if list.delete_item(name)
151
+ output "#{green("Bmo2")} #{cyan(name)} is gone forever."
152
+ save
153
+ else
154
+ output "#{cyan(name)} #{red("not found in")} #{cyan(list_name)}"
155
+ end
156
+ else
157
+ output "We couldn't find that list."
158
+ end
159
+ end
160
+
161
+ def search_items(name)
162
+ item = storage.items.detect do |item|
163
+ item.name == name
164
+ end
165
+
166
+ output "#{green("Bmo2")} We just copied #{cyan(Platform.copy(item))} to your clipboard."
167
+ end
168
+
169
+ def search_list_for_item(list_name, item_name)
170
+ list = List.find(list_name)
171
+ item = list.find_item(item_name)
172
+
173
+ if item
174
+ output "#{green("Bmo2")} We just copied #{cyan(Platform.copy(item))} to your clipboard."
175
+ else
176
+ output "#{cyan(item_name)} #{red("not found in")} #{cyan(list_name)}"
177
+ end
178
+ end
179
+
180
+ def save
181
+ storage.save
182
+ end
183
+
184
+ def version
185
+ output "You're running bmo2 #{Bmo::VERSION}. Congratulations!"
186
+ end
187
+
188
+ def edit
189
+ output "#{green("Bmo2")} #{Platform.edit(storage.json_file)}"
190
+ end
191
+
192
+ def help
193
+ text = %{\e[32m----------------------------------------------------------------------------\e[0m
194
+ bmo2 display high-level overview
195
+ bmo2 all show all items in all lists
196
+ bmo2 help this help text
197
+ bmo2 <list> create/show a list
198
+ bmo2 delete <list> deletes a list
199
+
200
+ bmo2 <list> <name> <value> create a new list item
201
+ bmo2 <name> copy item's value to clipboard
202
+ bmo2 <list> <name> copy item's value to clipboard
203
+ bmo2 echo <name> echo the item's value without copying
204
+ bmo2 echo <list> <name> echo the item's value without copying
205
+ bmo2 copy <name> copy the item's value without echo
206
+ bmo2 copy <list> <name> copy the item's value without echo
207
+ bmo2 delete <list> <name> deletes an item
208
+
209
+ all other documentation is located at:
210
+ https://github.com/bmo2/bmo
211
+ }.gsub(/^ {8}/, '')
212
+ output text
213
+ end
214
+
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,7 @@
1
+ unless Symbol.method_defined?(:to_proc)
2
+ class Symbol
3
+ def to_proc
4
+ Proc.new { |obj, *args| obj.send(self, *args) }
5
+ end
6
+ end
7
+ end
data/lib/bmo2/item.rb ADDED
@@ -0,0 +1,27 @@
1
+ module Bmo2
2
+ class Item
3
+ attr_accessor :name
4
+ attr_accessor :value
5
+
6
+ def initialize(name,value)
7
+ @name = name
8
+ @value = value
9
+ end
10
+
11
+ def short_name
12
+ name.length > 15 ? "#{name[0..14]}…" : name[0..14]
13
+ end
14
+
15
+ def spacer
16
+ name.length > 15 ? '' : ' '*(15-name.length+1)
17
+ end
18
+
19
+ def url
20
+ @url ||= value.split(/\s+/).detect { |v| v =~ %r{\A[a-z0-9]+:\S+}i } || value
21
+ end
22
+
23
+ def to_hash
24
+ { @name => @value }
25
+ end
26
+ end
27
+ end
data/lib/bmo2/list.rb ADDED
@@ -0,0 +1,50 @@
1
+ module Bmo2
2
+ class List
3
+
4
+ def initialize(name)
5
+ @items = []
6
+ @name = name
7
+ end
8
+
9
+ def self.storage
10
+ Bmo2.storage
11
+ end
12
+
13
+ attr_accessor :items
14
+
15
+ attr_accessor :name
16
+
17
+ def add_item(item)
18
+ delete_item(item.name) if find_item(item.name)
19
+ @items << item
20
+ end
21
+
22
+ def self.find(name)
23
+ storage.lists.find { |list| list.name == name }
24
+ end
25
+
26
+ def self.delete(name)
27
+ previous = storage.lists.size
28
+ storage.lists = storage.lists.reject { |list| list.name == name }
29
+ previous != storage.lists.size
30
+ end
31
+
32
+ def delete_item(name)
33
+ previous = items.size
34
+ items.reject! { |item| item.name == name}
35
+ previous != items.size
36
+ end
37
+
38
+ def find_item(name)
39
+ items.find do |item|
40
+ item.name == name ||
41
+ item.short_name.gsub('…','') == name.gsub('…','')
42
+ end
43
+ end
44
+
45
+ def to_hash
46
+ { name => items.collect(&:to_hash) }
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,73 @@
1
+ module Bmo2
2
+ class Platform
3
+ class << self
4
+ def cygwin?
5
+ !!(RbConfig::CONFIG['host_os'] =~ /cygwin/)
6
+ end
7
+ def darwin?
8
+ !!(RbConfig::CONFIG['host_os'] =~ /darwin/)
9
+ end
10
+
11
+ def windows?
12
+ !!(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/)
13
+ end
14
+
15
+ def open_command
16
+ if darwin?
17
+ 'open'
18
+ elsif windows?
19
+ 'start'
20
+ elsif cygwin?
21
+ 'cygstart'
22
+ else
23
+ 'xdg-open'
24
+ end
25
+ end
26
+
27
+ def open(item)
28
+ unless windows?
29
+ system("#{open_command} '#{item.url.gsub("\'","'\\\\''")}'")
30
+ else
31
+ system("#{open_command} #{item.url.gsub("\'","'\\\\''")}")
32
+ end
33
+
34
+ item.value
35
+ end
36
+
37
+ def copy_command
38
+ if darwin?
39
+ 'pbcopy'
40
+ elsif windows? || cygwin?
41
+ 'clip'
42
+ else
43
+ 'xclip -selection clipboard'
44
+ end
45
+ end
46
+
47
+ def copy(item)
48
+ begin
49
+ IO.popen(copy_command,"w") {|cc| cc.write(item.value)}
50
+ item.value
51
+ rescue Errno::ENOENT
52
+ puts item.value
53
+ puts "Please install #{copy_command[0..5]} to copy this item to your clipboard"
54
+ exit
55
+ end
56
+ end
57
+
58
+ def edit(json_file)
59
+ unless ENV['EDITOR'].nil?
60
+ unless windows?
61
+ system("`echo $EDITOR` #{json_file} &")
62
+ else
63
+ system("start %EDITOR% #{json_file}")
64
+ end
65
+ else
66
+ system("#{open_command} #{json_file}")
67
+ end
68
+
69
+ "Make your edits, and do be sure to save."
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,69 @@
1
+ module Bmo2
2
+ class Storage
3
+ JSON_FILE = "#{ENV['HOME']}/.bmo2"
4
+
5
+ def json_file
6
+ ENV['BMO2MFILE'] || JSON_FILE
7
+ end
8
+
9
+ def initialize
10
+ @lists = []
11
+ bootstrap
12
+ populate
13
+ end
14
+
15
+ attr_writer :lists
16
+
17
+ def lists
18
+ @lists.sort_by { |list| -list.items.size }
19
+ end
20
+
21
+ def list_exists?(name)
22
+ @lists.detect { |list| list.name == name }
23
+ end
24
+
25
+ def items
26
+ @lists.collect(&:items).flatten
27
+ end
28
+
29
+ def item_exists?(name)
30
+ items.detect { |item| item.name == name }
31
+ end
32
+
33
+ def to_hash
34
+ { :lists => lists.collect(&:to_hash) }
35
+ end
36
+
37
+ def bootstrap
38
+ return if File.exist?(json_file) and !File.zero?(json_file)
39
+ FileUtils.touch json_file
40
+ File.open(json_file, 'w') {|f| f.write(to_json) }
41
+ save
42
+ end
43
+
44
+ def populate
45
+ file = File.new(json_file, 'r')
46
+ storage = Yajl::Parser.parse(file)
47
+
48
+ storage['lists'].each do |lists|
49
+ lists.each do |list_name, items|
50
+ @lists << list = List.new(list_name)
51
+
52
+ items.each do |item|
53
+ item.each do |name,value|
54
+ list.add_item(Item.new(name,value))
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ def save
62
+ File.open(json_file, 'w') {|f| f.write(to_json) }
63
+ end
64
+
65
+ def to_json
66
+ Yajl::Encoder.encode(to_hash, :pretty => true)
67
+ end
68
+ end
69
+ end
data/lib/bmo2.rb ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+
3
+ begin
4
+ require 'rubygems'
5
+ rescue LoadError
6
+ end
7
+
8
+ require 'fileutils'
9
+ require 'yajl'
10
+
11
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
12
+
13
+ require 'bmo2/color'
14
+ require 'bmo2/platform'
15
+ require 'bmo2/command'
16
+ require 'bmo2/item'
17
+ require 'bmo2/list'
18
+ require 'bmo2/storage'
19
+
20
+ require 'bmo2/ext/symbol'
21
+
22
+ module Bmo2
23
+ VERSION = '0.1.0'
24
+
25
+ def self.storage
26
+ @storage ||= Storage.new
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bmo2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Peter Boriskin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Bmo2 can order links, path or whatewer you want!
14
+ email: x66w@ya.ru
15
+ executables:
16
+ - bmo2
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - LICENSE.md
21
+ - README.md
22
+ - bin/bmo2
23
+ - lib/bmo2.rb
24
+ - lib/bmo2/color.rb
25
+ - lib/bmo2/command.rb
26
+ - lib/bmo2/ext/symbol.rb
27
+ - lib/bmo2/item.rb
28
+ - lib/bmo2/list.rb
29
+ - lib/bmo2/platform.rb
30
+ - lib/bmo2/storage.rb
31
+ homepage: https://github.com/bmo2/gem
32
+ licenses:
33
+ - MIT
34
+ metadata: {}
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project:
51
+ rubygems_version: 2.4.6
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Bmo2 is a simple server helper
55
+ test_files: []