parse-stack 1.8.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.solargraph.yml +23 -0
- data/.travis.yml +0 -1
- data/Gemfile +13 -12
- data/Gemfile.lock +88 -51
- data/README.md +2 -4
- data/Rakefile +14 -14
- data/lib/parse/api/aggregate.rb +4 -7
- data/lib/parse/api/all.rb +1 -1
- data/lib/parse/api/analytics.rb +0 -3
- data/lib/parse/api/batch.rb +3 -5
- data/lib/parse/api/cloud_functions.rb +0 -3
- data/lib/parse/api/config.rb +0 -4
- data/lib/parse/api/files.rb +3 -7
- data/lib/parse/api/hooks.rb +4 -8
- data/lib/parse/api/objects.rb +7 -12
- data/lib/parse/api/push.rb +0 -4
- data/lib/parse/api/schema.rb +2 -6
- data/lib/parse/api/server.rb +4 -7
- data/lib/parse/api/sessions.rb +2 -5
- data/lib/parse/api/users.rb +9 -14
- data/lib/parse/client.rb +54 -50
- data/lib/parse/client/authentication.rb +29 -33
- data/lib/parse/client/batch.rb +8 -11
- data/lib/parse/client/body_builder.rb +19 -20
- data/lib/parse/client/caching.rb +23 -28
- data/lib/parse/client/protocol.rb +11 -12
- data/lib/parse/client/request.rb +4 -6
- data/lib/parse/client/response.rb +5 -7
- data/lib/parse/model/acl.rb +14 -12
- data/lib/parse/model/associations/belongs_to.rb +14 -21
- data/lib/parse/model/associations/collection_proxy.rb +328 -329
- data/lib/parse/model/associations/has_many.rb +18 -25
- data/lib/parse/model/associations/has_one.rb +6 -11
- data/lib/parse/model/associations/pointer_collection_proxy.rb +5 -8
- data/lib/parse/model/associations/relation_collection_proxy.rb +5 -9
- data/lib/parse/model/bytes.rb +8 -10
- data/lib/parse/model/classes/installation.rb +2 -4
- data/lib/parse/model/classes/product.rb +2 -5
- data/lib/parse/model/classes/role.rb +3 -5
- data/lib/parse/model/classes/session.rb +2 -5
- data/lib/parse/model/classes/user.rb +20 -16
- data/lib/parse/model/core/actions.rb +31 -46
- data/lib/parse/model/core/builder.rb +6 -6
- data/lib/parse/model/core/errors.rb +0 -1
- data/lib/parse/model/core/fetching.rb +45 -50
- data/lib/parse/model/core/properties.rb +51 -66
- data/lib/parse/model/core/querying.rb +291 -294
- data/lib/parse/model/core/schema.rb +89 -92
- data/lib/parse/model/date.rb +16 -17
- data/lib/parse/model/file.rb +171 -174
- data/lib/parse/model/geopoint.rb +12 -16
- data/lib/parse/model/model.rb +31 -37
- data/lib/parse/model/object.rb +47 -53
- data/lib/parse/model/pointer.rb +177 -176
- data/lib/parse/model/push.rb +8 -10
- data/lib/parse/model/shortnames.rb +1 -2
- data/lib/parse/model/time_zone.rb +3 -5
- data/lib/parse/query.rb +34 -35
- data/lib/parse/query/constraint.rb +4 -6
- data/lib/parse/query/constraints.rb +21 -29
- data/lib/parse/query/operation.rb +8 -11
- data/lib/parse/query/ordering.rb +45 -49
- data/lib/parse/stack.rb +11 -12
- data/lib/parse/stack/generators/rails.rb +28 -30
- data/lib/parse/stack/generators/templates/model.erb +5 -6
- data/lib/parse/stack/generators/templates/model_installation.rb +0 -1
- data/lib/parse/stack/generators/templates/model_role.rb +0 -1
- data/lib/parse/stack/generators/templates/model_session.rb +0 -1
- data/lib/parse/stack/generators/templates/model_user.rb +0 -1
- data/lib/parse/stack/generators/templates/parse.rb +9 -9
- data/lib/parse/stack/generators/templates/webhooks.rb +1 -2
- data/lib/parse/stack/railtie.rb +2 -4
- data/lib/parse/stack/tasks.rb +70 -86
- data/lib/parse/stack/version.rb +1 -1
- data/lib/parse/webhooks.rb +19 -26
- data/lib/parse/webhooks/payload.rb +26 -28
- data/lib/parse/webhooks/registration.rb +23 -31
- data/parse-stack.gemspec +25 -25
- data/parse-stack.png +0 -0
- metadata +13 -7
- data/.github/parse-ruby-sdk.png +0 -0
@@ -8,110 +8,107 @@ module Parse
|
|
8
8
|
# Defines the Schema methods applied to a Parse::Object.
|
9
9
|
module Schema
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
sch[:fields][k] = result
|
39
|
-
|
11
|
+
# Generate a Parse-server compatible schema hash for performing changes to the
|
12
|
+
# structure of the remote collection.
|
13
|
+
# @return [Hash] the schema for this Parse::Object subclass.
|
14
|
+
def schema
|
15
|
+
sch = { className: parse_class, fields: {} }
|
16
|
+
#first go through all the attributes
|
17
|
+
attributes.each do |k, v|
|
18
|
+
# don't include the base Parse fields
|
19
|
+
next if Parse::Properties::BASE.include?(k)
|
20
|
+
next if v.nil?
|
21
|
+
result = { type: v.to_s.camelize }
|
22
|
+
# if it is a basic column property, find the right datatype
|
23
|
+
case v
|
24
|
+
when :integer, :float
|
25
|
+
result[:type] = Parse::Model::TYPE_NUMBER
|
26
|
+
when :geopoint, :geo_point
|
27
|
+
result[:type] = Parse::Model::TYPE_GEOPOINT
|
28
|
+
when :pointer
|
29
|
+
result = { type: Parse::Model::TYPE_POINTER, targetClass: references[k] }
|
30
|
+
when :acl
|
31
|
+
result[:type] = Parse::Model::ACL
|
32
|
+
when :timezone, :time_zone
|
33
|
+
result[:type] = "String" # no TimeZone native in Parse
|
34
|
+
else
|
35
|
+
result[:type] = v.to_s.camelize
|
40
36
|
end
|
41
|
-
#then add all the relational column attributes
|
42
|
-
relations.each do |k,v|
|
43
|
-
sch[:fields][k] = { type: Parse::Model::TYPE_RELATION, targetClass: relations[k] }
|
44
|
-
end
|
45
|
-
sch
|
46
|
-
end
|
47
37
|
|
48
|
-
|
49
|
-
# @param schema_updates [Hash] the changes to be made to the schema.
|
50
|
-
# @return [Parse::Response]
|
51
|
-
def update_schema(schema_updates = nil)
|
52
|
-
schema_updates ||= schema
|
53
|
-
client.update_schema parse_class, schema_updates
|
38
|
+
sch[:fields][k] = result
|
54
39
|
end
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
# @return [Parse::Response]
|
59
|
-
# @see Schema.schema
|
60
|
-
def create_schema
|
61
|
-
client.create_schema parse_class, schema
|
40
|
+
#then add all the relational column attributes
|
41
|
+
relations.each do |k, v|
|
42
|
+
sch[:fields][k] = { type: Parse::Model::TYPE_RELATION, targetClass: relations[k] }
|
62
43
|
end
|
44
|
+
sch
|
45
|
+
end
|
63
46
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
47
|
+
# Update the remote schema for this Parse collection.
|
48
|
+
# @param schema_updates [Hash] the changes to be made to the schema.
|
49
|
+
# @return [Parse::Response]
|
50
|
+
def update_schema(schema_updates = nil)
|
51
|
+
schema_updates ||= schema
|
52
|
+
client.update_schema parse_class, schema_updates
|
53
|
+
end
|
69
54
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
# @return [Boolean] if no changes were made to the schema, it returns true.
|
78
|
-
def auto_upgrade!
|
55
|
+
# Create a new collection for this model with the schema defined by the local
|
56
|
+
# model.
|
57
|
+
# @return [Parse::Response]
|
58
|
+
# @see Schema.schema
|
59
|
+
def create_schema
|
60
|
+
client.create_schema parse_class, schema
|
61
|
+
end
|
79
62
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
response = fetch_schema
|
63
|
+
# Fetche the current schema for this collection from Parse server.
|
64
|
+
# @return [Parse::Response]
|
65
|
+
def fetch_schema
|
66
|
+
client.schema parse_class
|
67
|
+
end
|
86
68
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
69
|
+
# A class method for non-destructive auto upgrading a remote schema based
|
70
|
+
# on the properties and relations you have defined in your local model. If
|
71
|
+
# the collection doesn't exist, we create the schema. If the collection already
|
72
|
+
# exists, the current schema is fetched, and only add the additional fields
|
73
|
+
# that are missing.
|
74
|
+
# @note This feature requires use of the master_key. No columns or fields are removed, this is a safe non-destructive upgrade.
|
75
|
+
# @return [Parse::Response] if the remote schema was modified.
|
76
|
+
# @return [Boolean] if no changes were made to the schema, it returns true.
|
77
|
+
def auto_upgrade!
|
78
|
+
unless client.master_key.present?
|
79
|
+
warn "[Parse] Schema changes for #{parse_class} is only available with the master key!"
|
80
|
+
return false
|
81
|
+
end
|
82
|
+
# fetch the current schema (requires master key)
|
83
|
+
response = fetch_schema
|
99
84
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
return
|
110
|
-
return update_schema( current_schema )
|
85
|
+
# if it's a core class that doesn't exist, then create the collection without any fields,
|
86
|
+
# since parse-server will automatically create the collection with the set of core fields.
|
87
|
+
# then fetch the schema again, to add the missing fields.
|
88
|
+
if response.error? && self.to_s.start_with?("Parse::") #is it a core class?
|
89
|
+
client.create_schema parse_class, {}
|
90
|
+
response = fetch_schema
|
91
|
+
# if it still wasn't able to be created, raise an error.
|
92
|
+
if response.error?
|
93
|
+
warn "[Parse] Schema error: unable to create class #{parse_class}"
|
94
|
+
return response
|
111
95
|
end
|
112
|
-
create_schema
|
113
96
|
end
|
114
97
|
|
98
|
+
if response.success?
|
99
|
+
#let's figure out the diff fields
|
100
|
+
remote_fields = response.result["fields"]
|
101
|
+
current_schema = schema
|
102
|
+
current_schema[:fields] = current_schema[:fields].reduce({}) do |h, (k, v)|
|
103
|
+
#if the field does not exist in Parse, then add it to the update list
|
104
|
+
h[k] = v if remote_fields[k.to_s].nil?
|
105
|
+
h
|
106
|
+
end
|
107
|
+
return true if current_schema[:fields].empty?
|
108
|
+
return update_schema(current_schema)
|
109
|
+
end
|
110
|
+
create_schema
|
111
|
+
end
|
115
112
|
end
|
116
113
|
end
|
117
114
|
end
|
data/lib/parse/model/date.rb
CHANGED
@@ -1,31 +1,32 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require_relative
|
4
|
+
require "time"
|
5
|
+
require "date"
|
6
|
+
require "active_model"
|
7
|
+
require "active_support"
|
8
|
+
require "active_support/inflector"
|
9
|
+
require "active_support/core_ext/object"
|
10
|
+
require "active_support/core_ext/date/calculations"
|
11
|
+
require "active_support/core_ext/date_time/calculations"
|
12
|
+
require "active_support/core_ext/time/calculations"
|
13
|
+
require "active_model_serializers"
|
14
|
+
require_relative "model"
|
15
15
|
|
16
16
|
module Parse
|
17
17
|
# This class manages dates in the special JSON format it requires for
|
18
|
-
# properties of type _:date_.
|
18
|
+
# properties of type _:date_.
|
19
19
|
class Date < ::DateTime
|
20
20
|
# The default attributes in a Parse Date hash.
|
21
|
-
ATTRIBUTES = {
|
21
|
+
ATTRIBUTES = { __type: :string, iso: :string }.freeze
|
22
22
|
include ::ActiveModel::Model
|
23
23
|
include ::ActiveModel::Serializers::JSON
|
24
24
|
|
25
25
|
# @return [Parse::Model::TYPE_DATE]
|
26
|
-
def self.parse_class; Parse::Model::TYPE_DATE; end
|
26
|
+
def self.parse_class; Parse::Model::TYPE_DATE; end
|
27
27
|
# @return [Parse::Model::TYPE_DATE]
|
28
|
-
def parse_class; self.class.parse_class; end
|
28
|
+
def parse_class; self.class.parse_class; end
|
29
|
+
|
29
30
|
alias_method :__type, :parse_class
|
30
31
|
|
31
32
|
# @return [Hash]
|
@@ -42,7 +43,6 @@ module Parse
|
|
42
43
|
def to_s(*args)
|
43
44
|
args.empty? ? iso : super(*args)
|
44
45
|
end
|
45
|
-
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -52,7 +52,6 @@ class Time
|
|
52
52
|
def parse_date
|
53
53
|
Parse::Date.parse iso8601(3)
|
54
54
|
end
|
55
|
-
|
56
55
|
end
|
57
56
|
|
58
57
|
# Adds extensions to DateTime class to be compatible with {Parse::Date}.
|
data/lib/parse/model/file.rb
CHANGED
@@ -1,204 +1,201 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require "active_support"
|
5
|
+
require "active_support/core_ext/object"
|
6
6
|
require_relative "model"
|
7
|
-
require
|
7
|
+
require "open-uri"
|
8
8
|
|
9
9
|
module Parse
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
# @return [Boolean] When set to true, it will make all calls to File#url
|
66
|
-
def force_ssl
|
67
|
-
@force_ssl ||= false
|
68
|
-
end
|
69
|
-
|
10
|
+
# This class represents a Parse file pointer. `Parse::File` has helper
|
11
|
+
# methods to upload Parse files directly to Parse and manage file
|
12
|
+
# associations with your classes.
|
13
|
+
# @example
|
14
|
+
# file = File.open("file_path.jpg")
|
15
|
+
# contents = file.read
|
16
|
+
# file = Parse::File.new("myimage.jpg", contents , "image/jpeg")
|
17
|
+
# file.saved? # => false
|
18
|
+
# file.save
|
19
|
+
#
|
20
|
+
# file.url # https://files.parsetfss.com/....
|
21
|
+
#
|
22
|
+
# # or create and upload a remote file (auto-detected mime type)
|
23
|
+
# file = Parse::File.create(some_url)
|
24
|
+
#
|
25
|
+
#
|
26
|
+
# @note The default MIME type for all files is _image/jpeg_. This can be default
|
27
|
+
# can be changed by setting a value to `Parse::File.default_mime_type`.
|
28
|
+
class File < Model
|
29
|
+
# Regular expression that matches the old legacy Parse hosted file name
|
30
|
+
LEGACY_FILE_RX = /^tfss-[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}-/
|
31
|
+
# The default attributes in a Parse File hash.
|
32
|
+
ATTRIBUTES = { __type: :string, name: :string, url: :string }.freeze
|
33
|
+
# @return [String] the name of the file including extension (if any)
|
34
|
+
attr_accessor :name
|
35
|
+
# @return [String] the url resource of the file.
|
36
|
+
attr_accessor :url
|
37
|
+
|
38
|
+
# @return [Object] the contents of the file.
|
39
|
+
attr_accessor :contents
|
40
|
+
|
41
|
+
# @return [String] the mime-type of the file whe
|
42
|
+
attr_accessor :mime_type
|
43
|
+
# @return [Model::TYPE_FILE]
|
44
|
+
def self.parse_class; TYPE_FILE; end
|
45
|
+
# @return [Model::TYPE_FILE]
|
46
|
+
def parse_class; self.class.parse_class; end
|
47
|
+
|
48
|
+
alias_method :__type, :parse_class
|
49
|
+
# @!visibility private
|
50
|
+
FIELD_NAME = "name"
|
51
|
+
# @!visibility private
|
52
|
+
FIELD_URL = "url"
|
53
|
+
class << self
|
54
|
+
|
55
|
+
# @return [String] the default mime-type
|
56
|
+
attr_accessor :default_mime_type
|
57
|
+
|
58
|
+
# @return [Boolean] whether to force all urls to be https.
|
59
|
+
attr_accessor :force_ssl
|
60
|
+
|
61
|
+
# @return [String] The default mime type for created instances. Default: _'image/jpeg'_
|
62
|
+
def default_mime_type
|
63
|
+
@default_mime_type ||= "image/jpeg"
|
70
64
|
end
|
71
|
-
# The initializer to create a new file supports different inputs.
|
72
|
-
# If the first paramter is a string which starts with 'http', we then download
|
73
|
-
# the content of the file (and use the detected mime-type) to set the content and mime_type fields.
|
74
|
-
# If the first parameter is a hash, we assume it might be the Parse File hash format which contains url and name fields only.
|
75
|
-
# If the first paramter is a Parse::File, then we copy fields over
|
76
|
-
# Otherwise, creating a new file requires a name, the actual contents (usually from a File.open("local.jpg").read ) and the mime-type
|
77
|
-
# @param name [String]
|
78
|
-
# @param contents [Object]
|
79
|
-
# @param mime_type [String] Default see default_mime_type
|
80
|
-
def initialize(name, contents = nil, mime_type = nil)
|
81
|
-
mime_type ||= Parse::File.default_mime_type
|
82
|
-
|
83
|
-
if name.is_a?(String) && name.start_with?('http') #could be url string
|
84
|
-
file = open( name )
|
85
|
-
@contents = file.read
|
86
|
-
@name = File.basename file.base_uri.to_s
|
87
|
-
@mime_type = file.content_type
|
88
|
-
elsif name.is_a?(Hash)
|
89
|
-
self.attributes = name
|
90
|
-
elsif name.is_a?(::File)
|
91
|
-
@contents = contents || name.read
|
92
|
-
@name = File.basename name.to_path
|
93
|
-
elsif name.is_a?(Parse::File)
|
94
|
-
@name = name.name
|
95
|
-
@url = name.url
|
96
|
-
else
|
97
|
-
@name = name
|
98
|
-
@contents = contents
|
99
|
-
end
|
100
|
-
if @name.blank?
|
101
|
-
raise ArgumentError, "Invalid Parse::File initialization with name '#{@name}'"
|
102
|
-
end
|
103
|
-
|
104
|
-
@mime_type ||= mime_type
|
105
65
|
|
66
|
+
# @return [Boolean] When set to true, it will make all calls to File#url
|
67
|
+
def force_ssl
|
68
|
+
@force_ssl ||= false
|
106
69
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
70
|
+
end
|
71
|
+
# The initializer to create a new file supports different inputs.
|
72
|
+
# If the first paramter is a string which starts with 'http', we then download
|
73
|
+
# the content of the file (and use the detected mime-type) to set the content and mime_type fields.
|
74
|
+
# If the first parameter is a hash, we assume it might be the Parse File hash format which contains url and name fields only.
|
75
|
+
# If the first paramter is a Parse::File, then we copy fields over
|
76
|
+
# Otherwise, creating a new file requires a name, the actual contents (usually from a File.open("local.jpg").read ) and the mime-type
|
77
|
+
# @param name [String]
|
78
|
+
# @param contents [Object]
|
79
|
+
# @param mime_type [String] Default see default_mime_type
|
80
|
+
def initialize(name, contents = nil, mime_type = nil)
|
81
|
+
mime_type ||= Parse::File.default_mime_type
|
82
|
+
|
83
|
+
if name.is_a?(String) && name.start_with?("http") #could be url string
|
84
|
+
file = open(name)
|
85
|
+
@contents = file.read
|
86
|
+
@name = File.basename file.base_uri.to_s
|
87
|
+
@mime_type = file.content_type
|
88
|
+
elsif name.is_a?(Hash)
|
89
|
+
self.attributes = name
|
90
|
+
elsif name.is_a?(::File)
|
91
|
+
@contents = contents || name.read
|
92
|
+
@name = File.basename name.to_path
|
93
|
+
elsif name.is_a?(Parse::File)
|
94
|
+
@name = name.name
|
95
|
+
@url = name.url
|
96
|
+
else
|
97
|
+
@name = name
|
98
|
+
@contents = contents
|
116
99
|
end
|
117
|
-
|
118
|
-
|
119
|
-
# @return [Boolean] true if this file has already been saved.
|
120
|
-
def saved?
|
121
|
-
@url.present? && @name.present? && @name == File.basename(@url)
|
100
|
+
if @name.blank?
|
101
|
+
raise ArgumentError, "Invalid Parse::File initialization with name '#{@name}'"
|
122
102
|
end
|
123
103
|
|
124
|
-
|
125
|
-
|
126
|
-
# @return [String] the url string for the file.
|
127
|
-
def url
|
128
|
-
if @url.present? && Parse::File.force_ssl && @url.starts_with?('http://')
|
129
|
-
return @url.sub('http://', 'https://')
|
130
|
-
end
|
131
|
-
@url
|
132
|
-
end
|
104
|
+
@mime_type ||= mime_type
|
105
|
+
end
|
133
106
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
107
|
+
# This creates a new Parse File Object with from a URL, saves it and returns it
|
108
|
+
# @param url [String] A url which will be used to create the file and automatically save it.
|
109
|
+
# @return [Parse::File] A newly saved file based on contents of _url_
|
110
|
+
def self.create(url)
|
111
|
+
url = url.url if url.is_a?(Parse::File)
|
112
|
+
file = self.new(url)
|
113
|
+
file.save
|
114
|
+
file
|
115
|
+
end
|
138
116
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
117
|
+
# A File object is considered saved if the basename of the URL and the name parameters are equal
|
118
|
+
# @return [Boolean] true if this file has already been saved.
|
119
|
+
def saved?
|
120
|
+
@url.present? && @name.present? && @name == File.basename(@url)
|
121
|
+
end
|
144
122
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
@url = h[FIELD_URL] || h[:url] || @url
|
152
|
-
@name = h[FIELD_NAME] || h[:name] || @name
|
153
|
-
end
|
123
|
+
# Returns the url string for this Parse::File pointer. If the *force_ssl* option is
|
124
|
+
# set to true, it will make sure it returns a secure url.
|
125
|
+
# @return [String] the url string for the file.
|
126
|
+
def url
|
127
|
+
if @url.present? && Parse::File.force_ssl && @url.starts_with?("http://")
|
128
|
+
return @url.sub("http://", "https://")
|
154
129
|
end
|
130
|
+
@url
|
131
|
+
end
|
155
132
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
# @see ::File.basename
|
161
|
-
def self.basename(file_name, suffix = nil)
|
162
|
-
if suffix.nil?
|
163
|
-
::File.basename(file_name)
|
164
|
-
else
|
165
|
-
::File.basename(file_name, suffix)
|
166
|
-
end
|
167
|
-
end
|
133
|
+
# @return [Hash]
|
134
|
+
def attributes
|
135
|
+
ATTRIBUTES
|
136
|
+
end
|
168
137
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
unless response.error?
|
175
|
-
result = response.result
|
176
|
-
@name = result[FIELD_NAME] || File.basename(result[FIELD_URL])
|
177
|
-
@url = result[FIELD_URL]
|
178
|
-
end
|
179
|
-
end
|
180
|
-
saved?
|
181
|
-
end
|
138
|
+
# @return [Boolean] Two files are equal if they have the same url
|
139
|
+
def ==(u)
|
140
|
+
return false unless u.is_a?(self.class)
|
141
|
+
@url == u.url
|
142
|
+
end
|
182
143
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
144
|
+
# Allows mass assignment from a Parse JSON hash.
|
145
|
+
def attributes=(h)
|
146
|
+
if h.is_a?(String)
|
147
|
+
@url = h
|
148
|
+
@name = File.basename(h)
|
149
|
+
elsif h.is_a?(Hash)
|
150
|
+
@url = h[FIELD_URL] || h[:url] || @url
|
151
|
+
@name = h[FIELD_NAME] || h[:name] || @name
|
187
152
|
end
|
153
|
+
end
|
188
154
|
|
189
|
-
|
190
|
-
|
191
|
-
|
155
|
+
# A proxy method for ::File.basename
|
156
|
+
# @param file_name [String]
|
157
|
+
# @param suffix [String]
|
158
|
+
# @return [String] File.basename(file_name)
|
159
|
+
# @see ::File.basename
|
160
|
+
def self.basename(file_name, suffix = nil)
|
161
|
+
if suffix.nil?
|
162
|
+
::File.basename(file_name)
|
163
|
+
else
|
164
|
+
::File.basename(file_name, suffix)
|
192
165
|
end
|
166
|
+
end
|
193
167
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
168
|
+
# Save the file by uploading it to Parse and creating a file pointer.
|
169
|
+
# @return [Boolean] true if successfully uploaded and saved.
|
170
|
+
def save
|
171
|
+
unless saved? || @contents.nil? || @name.nil?
|
172
|
+
response = client.create_file(@name, @contents, @mime_type)
|
173
|
+
unless response.error?
|
174
|
+
result = response.result
|
175
|
+
@name = result[FIELD_NAME] || File.basename(result[FIELD_URL])
|
176
|
+
@url = result[FIELD_URL]
|
177
|
+
end
|
198
178
|
end
|
179
|
+
saved?
|
180
|
+
end
|
199
181
|
|
182
|
+
# @return [Boolean] true if this file is hosted by Parse's servers.
|
183
|
+
def parse_hosted_file?
|
184
|
+
return false if @url.blank?
|
185
|
+
::File.basename(@url).starts_with?("tfss-") || @url.starts_with?("http://files.parsetfss.com")
|
200
186
|
end
|
201
187
|
|
188
|
+
# @!visibility private
|
189
|
+
def inspect
|
190
|
+
"<Parse::File @name='#{@name}' @mime_type='#{@mime_type}' @contents=#{@contents.nil?} @url='#{@url}'>"
|
191
|
+
end
|
192
|
+
|
193
|
+
# @return [String] the url
|
194
|
+
# @see #url
|
195
|
+
def to_s
|
196
|
+
@url
|
197
|
+
end
|
198
|
+
end
|
202
199
|
end
|
203
200
|
|
204
201
|
# Adds extensions to Hash class.
|