obf 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/obf.rb +2 -1
- data/lib/obf/{avaz.rb → avz.rb} +1 -1
- data/lib/obf/external.rb +6 -6
- data/lib/obf/sfy.rb +150 -0
- data/lib/obf/unknown_file.rb +14 -3
- data/lib/obf/utils.rb +40 -21
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28978f7be3cb038907f145a7bc6b4a50959dfac9
|
4
|
+
data.tar.gz: 426f20f1507fd57be3691d1c6f8246b60eec0efd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de82778618d0a6ed121009c83721b6ec206a2b4bf6f564118c78ce4ed7f3868fcd7bfe32110d04080ac383edebf215b72d554666ad2acf8d1ff88e01796e98c8
|
7
|
+
data.tar.gz: c17d33b14d1945752d828a89d826e6ed2b81c06e0d9453aa30309b4a4886a99d0b8c72b3be2fd636b677b1f15c5904b9014def9717729eb923a8c68d03553817
|
data/lib/obf.rb
CHANGED
data/lib/obf/{avaz.rb → avz.rb}
RENAMED
data/lib/obf/external.rb
CHANGED
@@ -3,8 +3,8 @@ module OBF::External
|
|
3
3
|
if hash['boards']
|
4
4
|
old_hash = hash
|
5
5
|
hash = old_hash['boards'][0]
|
6
|
-
hash['images'] =
|
7
|
-
hash['sounds'] =
|
6
|
+
hash['images'] = old_hash['images'] || []
|
7
|
+
hash['sounds'] = old_hash['sounds'] || []
|
8
8
|
path_hash = nil
|
9
9
|
end
|
10
10
|
|
@@ -51,7 +51,7 @@ module OBF::External
|
|
51
51
|
'url' => original_button['load_board']['url'],
|
52
52
|
'data_url' => original_button['load_board']['data_url']
|
53
53
|
}
|
54
|
-
if path_hash && path_hash['included_boards'][original_button['load_board']['id']]
|
54
|
+
if path_hash && path_hash['included_boards'] && path_hash['included_boards'][original_button['load_board']['id']]
|
55
55
|
button['load_board']['path'] = "board_#{original_button['load_board']['id']}.obf"
|
56
56
|
end
|
57
57
|
end
|
@@ -94,7 +94,7 @@ module OBF::External
|
|
94
94
|
'content_type' => original_image['content_type']
|
95
95
|
}
|
96
96
|
if !path_hash
|
97
|
-
image['data'] = OBF::Utils.image_base64(image['url'])
|
97
|
+
image['data'] = OBF::Utils.image_base64(image['url']) if image['url']
|
98
98
|
else
|
99
99
|
if path_hash['images'] && path_hash['images'][image['id']]
|
100
100
|
image['path'] = path_hash['images'][image['id']]['path']
|
@@ -307,10 +307,10 @@ module OBF::External
|
|
307
307
|
dest_path
|
308
308
|
end
|
309
309
|
|
310
|
-
def self.to_png(board, dest_path)
|
310
|
+
def self.to_png(board, dest_path, opts)
|
311
311
|
tmp_path = OBF::Utils.temp_path("stash")
|
312
312
|
OBF::Utils.as_progress_percent(0, 0.5) do
|
313
|
-
self.to_pdf(board, tmp_path)
|
313
|
+
self.to_pdf(board, tmp_path, opts)
|
314
314
|
end
|
315
315
|
OBF::Utils.as_progress_percent(0.5, 1.0) do
|
316
316
|
OBF::PDF.to_png(tmp_path, dest_path)
|
data/lib/obf/sfy.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
module OBF::Sfy
|
2
|
+
def self.to_external(path)
|
3
|
+
boards = []
|
4
|
+
images = []
|
5
|
+
sounds = []
|
6
|
+
|
7
|
+
plist = CFPropertyList::List.new(:file => path)
|
8
|
+
data = CFPropertyList.native_types(plist.value)
|
9
|
+
|
10
|
+
top = data['$top']['root']
|
11
|
+
list = data['$objects'][top]
|
12
|
+
|
13
|
+
items = {
|
14
|
+
'strings' => {},
|
15
|
+
'buttons' => []
|
16
|
+
}
|
17
|
+
board_ids = []
|
18
|
+
images = []
|
19
|
+
data['$objects'].each_with_index do |item, idx|
|
20
|
+
if item.is_a?(String)
|
21
|
+
items['strings'][idx] = item
|
22
|
+
elsif item.is_a?(Hash) && item['mScreen']
|
23
|
+
item['word'] = data['$objects'][item['wordKey']] if item['wordKey']
|
24
|
+
item['symbol'] = data['$objects'][item['imageName']] if item['imageName']
|
25
|
+
board_ids[item['mScreen']] = true
|
26
|
+
items['buttons'] << item
|
27
|
+
else
|
28
|
+
# puts item.to_json
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
image_counter = 0
|
33
|
+
board_ids.each_with_index do |present, idx|
|
34
|
+
if present
|
35
|
+
name = "HOME"
|
36
|
+
if idx > 0
|
37
|
+
if boards[0]
|
38
|
+
name = boards[0]['buttons'][idx - 1]['label']
|
39
|
+
else
|
40
|
+
name = "Screen #{idx}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
raw_buttons = items['buttons'].select{|b| b['mScreen'] == idx }
|
45
|
+
buttons = []
|
46
|
+
rows = 0
|
47
|
+
columns = 0
|
48
|
+
raw_buttons.each do |b|
|
49
|
+
rows = [rows, b['mRow']].max
|
50
|
+
columns = [columns, b['mColumn']].max
|
51
|
+
end
|
52
|
+
rows += 1
|
53
|
+
columns += 1
|
54
|
+
grid = {
|
55
|
+
'rows' => rows,
|
56
|
+
'columns' => columns,
|
57
|
+
'order' => []
|
58
|
+
}
|
59
|
+
button_counter = 0
|
60
|
+
rows.times do |i|
|
61
|
+
grid['order'][i] = []
|
62
|
+
columns.times do |j|
|
63
|
+
grid['order'][i][j] = nil
|
64
|
+
raw_button = raw_buttons.detect{|b| b['mRow'] == i && b['mColumn'] == j }
|
65
|
+
colors = {
|
66
|
+
0 => 'rgb(255, 255, 255)', # white
|
67
|
+
1 => 'rgb(255, 0, 0)', # red
|
68
|
+
3 => 'rgb(255, 112, 156)', # red pink
|
69
|
+
2 => 'rgb(255, 115, 222)', # pinky purple
|
70
|
+
4 => 'rgb(250, 196, 140)', # light red-orange
|
71
|
+
5 => 'rgb(255, 196, 87)', # orange
|
72
|
+
6 => 'rgb(255, 234, 117)', # yellow
|
73
|
+
7 => 'rgb(255, 241, 92)', # yellowy
|
74
|
+
8 => 'rgb(252, 242, 134)', # light yellow
|
75
|
+
9 => 'rgb(82, 209, 86)', # dark green
|
76
|
+
10 => 'rgb(149, 189, 42)', # navy green
|
77
|
+
11 => 'rgb(161, 245, 113)', # green
|
78
|
+
12 => 'rgb(196, 252, 141)', # pale green
|
79
|
+
13 => 'rgb(94, 207, 255)', # strong blue
|
80
|
+
14 => 'rgb(148, 223, 255)', # happy blue
|
81
|
+
15 => 'rgb(176, 223, 255)', # bluey
|
82
|
+
16 => 'rgb(194, 241, 255)', # light blue
|
83
|
+
17 => 'rgb(118, 152, 199)', # dark purple
|
84
|
+
18 => 'rgb(208, 190, 232)', # light purple
|
85
|
+
19 => 'rgb(153, 79, 0)', # brown
|
86
|
+
20 => 'rgb(0, 109, 235)', # dark blue
|
87
|
+
21 => 'rgb(0, 0, 0)', # black
|
88
|
+
22 => 'rgb(161, 161, 161)', # gray
|
89
|
+
23 => 'rgb(255, 108, 59)', # dark orange
|
90
|
+
}
|
91
|
+
if raw_button
|
92
|
+
image_id = nil
|
93
|
+
if raw_button['symbol']
|
94
|
+
# TODO: what's the difference in name between provided symbols and user images?
|
95
|
+
if raw_button['symbol'].match(/-/)
|
96
|
+
# probably a user-defined symbol
|
97
|
+
else
|
98
|
+
images << {
|
99
|
+
'id' => image_counter,
|
100
|
+
'symbol' => {
|
101
|
+
'set' => 'sfy',
|
102
|
+
'name' => raw_button['symbol']
|
103
|
+
}
|
104
|
+
}
|
105
|
+
image_id = image_counter
|
106
|
+
image_counter += 1
|
107
|
+
end
|
108
|
+
end
|
109
|
+
button = {
|
110
|
+
'id' => button_counter,
|
111
|
+
'label' => raw_button['word'],
|
112
|
+
'background_color' => colors[raw_button['backgroundColorID']],
|
113
|
+
'image_id' => image_id,
|
114
|
+
'hidden' => !raw_button['isOpen'],
|
115
|
+
'ext_sfy_isLinked' => raw_button['isLinked'],
|
116
|
+
'ext_sfy_isProtected' => raw_button['isProtected'],
|
117
|
+
'ext_sfy_backgroundColorID' => raw_button['backgroundColorID']
|
118
|
+
}
|
119
|
+
if raw_button['customLabel'] && data['$objects'][raw_button['customLabel']] && data['$objects'][raw_button['customLabel']] != ""
|
120
|
+
button['vocalization'] = button['label']
|
121
|
+
button['label'] = data['$objects'][raw_button['customLabel']]
|
122
|
+
end
|
123
|
+
if idx == 0 && raw_button['isLinked'] && board_ids[button_counter + 1]
|
124
|
+
button['load_board'] = {
|
125
|
+
'id' => (button_counter + 1).to_s
|
126
|
+
}
|
127
|
+
end
|
128
|
+
grid['order'][i][j] = button['id']
|
129
|
+
buttons << button
|
130
|
+
end
|
131
|
+
button_counter += 1
|
132
|
+
end
|
133
|
+
end
|
134
|
+
board = {
|
135
|
+
'id' => idx.to_s,
|
136
|
+
'name' => name,
|
137
|
+
'buttons' => buttons,
|
138
|
+
'grid' => grid,
|
139
|
+
'ext_sfy_screen' => idx
|
140
|
+
}
|
141
|
+
boards << board
|
142
|
+
end
|
143
|
+
end
|
144
|
+
return {
|
145
|
+
'boards' => boards,
|
146
|
+
'images' => images,
|
147
|
+
'sounds' => []
|
148
|
+
}
|
149
|
+
end
|
150
|
+
end
|
data/lib/obf/unknown_file.rb
CHANGED
@@ -5,18 +5,29 @@ module OBF::UnknownFile
|
|
5
5
|
OBF::OBF.to_external(path, {})
|
6
6
|
elsif type == :obz
|
7
7
|
OBF::OBZ.to_external(path, {})
|
8
|
-
elsif type == :
|
9
|
-
OBF::
|
8
|
+
elsif type == :avz
|
9
|
+
OBF::Avz.to_external(path)
|
10
10
|
elsif type == :picto4me
|
11
11
|
OBF::Picto4me.to_external(path)
|
12
|
+
elsif type == :sfy
|
13
|
+
OBF::Sfy.to_external(path)
|
12
14
|
else
|
13
15
|
raise "unrecognized file type"
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
19
|
+
def self.to_obf_or_obz(path, dest_path_no_extension)
|
20
|
+
ext = to_external(path)
|
21
|
+
if !ext['boards'] || (ext['boards'] && ext['boards'].length == 1)
|
22
|
+
OBF::External.to_obf(ext, dest_path_no_extension + ".obf", {})
|
23
|
+
else
|
24
|
+
OBF::External.to_obz(ext, dest_path_no_extension + ".obz", {})
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
17
28
|
def self.to_obf(path, dest_path)
|
18
29
|
ext = to_external(path)
|
19
|
-
OBF::External.to_obf(ext, dest_path
|
30
|
+
OBF::External.to_obf(ext, dest_path)
|
20
31
|
end
|
21
32
|
|
22
33
|
def self.to_obz(path, dest_path)
|
data/lib/obf/utils.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'cfpropertylist'
|
1
2
|
module OBF::Utils
|
2
3
|
def self.get_url(url)
|
3
4
|
return nil unless url
|
@@ -26,42 +27,55 @@ module OBF::Utils
|
|
26
27
|
}
|
27
28
|
end
|
28
29
|
|
29
|
-
def self.identify_file(
|
30
|
-
name = File.basename(
|
30
|
+
def self.identify_file(path)
|
31
|
+
name = File.basename(path) rescue nil
|
31
32
|
if name.match(/\.obf$/)
|
32
33
|
return :obf
|
33
34
|
elsif name.match(/\.obz$/)
|
34
35
|
return :obz
|
35
36
|
elsif name.match(/\.avz$/)
|
36
|
-
return :
|
37
|
+
return :avz
|
37
38
|
else
|
38
|
-
json = JSON.parse(
|
39
|
+
json = JSON.parse(File.read(path)) rescue nil
|
39
40
|
if json
|
40
41
|
if json['format'] && json['format'].match(/^open-board-/)
|
41
42
|
return :obf
|
42
43
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
44
|
+
return :unknown
|
45
|
+
end
|
46
|
+
|
47
|
+
begin
|
48
|
+
plist = CFPropertyList::List.new(:file => path) rescue nil
|
49
|
+
plist_data = CFPropertyList.native_types(plist.value) rescue nil
|
50
|
+
if plist_data
|
51
|
+
if plist_data['$objects'] && plist_data['$objects'].any?{|o| o['$classname'] == 'SYWord' }
|
52
|
+
return :sfy
|
53
|
+
end
|
54
|
+
return :unknown
|
55
|
+
end
|
56
|
+
rescue CFFormatError => e
|
57
|
+
end
|
58
|
+
|
59
|
+
begin
|
60
|
+
type = nil
|
61
|
+
load_zip(path) do |zipper|
|
62
|
+
if zipper.glob('manifest.json').length > 0
|
63
|
+
json = JSON.parse(zipper.read('manifest.json')) rescue nil
|
64
|
+
if json['root'] && json['format'] && json['format'].match(/^open-board-/)
|
65
|
+
type = :obz
|
52
66
|
end
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
67
|
+
end
|
68
|
+
if !type && zipper.glob('*.js').length > 0
|
69
|
+
json = JSON.parse(zipper.read('*.js')) rescue nil
|
70
|
+
if json['locale'] && json['sheets']
|
71
|
+
type = :picto4me
|
58
72
|
end
|
59
73
|
end
|
60
|
-
|
74
|
+
end
|
75
|
+
return type if type
|
61
76
|
# rescue => e
|
62
77
|
# puts e.class.to_s
|
63
78
|
# puts e.message.to_s
|
64
|
-
end
|
65
79
|
end
|
66
80
|
end
|
67
81
|
return :unknown
|
@@ -123,7 +137,8 @@ module OBF::Utils
|
|
123
137
|
elsif image['raw_data']
|
124
138
|
file.write image['raw_data']
|
125
139
|
else
|
126
|
-
|
140
|
+
file.close
|
141
|
+
return nil
|
127
142
|
end
|
128
143
|
file.close
|
129
144
|
`convert #{file.path} -density 1200 -resize 300x300 -background none -gravity center -extent 300x300 #{file.path}.png`
|
@@ -246,6 +261,10 @@ module OBF::Utils
|
|
246
261
|
entry = @zipfile.glob(path).first
|
247
262
|
entry ? entry.get_input_stream.read : nil
|
248
263
|
end
|
264
|
+
|
265
|
+
def glob(path)
|
266
|
+
@zipfile.glob(path)
|
267
|
+
end
|
249
268
|
|
250
269
|
def read_as_data(path)
|
251
270
|
attrs = {}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: obf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Whitmer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -118,13 +118,14 @@ files:
|
|
118
118
|
- LICENSE
|
119
119
|
- README.md
|
120
120
|
- lib/obf.rb
|
121
|
-
- lib/obf/
|
121
|
+
- lib/obf/avz.rb
|
122
122
|
- lib/obf/external.rb
|
123
123
|
- lib/obf/obf.rb
|
124
124
|
- lib/obf/obz.rb
|
125
125
|
- lib/obf/pdf.rb
|
126
126
|
- lib/obf/picto4me.rb
|
127
127
|
- lib/obf/png.rb
|
128
|
+
- lib/obf/sfy.rb
|
128
129
|
- lib/obf/unknown_file.rb
|
129
130
|
- lib/obf/utils.rb
|
130
131
|
- lib/tinycolor_convert.js
|