spreadsheet_architect 1.4.8 → 2.0.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.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -2
  3. data/README.md +117 -98
  4. data/Rakefile +8 -1
  5. data/lib/generators/spreadsheet_architect/add_project_defaults_generator.rb +12 -3
  6. data/lib/spreadsheet_architect.rb +19 -330
  7. data/lib/spreadsheet_architect/action_controller_renderers.rb +9 -19
  8. data/lib/spreadsheet_architect/class_methods/csv.rb +22 -0
  9. data/lib/spreadsheet_architect/class_methods/ods.rb +61 -0
  10. data/lib/spreadsheet_architect/class_methods/xlsx.rb +162 -0
  11. data/lib/spreadsheet_architect/exceptions.rb +47 -0
  12. data/lib/spreadsheet_architect/{set_mime_types.rb → mime_types.rb} +0 -2
  13. data/lib/spreadsheet_architect/monkey_patches/axlsx_column_width.rb +23 -0
  14. data/lib/spreadsheet_architect/utils.rb +223 -0
  15. data/lib/spreadsheet_architect/utils/xlsx.rb +126 -0
  16. data/lib/spreadsheet_architect/version.rb +1 -1
  17. data/test/rails_app/Gemfile +17 -0
  18. data/test/rails_app/Gemfile.lock +176 -0
  19. data/test/rails_app/README.md +24 -0
  20. data/test/rails_app/Rakefile +6 -0
  21. data/test/rails_app/app/assets/config/manifest.js +3 -0
  22. data/test/rails_app/app/assets/javascripts/application.js +16 -0
  23. data/test/rails_app/app/assets/javascripts/cable.js +13 -0
  24. data/test/rails_app/app/assets/stylesheets/application.css +15 -0
  25. data/test/rails_app/app/channels/application_cable/channel.rb +4 -0
  26. data/test/rails_app/app/channels/application_cable/connection.rb +4 -0
  27. data/test/rails_app/app/controllers/application_controller.rb +3 -0
  28. data/test/rails_app/app/controllers/spreadsheets_controller.rb +74 -0
  29. data/test/rails_app/app/helpers/application_helper.rb +2 -0
  30. data/test/rails_app/app/jobs/application_job.rb +2 -0
  31. data/test/rails_app/app/mailers/application_mailer.rb +4 -0
  32. data/test/rails_app/app/models/active_model_object.rb +14 -0
  33. data/test/rails_app/app/models/application_record.rb +3 -0
  34. data/test/rails_app/app/models/bad_plain_ruby_object.rb +3 -0
  35. data/test/rails_app/app/models/custom_post.rb +15 -0
  36. data/test/rails_app/app/models/plain_ruby_object.rb +19 -0
  37. data/test/rails_app/app/models/post.rb +3 -0
  38. data/test/rails_app/app/views/layouts/application.html.erb +14 -0
  39. data/test/rails_app/app/views/layouts/mailer.html.erb +13 -0
  40. data/test/rails_app/app/views/layouts/mailer.text.erb +1 -0
  41. data/test/rails_app/bin/bundle +3 -0
  42. data/test/rails_app/bin/rails +9 -0
  43. data/test/rails_app/bin/rake +9 -0
  44. data/test/rails_app/bin/setup +34 -0
  45. data/test/rails_app/bin/spring +16 -0
  46. data/test/rails_app/bin/update +29 -0
  47. data/test/rails_app/config.ru +5 -0
  48. data/test/rails_app/config/application.rb +15 -0
  49. data/test/rails_app/config/boot.rb +3 -0
  50. data/test/rails_app/config/cable.yml +9 -0
  51. data/test/rails_app/config/database.yml +16 -0
  52. data/test/rails_app/config/environment.rb +5 -0
  53. data/test/rails_app/config/environments/development.rb +54 -0
  54. data/test/rails_app/config/environments/production.rb +86 -0
  55. data/test/rails_app/config/environments/test.rb +42 -0
  56. data/test/rails_app/config/initializers/application_controller_renderer.rb +6 -0
  57. data/test/rails_app/config/initializers/assets.rb +11 -0
  58. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  59. data/test/rails_app/config/initializers/cookies_serializer.rb +5 -0
  60. data/test/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
  61. data/test/rails_app/config/initializers/inflections.rb +16 -0
  62. data/test/rails_app/config/initializers/mime_types.rb +4 -0
  63. data/test/rails_app/config/initializers/new_framework_defaults.rb +24 -0
  64. data/test/rails_app/config/initializers/session_store.rb +3 -0
  65. data/test/rails_app/config/initializers/wrap_parameters.rb +14 -0
  66. data/test/rails_app/config/locales/en.yml +23 -0
  67. data/test/rails_app/config/routes.rb +7 -0
  68. data/test/rails_app/config/secrets.yml +22 -0
  69. data/test/{spreadsheet_architect.sqlite3.db → rails_app/db/development.sqlite3} +0 -0
  70. data/test/rails_app/db/migrate/20170103234524_add_posts.rb +10 -0
  71. data/test/rails_app/db/schema.rb +23 -0
  72. data/test/rails_app/db/seeds.rb +7 -0
  73. data/test/rails_app/db/test.sqlite3 +0 -0
  74. data/test/rails_app/log/development.log +1195 -0
  75. data/test/rails_app/log/test.log +52766 -0
  76. data/test/rails_app/public/404.html +67 -0
  77. data/test/rails_app/public/422.html +67 -0
  78. data/test/rails_app/public/500.html +66 -0
  79. data/test/rails_app/public/apple-touch-icon-precomposed.png +0 -0
  80. data/test/rails_app/public/apple-touch-icon.png +0 -0
  81. data/test/rails_app/public/favicon.ico +0 -0
  82. data/test/rails_app/public/robots.txt +5 -0
  83. data/test/rails_app/test/controllers/spreadsheets_controller_test.rb +46 -0
  84. data/test/rails_app/test/models/active_model_object_test.rb +54 -0
  85. data/test/rails_app/test/models/bad_plain_ruby_object_test.rb +30 -0
  86. data/test/rails_app/test/models/csv_test.rb +60 -0
  87. data/test/rails_app/test/models/custom_post_test.rb +47 -0
  88. data/test/rails_app/test/models/ods_test.rb +68 -0
  89. data/test/rails_app/test/models/plain_ruby_object_test.rb +54 -0
  90. data/test/rails_app/test/models/post_test.rb +47 -0
  91. data/test/rails_app/test/models/spreadsheet_architect_utils_test.rb +68 -0
  92. data/test/rails_app/test/models/xlsx_test.rb +99 -0
  93. data/test/rails_app/test/test_helper.rb +21 -0
  94. data/test/rails_app/tmp/active_model_object/csv.csv +21 -0
  95. data/test/rails_app/tmp/active_model_object/ods.ods +0 -0
  96. data/test/rails_app/tmp/active_model_object/xlsx.xlsx +0 -0
  97. data/test/rails_app/tmp/controller_tests/alt_xlsx.xlsx +0 -0
  98. data/test/rails_app/tmp/controller_tests/csv.csv +1 -0
  99. data/test/rails_app/tmp/controller_tests/ods.ods +0 -0
  100. data/test/rails_app/tmp/controller_tests/xlsx.xlsx +0 -0
  101. data/test/rails_app/tmp/custom_posts/csv.csv +1 -0
  102. data/test/rails_app/tmp/custom_posts/empty.xlsx +0 -0
  103. data/test/rails_app/tmp/custom_posts/ods.ods +0 -0
  104. data/test/rails_app/tmp/custom_posts/xlsx.xlsx +0 -0
  105. data/test/rails_app/tmp/empty_model.csv +1 -0
  106. data/test/rails_app/tmp/empty_model.xlsx +0 -0
  107. data/test/rails_app/tmp/empty_sa.csv +0 -0
  108. data/test/rails_app/tmp/empty_sa.xlsx +0 -0
  109. data/test/rails_app/tmp/extreme.xlsx +0 -0
  110. data/test/rails_app/tmp/model.csv +1 -0
  111. data/test/rails_app/tmp/model.xlsx +0 -0
  112. data/test/rails_app/tmp/ods/empty_model.ods +0 -0
  113. data/test/rails_app/tmp/ods/empty_sa.ods +0 -0
  114. data/test/rails_app/tmp/ods/model.ods +0 -0
  115. data/test/rails_app/tmp/ods/model_options.ods +0 -0
  116. data/test/rails_app/tmp/ods/sa.ods +0 -0
  117. data/test/rails_app/tmp/options.csv +1 -0
  118. data/test/rails_app/tmp/plain_ruby_object/csv.csv +4 -0
  119. data/test/rails_app/tmp/plain_ruby_object/ods.ods +0 -0
  120. data/test/rails_app/tmp/plain_ruby_object/xlsx.xlsx +0 -0
  121. data/test/rails_app/tmp/posts/csv.csv +1 -0
  122. data/test/rails_app/tmp/posts/empty.xlsx +0 -0
  123. data/test/rails_app/tmp/posts/ods.ods +0 -0
  124. data/test/rails_app/tmp/posts/xlsx.xlsx +0 -0
  125. data/test/rails_app/tmp/sa.csv +4 -0
  126. data/test/rails_app/tmp/sa.xlsx +0 -0
  127. metadata +255 -21
  128. data/lib/spreadsheet_architect/axlsx_column_width_patch.rb +0 -13
  129. data/test/database.yml +0 -3
  130. data/test/helper.rb +0 -52
  131. data/test/tc_spreadsheet_architect.rb +0 -84
