parse-stack 1.8.0 → 1.8.1
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|