built.io 0.7 → 0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/built/acl.rb +196 -0
- data/lib/built/application.rb +1 -1
- data/lib/built/class.rb +2 -2
- data/lib/built/client.rb +40 -12
- data/lib/built/constants.rb +7 -2
- data/lib/built/error.rb +2 -2
- data/lib/built/installation.rb +4 -0
- data/lib/built/location.rb +72 -0
- data/lib/built/object.rb +287 -12
- data/lib/built/query.rb +129 -59
- data/lib/built/role.rb +4 -0
- data/lib/built/upload.rb +202 -0
- data/lib/built/user.rb +147 -0
- data/lib/built/util.rb +17 -2
- data/lib/built.rb +10 -4
- data/lib/locales/en.yml +8 -1
- metadata +11 -5
data/lib/built/acl.rb
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
module Built
|
2
|
+
class ACL
|
3
|
+
attr_accessor :disabled
|
4
|
+
attr_accessor :others
|
5
|
+
attr_accessor :users
|
6
|
+
attr_accessor :roles
|
7
|
+
|
8
|
+
def initialize(data)
|
9
|
+
data ||= {}
|
10
|
+
|
11
|
+
@disabled = data["disable"] == true
|
12
|
+
@others = data["others"] || {}
|
13
|
+
@users = data["users"] || []
|
14
|
+
@roles = data["roles"] || []
|
15
|
+
@can = data["can"] || []
|
16
|
+
end
|
17
|
+
|
18
|
+
# Disable / Enable ACL ============================
|
19
|
+
|
20
|
+
# Is the ACL disabled?
|
21
|
+
# @return [Boolean]
|
22
|
+
def is_disabled?
|
23
|
+
@disabled
|
24
|
+
end
|
25
|
+
|
26
|
+
# Disable the ACL
|
27
|
+
def disable
|
28
|
+
@disabled = true
|
29
|
+
end
|
30
|
+
|
31
|
+
# Enable the ACL
|
32
|
+
def enable
|
33
|
+
@disabled = false
|
34
|
+
end
|
35
|
+
|
36
|
+
# ACL can =========================================
|
37
|
+
|
38
|
+
# Can the current user update this object?
|
39
|
+
def can_update?
|
40
|
+
!!@can.find {|x| x == "update"}
|
41
|
+
end
|
42
|
+
|
43
|
+
# Can the current user delete this object?
|
44
|
+
def can_delete?
|
45
|
+
!!@can.find {|x| x == "delete"}
|
46
|
+
end
|
47
|
+
|
48
|
+
# Can others? =====================================
|
49
|
+
|
50
|
+
# Read permission for others
|
51
|
+
# @return [Boolean]
|
52
|
+
def can_others_read?
|
53
|
+
@others["read"]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Update permission for others
|
57
|
+
# @return [Boolean]
|
58
|
+
def can_others_update?
|
59
|
+
@others["update"]
|
60
|
+
end
|
61
|
+
|
62
|
+
# Update permission for others
|
63
|
+
# @return [Boolean]
|
64
|
+
def can_others_delete?
|
65
|
+
@others["delete"]
|
66
|
+
end
|
67
|
+
|
68
|
+
# Set others ======================================
|
69
|
+
|
70
|
+
# Set read permission for others
|
71
|
+
# @param [Boolean]
|
72
|
+
def others_read(bool)
|
73
|
+
@others["read"] = bool
|
74
|
+
end
|
75
|
+
|
76
|
+
# Set update permission for others
|
77
|
+
# @param [Boolean]
|
78
|
+
def others_update(bool)
|
79
|
+
@others["update"] = bool
|
80
|
+
end
|
81
|
+
|
82
|
+
# Set delete permission for others
|
83
|
+
# @param [Boolean]
|
84
|
+
def others_delete(bool)
|
85
|
+
@others["delete"] = bool
|
86
|
+
end
|
87
|
+
|
88
|
+
# Can users? ======================================
|
89
|
+
|
90
|
+
# Get read permission for user
|
91
|
+
def can_user_read?(user)
|
92
|
+
can_user_op(user, "read")
|
93
|
+
end
|
94
|
+
|
95
|
+
# Get update permission for user
|
96
|
+
def can_user_update?(user)
|
97
|
+
can_user_op(user, "update")
|
98
|
+
end
|
99
|
+
|
100
|
+
# Get delete permission for user
|
101
|
+
def can_user_delete?(user)
|
102
|
+
can_user_op(user, "delete")
|
103
|
+
end
|
104
|
+
|
105
|
+
# Can roles? ======================================
|
106
|
+
|
107
|
+
# Get read permission for role
|
108
|
+
def can_role_read?(role)
|
109
|
+
can_role_op(role, "read")
|
110
|
+
end
|
111
|
+
|
112
|
+
# Get update permission for role
|
113
|
+
def can_role_update?(role)
|
114
|
+
can_role_op(role, "update")
|
115
|
+
end
|
116
|
+
|
117
|
+
# Get delete permission for role
|
118
|
+
def can_role_delete?(role)
|
119
|
+
can_role_op(role, "delete")
|
120
|
+
end
|
121
|
+
|
122
|
+
# Set users =======================================
|
123
|
+
|
124
|
+
# Set read permission for the user
|
125
|
+
def user_read(user, bool)
|
126
|
+
user_op(user, "read", bool)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Set update permission for the user
|
130
|
+
def user_update(user, bool)
|
131
|
+
user_op(user, "update", bool)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Set delete permission for the user
|
135
|
+
def user_delete(user, bool)
|
136
|
+
user_op(user, "delete", bool)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Set roles =======================================
|
140
|
+
|
141
|
+
# Set read permission for the role
|
142
|
+
def role_read(role, bool)
|
143
|
+
role_op(role, "read", bool)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Set update permission for the role
|
147
|
+
def role_update(role, bool)
|
148
|
+
role_op(role, "update", bool)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Set delete permission for the role
|
152
|
+
def role_delete(role, bool)
|
153
|
+
role_op(role, "delete", bool)
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def to_s
|
159
|
+
"#<Built::ACL disabled=#{disabled}>"
|
160
|
+
end
|
161
|
+
|
162
|
+
def user_op(user, op, bool)
|
163
|
+
elem_op(@users, user, op, bool)
|
164
|
+
end
|
165
|
+
|
166
|
+
def role_op(role, op, bool)
|
167
|
+
elem_op(@roles, role, op, bool)
|
168
|
+
end
|
169
|
+
|
170
|
+
def elem_op(store, elem, op, bool)
|
171
|
+
uid = elem.is_a?(String) ? elem : elem.uid
|
172
|
+
|
173
|
+
if acl = store.find {|u| u == uid}
|
174
|
+
acl[op] = bool
|
175
|
+
else
|
176
|
+
store << {"uid" => uid, op => bool}
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def can_role_op(role, op)
|
181
|
+
can_elem_op(@roles, role, op)
|
182
|
+
end
|
183
|
+
|
184
|
+
def can_user_op(user, op)
|
185
|
+
can_elem_op(@users, user, op)
|
186
|
+
end
|
187
|
+
|
188
|
+
def can_elem_op(store, elem, op)
|
189
|
+
uid = elem.is_a?(String) ? elem : elem.uid
|
190
|
+
|
191
|
+
acl = store.find {|u| u == uid} || {}
|
192
|
+
|
193
|
+
acl[op]
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
data/lib/built/application.rb
CHANGED
data/lib/built/class.rb
CHANGED
@@ -39,7 +39,7 @@ module Built
|
|
39
39
|
# @return [Array] classes An array of classes
|
40
40
|
def get_all
|
41
41
|
Built.client.request(uri)
|
42
|
-
.
|
42
|
+
.json["classes"].map {|o| instantiate(o)}
|
43
43
|
end
|
44
44
|
|
45
45
|
# Get a single class by its uid
|
@@ -49,7 +49,7 @@ module Built
|
|
49
49
|
def get(uid)
|
50
50
|
instantiate(
|
51
51
|
Built.client.request(uri(uid))
|
52
|
-
.
|
52
|
+
.json["class"]
|
53
53
|
)
|
54
54
|
end
|
55
55
|
|
data/lib/built/client.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Built
|
2
2
|
class Client
|
3
|
-
|
3
|
+
attr_accessor :authtoken
|
4
|
+
attr_accessor :current_user
|
4
5
|
|
5
6
|
def initialize(options={})
|
6
7
|
@api_key = options[:application_api_key]
|
@@ -10,37 +11,64 @@ module Built
|
|
10
11
|
@authtoken = options[:authtoken]
|
11
12
|
|
12
13
|
# set the base uri
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
# set the authtoken
|
17
|
-
def authtoken=(authtoken)
|
18
|
-
@authtoken = authtoken
|
14
|
+
@base_uri = @version ? [@host, @version].join('/') : @host
|
19
15
|
end
|
20
16
|
|
21
17
|
# perform a regular request
|
22
18
|
def request(uri, method=:get, body=nil, query=nil, additionalHeaders={})
|
23
19
|
options = {}
|
24
|
-
options[:
|
25
|
-
options[:
|
20
|
+
options[:url] = @base_uri + uri
|
21
|
+
options[:method] = method
|
26
22
|
|
27
23
|
options[:headers] = {
|
28
24
|
"application_api_key" => @api_key,
|
29
25
|
"Content-Type" => "application/json"
|
30
26
|
}
|
31
27
|
|
28
|
+
options[:headers][:params] = query if query
|
29
|
+
|
32
30
|
options[:headers][:authtoken] = @authtoken if @authtoken
|
33
31
|
options[:headers][:master_key] = @master_key if @master_key
|
34
32
|
options[:headers].merge!(additionalHeaders)
|
35
33
|
|
36
|
-
|
34
|
+
if body
|
35
|
+
is_json = options[:headers]["Content-Type"] == "application/json"
|
36
|
+
options[:payload] = is_json ? body.to_json : body
|
37
|
+
unless is_json
|
38
|
+
options[:headers].delete("Content-Type")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
begin
|
43
|
+
response = Response.new(RestClient::Request.execute(options))
|
44
|
+
rescue => e
|
45
|
+
response = Response.new(e.response)
|
46
|
+
end
|
37
47
|
|
38
|
-
if !
|
48
|
+
if !(200..299).include?(response.code)
|
39
49
|
# error, throw it
|
40
|
-
raise BuiltAPIError.new(response.
|
50
|
+
raise BuiltAPIError.new(response.json)
|
41
51
|
end
|
42
52
|
|
43
53
|
response
|
44
54
|
end
|
45
55
|
end
|
56
|
+
|
57
|
+
class Response
|
58
|
+
attr_reader :raw
|
59
|
+
attr_reader :code
|
60
|
+
attr_reader :body
|
61
|
+
attr_reader :headers
|
62
|
+
|
63
|
+
def initialize(response)
|
64
|
+
@raw = response
|
65
|
+
@code = response.code
|
66
|
+
@body = response.body
|
67
|
+
@headers = response.headers
|
68
|
+
end
|
69
|
+
|
70
|
+
def json
|
71
|
+
JSON.parse @body
|
72
|
+
end
|
73
|
+
end
|
46
74
|
end
|
data/lib/built/constants.rb
CHANGED
@@ -1,4 +1,9 @@
|
|
1
1
|
# constants
|
2
|
-
API_URI
|
2
|
+
Built::API_URI = "https://api.built.io"
|
3
3
|
# we no longer need version strings
|
4
|
-
API_VERSION
|
4
|
+
Built::API_VERSION = nil
|
5
|
+
# where location is stored in the object
|
6
|
+
Built::LOCATION_PATH = "__loc"
|
7
|
+
Built::USER_CLASS_UID = "built_io_application_user"
|
8
|
+
Built::ROLE_CLASS_UID = "built_io_application_user_role"
|
9
|
+
Built::INST_CLASS_UID = "built_io_installation_data"
|
data/lib/built/error.rb
CHANGED
@@ -6,7 +6,7 @@ module Built
|
|
6
6
|
# Errors thrown by the built.io API
|
7
7
|
class BuiltAPIError < BuiltError
|
8
8
|
attr_accessor :error_code
|
9
|
-
attr_accessor :
|
9
|
+
attr_accessor :errors
|
10
10
|
attr_accessor :error_message
|
11
11
|
|
12
12
|
def initialize(response)
|
@@ -14,7 +14,7 @@ module Built
|
|
14
14
|
|
15
15
|
if @response
|
16
16
|
@error_code = response["error_code"]
|
17
|
-
@
|
17
|
+
@errors = response["errors"]
|
18
18
|
@error_message = response["error_message"]
|
19
19
|
end
|
20
20
|
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Built
|
2
|
+
# This is used to specify a long/lat pair in built.io
|
3
|
+
class Location
|
4
|
+
attr_accessor :long
|
5
|
+
attr_accessor :lat
|
6
|
+
|
7
|
+
# Create a new Location object
|
8
|
+
# @param [Float] long Longitude of the location
|
9
|
+
# @param [Float] lat Latitude of the location
|
10
|
+
# @return [Location] location A new location
|
11
|
+
def initialize(long, lat)
|
12
|
+
Util.type_check("long", long, Float)
|
13
|
+
Util.type_check("lat", lat, Float)
|
14
|
+
|
15
|
+
@long = long
|
16
|
+
@lat = lat
|
17
|
+
end
|
18
|
+
|
19
|
+
# Distance in meters from a certain location
|
20
|
+
# @param [Location] location The location
|
21
|
+
# @return [Integer] distance in meters
|
22
|
+
def metersFrom(location)
|
23
|
+
Util.type_check("location", location, Location)
|
24
|
+
|
25
|
+
haversine(location.lat, location.long, lat, long, 1000)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Distance in kilometers from a certain location
|
29
|
+
# @param [Location] location The location
|
30
|
+
# @return [Integer] distance in kilometers
|
31
|
+
def kilometersFrom(location)
|
32
|
+
Util.type_check("location", location, Location)
|
33
|
+
|
34
|
+
haversine(location.lat, location.long, lat, long, 1)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Convert this into an array of [long, lat]
|
38
|
+
# @return [Array<Float, Float>]
|
39
|
+
def to_arr
|
40
|
+
[long, lat]
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
"#<Built::Object long=#{long}, lat=#{lat}>"
|
47
|
+
end
|
48
|
+
|
49
|
+
def power(num, pow)
|
50
|
+
num ** pow
|
51
|
+
end
|
52
|
+
|
53
|
+
def haversine(lat1, long1, lat2, long2, factor)
|
54
|
+
dtor = Math::PI/180
|
55
|
+
r = 6378.14*factor
|
56
|
+
|
57
|
+
rlat1 = lat1 * dtor
|
58
|
+
rlong1 = long1 * dtor
|
59
|
+
rlat2 = lat2 * dtor
|
60
|
+
rlong2 = long2 * dtor
|
61
|
+
|
62
|
+
dlon = rlong1 - rlong2
|
63
|
+
dlat = rlat1 - rlat2
|
64
|
+
|
65
|
+
a = power(Math::sin(dlat/2), 2) + Math::cos(rlat1) * Math::cos(rlat2) * power(Math::sin(dlon/2), 2)
|
66
|
+
c = 2 * Math::atan2(Math::sqrt(a), Math::sqrt(1-a))
|
67
|
+
d = r * c
|
68
|
+
|
69
|
+
return d.ceil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|