@@ -0,0 +1,68 @@
1
+ require 'test_helper'
2
+
3
+ class OdsTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ DatabaseCleaner.start
7
+
8
+ FileUtils.mkdir_p('tmp/ods')
9
+
10
+ 10.times.each do
11
+ CustomPost.create(name: SecureRandom.hex, content: SecureRandom.hex, age: 2)
12
+ end
13
+
14
+ @headers = ['test1', 'test2','test3']
15
+ @data = [
16
+ ['row1','test1'],
17
+ ['row2 c1', nil, '123'],
18
+ ['the',Date.today,Time.now]
19
+ ]
20
+ @options = {
21
+ headers: true,
22
+ header_style: {background_color: 'AAAAAA', color: 'FFFFFF', align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},
23
+ row_style: {background_color: nil, color: '000000', align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},
24
+ sheet_name: 'My Project Export',
25
+ column_styles: [],
26
+ range_styles: [],
27
+ merges: [],
28
+ borders: [],
29
+ column_types: [:string, :date, :date]
30
+ }
31
+ end
32
+
33
+ def test_empty_model
34
+ CustomPost.delete_all
35
+ File.open('tmp/ods/empty_model.ods','w+b') do |f|
36
+ f.write CustomPost.to_ods
37
+ end
38
+ end
39
+
40
+ def test_empty_sa
41
+ File.open('tmp/ods/empty_sa.ods','w+b') do |f|
42
+ f.write SpreadsheetArchitect.to_ods(data: [])
43
+ end
44
+ end
45
+
46
+ def test_sa
47
+ File.open('tmp/ods/sa.ods','w+b') do |f|
48
+ f.write SpreadsheetArchitect.to_ods(headers: @headers, data: @data)
49
+ end
50
+ end
51
+
52
+ def test_model
53
+ File.open('tmp/ods/model.ods','w+b') do |f|
54
+ f.write CustomPost.to_ods
55
+ end
56
+ end
57
+
58
+ def test_options
59
+ File.open('tmp/ods/model_options.ods','w+b') do |f|
60
+ f.write CustomPost.to_ods(@options)
61
+ end
62
+ end
63
+
64
+ def teardown
65
+ DatabaseCleaner.clean
66
+ end
67
+
68
+ end
@@ -0,0 +1,54 @@
1
+ require "test_helper"
2
+
3
+ class PlainRubyObjectTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ @path = 'tmp/plain_ruby_object'
7
+ FileUtils.mkdir_p(@path)
8
+
9
+ DatabaseCleaner.start
10
+ end
11
+
12
+ def test_csv
13
+ assert_raise SpreadsheetArchitect::Exceptions::NoInstancesError do
14
+ PlainRubyObject.to_csv
15
+ end
16
+
17
+ instances = 3.times.map{|_| PlainRubyObject.new}
18
+ data = PlainRubyObject.to_csv(instances: instances)
19
+
20
+ File.open(File.join(@path, 'csv.csv'), 'w+b') do |f|
21
+ f.write data
22
+ end
23
+ end
24
+
25
+ def test_ods
26
+ assert_raise SpreadsheetArchitect::Exceptions::NoInstancesError do
27
+ PlainRubyObject.to_ods
28
+ end
29
+
30
+ instances = 3.times.map{|_| PlainRubyObject.new}
31
+ data = PlainRubyObject.to_ods(instances: instances)
32
+
33
+ File.open(File.join(@path, 'ods.ods'), 'w+b') do |f|
34
+ f.write data
35
+ end
36
+ end
37
+
38
+ def test_xlsx
39
+ assert_raise SpreadsheetArchitect::Exceptions::NoInstancesError do
40
+ PlainRubyObject.to_xlsx
41
+ end
42
+
43
+ instances = 3.times.map{|_| PlainRubyObject.new}
44
+ data = PlainRubyObject.to_xlsx(instances: instances)
45
+
46
+ File.open(File.join(@path, 'xlsx.xlsx'), 'w+b') do |f|
47
+ f.write data
48
+ end
49
+ end
50
+
51
+ def teardown
52
+ DatabaseCleaner.clean
53
+ end
54
+ end
@@ -0,0 +1,47 @@
1
+ require "test_helper"
2
+
3
+ class PostTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ @path = 'tmp/posts'
7
+ FileUtils.mkdir_p(@path)
8
+
9
+ DatabaseCleaner.start
10
+ end
11
+
12
+ def test_csv
13
+ data = Post.to_csv
14
+
15
+ File.open(File.join(@path, 'csv.csv'), 'w+b') do |f|
16
+ f.write data
17
+ end
18
+ end
19
+
20
+ def test_ods
21
+ data = Post.to_ods
22
+
23
+ File.open(File.join(@path, 'ods.ods'), 'w+b') do |f|
24
+ f.write data
25
+ end
26
+ end
27
+
28
+ def test_xlsx
29
+ data = Post.all.to_xlsx
30
+
31
+ File.open(File.join(@path, 'xlsx.xlsx'), 'w+b') do |f|
32
+ f.write data
33
+ end
34
+ end
35
+
36
+ def test_empty
37
+ Post.destroy_all
38
+
39
+ File.open(File.join(@path, 'empty.xlsx'), 'w+b') do |f|
40
+ f.write Post.to_xlsx
41
+ end
42
+ end
43
+
44
+ def teardown
45
+ DatabaseCleaner.clean
46
+ end
47
+ end
@@ -0,0 +1,68 @@
1
+ require 'test_helper'
2
+
3
+ class SpreadsheetArchitectUtilsTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ @headers = ['test1', 'test2','test3']
7
+ @data = [
8
+ ['row1'],
9
+ ['row2 c1', 'row2 c2'],
10
+ ['the','data']
11
+ ]
12
+ @options = {
13
+ headers: true,
14
+ header_style: {background_color: 'AAAAAA', color: 'FFFFFF', align: :center, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},
15
+ row_style: {background_color: nil, color: '000000', align: :left, font_name: 'Arial', font_size: 10, bold: false, italic: false, underline: false},
16
+ sheet_name: 'My Project Export',
17
+ column_styles: [],
18
+ range_styles: [],
19
+ merges: [],
20
+ borders: [],
21
+ column_types: [],
22
+ data: []
23
+ }
24
+ end
25
+
26
+ def test_str_humanize
27
+ assert_equal(SpreadsheetArchitect::Utils.str_humanize('my_project_export'), 'My Project Export')
28
+ assert_equal(SpreadsheetArchitect::Utils.str_humanize('My Project Export'), 'My Project Export')
29
+ assert_equal(SpreadsheetArchitect::Utils.str_humanize('TBS report'), 'TBS Report')
30
+ end
31
+
32
+ def test_get_type
33
+ assert_equal(SpreadsheetArchitect::Utils::XLSX.get_type('string'), :string)
34
+ assert_equal(SpreadsheetArchitect::Utils::XLSX.get_type(123.01), :float)
35
+ assert_equal(SpreadsheetArchitect::Utils::XLSX.get_type(BigDecimal('123.01')), :float)
36
+ assert_equal(SpreadsheetArchitect::Utils::XLSX.get_type(10), :integer)
37
+ assert_equal(SpreadsheetArchitect::Utils::XLSX.get_type(:test), :string)
38
+ assert_equal(SpreadsheetArchitect::Utils::XLSX.get_type(Time.now.to_date), :date)
39
+ assert_equal(SpreadsheetArchitect::Utils::XLSX.get_type(DateTime.now), :time)
40
+ assert_equal(SpreadsheetArchitect::Utils::XLSX.get_type(Time.now), :time)
41
+ end
42
+
43
+ def test_get_cell_data
44
+ SpreadsheetArchitect::Utils.get_cell_data(@options, SpreadsheetArchitect)
45
+
46
+ SpreadsheetArchitect::Utils.get_cell_data(@options, Post)
47
+ end
48
+
49
+ def test_get_options
50
+ SpreadsheetArchitect::Utils.get_options(@options, SpreadsheetArchitect)
51
+
52
+ SpreadsheetArchitect::Utils.get_options(@options, Post)
53
+ end
54
+
55
+ def test_convert_styles_to_axlsx
56
+ xlsx_styles = SpreadsheetArchitect::Utils::XLSX.convert_styles_to_axlsx({background_color: '333333', color: '000000', align: true, bold: true, font_size: 14, italic: true, underline: true, test: true})
57
+ assert_equal(xlsx_styles, {bg_color: '333333', fg_color: '000000', alignment: {horizontal: true}, b: true, sz: 14, i: true, u: true, test: true})
58
+ end
59
+
60
+ def test_convert_styles_to_ods
61
+ ods_styles = SpreadsheetArchitect::Utils.convert_styles_to_ods({background_color: '333333', color: '000000', align: true, bold: true, font_size: 14, italic: true, underline: true, test: true})
62
+ assert_equal(ods_styles, {'cell' => {'background-color' => '#333333'}, 'text' => {'color' => '#000000', 'align' => true, 'font-weight' => 'bold', 'font-size' => 14, 'font-style' => 'italic', 'text-underline-type' => 'single', 'text-underline-style' => 'solid'}})
63
+ end
64
+
65
+ def teardown
66
+ DatabaseCleaner.clean
67
+ end
68
+ end
@@ -0,0 +1,99 @@
1
+ require 'test_helper'
2
+
3
+ class XlsxTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ @headers = ['test1', 'test2','test3']
7
+ @data = [
8
+ ['row1'],
9
+ ['row2 c1', 'row2 c2'],
10
+ ['the','data']
11
+ ]
12
+ end
13
+
14
+ def test_empty_model
15
+ Post.delete_all
16
+ File.open('tmp/empty_model.xlsx','w+b') do |f|
17
+ f.write Post.to_xlsx
18
+ end
19
+ end
20
+
21
+ def test_empty_sa
22
+ File.open('tmp/empty_sa.xlsx','w+b') do |f|
23
+ f.write SpreadsheetArchitect.to_xlsx(data: [])
24
+ end
25
+ end
26
+
27
+ def test_sa
28
+ File.open('tmp/sa.xlsx','w+b') do |f|
29
+ f.write SpreadsheetArchitect.to_xlsx(headers: @headers, data: @data)
30
+ end
31
+ end
32
+
33
+ def test_model
34
+ File.open('tmp/model.xlsx','w+b') do |f|
35
+ f.write Post.to_xlsx
36
+ end
37
+ end
38
+
39
+ def test_extreme
40
+ headers = [
41
+ ['Latest Posts'],
42
+ ['Title','Category','Author','Posted on','Earnings']
43
+ ]
44
+
45
+ data = 50.times.map{|x| ['Title','Category','Author','Posted on','Earnings']}
46
+
47
+ header_style = {}
48
+
49
+ row_style = {}
50
+
51
+ column_styles = [
52
+ {columns: 0, styles: {bold: true}},
53
+ {columns: (1..3), styles: {format_code: "$#,##0.00"}},
54
+ {columns: [4], include_header: true, styles: {italic: true}}
55
+ ]
56
+
57
+ range_styles = [
58
+ {range: "B2:C4", styles: {background_color: "CCCCCC"}},
59
+ {range: {rows: 1, columns: :all}, styles: {bold: true}},
60
+ {range: {rows: (0..5), columns: (1..4)}, styles: {italic: true}},
61
+ {range: {rows: :all, columns: (3..4)}, styles: {color: "FFFFFF"}}
62
+ ]
63
+
64
+ borders = [
65
+ {range: "B2:C4"},
66
+ {range: "D6:D7", border_styles: {style: :dashDot, color: "333333"}},
67
+ {range: {rows: (2..11), columns: :all}, border_styles: {edges: [:top,:bottom]}},
68
+ {range: {rows: 3, columns: 4}, border_styles: {edges: [:top,:bottom]}}
69
+ ]
70
+
71
+ merges = [
72
+ {range: "A1:C1"},
73
+ {range: {rows: 0, columns: :all}},
74
+ {range: {rows: (0..1), columns: (0..3)}}
75
+ ]
76
+
77
+
78
+ # Using Array Data
79
+ file_data = SpreadsheetArchitect.to_xlsx({
80
+ headers: headers,
81
+ data: data,
82
+ header_style: header_style,
83
+ row_style: row_style,
84
+ column_styles: column_styles,
85
+ range_styles: range_styles,
86
+ borders: borders,
87
+ merges: merges
88
+ })
89
+
90
+ File.open('tmp/extreme.xlsx','w+b') do |f|
91
+ f.write file_data
92
+ end
93
+ end
94
+
95
+ def teardown
96
+ DatabaseCleaner.clean
97
+ end
98
+
99
+ end
@@ -0,0 +1,21 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+
3
+ require File.expand_path("../../config/environment", __FILE__)
4
+
5
+ ActiveRecord::Migrator.migrate("db/migrate")
6
+
7
+ require "rails/test_help"
8
+ require "minitest/rails"
9
+ require 'minitest/pride'
10
+ require 'minitest/reporters'
11
+ require 'database_cleaner'
12
+
13
+ Minitest::Reporters.use!
14
+ DatabaseCleaner.strategy = :transaction
15
+
16
+ class ActiveSupport::TestCase
17
+ # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
18
+ fixtures :all
19
+
20
+ # Add more helper methods to be used by all tests here...
21
+ end
@@ -0,0 +1,21 @@
1
+ Name,Content,Created At
2
+ asd,asd,2017-01-28 14:29:58 -0800
3
+ asd,asd,2017-01-28 14:29:58 -0800
4
+ asd,asd,2017-01-28 14:29:58 -0800
5
+ asd,asd,2017-01-28 14:29:58 -0800
6
+ asd,asd,2017-01-28 14:29:58 -0800
7
+ asd,asd,2017-01-28 14:29:58 -0800
8
+ asd,asd,2017-01-28 14:29:58 -0800
9
+ asd,asd,2017-01-28 14:29:58 -0800
10
+ asd,asd,2017-01-28 14:29:58 -0800
11
+ asd,asd,2017-01-28 14:29:58 -0800
12
+ asd,asd,2017-01-28 14:29:58 -0800
13
+ asd,asd,2017-01-28 14:29:58 -0800
14
+ asd,asd,2017-01-28 14:29:58 -0800
15
+ asd,asd,2017-01-28 14:29:58 -0800
16
+ asd,asd,2017-01-28 14:29:58 -0800
17
+ asd,asd,2017-01-28 14:29:58 -0800
18
+ asd,asd,2017-01-28 14:29:58 -0800
19
+ asd,asd,2017-01-28 14:29:58 -0800
20
+ asd,asd,2017-01-28 14:29:58 -0800
21
+ asd,asd,2017-01-28 14:29:58 -0800
@@ -0,0 +1 @@
1
+ Name,Content,Age
@@ -0,0 +1 @@
1
+ Name,Content,Age
Binary file
File without changes
Binary file
Binary file
@@ -0,0 +1 @@
1
+ Name,Content,Age
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ Name,Content,Age