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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.solargraph.yml +23 -0
  3. data/.travis.yml +0 -1
  4. data/Gemfile +13 -12
  5. data/Gemfile.lock +88 -51
  6. data/README.md +2 -4
  7. data/Rakefile +14 -14
  8. data/lib/parse/api/aggregate.rb +4 -7
  9. data/lib/parse/api/all.rb +1 -1
  10. data/lib/parse/api/analytics.rb +0 -3
  11. data/lib/parse/api/batch.rb +3 -5
  12. data/lib/parse/api/cloud_functions.rb +0 -3
  13. data/lib/parse/api/config.rb +0 -4
  14. data/lib/parse/api/files.rb +3 -7
  15. data/lib/parse/api/hooks.rb +4 -8
  16. data/lib/parse/api/objects.rb +7 -12
  17. data/lib/parse/api/push.rb +0 -4
  18. data/lib/parse/api/schema.rb +2 -6
  19. data/lib/parse/api/server.rb +4 -7
  20. data/lib/parse/api/sessions.rb +2 -5
  21. data/lib/parse/api/users.rb +9 -14
  22. data/lib/parse/client.rb +54 -50
  23. data/lib/parse/client/authentication.rb +29 -33
  24. data/lib/parse/client/batch.rb +8 -11
  25. data/lib/parse/client/body_builder.rb +19 -20
  26. data/lib/parse/client/caching.rb +23 -28
  27. data/lib/parse/client/protocol.rb +11 -12
  28. data/lib/parse/client/request.rb +4 -6
  29. data/lib/parse/client/response.rb +5 -7
  30. data/lib/parse/model/acl.rb +14 -12
  31. data/lib/parse/model/associations/belongs_to.rb +14 -21
  32. data/lib/parse/model/associations/collection_proxy.rb +328 -329
  33. data/lib/parse/model/associations/has_many.rb +18 -25
  34. data/lib/parse/model/associations/has_one.rb +6 -11
  35. data/lib/parse/model/associations/pointer_collection_proxy.rb +5 -8
  36. data/lib/parse/model/associations/relation_collection_proxy.rb +5 -9
  37. data/lib/parse/model/bytes.rb +8 -10
  38. data/lib/parse/model/classes/installation.rb +2 -4
  39. data/lib/parse/model/classes/product.rb +2 -5
  40. data/lib/parse/model/classes/role.rb +3 -5
  41. data/lib/parse/model/classes/session.rb +2 -5
  42. data/lib/parse/model/classes/user.rb +20 -16
  43. data/lib/parse/model/core/actions.rb +31 -46
  44. data/lib/parse/model/core/builder.rb +6 -6
  45. data/lib/parse/model/core/errors.rb +0 -1
  46. data/lib/parse/model/core/fetching.rb +45 -50
  47. data/lib/parse/model/core/properties.rb +51 -66
  48. data/lib/parse/model/core/querying.rb +291 -294
  49. data/lib/parse/model/core/schema.rb +89 -92
  50. data/lib/parse/model/date.rb +16 -17
  51. data/lib/parse/model/file.rb +171 -174
  52. data/lib/parse/model/geopoint.rb +12 -16
  53. data/lib/parse/model/model.rb +31 -37
  54. data/lib/parse/model/object.rb +47 -53
  55. data/lib/parse/model/pointer.rb +177 -176
  56. data/lib/parse/model/push.rb +8 -10
  57. data/lib/parse/model/shortnames.rb +1 -2
  58. data/lib/parse/model/time_zone.rb +3 -5
  59. data/lib/parse/query.rb +34 -35
  60. data/lib/parse/query/constraint.rb +4 -6
  61. data/lib/parse/query/constraints.rb +21 -29
  62. data/lib/parse/query/operation.rb +8 -11
  63. data/lib/parse/query/ordering.rb +45 -49
  64. data/lib/parse/stack.rb +11 -12
  65. data/lib/parse/stack/generators/rails.rb +28 -30
  66. data/lib/parse/stack/generators/templates/model.erb +5 -6
  67. data/lib/parse/stack/generators/templates/model_installation.rb +0 -1
  68. data/lib/parse/stack/generators/templates/model_role.rb +0 -1
  69. data/lib/parse/stack/generators/templates/model_session.rb +0 -1
  70. data/lib/parse/stack/generators/templates/model_user.rb +0 -1
  71. data/lib/parse/stack/generators/templates/parse.rb +9 -9
  72. data/lib/parse/stack/generators/templates/webhooks.rb +1 -2
  73. data/lib/parse/stack/railtie.rb +2 -4
  74. data/lib/parse/stack/tasks.rb +70 -86
  75. data/lib/parse/stack/version.rb +1 -1
  76. data/lib/parse/webhooks.rb +19 -26
  77. data/lib/parse/webhooks/payload.rb +26 -28
  78. data/lib/parse/webhooks/registration.rb +23 -31
  79. data/parse-stack.gemspec +25 -25
  80. data/parse-stack.png +0 -0
  81. metadata +13 -7
  82. 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
- # 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
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
- # Update the remote schema for this Parse collection.
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
- # Create a new collection for this model with the schema defined by the local
57
- # model.
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
- # Fetche the current schema for this collection from Parse server.
65
- # @return [Parse::Response]
66
- def fetch_schema
67
- client.schema parse_class
68
- end
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
- # A class method for non-destructive auto upgrading a remote schema based
71
- # on the properties and relations you have defined in your local model. If
72
- # the collection doesn't exist, we create the schema. If the collection already
73
- # exists, the current schema is fetched, and only add the additional fields
74
- # that are missing.
75
- # @note This feature requires use of the master_key. No columns or fields are removed, this is a safe non-destructive upgrade.
76
- # @return [Parse::Response] if the remote schema was modified.
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
- unless client.master_key.present?
81
- warn "[Parse] Schema changes for #{parse_class} is only available with the master key!"
82
- return false
83
- end
84
- # fetch the current schema (requires master key)
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
- # if it's a core class that doesn't exist, then create the collection without any fields,
88
- # since parse-server will automatically create the collection with the set of core fields.
89
- # then fetch the schema again, to add the missing fields.
90
- if response.error? && self.to_s.start_with?('Parse::') #is it a core class?
91
- client.create_schema parse_class, {}
92
- response = fetch_schema
93
- # if it still wasn't able to be created, raise an error.
94
- if response.error?
95
- warn "[Parse] Schema error: unable to create class #{parse_class}"
96
- return response
97
- end
98
- end
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
- if response.success?
101
- #let's figure out the diff fields
102
- remote_fields = response.result['fields']
103
- current_schema = schema
104
- current_schema[:fields] = current_schema[:fields].reduce({}) do |h,(k,v)|
105
- #if the field does not exist in Parse, then add it to the update list
106
- h[k] = v if remote_fields[k.to_s].nil?
107
- h
108
- end
109
- return true if current_schema[:fields].empty?
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
@@ -1,31 +1,32 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
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'
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 = { __type: :string, iso: :string }.freeze
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}.
@@ -1,204 +1,201 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'active_support'
5
- require 'active_support/core_ext/object'
4
+ require "active_support"
5
+ require "active_support/core_ext/object"
6
6
  require_relative "model"
7
- require 'open-uri'
7
+ require "open-uri"
8
8
 
9
9
  module Parse
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
- alias_method :__type, :parse_class
48
- # @!visibility private
49
- FIELD_NAME = "name"
50
- # @!visibility private
51
- FIELD_URL = "url"
52
- class << self
53
-
54
- # @return [String] the default mime-type
55
- attr_accessor :default_mime_type
56
-
57
- # @return [Boolean] whether to force all urls to be https.
58
- attr_accessor :force_ssl
59
-
60
- # @return [String] The default mime type for created instances. Default: _'image/jpeg'_
61
- def default_mime_type
62
- @default_mime_type ||= "image/jpeg"
63
- end
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
- # This creates a new Parse File Object with from a URL, saves it and returns it
109
- # @param url [String] A url which will be used to create the file and automatically save it.
110
- # @return [Parse::File] A newly saved file based on contents of _url_
111
- def self.create(url)
112
- url = url.url if url.is_a?(Parse::File)
113
- file = self.new(url)
114
- file.save
115
- file
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
- # A File object is considered saved if the basename of the URL and the name parameters are equal
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
- # Returns the url string for this Parse::File pointer. If the *force_ssl* option is
125
- # set to true, it will make sure it returns a secure url.
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
- # @return [Hash]
135
- def attributes
136
- ATTRIBUTES
137
- end
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
- # @return [Boolean] Two files are equal if they have the same url
140
- def ==(u)
141
- return false unless u.is_a?(self.class)
142
- @url == u.url
143
- end
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
- # Allows mass assignment from a Parse JSON hash.
146
- def attributes=(h)
147
- if h.is_a?(String)
148
- @url = h
149
- @name = File.basename(h)
150
- elsif h.is_a?(Hash)
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
- # A proxy method for ::File.basename
157
- # @param file_name [String]
158
- # @param suffix [String]
159
- # @return [String] File.basename(file_name)
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
- # Save the file by uploading it to Parse and creating a file pointer.
170
- # @return [Boolean] true if successfully uploaded and saved.
171
- def save
172
- unless saved? || @contents.nil? || @name.nil?
173
- response = client.create_file(@name, @contents, @mime_type)
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
- # @return [Boolean] true if this file is hosted by Parse's servers.
184
- def parse_hosted_file?
185
- return false if @url.blank?
186
- ::File.basename(@url).starts_with?('tfss-') || @url.starts_with?('http://files.parsetfss.com')
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
- # @!visibility private
190
- def inspect
191
- "<Parse::File @name='#{@name}' @mime_type='#{@mime_type}' @contents=#{@contents.nil?} @url='#{@url}'>"
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
- # @return [String] the url
195
- # @see #url
196
- def to_s
197
- @url
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.