printsly 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/printsly +49 -0
- data/lib/choice.rb +38 -0
- data/lib/common_stuff.rb +68 -0
- data/lib/menu.rb +235 -0
- data/lib/printers.rb +53 -0
- data/lib/printsly.rb +10 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8da3d85ea277260cdc0fac34aae335958ffd635c
|
4
|
+
data.tar.gz: 98d17e2ba3ca4ae2e42523d24abac413dbc46bc5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1c1c0f6663544bee54fd44eeaabab71d652d889509f462d903406d603c42223875e7bf223604b334089987f638a93008ee9abc9a567b302080829ee0f48bd84b
|
7
|
+
data.tar.gz: f861e7073bb230ec2faaa42cd8fb982fb95fc4d604ca38998d44ff7a01c40d43f471ff232fc69d7a518254233f13617b19d8a2dce71920ff0a48565f0ab046bd
|
data/bin/printsly
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'printsly'
|
4
|
+
|
5
|
+
v = ARGV
|
6
|
+
case
|
7
|
+
when v.empty? == true
|
8
|
+
puts bar_top.yellow
|
9
|
+
puts " "*24 + "Helps you add printers to CUPS".yellow + " "*19
|
10
|
+
puts bar_low.yellow
|
11
|
+
puts # formatting
|
12
|
+
puts "Selectable options will normally be enclosed in " + "[ ]".yellow + "'s."
|
13
|
+
puts # formatting
|
14
|
+
Menu.new.choices
|
15
|
+
when v.count > 1
|
16
|
+
puts # formatting
|
17
|
+
puts "Please pass only one directory at a time!".red
|
18
|
+
puts # formatting
|
19
|
+
exit 1 #something went wrong
|
20
|
+
when v.count < 2
|
21
|
+
v.each do |dirk|
|
22
|
+
if /^\//.match(dirk) #does path start at root?
|
23
|
+
case Dir.exists?(dirk)
|
24
|
+
when false
|
25
|
+
puts # formatting
|
26
|
+
puts "That directory does not exist!".red
|
27
|
+
puts # formatting
|
28
|
+
exit 1 #something went wrong
|
29
|
+
when true
|
30
|
+
spreads = Dir.glob(File.join(dirk, '*.xls'))
|
31
|
+
case spreads.size > 0
|
32
|
+
when true
|
33
|
+
spreads.each do |sheety|
|
34
|
+
Printers.new.build(sheety)
|
35
|
+
end
|
36
|
+
when false
|
37
|
+
puts # formatting
|
38
|
+
puts "There are no spreadsheets in specified directory!".red
|
39
|
+
puts # formatting
|
40
|
+
end
|
41
|
+
end
|
42
|
+
else
|
43
|
+
puts # formatting
|
44
|
+
puts "Please pass the full path to the directory you wish to process and nothing else!".red
|
45
|
+
puts # formatting
|
46
|
+
exit 1 #something went wrong
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/choice.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
|
3
|
+
class Choice
|
4
|
+
attr_reader :choices
|
5
|
+
|
6
|
+
def initialize msg, choices
|
7
|
+
@msg = msg
|
8
|
+
@choices = choices
|
9
|
+
end
|
10
|
+
|
11
|
+
def prompt
|
12
|
+
put_prompt_msg
|
13
|
+
get_prompt_resp
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
@choices
|
18
|
+
end
|
19
|
+
|
20
|
+
def add(command, msg)
|
21
|
+
@choices[command] = msg
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def put_prompt_msg
|
26
|
+
p = []
|
27
|
+
p << @msg
|
28
|
+
@choices.each do |key, description|
|
29
|
+
p << "[#{key}] ".yellow + description
|
30
|
+
end
|
31
|
+
puts "#{p.join("\n")}\n"
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_prompt_resp
|
35
|
+
gets.chomp
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/lib/common_stuff.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
module CommonStuff
|
2
|
+
|
3
|
+
@@config_file = File.join(Dir.home, "printsly.json")
|
4
|
+
|
5
|
+
def prompt
|
6
|
+
print ">> "
|
7
|
+
end
|
8
|
+
|
9
|
+
def yes_no
|
10
|
+
#restrict input to valid answers, but don't worry about case
|
11
|
+
begin
|
12
|
+
puts "Please enter " + "[yes]".yellow + " or " + "[no]".yellow + ":"
|
13
|
+
prompt; @yes_no = STDIN.gets.chomp.downcase
|
14
|
+
end while not (@yes_no == "yes" or @yes_no == "no")
|
15
|
+
end
|
16
|
+
|
17
|
+
def choose_file
|
18
|
+
puts #formatting
|
19
|
+
puts "Please enter the full path to the spreadsheet(s):"
|
20
|
+
prompt; gets.chomp
|
21
|
+
end
|
22
|
+
|
23
|
+
def bar_top
|
24
|
+
"_"*34 + " " + "Printsly" + " " + "_"*34
|
25
|
+
end
|
26
|
+
|
27
|
+
def bar_low
|
28
|
+
"-"*78
|
29
|
+
end
|
30
|
+
|
31
|
+
def fill_hash work_dir, batchy, auto_mater
|
32
|
+
cur_conf = Hash.new
|
33
|
+
cur_conf[:work_dir] = work_dir
|
34
|
+
cur_conf[:batchy] = batchy
|
35
|
+
cur_conf[:auto_mater] = auto_mater
|
36
|
+
cur_conf
|
37
|
+
end
|
38
|
+
|
39
|
+
def load_config
|
40
|
+
file_conf = JSON.parse(File.read(@@config_file))
|
41
|
+
cur_conf = fill_hash(file_conf['work_dir'], file_conf['batchy'], file_conf['auto_mater'])
|
42
|
+
cur_conf
|
43
|
+
end
|
44
|
+
|
45
|
+
def save_config(cur_conf)
|
46
|
+
File.open(@@config_file, "w") do |f|
|
47
|
+
f.write(cur_conf.to_json)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def work_dir_text
|
52
|
+
puts #format
|
53
|
+
puts "The " + "working directory".yellow + " is the location " + "Printsly".yellow + " will look for"
|
54
|
+
puts "spreadsheets containing printers to add to " + "CUPS".yellow + "."
|
55
|
+
end
|
56
|
+
|
57
|
+
def batchy_text
|
58
|
+
puts #format
|
59
|
+
puts "Batch mode".yellow + " means all spreadsheets in the " + "working directory".yellow + " will be processed."
|
60
|
+
end
|
61
|
+
|
62
|
+
def auto_text
|
63
|
+
puts #format
|
64
|
+
puts "Auto provision".yellow + " means provisioning is done immediately with no"
|
65
|
+
puts "confirmation dialogue."
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/lib/menu.rb
ADDED
@@ -0,0 +1,235 @@
|
|
1
|
+
# The menu system for Printsly's command line interface
|
2
|
+
|
3
|
+
require 'choice'
|
4
|
+
|
5
|
+
class Menu
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
case File.exists?(File.join(Dir.home, "printsly.json"))
|
9
|
+
when false
|
10
|
+
puts "If this is the first time to run Printsly, please choose " + "[3]".yellow + " and configure."
|
11
|
+
puts #format
|
12
|
+
puts "The configuration file is stored in your home directory by default."
|
13
|
+
work_dir = "Not Set" if work_dir.nil? || work_dir.empty?
|
14
|
+
batchy = "Off" if batchy.nil? || batchy.empty?
|
15
|
+
auto_mater = "Off" if auto_mater.nil? || auto_mater.empty?
|
16
|
+
@cur_conf = fill_hash(work_dir, batchy, auto_mater)
|
17
|
+
when true
|
18
|
+
@cur_conf = load_config
|
19
|
+
puts "Using configuration found in your home directory.".yellow
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def choices
|
24
|
+
move = 0
|
25
|
+
until move == "6"
|
26
|
+
begin
|
27
|
+
puts # formatting
|
28
|
+
puts bar_top.yellow
|
29
|
+
puts bar_low.yellow
|
30
|
+
puts # formatting
|
31
|
+
c = Choice.new "Please choose what you would like to do:",
|
32
|
+
{
|
33
|
+
"1" => "Process Single Spreadsheet",
|
34
|
+
"2" => "Process All Spreadsheets",
|
35
|
+
"3" => "Configure Printsly",
|
36
|
+
"4" => "Show Configuration",
|
37
|
+
"5" => "Reset Configuration",
|
38
|
+
"6" => "Exit"
|
39
|
+
}
|
40
|
+
move = c.prompt
|
41
|
+
end while not (move == "1" or move == "2" or move == "3" or move == "4" or move == "5" or move == "6")
|
42
|
+
case
|
43
|
+
when move == "1"
|
44
|
+
begin
|
45
|
+
spread = choose_file
|
46
|
+
puts #formatting
|
47
|
+
puts "You have chosen " + "#{spread}".yellow + ". Is this correct?"
|
48
|
+
yes_no
|
49
|
+
end while not (@yes_no == "yes")
|
50
|
+
Printers.new.build(spread)
|
51
|
+
when move == "2"
|
52
|
+
Batch.new.choices
|
53
|
+
when move == "3"
|
54
|
+
@cur_conf = Configurator.new.choices(@cur_conf)
|
55
|
+
when move == "4"
|
56
|
+
puts #format
|
57
|
+
puts "Current Working Directory: " + @cur_conf[:work_dir].green
|
58
|
+
puts "Current Batch Mode Setting: " + @cur_conf[:batchy].green
|
59
|
+
puts "Current Auto Provision Setting: " + @cur_conf[:auto_mater].green
|
60
|
+
when move == "5"
|
61
|
+
puts #format
|
62
|
+
puts "Resetting to default configuration...".yellow
|
63
|
+
sleep(0.5)
|
64
|
+
puts "...".yellow
|
65
|
+
sleep(0.5)
|
66
|
+
puts "......".red
|
67
|
+
@cur_conf = fill_hash("Not Set", "Off", "Off")
|
68
|
+
save_config(@cur_conf)
|
69
|
+
sleep(0.5)
|
70
|
+
puts ".........done!".green
|
71
|
+
when move == "6"
|
72
|
+
# leave application
|
73
|
+
puts #format
|
74
|
+
puts "As you wish.".yellow
|
75
|
+
puts #format
|
76
|
+
exit
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
class Batch
|
84
|
+
# Process all spreadsheets in specified directory
|
85
|
+
|
86
|
+
def initialize
|
87
|
+
puts # formatting
|
88
|
+
puts "From here we can process all spreadsheets in the directory of your choice."
|
89
|
+
puts # formatting
|
90
|
+
end
|
91
|
+
|
92
|
+
def choices
|
93
|
+
move = 0
|
94
|
+
until move == "3"
|
95
|
+
puts # formatting
|
96
|
+
puts bar_top.yellow
|
97
|
+
puts bar_low.yellow
|
98
|
+
puts # formatting
|
99
|
+
|
100
|
+
c = Choice.new "Please choose what you would like to do:",
|
101
|
+
{
|
102
|
+
"1" => "Choose Directory",
|
103
|
+
"2" => "Process All Spreadsheets",
|
104
|
+
"3" => "Return to Main Menu"
|
105
|
+
}
|
106
|
+
move = c.prompt
|
107
|
+
case
|
108
|
+
when move == "1"
|
109
|
+
begin
|
110
|
+
@work_dir = choose_file
|
111
|
+
puts #format
|
112
|
+
puts "You have chosen " + @work_dir.yellow + " Is this correct?"
|
113
|
+
yes_no
|
114
|
+
end while not (@yes_no == "yes")
|
115
|
+
when move == "2"
|
116
|
+
if @work_dir.nil? || @work_dir.empty? || @work_dir == "Not Set"
|
117
|
+
puts #format
|
118
|
+
puts "You must choose a directory to process!".red
|
119
|
+
begin
|
120
|
+
@work_dir = choose_file
|
121
|
+
puts #format
|
122
|
+
puts "You have chosen " + @work_dir.yellow + " Is this correct?"
|
123
|
+
yes_no
|
124
|
+
end while not (@yes_no == "yes")
|
125
|
+
end
|
126
|
+
puts #format
|
127
|
+
puts "I will process " + @work_dir.yellow + " now."
|
128
|
+
sleep(0.5)
|
129
|
+
puts "...".yellow
|
130
|
+
sleep(0.5)
|
131
|
+
puts "......".red
|
132
|
+
sleep(0.5)
|
133
|
+
puts ".........done!".green
|
134
|
+
when move == "3"
|
135
|
+
puts #format
|
136
|
+
puts "Returning to main menu.".yellow
|
137
|
+
return
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
class Configurator
|
145
|
+
|
146
|
+
# Set and save Printsly defaults
|
147
|
+
def initialize
|
148
|
+
File.new(File.join(Dir.home, "printsly.json"), "w+") unless File.exists?(File.join(Dir.home, "printsly.json"))
|
149
|
+
puts #format
|
150
|
+
puts "Let's configure " + "Printsly".yellow + "."
|
151
|
+
work_dir_text
|
152
|
+
batchy_text
|
153
|
+
auto_text
|
154
|
+
end
|
155
|
+
|
156
|
+
def choices(cur_conf)
|
157
|
+
work_dir = cur_conf[:work_dir]
|
158
|
+
batchy = cur_conf[:batchy]
|
159
|
+
auto_mater = cur_conf[:auto_mater]
|
160
|
+
move = 0
|
161
|
+
until move == "4"
|
162
|
+
puts # formatting
|
163
|
+
puts bar_top.yellow
|
164
|
+
puts bar_low.yellow
|
165
|
+
puts # formatting
|
166
|
+
c = Choice.new "What would you like to configure?",
|
167
|
+
{
|
168
|
+
"1" => "Set Working Directory | Current: " + work_dir.green,
|
169
|
+
"2" => "Batch Mode | Current: " + batchy.green,
|
170
|
+
"3" => "Auto Provision? | Current: " + auto_mater.green,
|
171
|
+
"4" => "Return To Main Menu."
|
172
|
+
}
|
173
|
+
move = c.prompt
|
174
|
+
case
|
175
|
+
when move == "1"
|
176
|
+
begin
|
177
|
+
work_dir_text
|
178
|
+
puts #format
|
179
|
+
puts "The working directory is currently: " + work_dir.green
|
180
|
+
work_dir = choose_file
|
181
|
+
puts #format
|
182
|
+
puts "You have chosen " + work_dir.yellow + " Is this correct?"
|
183
|
+
yes_no
|
184
|
+
end while not (@yes_no == "yes")
|
185
|
+
when move == "2"
|
186
|
+
batchy_text
|
187
|
+
puts #format
|
188
|
+
puts "Batch mode is currently turned " + batchy.green + "."
|
189
|
+
puts #format
|
190
|
+
case
|
191
|
+
when batchy == "Off"
|
192
|
+
puts "Turn batch mode on?"
|
193
|
+
begin
|
194
|
+
yes_no
|
195
|
+
end while not (@yes_no == "yes" or @yes_no == "no")
|
196
|
+
batchy = "On" if @yes_no == "yes"
|
197
|
+
when
|
198
|
+
batchy == "On"
|
199
|
+
puts "Turn batch mode off?"
|
200
|
+
begin
|
201
|
+
yes_no
|
202
|
+
end while not (@yes_no == "yes" or @yes_no == "no")
|
203
|
+
batchy = "Off" if @yes_no == "yes"
|
204
|
+
end
|
205
|
+
when move == "3"
|
206
|
+
auto_text
|
207
|
+
puts #format
|
208
|
+
puts "Auto provision is currently turned " + auto_mater.green + "."
|
209
|
+
puts #format
|
210
|
+
case
|
211
|
+
when auto_mater == "Off"
|
212
|
+
puts "Turn auto provision on?"
|
213
|
+
begin
|
214
|
+
yes_no
|
215
|
+
end while not (@yes_no == "yes" or @yes_no == "no")
|
216
|
+
auto_mater = "On" if @yes_no == "yes"
|
217
|
+
when
|
218
|
+
auto_mater == "On"
|
219
|
+
puts "Turn auto provision off?"
|
220
|
+
begin
|
221
|
+
yes_no
|
222
|
+
end while not (@yes_no == "yes" or @yes_no == "no")
|
223
|
+
auto_mater = "Off" if @yes_no == "yes"
|
224
|
+
end
|
225
|
+
when move == "4"
|
226
|
+
puts #format
|
227
|
+
puts "Returning to main menu."
|
228
|
+
@cur_conf = fill_hash(work_dir, batchy, auto_mater)
|
229
|
+
save_config(@cur_conf)
|
230
|
+
return @cur_conf
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
data/lib/printers.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
class Printers
|
2
|
+
attr_accessor :store_printers
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
puts
|
6
|
+
puts "Let's get started."
|
7
|
+
puts
|
8
|
+
end
|
9
|
+
|
10
|
+
def build spread
|
11
|
+
|
12
|
+
book = Spreadsheet.open spread
|
13
|
+
sheet1 = book.worksheet 0
|
14
|
+
store = sheet1.row(0)[0][6..8]
|
15
|
+
printers = Hash.new
|
16
|
+
sheet1.each 5 do |row|
|
17
|
+
break if row[0].nil?
|
18
|
+
printername = row[4]
|
19
|
+
if printername != nil
|
20
|
+
if printername.include?(store) || printername.include?('RT') || printername.include?('SIM')
|
21
|
+
printer = Array.new
|
22
|
+
printer = printer.push row[4] # name
|
23
|
+
printer = printer.push row[5] # ip address
|
24
|
+
printer = printer.push row[3] # Model
|
25
|
+
printer = printer.push row[0] # Description
|
26
|
+
printers[printername] = printer
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
puts
|
32
|
+
puts "This is what I am planning on provisioning for store " + store + ":"
|
33
|
+
puts
|
34
|
+
|
35
|
+
if Dir.exists?("/var/log/cups")
|
36
|
+
File.new("/var/log/cups/provision_log", "w+") unless File.exists?("/var/log/cups/provision_log")
|
37
|
+
end
|
38
|
+
|
39
|
+
printers.each do | printername, printerdata |
|
40
|
+
printerdata[0] = "0" + store + printerdata[0] if printerdata[0].include?('RT')
|
41
|
+
printerdata[0] = "0" + store + printerdata[0] if printerdata[0].include?('SIM')
|
42
|
+
puts "lpadmin -p " + printerdata[0] + " -L \"" + printerdata[3] + "\" -D \"" + printerdata[2] + "\" -E -v socket://" + printerdata[1] + ":9100 -m raw"
|
43
|
+
#puts "Name: ".yellow + printerdata[0] + " " + "Type: ".yellow + printerdata[2] + " " + "IP: ".yellow + printerdata[1] + " " + "Desc: ".yellow + printerdata[3]
|
44
|
+
if File.exists?("/var/log/cups/provision_log")
|
45
|
+
timey = Time.new
|
46
|
+
File.open("/var/log/cups/provision_log", "a") do |f|
|
47
|
+
f.puts "Added: " + timey.inspect + " lpadmin -p " + printerdata[0] + " -L \"" + printerdata[3] + "\" -D \"" + printerdata[2] + "\" -E -v socket://" + printerdata[1] + ":9100 -m raw"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/lib/printsly.rb
ADDED
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: printsly
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kody Wilson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: spreadsheet
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.0.3
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.0.3
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.0.3
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.0.3
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: colorize
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.7.5
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.7.5
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 0.7.5
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.7.5
|
53
|
+
description: Helps you add printers to CUPS
|
54
|
+
email: kodywilson@gmail.com
|
55
|
+
executables:
|
56
|
+
- printsly
|
57
|
+
extensions: []
|
58
|
+
extra_rdoc_files: []
|
59
|
+
files:
|
60
|
+
- bin/printsly
|
61
|
+
- lib/choice.rb
|
62
|
+
- lib/common_stuff.rb
|
63
|
+
- lib/menu.rb
|
64
|
+
- lib/printers.rb
|
65
|
+
- lib/printsly.rb
|
66
|
+
homepage: https://github.com/kodywilson/printsly
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
metadata: {}
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 2.2.2
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: Printer management software
|
90
|
+
test_files: []
|