Skip to content

Commit 776df1b

Browse files
committed
Add a CSV Result analyzer
1 parent 7b7695a commit 776df1b

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed

README.md

+33-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,39 @@ bundle add shopify_toolkit
2222

2323
## Usage
2424

25-
TODO
25+
### Analyzing a Matrixify CSV Result files
26+
27+
Matrixify is a popular Shopify app that allows you to import/export data from Shopify using CSV files. The CSV files that Matrixify generates are very verbose and can be difficult to work with. This tool allows you to analyze the CSV files and extract the data you need.
28+
29+
The tool will import the file into a local SQLite database
30+
and open a console for you to run queries against the data
31+
using ActiveRecord.
32+
33+
```shell
34+
shopify-csv analyze products-result.csv --force-import
35+
==> Importing products-result.csv into /var/folders/hn/z7b7s1kj3js4k7_qk3lj27kr0000gn/T/shopify-toolkit-analyze-products_result_csv.sqlite3
36+
-- create_table(:results, {:force=>true})
37+
-> 0.0181s
38+
-- add_index(:results, :import_result)
39+
-> 0.0028s
40+
........................
41+
==> Starting console for products-result.csv
42+
>> comments
43+
=>
44+
["UPDATE: Found by Handle | Assuming MERGE for Variant Command | Assuming MERGE for Tags Command | Variants updated by SKU: 1",
45+
"UPDATE: Found by Handle | Assuming MERGE for Variant Command | Assuming MERGE for Tags Command | Variants updated by SKU: 1 | Warning: The following media were not uploaded to Shopify: [https://mymedia.com/image.jpg: Error downloading from Web: 302 Moved Temporarily]",
46+
...]
47+
>> first
48+
#<ShopifyCSV::Result:0x0000000300bf1668
49+
id: 1,
50+
data: nil,
51+
handle: "my-product",
52+
title: "My Product",
53+
import_result: "OK",
54+
import_comment: "UPDATE: Found by Handle | Assuming MERGE for Varia...">
55+
>> count
56+
=> 116103
57+
```
2658

2759
## Development
2860

exe/shopify-csv

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env ruby
2+
3+
require 'csv'
4+
require 'active_record'
5+
require 'thor'
6+
require 'tmpdir'
7+
8+
class ShopifyCSV < Thor
9+
RESERVED_COLUMN_NAMES = %w[select type id]
10+
11+
class Result < ActiveRecord::Base
12+
def self.comments
13+
distinct.pluck(:import_comment)
14+
end
15+
16+
def self.with_comment(text)
17+
where("import_comment LIKE ?", "%#{text}%")
18+
end
19+
end
20+
21+
desc "analyze CSV_PATH", "Analyze results file at path CSV_PATH"
22+
method_option :force_import, type: :boolean, default: false
23+
method_option :tmp_dir, type: :string, default: Dir.tmpdir
24+
def analyze(csv_path)
25+
csv_path = File.expand_path(csv_path)
26+
underscore = ->(string) { string.downcase.gsub(/[^a-z0-9]+/, "_").gsub(/(^_+|_+$)/, "") }
27+
csv = CSV.open(csv_path, liberal_parsing:true )
28+
header_to_column = -> { RESERVED_COLUMN_NAMES.include?(_1.to_s) ? "#{_1}_1" : _1 }
29+
headers = csv.shift.map(&underscore).map(&header_to_column)
30+
basename = File.basename csv_path
31+
database = "#{options[:tmp_dir]}/shopify-toolkit-analyze-#{underscore[basename]}.sqlite3"
32+
should_import = options[:force_import] || !File.exist?(database)
33+
to_record = ->(row) { headers.zip(row).to_h.transform_keys(&header_to_column) }
34+
35+
File.delete(database) if should_import && File.exist?(database)
36+
37+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database:)
38+
39+
if should_import
40+
puts "==> Importing #{csv_path}"
41+
puts "-- database: #{database}"
42+
ActiveRecord::Schema.define do
43+
create_table :results, force: true do |t|
44+
t.json :data
45+
headers.each { |header| t.string header }
46+
end
47+
add_index :results, :import_result if headers.include?('import_result')
48+
end
49+
csv.each_slice(5000) { |rows| print "."; Result.insert_all(rows.map(&to_record)) }
50+
puts
51+
end
52+
53+
puts "==> Starting console for #{basename}"
54+
require "irb"
55+
IRB.conf[:IRB_NAME] = basename
56+
Result.class_eval { binding.irb(show_code: false) }
57+
end
58+
end
59+
60+
ShopifyCSV.start(ARGV)

0 commit comments

Comments
 (0)