Skip to content

Instantly share code, notes, and snippets.

@mikker
Created February 23, 2022 14:06
Show Gist options
  • Save mikker/87462de6acdc6d06989f9aadcf111b0e to your computer and use it in GitHub Desktop.
Save mikker/87462de6acdc6d06989f9aadcf111b0e to your computer and use it in GitHub Desktop.

Revisions

  1. mikker created this gist Feb 23, 2022.
    42 changes: 42 additions & 0 deletions 0_sort.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,42 @@
    require_relative "sheet.rb"
    require 'digest'

    CURRENT_BLOCK = 12345
    COMMUNITY_REACTIONS = 54321

    def main
    sheet = Sheet.new('Metadata/InvisibleFriends_Metadata.csv')

    sheet.headers.concat(['Seed', 'Filename', 'SHA256'])

    puts "Extending metadata"
    sheet.each do |row|
    padded_id = row["Number"].rjust(5, '0')
    gif_path = "GIFs/INVISIBLE_FRIENDS_#{padded_id}.gif"

    row["Seed"] = row["Number"]
    row["Filename"] = gif_path
    row["SHA256"] = shasum(gif_path)
    print '.'
    end
    puts ""

    sorted = sheet.dup
    sorted.data.sort! { |a, b| a.fetch("SHA256") <=> b.fetch("SHA256") }
    sorted.data.shuffle!(random: Random.new(CURRENT_BLOCK))
    sorted.data.rotate!(COMMUNITY_REACTIONS)

    sorted.each_with_index { |row, i| row['Number'] = i + 1 }

    sorted.save("Metadata/enriched_and_sorted.csv")

    combined_shasum = sorted.reduce("") { |str, row| str + row["SHA256"] }
    provenance = Digest::SHA256.hexdigest(combined_shasum)
    File.open('provenance.txt', 'w') { |f| f << provenance }
    end

    def shasum(path)
    `shasum -a 256 "#{path}" | awk '{ print $1 }'`.chomp
    end

    main
    130 changes: 130 additions & 0 deletions 1_sheet.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@
    require "csv"

    class Sheet
    include Enumerable

    def initialize(path, **opts)
    @path = path
    @csv = CSV.read(path, headers: true, **opts)
    @data = csv.map(&:to_h)
    @headers = csv.first.headers
    end

    attr_accessor :data
    attr_reader :csv, :headers, :dest

    def each(&block)
    data.each(&block)
    end

    def generate
    each.reduce([headers.join(';')]) do |csv, row|
    csv.push(headers.map { |h| row[h] }.join(';'))
    end.join("\n")
    end

    def save(dest)
    File.open(dest, 'w') do |f|
    f << generate
    end
    end
    end

    if $0 == __FILE__
    require "rubygems"
    require "rspec"
    require "fileutils"

    RSpec.describe Sheet do
    let(:sheet) do
    <<-CSV
    a,b,c
    one,two,three
    x,y,z
    CSV
    end

    let(:path) { "test.csv" }

    before do
    File.open(path, "w") { |w| w << sheet }
    end

    subject do
    Sheet.new(path)
    end

    it "loads sheet data" do
    expect(subject.each.to_a).to(
    eq(
    [
    {
    "a" => "one",
    "b" => "two",
    "c" => "three"
    },
    {
    "a" => "x",
    "b" => "y",
    "c" => "z"
    }
    ]
    )
    )
    end

    it 'loads sheet headers' do
    expect(subject.headers).to eq(%w[a b c])
    end

    it 'can regenerate' do
    subject.data[0]['c'] = 'hello!'
    expect(subject.generate).to eq(
    <<-CSV
    a,b,c
    one,two,hello!
    x,y,z
    CSV
    .chomp
    )
    end

    it 'can add a header' do
    subject.headers.push('more')

    expect(subject.generate).to eq(
    <<-CSV
    a,b,c,more
    one,two,three,
    x,y,z,
    CSV
    .chomp
    )
    end

    it "can't save a copy with a path" do
    expect do
    subject.save
    end.to raise_error(ArgumentError)
    end

    it "can save a copy with a path" do
    out_path = 'test-output.csv'

    FileUtils.rm_rf(out_path)

    subject.save(out_path)

    expect(File.read(out_path)).to eq(
    <<-CSV
    a,b,c
    one,two,three
    x,y,z
    CSV
    .chomp
    )
    end
    end

    RSpec::Core::Runner.run([__FILE__])
    end