arcgis 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -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)
@@ -0,0 +1,4 @@
1
+ require File.dirname(__FILE__) + '/arcgis/base'
2
+ require File.dirname(__FILE__) + '/arcgis/configurable'
3
+ require File.dirname(__FILE__) + '/arcgis/online'
4
+ require File.dirname(__FILE__) + '/contrib/multipart'
@@ -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,8 @@
1
+ module Arcgis
2
+ class Client
3
+ include Arcgis::Configurable
4
+
5
+
6
+
7
+ end
8
+ 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: