Skip to content

Instantly share code, notes, and snippets.

@wiseleyb
Last active September 27, 2016 20:32
Show Gist options
  • Save wiseleyb/aab8474ef87d7c5d25070e3e83969ca3 to your computer and use it in GitHub Desktop.
Save wiseleyb/aab8474ef87d7c5d25070e3e83969ca3 to your computer and use it in GitHub Desktop.
=begin
This is a somewhat hacky user-recovery script that I hacked out at 3am after accidently deleting a bunch of users.
To use:
* get a good copy of the prod-db before you fucked up
* an array of user-ids you want to restore
* run users_to_yaml(user-ids)
* create a secret gist for each yml file created
* plug the urls of the gists into the Gists class
* paste this entire script into prod-con and pray
* delete the secret gists
Notes: The reason I'm using RecoverClass's instead of the normal class is we don't want to spam users and have all the validations/events fire. The remove const nonsense is necessary because of beloved STI Rails bullshit.
To get a prod db:
* heroku pg:backups --app zeemee-prod
* heroku pg:backups public-url a732 --app zeemee-prod
=end
require 'open-uri'
def users_to_yaml(uids)
users = User.where(id: uids)
f = File.open("tmp/recover/users.yml", 'w')
f << YAML::dump(users)
f.close
mim = MediaItemMetadata.where(user_id: uids)
f = File.open("tmp/recover/media_item_metadata.yml", 'w')
f << YAML::dump(mim)
f.close
p = Portfolio.where(user_id: uids)
f = File.open("tmp/recover/portfolios.yml", 'w')
f << YAML::dump(p)
f.close
pl = Placement.where(portfolio_id: p.map(&:id))
f = File.open("tmp/recover/placements.yml", 'w')
f << YAML::dump(pl)
f.close
# Photo, Video, Document
mim = MediaItemMetadata.where(user_id: uids)
mi = mim.map(&:media_item)
res = {}
[Photo, Video, Document].each do |klass|
res[klass.to_s.underscore] = mi.select {|r| r.is_a?(klass)}
end
res.each do |k, v|
f = File.open("tmp/recover/#{k}.yml", 'w')
f << YAML::dump(v)
f.close
end
s = Shoutout.where(user_id: uids)
f = File.open("tmp/recover/shoutouts.yml", 'w')
f << YAML::dump(s)
f.close
uos = UserOrganizationStatus.where(user_id: uids)
f = File.open("tmp/recover/uos.yml", 'w')
f << YAML::dump(uos)
f.close
end
class Gists
class << self
def media_item_metadata
'https://gist.githubusercontent.com/wiseleyb/eaf8c369c18ba6948978db59513e5b3a/raw/1d40064259c501b5abfb8e26bae26836c75ca5ee/media_item_metadata.yml'
end
def document
'https://gist.githubusercontent.com/wiseleyb/256dd15420aa1f3fed03342eb0d032f9/raw/90051f0dbfaa93754fffc16b8e1c46ddf44b7c8e/document.yml'
end
def photo
'https://gist.githubusercontent.com/wiseleyb/c40813ebd6575e772ee15c6154e67f49/raw/b2f27d166c088ad8b108b44aebc321bcc1de5c9a/photo.yml'
end
def video
'https://gist.githubusercontent.com/wiseleyb/ecc727401a7a8462edde9964ba279903/raw/b00c251210f5d7458dbdabb667cf9ed7cac45274/video.yml'
end
def placement
'https://gist.githubusercontent.com/wiseleyb/26ecf289c2263fa6dff73e3afb3af6f9/raw/8f356a75e9a4a9934e8eb9f8b7be6c2d6fe7e468/placements.yml'
end
def portfolio
'https://gist.githubusercontent.com/wiseleyb/28fe7853fc5f3885b4b163d437b497b5/raw/163c0272f8182076de9b1eb01fb3aaa1d237dcce/portfolios.yml'
end
def shoutout
'https://gist.githubusercontent.com/wiseleyb/12c705191f4309109268811dc6081430/raw/f08afea34c2b224ec2bf539a91cb32d65fffb329/shoutouts.yml'
end
def user_organization_status
'https://gist.githubusercontent.com/wiseleyb/f806ab86569772659022782e63c5d359/raw/66487736969165b8dc693c5759d2007ec1c8e682/uos.yml'
end
def user
'https://gist.githubusercontent.com/wiseleyb/c0028c57a5532f7050f0a9c762be6545/raw/b21f957a89516188ccf1a0f7fc45eff5ae547f44/users.yml'
end
end
end
def load_from_yaml(klass_name)
klass = "Recover#{klass_name}".constantize
url = Gists.send(klass_name.underscore)
objs = load_from_gist(url, klass_name).map do |r|
klass.new(r.attributes)
end
objs.each do |obj|
puts "#{klass_name}: #{obj.id}"
next if klass_name == 'User' && klass.find_by_slug(obj.slug)
next if klass.find_by_id(obj.id)
obj.save!
end
end
def load_from_gist(url, fname)
open("tmp/#{fname}.yml", 'wb') do |f|
f << open(url).read
end
YAML.load_file("tmp/#{fname}.yml")
end
class RecoverUser < ActiveRecord::Base
self.table_name = User.table_name
# MailchimpSubscribe.perform_later email, first_name, last_name
end
class Student < RecoverUser; end
class AdmissionsRep < RecoverUser; end
class RecoverMediaItemMetadata < ActiveRecord::Base
self.table_name = MediaItemMetadata.table_name
end
class RecoverPhoto < ActiveRecord::Base
self.table_name = Photo.table_name
end
class RecoverVideo < ActiveRecord::Base
self.table_name = Video.table_name
end
class RecoverDocument < ActiveRecord::Base
self.table_name = Document.table_name
end
class RecoverPlacement < ActiveRecord::Base
self.table_name = Placement.table_name
end
class RecoverPortfolio < ActiveRecord::Base
self.table_name = Portfolio.table_name
end
class RecoverShoutout < ActiveRecord::Base
self.table_name = Shoutout.table_name
end
class RecoverUserOrganizationStatus < ActiveRecord::Base
attr_accessor :pending_accepted, :acceptance_letter_url
self.table_name = UserOrganizationStatus.table_name
end
Object.send(:remove_const, Student.to_s)
class Student < RecoverUser; end
Object.send(:remove_const, AdmissionsRep.to_s)
class AdmissionsRep < RecoverUser; end
[User, UserOrganizationStatus, Shoutout,
Portfolio, Placement, Photo, Document,
MediaItemMetadata].each do |klass|
puts '*' * 80
puts "Loading #{klass.to_s}"
load_from_yaml(klass.to_s)
puts '*' * 80
puts ''
puts ''
end
def undelete(klass_name)
klass = "#{klass_name}".constantize
url = Gists.send(klass_name.underscore)
objs = load_from_gist(url, klass_name).map do |r|
if obj = klass.unscoped.find_by_id(r.id)
obj.deleted_at = nil
obj.save!
end
end
end
[Portfolio, Photo, Video].each do |klass|
undelete(klass.to_s)
end
def video_load_from_yaml
klass_name = 'Video'
klass = Video
url = Gists.send(klass_name.underscore)
objs = load_from_gist(url, klass_name).map { |r| klass.new(r.attributes) }
objs.each do |obj|
puts "#{klass_name}: #{obj.id}"
next if klass_name == 'User' && klass.find_by_slug(obj.slug)
next if klass.unscoped.find_by_id(obj.id)
obj.save!
end
end
video_load_from_yaml
users = User.where(id: uid)
users.each do |u|
MailchimpSubscribe.perform_later u.email, u.first_name, u.last_name
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment