arcgis 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +48 -0
- data/README.md +78 -0
- data/lib/arcgis.rb +4 -0
- data/lib/arcgis/base.rb +29 -0
- data/lib/arcgis/client.rb +8 -0
- data/lib/arcgis/configurable.rb +22 -0
- data/lib/arcgis/online.rb +119 -0
- data/lib/arcgis/portal/portal.rb +14 -0
- data/lib/arcgis/sharing/comment.rb +36 -0
- data/lib/arcgis/sharing/community.rb +24 -0
- data/lib/arcgis/sharing/features.rb +19 -0
- data/lib/arcgis/sharing/group.rb +30 -0
- data/lib/arcgis/sharing/item.rb +127 -0
- data/lib/arcgis/sharing/search.rb +71 -0
- data/lib/arcgis/sharing/user.rb +74 -0
- data/lib/contrib/multipart.rb +22 -0
- metadata +73 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cb19680c0b9305d014b4ba531b316cee6448b754
|
4
|
+
data.tar.gz: c2196e8f2d6aea46643267433c28e7612ef27262
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: faff1e282f34001b2604cbca4dec2ef257cf15990e0d053ecd6fa4e3f14e0ccc8471954599ddd77dc2f68e1ce88af9ca068311963f05d23044cfc3b5022039ef
|
7
|
+
data.tar.gz: 7d8d32cce9c5dcf15a9493a82faa3e225c5c6ad6a57becfb51cc225c06f5a94371a8629b8ea19663a0c397e51d30dc2bb4046701aef4fbc372b5393a6b56d211
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
Apache License – 2.0
|
2
|
+
|
3
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
4
|
+
|
5
|
+
1. Definitions.
|
6
|
+
|
7
|
+
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
8
|
+
|
9
|
+
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
10
|
+
|
11
|
+
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
12
|
+
|
13
|
+
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
14
|
+
|
15
|
+
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
16
|
+
|
17
|
+
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
18
|
+
|
19
|
+
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
20
|
+
|
21
|
+
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
22
|
+
|
23
|
+
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
24
|
+
|
25
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
26
|
+
|
27
|
+
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
28
|
+
|
29
|
+
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
30
|
+
|
31
|
+
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
32
|
+
|
33
|
+
1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
34
|
+
2. You must cause any modified files to carry prominent notices stating that You changed the files; and
|
35
|
+
3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
36
|
+
4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
37
|
+
|
38
|
+
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
39
|
+
|
40
|
+
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
41
|
+
|
42
|
+
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
43
|
+
|
44
|
+
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
45
|
+
|
46
|
+
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
47
|
+
|
48
|
+
END OF TERMS AND CONDITIONS
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# ArcGIS Online Ruby Library
|
2
|
+
|
3
|
+
This library is a simple wrapper around the ArcGIS API's for GeoServices and ArcGIS Online using the sharing API.
|
4
|
+
|
5
|
+
The library currently just exposes the service endpoints and accepts unverified hashes of input parameters as specified in the [ArcGIS API](http://www.arcgis.com/apidocs/rest/). As it evolves more endpoints will be added as well as more Ruby-like objects for the various API capabilities.
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
## Instructions
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
# Create a client
|
13
|
+
@online = Arcgis::Online.new(:host => "http://www.arcgis.com/sharing/rest/")
|
14
|
+
# Do an unauthenticated search
|
15
|
+
results = @online.search(:q => "weather", :itemtype => "Web Map")
|
16
|
+
|
17
|
+
# For features with permissions, first log in
|
18
|
+
@online.login(:username => @username, :password => @password)
|
19
|
+
|
20
|
+
# Create an item
|
21
|
+
response = @online.item_add( :title => "Weather Station Temperatures",
|
22
|
+
:type => "CSV",
|
23
|
+
:file => File.open("my_data.csv"),
|
24
|
+
:tags => %w{temperature stations}.join(","))
|
25
|
+
|
26
|
+
@id = response["id"]
|
27
|
+
puts "This item has #{response['numComments']} comments."
|
28
|
+
|
29
|
+
# Publish as a feature service
|
30
|
+
analysis = @online.item_analyze(:id => @id, :type => "CSV")
|
31
|
+
publish = @online.item_publish(:id => @id,
|
32
|
+
:filetype => "Feature Service",
|
33
|
+
:publishParameters => analysis["publishParameters"].to_json)
|
34
|
+
|
35
|
+
puts "Feature Service URL: " + publish["services"].first["serviceurl"]
|
36
|
+
|
37
|
+
# Clean up
|
38
|
+
@online.item_delete(:items => [@id, publish["services"].first["serviceItemId"]])
|
39
|
+
```
|
40
|
+
|
41
|
+
### Testing
|
42
|
+
|
43
|
+
arcgis-ruby uses RSpec for tests. First copy @config.yml.example@ to @config.yml@ and modify the username and password. Then from the command line run:
|
44
|
+
|
45
|
+
$ rspec
|
46
|
+
|
47
|
+
If your arcgis online user is a public user, i.e. not allowed to create groups or publish items, then run:
|
48
|
+
|
49
|
+
$ rspec --tag ~@privileged
|
50
|
+
|
51
|
+
This will skip tests that require publisher access.
|
52
|
+
|
53
|
+
|
54
|
+
## Requirements
|
55
|
+
|
56
|
+
* Ruby
|
57
|
+
|
58
|
+
## Resources
|
59
|
+
|
60
|
+
* [ArcGIS Portal API](http://www.arcgis.com/apidocs/rest/)
|
61
|
+
|
62
|
+
## Licensing
|
63
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
64
|
+
you may not use this file except in compliance with the License.
|
65
|
+
You may obtain a copy of the License at
|
66
|
+
|
67
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
68
|
+
|
69
|
+
Unless required by applicable law or agreed to in writing, software
|
70
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
71
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
72
|
+
See the License for the specific language governing permissions and
|
73
|
+
limitations under the License.
|
74
|
+
|
75
|
+
A copy of the license is available in the repository's [license.txt](./license.txt) file.
|
76
|
+
|
77
|
+
[](Esri Tags: ArcGIS Ruby API AGOL Public)
|
78
|
+
[](Esri Language: Ruby)
|
data/lib/arcgis.rb
ADDED
data/lib/arcgis/base.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Arcgis
|
2
|
+
module Base
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
# Factory for building API endpoints from Definitions
|
9
|
+
def extend_api(api,definition)
|
10
|
+
definition.each do |parent,ops|
|
11
|
+
ops.each do |op,methods|
|
12
|
+
methods.each do |method|
|
13
|
+
# build the method, but allow for 'root' level methods with the parent
|
14
|
+
# (e.g. /community/user = user_community; /community/user/update = user_update)
|
15
|
+
subapi = method.length == 0 ? parent.to_s : method
|
16
|
+
define_method("#{api}_#{subapi}".gsub(/_$/,'')) { |options|
|
17
|
+
# differentiate 'items' for /content/ from '' for /community/ - e.g. content/users/id vs. community/users/id
|
18
|
+
url = "#{self.send(parent.to_s+'_url')}#{self.send(api.to_s+'_url')}#{options.delete(:id)}/#{method.gsub(/items/,'')}"
|
19
|
+
url.gsub!(/\/+/, '/')
|
20
|
+
url.gsub!(/community\/community/,'community')
|
21
|
+
self.send(op,url,options)
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Arcgis
|
2
|
+
module Configurable
|
3
|
+
attr_accessor :host, :username, :password, :token, :debug
|
4
|
+
class << self
|
5
|
+
# TODO: include defaults? - ajturner
|
6
|
+
def keys
|
7
|
+
@keys ||= [
|
8
|
+
:host,
|
9
|
+
:username,
|
10
|
+
:password,
|
11
|
+
:token,
|
12
|
+
:debug
|
13
|
+
]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def configure
|
18
|
+
yield self
|
19
|
+
self
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../arcgis/base'
|
2
|
+
require File.dirname(__FILE__) + '/../arcgis/sharing/community'
|
3
|
+
require File.dirname(__FILE__) + '/../arcgis/sharing/item'
|
4
|
+
require File.dirname(__FILE__) + '/../arcgis/sharing/search'
|
5
|
+
require File.dirname(__FILE__) + '/../arcgis/sharing/user'
|
6
|
+
require File.dirname(__FILE__) + '/../arcgis/sharing/group'
|
7
|
+
require File.dirname(__FILE__) + '/../arcgis/sharing/features'
|
8
|
+
require File.dirname(__FILE__) + '/../arcgis/sharing/comment'
|
9
|
+
require File.dirname(__FILE__) + '/../arcgis/portal/portal'
|
10
|
+
require 'json'
|
11
|
+
require 'net/http'
|
12
|
+
require 'net/https'
|
13
|
+
require 'uri'
|
14
|
+
require 'date'
|
15
|
+
module Arcgis
|
16
|
+
class Online
|
17
|
+
include Arcgis::Base
|
18
|
+
include Arcgis::Sharing::Community
|
19
|
+
include Arcgis::Sharing::Item
|
20
|
+
include Arcgis::Sharing::Search
|
21
|
+
include Arcgis::Sharing::User
|
22
|
+
include Arcgis::Sharing::Group
|
23
|
+
include Arcgis::Sharing::Features
|
24
|
+
include Arcgis::Sharing::Comment
|
25
|
+
include Arcgis::Portal
|
26
|
+
include Arcgis::Configurable
|
27
|
+
|
28
|
+
class ErrorResponse < RuntimeError
|
29
|
+
attr_accessor :response
|
30
|
+
def initialize(response={})
|
31
|
+
message = response["message"] || response[:message] || response[:code] || response.inspect
|
32
|
+
message += response["details"].join("\n") if response["details"]
|
33
|
+
super(message)
|
34
|
+
@response = response
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def initialize(options={})
|
40
|
+
update_configuration(options)
|
41
|
+
end
|
42
|
+
|
43
|
+
# The root path or url in the service
|
44
|
+
def root_url
|
45
|
+
"" #host included in #get and #post
|
46
|
+
end
|
47
|
+
|
48
|
+
def client
|
49
|
+
@client = Arcgis::Client.new(options) unless defined?(@client) && @client.hash == options.hash
|
50
|
+
@client
|
51
|
+
end
|
52
|
+
|
53
|
+
attr_accessor :token, :token_expires
|
54
|
+
# username, password, referrer
|
55
|
+
def login(options={})
|
56
|
+
update_configuration(options)
|
57
|
+
@token = nil if (@token_expires && @token_expires < DateTime.now)
|
58
|
+
if(@token.nil?)
|
59
|
+
user = post("/generateToken", {:secure => true, :username => @username, :password => @password,
|
60
|
+
:referer => "http://arcgis.com"}.merge(options))
|
61
|
+
@token = user["token"]
|
62
|
+
@token_expires = DateTime.strptime((user["expires"]/1000).to_s, "%s")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
def logout
|
66
|
+
@token = nil
|
67
|
+
@token_expires = nil
|
68
|
+
end
|
69
|
+
|
70
|
+
def get(path,options={})
|
71
|
+
path.gsub!(/%username%/,@username || "")
|
72
|
+
uri = URI.parse(@host + path)
|
73
|
+
uri.query = URI.encode_www_form({:f => "json",
|
74
|
+
:token => @token}.merge(options))
|
75
|
+
|
76
|
+
return handle_response(Net::HTTP.get_response(uri))
|
77
|
+
end
|
78
|
+
|
79
|
+
def post(path, options={})
|
80
|
+
secure = options.delete(:secure) || false
|
81
|
+
path.gsub!(/%username%/,@username || "")
|
82
|
+
uri = URI.parse(@host + path)
|
83
|
+
http = Net::HTTP.new(uri.host, secure ? 443 : uri.port)
|
84
|
+
if(secure)
|
85
|
+
http.use_ssl = true
|
86
|
+
# http.ssl_version = :SSLv3
|
87
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
88
|
+
end
|
89
|
+
|
90
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
91
|
+
params = {:f => "json", :token => @token}.merge(options)
|
92
|
+
request.set_multipart_form_data(params)
|
93
|
+
|
94
|
+
return handle_response(http.request(request))
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
# TODO: Add defaults for this? - ajturner
|
99
|
+
def update_configuration(options={})
|
100
|
+
Arcgis::Configurable.keys.each do |key|
|
101
|
+
instance_variable_set(:"@#{key}", options[key]) if options.include?(key)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def handle_response(res)
|
106
|
+
if res.is_a?(Net::HTTPSuccess)
|
107
|
+
unless res.nil? or res.body.nil? or res.body == 'null'
|
108
|
+
response = JSON.parse(res.body)
|
109
|
+
raise ErrorResponse.new(response["error"]) if response["error"]
|
110
|
+
return response
|
111
|
+
else
|
112
|
+
nil
|
113
|
+
end
|
114
|
+
else
|
115
|
+
throw res.status
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Arcgis
|
2
|
+
module Portal
|
3
|
+
# API Docs: http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/Portal_Self/02r3000001m7000000/
|
4
|
+
# http://dcdev.maps.arcgis.com/sharing/rest/portals/self
|
5
|
+
include Arcgis::Base
|
6
|
+
def portal_url
|
7
|
+
"portals/"
|
8
|
+
end
|
9
|
+
|
10
|
+
def organization(options = {})
|
11
|
+
get("#{portal_url}/self",options)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Arcgis
|
2
|
+
module Sharing
|
3
|
+
module Comment
|
4
|
+
include Arcgis::Base
|
5
|
+
# API Docs: http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/Item_Comments/02r300000088000000/
|
6
|
+
def comment_url
|
7
|
+
"comments/"
|
8
|
+
end
|
9
|
+
|
10
|
+
# TODO is this better as a const or a method? - ajturner
|
11
|
+
GROUP_METHODS = {
|
12
|
+
:content => {
|
13
|
+
:get => [""],
|
14
|
+
:post => ["update","delete"]
|
15
|
+
},
|
16
|
+
:community => {}
|
17
|
+
}
|
18
|
+
|
19
|
+
extend_api(self.name.split("::").last.downcase,GROUP_METHODS)
|
20
|
+
|
21
|
+
# Helper function for finding a group
|
22
|
+
def comment(options)
|
23
|
+
get("/content/items/#{options.delete(:item)}/comments/#{options[:id]}",options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def comment_update(options)
|
27
|
+
post("/content/items/#{options.delete(:item)}/comments/#{options[:id]}/update",options)
|
28
|
+
end
|
29
|
+
|
30
|
+
def comment_delete(options)
|
31
|
+
post("/content/items/#{options.delete(:item)}/comments/#{options[:id]}/delete",options)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Arcgis
|
2
|
+
module Sharing
|
3
|
+
module Community
|
4
|
+
include Arcgis::Base
|
5
|
+
# API Docs: http://www.arcgis.com/apidocs/rest/community.html
|
6
|
+
def community_url
|
7
|
+
root_url + "community/"
|
8
|
+
end
|
9
|
+
def content_url
|
10
|
+
root_url + "content/"
|
11
|
+
end
|
12
|
+
|
13
|
+
COMMUNITY_METHODS = {
|
14
|
+
:community => {
|
15
|
+
:get => ["users", "groups"],
|
16
|
+
:post => ["createGroup"]
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
extend_api("community", COMMUNITY_METHODS)
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Arcgis
|
2
|
+
module Sharing
|
3
|
+
module Features
|
4
|
+
include Arcgis::Base
|
5
|
+
# API Docs: http://devext.arcgis.com/apidocs/rest/features.html
|
6
|
+
def features_url
|
7
|
+
"features/"
|
8
|
+
end
|
9
|
+
|
10
|
+
FEATURES_METHODS = {
|
11
|
+
:content => {
|
12
|
+
:post => ["analyze", "generate"]
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
extend_api(self.name.split("::").last.downcase,FEATURES_METHODS)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Arcgis
|
2
|
+
module Sharing
|
3
|
+
module Group
|
4
|
+
include Arcgis::Base
|
5
|
+
# API Docs: http://www.arcgis.com/apidocs/rest/group.html
|
6
|
+
def group_url
|
7
|
+
"groups/"
|
8
|
+
end
|
9
|
+
|
10
|
+
# TODO is this better as a const or a method? - ajturner
|
11
|
+
GROUP_METHODS = {
|
12
|
+
:content => {
|
13
|
+
:get => ["", "items"]
|
14
|
+
},
|
15
|
+
:community => {
|
16
|
+
:post => %w{update reassign delete join invite leave removeUsers },
|
17
|
+
:get => ["", "users", "applications"]
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
extend_api(self.name.split("::").last.downcase,GROUP_METHODS)
|
22
|
+
|
23
|
+
# Helper function for finding a group
|
24
|
+
def group(options)
|
25
|
+
group_community(options)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module Arcgis
|
2
|
+
module Sharing
|
3
|
+
# API Docs: http://www.arcgis.com/apidocs/rest/item.html
|
4
|
+
module Item
|
5
|
+
MAX_SERVICENAME_LIMIT = 80
|
6
|
+
|
7
|
+
include Arcgis::Base
|
8
|
+
def item_url
|
9
|
+
"items/"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Methods:
|
13
|
+
# <item-url> GET comments rating relatedItems
|
14
|
+
# <item-url> POST addComment addRating deleteRating
|
15
|
+
ITEM_METHODS = {
|
16
|
+
:content => {
|
17
|
+
:get => ["", "comments", "rating", "relatedItems", "data","groups"],
|
18
|
+
:post => %w{addRelationship deleteRelationship addItem addComment addRating deleteRating share unshare}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
extend_api(self.name.split("::").last.downcase,ITEM_METHODS)
|
23
|
+
|
24
|
+
# Helper function for loading an item
|
25
|
+
def item(options)
|
26
|
+
item_content(options)
|
27
|
+
end
|
28
|
+
|
29
|
+
# http://www.arcgis.com/sharing/rest/content/items/{id}?f=json
|
30
|
+
# def initialize(options)
|
31
|
+
# options.each do |k,v|
|
32
|
+
# self[k] = v
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
|
36
|
+
# def item(options)
|
37
|
+
# item = get("/content/items/#{options[:id]}")
|
38
|
+
# # return Item.new(item)
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# def item_groups(options={})
|
42
|
+
# get("/content/items/#{item["id"]}/groups",)
|
43
|
+
# end
|
44
|
+
# # http://www.arcgis.com/apidocs/rest/itemshareitem.html
|
45
|
+
# # options
|
46
|
+
# # everyone <boolean>
|
47
|
+
# # org <boolean>
|
48
|
+
# # groups <array>
|
49
|
+
# def item_share(options={})
|
50
|
+
# options[:groups] = options.delete(:groups).join(",") if options.include?(:groups) && options.is_a?(Array)
|
51
|
+
# post("/content/items/#{item["id"]}/share",options)
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# # http://www.arcgis.com/apidocs/rest/itemunshareitem.html
|
55
|
+
# def item_unshare(options={})
|
56
|
+
# options[:groups] = options.delete(:groups).join(",") if options.include?(:groups) && options.is_a?(Array)
|
57
|
+
# post("/content/items/#{item["id"]}/unshare",options)
|
58
|
+
# end
|
59
|
+
|
60
|
+
|
61
|
+
#
|
62
|
+
# USER CONTENT
|
63
|
+
#
|
64
|
+
|
65
|
+
# Register a new item in ArcGIS Online
|
66
|
+
#
|
67
|
+
# username is optional. If included it will be added to that user.
|
68
|
+
# Otherwise it will use the username of the login credentials
|
69
|
+
def item_add(options={})
|
70
|
+
options = options.dup
|
71
|
+
username = options.delete(:username) || "%username%"
|
72
|
+
options[:file] = File.open(options.delete[:file]) if options.include?(:file) && options[:file].is_a?(String)
|
73
|
+
post("/content/users/#{username}/addItem",options)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Delete an item from ArcGIS Online
|
77
|
+
#
|
78
|
+
# options
|
79
|
+
# items array of item id's
|
80
|
+
# Returns {"error"=>{"code"=>400, "messageCode"=>"CONT_0001", "message"=>"Item '8960a63b2f1443f9a0a07922fc4bffec' does not exist or is inaccessible.", "details"=>[]}}
|
81
|
+
def item_delete(options={})
|
82
|
+
options = options.dup
|
83
|
+
username = options.delete(:username) || "%username%"
|
84
|
+
post("/content/users/#{username}/deleteItems",{:items => options[:items].join(",")})
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
def item_update(options={})
|
90
|
+
options = options.dup
|
91
|
+
id = options.delete(:id)
|
92
|
+
item = get("/content/items/#{id}")
|
93
|
+
item = post("/content/users/#{item["owner"]}/items/#{item["id"]}/update",options)
|
94
|
+
end
|
95
|
+
|
96
|
+
# http://www.arcgis.com/apidocs/rest/itemunshareitem.html
|
97
|
+
#
|
98
|
+
# itemId
|
99
|
+
# filetype serviceDefinition | shapefile | csv | Tile Package | Feature Service
|
100
|
+
# publishParameters
|
101
|
+
# outputType
|
102
|
+
#
|
103
|
+
# name (required)
|
104
|
+
def item_publish(options={})
|
105
|
+
options = options.dup
|
106
|
+
options[:itemId] = options.delete(:id) unless options.include?(:itemId)
|
107
|
+
post("/content/users/#{username}/publish",options)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Analyze returns information about an item including the fields present as well as sample records.
|
111
|
+
# http://www.arcgis.com/apidocs/rest/analyze.html
|
112
|
+
#
|
113
|
+
# id - id of the item
|
114
|
+
# type shapefile | csv
|
115
|
+
# file
|
116
|
+
# text
|
117
|
+
#
|
118
|
+
def item_analyze(options={})
|
119
|
+
options = options.dup
|
120
|
+
options[:itemId] = options.delete(:id) unless options.include?(:itemId)
|
121
|
+
response = post("/content/features/analyze",options)
|
122
|
+
response["publishParameters"]["name"] = response["publishParameters"]["name"][0..MAX_SERVICENAME_LIMIT] if response["publishParameters"]["name"].length > MAX_SERVICENAME_LIMIT
|
123
|
+
response
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'uri'
|
2
|
+
module Arcgis
|
3
|
+
module Sharing
|
4
|
+
module Search
|
5
|
+
include Arcgis
|
6
|
+
|
7
|
+
# q Description: The query string to search with.
|
8
|
+
#
|
9
|
+
# Example: q=relands+map
|
10
|
+
# bbox
|
11
|
+
# Description: The bounding box for a spatial search and is defined as minx, miny, maxx, maxy. Search requires q, bbox or both.
|
12
|
+
#
|
13
|
+
# Spatial search is an overlaps/intersects function of the query bbox and the extent of the document.
|
14
|
+
#
|
15
|
+
# Documents that have no extent (e.g., mxds, 3dds, lyr) will not be found when doing a bbox search.
|
16
|
+
#
|
17
|
+
# Document extent is assumed to be in the WGS84 geographic coordinate system.
|
18
|
+
#
|
19
|
+
# Example: bbox=-118,32,-116,34
|
20
|
+
#
|
21
|
+
# start Description: The number of the first entry in the result set response. The index number is 1-based.
|
22
|
+
#
|
23
|
+
# The default value of start is 1. (i.e. the first search result)
|
24
|
+
#
|
25
|
+
# The start parameter, along with the num parameter can be used to paginate the search results.
|
26
|
+
#
|
27
|
+
# Example: start=11 (return result #11 as the first entry in the response)
|
28
|
+
# num Description: The maximum number of results to be included in the result set response.
|
29
|
+
#
|
30
|
+
# The default value is 10 and the maximum allowed value is 100
|
31
|
+
#
|
32
|
+
# The start parameter, along with the num parameter can be used to paginate the search results.
|
33
|
+
#
|
34
|
+
# Note that the actual number of returned results may be less than num. This happens when the number of results remaining after start is less than num.
|
35
|
+
#
|
36
|
+
# Example: num=50 (return a max of 50 results in the response)
|
37
|
+
# sortField Description: Field to sort by. You can also sort by multiple fields for an item, comma separated.
|
38
|
+
# The allowed sort field names are title, created, type, owner, avgRating, numRatings, numComments and numViews.
|
39
|
+
# sortOrder Values: asc | desc
|
40
|
+
|
41
|
+
# q only:
|
42
|
+
# id Id of the item, for example, id: 4e770315ad9049e7950b552aa1e40869 returns the item for that id.
|
43
|
+
# itemtype Item type is either URL, Text, or File. See Item Types for a listing of the different types. This field is pre-defined. For example, itemtype:file return items of the type file.
|
44
|
+
# owner Owner of the item, for example, owner:esri returns all content published by Esri.
|
45
|
+
# created Created is the date created, for example created: [0000001249084800000 TO 0000001249548000000] finds all items published between August 1, 2009, 12:00AM to August 6, 2009 08:40AM.
|
46
|
+
# title Item title, for example, title:"Southern California" returns items with Southern California in the title.
|
47
|
+
# type Type returns the type of item and is a pre-defined field. See Item Types for a listing of the different types. For example, type:map returns items with map as the type, such as map documents and map services.
|
48
|
+
# typekeywords Type keywords, for example, typekeywords:tool returns items with the tool type keyword such as Network Analysis or Geoprocessing services. See Item Types for a listing of the different types.
|
49
|
+
# description Item description, for example, description:California finds all items with the term California in the description.
|
50
|
+
# tags The tag field, for example, tags:"San Francisco" returns items tagged with the term San Francisco.
|
51
|
+
# snippet Snippet or summary of the item, for example, snippet:"natural resources" returns items with natural resources in the snippet.
|
52
|
+
# extent The bounding rectangle of the item. For example, extent: [-114.3458, 21.7518] - [-73.125, 44.0658] returns items within that extent.
|
53
|
+
# spatialreference Spatial reference, for example, spatialreference:102100 returns items in the Web Mercator Auxiliary Sphere projection.
|
54
|
+
# accessinformaton Accessinformaton, for example, accessinformation:esri returns items with esri as the source credit.
|
55
|
+
# access The access field, for example, access:public returns public items. This field is pre-defined and the options are public, private or shared. You will only see private or shared items that you have access to.
|
56
|
+
# group The id of the group, for example, group:1652a410f59c4d8f98fb87b25e0a2669 returns items within the given group.
|
57
|
+
# numratings Number of Ratings, for example, numratings:6 returns items with six ratings.
|
58
|
+
# numcomments Number of comments, for example, numcomments:[1 TO 3] returns items that have one to three comments.
|
59
|
+
# avgrating Average rating, for example, avgrating:3.5 returns items with 3.5 as the average rating.
|
60
|
+
# culture Culture, for example, culture:en-US, returns the locale of the item. The search engine treats the two parts of the culture code as two different terms and searches for individual languages can be done. For example, culture:en returns all records that have an 'en' in their culture code. There may be overlaps between the codes used for language and the codes used for country, for instance fr-FR, but if the client needs to target a code with this problem they can pass in the complete code.
|
61
|
+
SEARCH_OPTIONS = %w{q bbox start num sortField sortOrder}
|
62
|
+
SEARCH_FIELDS = %w{id itemtype owner created title type typekeywords description tags snippet extent spatialreference accessinformation access group numratings numcomments avgrating culture}
|
63
|
+
def search(options)
|
64
|
+
options = options.inject({}) {|hash,(k,v)| hash[k.to_s] = v; hash}
|
65
|
+
options['q'] = (SEARCH_FIELDS.collect {|s| "#{s}:#{'"'+options.delete(s)+'"'}" if options.keys.include?(s) } + [options['q']]).compact.join(" AND ")
|
66
|
+
# results["results"] = results["results"].collect { |r| Arcgis::Sharing::Item.new(r) }
|
67
|
+
get("/search",options)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Arcgis
|
2
|
+
module Sharing
|
3
|
+
# API Docs: http://www.arcgis.com/apidocs/rest/user.html
|
4
|
+
module User
|
5
|
+
include Arcgis::Base
|
6
|
+
|
7
|
+
def user_url
|
8
|
+
"users/"
|
9
|
+
end
|
10
|
+
|
11
|
+
# TODO add SubResource methods for Invitations, Notifications
|
12
|
+
# TODO is this better as a const or a method? - ajturner
|
13
|
+
USER_METHODS = {
|
14
|
+
:content => {
|
15
|
+
:get => ["items", ""],
|
16
|
+
:post => ["deleteItems", "addRelationship", "deleteRelationship",
|
17
|
+
"publishItem", "exportItem", "shareItems", "unshareItems", "moveItems", "deleteItems"]
|
18
|
+
},
|
19
|
+
:community => {
|
20
|
+
:get => ["", "notifications","tags","invitations"],
|
21
|
+
:post => %w{update delete}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
extend_api(self.name.split("::").last.downcase,USER_METHODS)
|
26
|
+
|
27
|
+
# simple placeholder for getting users.
|
28
|
+
def user(options)
|
29
|
+
user_community(options)
|
30
|
+
end
|
31
|
+
|
32
|
+
def user_createFolder(options)
|
33
|
+
username = options.delete(:username) || "%username%"
|
34
|
+
post("content/users/#{username}/createFolder",options)
|
35
|
+
end
|
36
|
+
|
37
|
+
def user_deleteFolder(options)
|
38
|
+
username = options.delete(:username) || "%username%"
|
39
|
+
post("content/users/#{username}/#{options[:id]}/delete",options)
|
40
|
+
end
|
41
|
+
# # http://www.arcgis.com/apidocs/rest/usersearch.html
|
42
|
+
# # http://www.arcgis.com/apidocs/rest/commonparams.html#commonparameters
|
43
|
+
# def user_search(options = {})
|
44
|
+
# get("/community/users",options)
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# def user(options = {})
|
48
|
+
# get("/community/users/#{options[:user]}")
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# # http://www.arcgis.com/apidocs/rest/updateuser.html
|
52
|
+
# # Parameters:
|
53
|
+
# # - http://www.arcgis.com/apidocs/rest/commonparams.html#commonparameters
|
54
|
+
# # - http://www.arcgis.com/apidocs/rest/commonparams.html#user
|
55
|
+
# def user_update(options = {})
|
56
|
+
# post("/community/users/#{options[:user]}/update",options)
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# # http://www.arcgis.com/apidocs/rest/commonparams.html
|
60
|
+
# # Parameters:
|
61
|
+
# # - http://www.arcgis.com/apidocs/rest/commonparams.html#commonparameters
|
62
|
+
# def user_delete(options = {})
|
63
|
+
# post("/community/users/#{options[:user]}/delete",options)
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# # http://www.arcgis.com/apidocs/rest/usercontent.html
|
67
|
+
# def user_items(options = {})
|
68
|
+
# url = "/content/users/#{options[:user]}"
|
69
|
+
# url << "/#{options[:folder]}" if options.include?(:folder)
|
70
|
+
# get(url)
|
71
|
+
# end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'digest/sha1'
|
3
|
+
require "erb"
|
4
|
+
include ERB::Util
|
5
|
+
|
6
|
+
class Net::HTTP::Post
|
7
|
+
def set_multipart_form_data(params, boundary=nil)
|
8
|
+
boundary ||= Digest::SHA1.hexdigest(params.inspect)
|
9
|
+
chunks = params.map { |k,v|
|
10
|
+
if(v.is_a?(File))
|
11
|
+
%Q{Content-Disposition: form-data; name="#{k}"; filename="#{File.basename(v.path)}"\r\n} +
|
12
|
+
%Q{Content-Transfer-Encoding: binary\r\nContent-Type: application/octet-stream\r\n\r\n} +
|
13
|
+
%Q{#{v.read}\r\n}
|
14
|
+
else
|
15
|
+
%Q{Content-Disposition: form-data; name="#{url_encode(k)}"\r\n} +
|
16
|
+
%Q{\r\n#{v}\r\n}
|
17
|
+
end
|
18
|
+
}
|
19
|
+
self.body = "--#{boundary}\r\n" + chunks.join("--#{boundary}\r\n") + "--#{boundary}--\r\n"
|
20
|
+
self.content_type = "multipart/form-data; boundary=#{boundary}"
|
21
|
+
end
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: arcgis
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.15
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrew Turner
|
8
|
+
autorequire: arcgis
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-02-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.13'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.13'
|
27
|
+
description:
|
28
|
+
email: aturner@esri.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- LICENSE.txt
|
34
|
+
- README.md
|
35
|
+
- lib/arcgis.rb
|
36
|
+
- lib/arcgis/base.rb
|
37
|
+
- lib/arcgis/client.rb
|
38
|
+
- lib/arcgis/configurable.rb
|
39
|
+
- lib/arcgis/online.rb
|
40
|
+
- lib/arcgis/portal/portal.rb
|
41
|
+
- lib/arcgis/sharing/comment.rb
|
42
|
+
- lib/arcgis/sharing/community.rb
|
43
|
+
- lib/arcgis/sharing/features.rb
|
44
|
+
- lib/arcgis/sharing/group.rb
|
45
|
+
- lib/arcgis/sharing/item.rb
|
46
|
+
- lib/arcgis/sharing/search.rb
|
47
|
+
- lib/arcgis/sharing/user.rb
|
48
|
+
- lib/contrib/multipart.rb
|
49
|
+
homepage:
|
50
|
+
licenses: []
|
51
|
+
metadata: {}
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
requirements: []
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 2.2.0
|
69
|
+
signing_key:
|
70
|
+
specification_version: 4
|
71
|
+
summary: A simple wrapper for ArcGIS Online sharing API
|
72
|
+
test_files: []
|
73
|
+
has_rdoc:
|