Skip to content

Instantly share code, notes, and snippets.

@danfinnie
Last active August 29, 2015 14:23
Show Gist options
  • Save danfinnie/4a6b55496ac1eac9b53f to your computer and use it in GitHub Desktop.
Save danfinnie/4a6b55496ac1eac9b53f to your computer and use it in GitHub Desktop.
Move files into directories based on dates in filenames
require 'fileutils'
require 'securerandom'
require 'pp'
require 'shellwords'
=begin
Given pictures in subdirectories structured as year/month/date/picture.jpg,
output year-month-date.tar.bz2.gpg and keys.txt.
Where:
* year-month-date.tar.bz2.gpg is an encrypted and compressed archive of the directory.
* keys.txt contains the randomly generated encryption keys for the files (one per file).
Then, store keys.txt securely (LastPass?) and upload the tarballs whereever.
=end
$passphrase_chars = [(?A..?Z), (?a..?z), (?0..?9)].map(&:to_a).flatten + %w[@ # $ % ^ & *]
$passphrase_length = 30
$dry_run = false
$output_dir = "output"
$keys_file = File.join($output_dir, "keys.txt")
FileUtils.mkdir_p($output_dir)
# If you run this multiple times, differentiate between program runs in the
# output
File.open($keys_file, "a+") do |f|
f.puts("-" * 50)
f.puts Time.now.to_s
end
def gen_passphrase
SecureRandom
.random_bytes($passphrase_length)
.unpack("C*")
.map { |i| $passphrase_chars[i % $passphrase_chars.size] }
.join
end
def sh str
$stderr.puts "+ #{str}"
unless $dry_run
Process.wait Process.spawn(str)
fail "subshell failed" if $?.exitstatus > 0
end
end
def esc str
Shellwords.shellescape(str)
end
Dir.glob("*/*/*").each do |directory|
next unless File.directory? directory
output_prefix = directory.gsub("/", "-")
passphrase = gen_passphrase
output_tar_file = "#{output_prefix}.tar.bz2"
File.open($keys_file, "a+") do |f|
f.puts([output_tar_file, passphrase].join("\t"))
end
sh %Q{tar cfj #{esc($output_dir + '/' + output_tar_file)} #{esc(directory)}}
sh %Q{gpg -c --no-use-agent --batch --passphrase #{esc(passphrase)} #{esc($output_dir + '/' + output_tar_file)}}
end
require 'fileutils'
require 'pp'
file_util_options = {verbose: true}
Dir.glob("*.{jpg,mp4}").each do |original_file_name|
matches = original_file_name.match(/^(\d{4})-(\d{2})-(\d{2})/)
next unless matches
year, month, day = matches[1..3]
directory = File.join(year, month, day)
FileUtils.mkdir_p(directory, file_util_options)
FileUtils.mv(original_file_name, File.join(directory, original_file_name), file_util_options)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment