parsecom-importer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ *.swp
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in parse-importer.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Ando Yasushi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # parsecom-import
2
+
3
+ You can import an exported zip file into your parse.com app.
4
+
5
+ ## Installation
6
+
7
+ $ gem install parse-importer
8
+
9
+ If you are using rbenv, please don't forget call rehash
10
+
11
+ $ rbenv rehash
12
+
13
+ ## Usage
14
+
15
+ Set environment variables to connect parse.com
16
+
17
+ export PARSE_APPLICATION_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
18
+ export PARSE_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
19
+ export PARSE_MASTER_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
20
+
21
+ Call parse-import command.
22
+
23
+ $ parse-import 50523f10-2b8a-4bb8-83ef-31d2fa71f82d_1585107803_export.zip
24
+
25
+ ## Note
26
+
27
+ The behavior of this command is different from exporting json files on the web. Though exporting on the web is allowed to set objectId and other reserved columns, this command is not. In short, this command changes objectIds and cannot copy some reserved columns.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'parse/importer'
5
+ rescue LoadError
6
+ require 'rubygems'
7
+ require 'parse/importer'
8
+ end
9
+
10
+ if ARGV.empty?
11
+ puts 'dirname'
12
+ exit
13
+ end
14
+ Parse::Importer.import ARGV.shift
@@ -0,0 +1,44 @@
1
+ require 'tmpdir'
2
+ require 'fileutils'
3
+ require 'securerandom'
4
+ require 'tempfile'
5
+ require 'open-uri'
6
+ require 'zipruby'
7
+ require 'parsecom'
8
+ require 'parse/importer/version'
9
+ require 'parse/importer/store'
10
+
11
+ module Parse
12
+ module Importer
13
+ module_function
14
+
15
+ def unzip zipname
16
+ output = Dir.tmpdir
17
+ Zip::Archive.open zipname do |archives|
18
+ archives.each do |archive|
19
+ filename = File.join output, archive.name
20
+ FileUtils.mkdir_p File.dirname(filename)
21
+ unless archive.directory?
22
+ File.open filename, 'w+b' do |file|
23
+ file.print archive.read
24
+ end
25
+ end
26
+ end
27
+ end
28
+ File.join output, File.dirname(zipname)
29
+ end
30
+
31
+ def import dirname, credentials=nil
32
+ if File.file? dirname
33
+ unless File.extname(dirname) == '.zip'
34
+ raise ArgumentError.new('should be a zip file or a directory')
35
+ end
36
+ dirname = unzip dirname
37
+ end
38
+
39
+ Parse.credentials credentials if credentials
40
+ store = Parse::Importer::Store.new dirname
41
+ store.save
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,105 @@
1
+ module Parse
2
+ module Importer
3
+ class Store
4
+ attr_reader :store
5
+
6
+ def initialize dirname=nil
7
+ @parse_class_table = {}
8
+ @parse_object_table = {}
9
+ @store = {}
10
+ @relations = []
11
+ load dirname if dirname
12
+ end
13
+
14
+ def load dirname
15
+ Dir["#{dirname}/*"].each do |filepath|
16
+ filename = filepath.sub(%r|#{dirname}/|, '')
17
+ if filename =~ /^_Join:(.*):(.*).json$/
18
+ column_name = $1
19
+ parse_class_name = $2
20
+ @relations << [filepath, column_name, parse_class_name]
21
+ elsif filename =~ /^(.*).json$/
22
+ parse_class_name = $1
23
+ parse_class = Parse::Object(parse_class_name)
24
+ rows = []
25
+ results = JSON.parse File.read(filepath)
26
+ results['results'].each do |data|
27
+ rows << data
28
+ @parse_class_table[data['objectId']] = parse_class
29
+ end
30
+ @store[parse_class_name] = rows
31
+ end
32
+ end
33
+ end
34
+
35
+ def new_object_id_from_old_one object_id
36
+ @parse_object_table[object_id].objectId
37
+ end
38
+
39
+ def save
40
+ create_blank_objects
41
+ update_objects
42
+ add_relations
43
+ end
44
+
45
+ def create_blank_objects
46
+ @parse_class_table.each do |old_object_id, parse_class|
47
+ parse_object = parse_class.new
48
+ if parse_class.parse_class_name == '_User'
49
+ parse_object.username = SecureRandom.uuid # temporary username
50
+ parse_object.password = 'password'
51
+ end
52
+ parse_object.save
53
+ @parse_object_table[old_object_id] = parse_object
54
+ puts "#{parse_class.parse_class_name}(#{old_object_id}) has been created."
55
+ end
56
+ end
57
+
58
+ def update_objects
59
+ @store.each do |parse_class_name, rows|
60
+ rows.each do |data|
61
+ parse_object = @parse_object_table[data['objectId']]
62
+ data.each do |k, v|
63
+ if v.is_a? Hash
64
+ case v['__type']
65
+ when 'Pointer'
66
+ v['objectId'] = new_object_id_from_old_one v['objectId']
67
+ when 'File'
68
+ open v['url'] do |filedata|
69
+ filepath = Tempfile.open 'temp' do |tempfile|
70
+ tempfile.write filedata.read
71
+ tempfile.path
72
+ end
73
+ name = File.basename(v['url']).split('-').last
74
+ parse_file = Parse::ParseFile.new :name => name, :content => filepath
75
+ parse_file.save
76
+ data[k] = parse_file
77
+ end
78
+ end
79
+ end
80
+ end
81
+ data.reject! do |k, v|
82
+ %w(sessionToken bcryptPassword).include? k
83
+ end
84
+ parse_object.update! data
85
+ puts "#{parse_object.parse_class_name}(#{data['objectId']}) has been updated."
86
+ end
87
+ end
88
+ end
89
+
90
+ def add_relations
91
+ @relations.each do |filepath, column_name, parse_class_name|
92
+ parse_class = Parse::Object(parse_class_name)
93
+ results = JSON.parse File.read(filepath)
94
+ results['results'].each do |relation|
95
+ object = parse_class.find_by_id new_object_id_from_old_one(relation['owningId'])
96
+ related_object = @parse_object_table[relation['relatedId']]
97
+ object.send "#{column_name}=", Parse::Op::AddRelation.new(related_object.pointer)
98
+ object.save!
99
+ puts "#{relation['owningId']} and #{relation['relatedId']} have been connected."
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,5 @@
1
+ module Parse
2
+ module Importer
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'parse/importer/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "parsecom-importer"
8
+ gem.version = Parse::Importer::VERSION
9
+ gem.authors = ["Ando Yasushi"]
10
+ gem.email = ["andyjpn@gmail.com"]
11
+ gem.description = %q{You can import an exported zip file into your parse.com app.}
12
+ gem.summary = %q{You can import an exported zip file into your parse.com app.}
13
+ gem.homepage = "https://github.com/technohippy/parsecom-importer"
14
+ gem.license = "MIT"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_dependency "zipruby"
22
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: parsecom-importer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ando Yasushi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: zipruby
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: You can import an exported zip file into your parse.com app.
31
+ email:
32
+ - andyjpn@gmail.com
33
+ executables:
34
+ - parsecom-import
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - .gitignore
39
+ - Gemfile
40
+ - LICENSE.txt
41
+ - README.md
42
+ - Rakefile
43
+ - bin/parsecom-import
44
+ - lib/parse/importer.rb
45
+ - lib/parse/importer/store.rb
46
+ - lib/parse/importer/version.rb
47
+ - parsecom-importer.gemspec
48
+ homepage: https://github.com/technohippy/parsecom-importer
49
+ licenses:
50
+ - MIT
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project:
69
+ rubygems_version: 1.8.23
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: You can import an exported zip file into your parse.com app.
73
+ test_files: []