envato-sdk 0.3.0 → 0.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3b1e5a612b369f84ba4ffa05d328ce11e3fad37b
4
- data.tar.gz: 90b5fb30a69f862f5d31323a0c19514bec638ac9
3
+ metadata.gz: 76873a2b09a7a9b82211f2abe8ecc4cfd84df4f7
4
+ data.tar.gz: bb2df3c454b56c01de0a664a6b2dec21f13dbcd9
5
5
  SHA512:
6
- metadata.gz: c43e463c51d9dbad4c21aa61cb4076aac9eb79d387dfe8a0f70213ea37df154eae6965b581fb310ec4eae9f7623b8baa3a97c83d566c8d7c5b1e19d1281398a6
7
- data.tar.gz: 128ab8408d3243989324556415c2eb6b8f6af2febe3234c890c83650a53ecc182aca9bd1081fc1b6ab52214778b8d74c7daf295315e27d38f3b56c49b06f43cd
6
+ metadata.gz: 0900c540e28c39dafb61053553e817f2f3d0c40b6977b4ac4e3290143c4355e5765387016f4b51f2eaaba320860551896ba959d5698927468a78a27960b0f8e2
7
+ data.tar.gz: adc8fe6f650034b86f383cc255d19577bc86adeef8b9960ee695cf37810e5e87c6bc20a5b7109f255a8bd10d0d4e847d9ec188741549031f2031e21ae6397557
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Envato Ruby SDK [![Build Status](https://travis-ci.org/jacobbednarz/envato-ruby-sdk.svg?branch=master)](https://travis-ci.org/jacobbednarz/envato-ruby-sdk)
1
+ # Envato Ruby SDK [![Build Status](https://travis-ci.org/jacobbednarz/envato-ruby-sdk.svg?branch=master)](https://travis-ci.org/jacobbednarz/envato-ruby-sdk) [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](www.rubydoc.info/github/jacobbednarz/envato-ruby-sdk)
2
2
 
3
3
  Interact with the [Envato API][envato_api_url] using Ruby.
4
4
 
@@ -26,169 +26,9 @@ client = Envato::Client.new(access_token: 'mytops3crettoken')
26
26
 
27
27
  # Send a 'GET' for the total number of users.
28
28
  response = client.get 'market/total-users.json'
29
- # => {"total-users"=>{"total_users"=>"5942654"}}
29
+ # => { :total-users" => { :total_users => "5942654" } }
30
30
  ```
31
31
 
32
- ## Examples
33
-
34
- Here is a list of the functionality available via this gem. All examples expect
35
- that you have already created a client called `client` as seen in the above
36
- example. `...` represents multiple of the previous item repeated such as a hash
37
- or array item.
38
-
39
- #### Catalog
40
-
41
- - [`get_public_collection`](https://build.envato.com/api/#market_0_Catalog_Collection)
42
-
43
- ```rb
44
- client.get_public_collection(5507368)
45
- # => {"id"=>5507368, "name"=>"Test public collection", "description"=>"This is an example public collection", "private"=>false, "item_count"=>1, "image"=>"default-collection.png"}
46
- ```
47
-
48
- - [`get_item`](https://build.envato.com/api/#market_0_Catalog_Item)
49
-
50
- ```rb
51
- client.get_item(14157442)
52
- # => {"id"=>14157442, "name"=>"Beautiful Watercolor - Hand Painted Creative WordPress", "description"=>"<p><img src=\"http://dtbaker.net/wp-content/uploads/sites ...
53
- ```
54
-
55
- - [`popular_items_by_site`](https://build.envato.com/api/#market_Popular)
56
-
57
- ```rb
58
- client.popular_items_by_site('themeforest')
59
- # => {"items_last_week"=>[{"id"=>"2833226", "item"=>"Avada | Responsive Multi-Purpose Theme", "url"=>"http://themeforest.net/item/avada-responsive-multipurpose-theme/2833226", "user"=>"ThemeFusion", "thumbnail"=>"https://0.s3.envato.com/files/169508862/Thumbnail.jpg", "sales"=>"1939", "rating"=>"5.0", "rating_decimal"=>"4.78", "cost"=>"59.00", "uploaded_on"=>"Thu Aug 16 01:28:46 +1000 2012", "last_update"=>"Thu Jan 28 12:13:49 +1100 2016", "tags"=>"blog, business, clean, corporate, creative, ecommerce, modern, multipurpose, one page, photography, portfolio, responsive, retina, woocommerce, wordpress", "category"=>"wordpress/corporate", "live_preview_url"=>"https://0.s3.envato.com/files/169508866/screenshots/00_preview.__large_preview.jpg"}, {"id"=>"5871901", "item"=>"X | The Theme", ...
60
- ```
61
-
62
- - [`categories_by_site`](https://build.envato.com/api/#market_Categories)
63
-
64
- ```rb
65
- client.categories_by_site('themeforest')
66
- # => [{"name"=>"Site Templates", "path"=>"site-templates"}, {"name"=>"Creative", "path"=>"site-templates/creative"}, {"name"=>"Portfolio", "path"=>"site-templates/creative/portfolio"}, {"name"=>"Photography", "path"=>"site-templates/creative/photography"}, {"name"=>"Art", "path"=>"site-templates/creative/art"}, {"name"=>"Experimental", "path"=>"site-templates/creative/experimental"} ...]
67
- ```
68
-
69
- - [`prices_for_item`](https://build.envato.com/api/#market_ItemPrices)
70
-
71
- ```rb
72
- client.prices_for_item(13582227)
73
- # => [{"licence"=>"Regular License", "price"=>"24.00"}, {"licence"=>"Extended License", "price"=>"1200.00"}]
74
- ```
75
-
76
- - [`featured_by_site`](https://build.envato.com/api/#market_Features)
77
-
78
- ```rb
79
- client.featured_by_site('themeforest')
80
- # => {"featured_file"=>{"id"=>"14631264", "item"=>"Luxury - Responsive Virtuemart Theme", "url"=>"http://themeforest.net/item/luxury-responsive-virtuemart-theme/14631264", "user"=>"dasinfomedia", "thumbnail"=>"https://0.s3.envato.com/files/169212120/luxury_thumb_jml.png", "sales"=>"27", "rating"=>"0.0", "rating_decimal"=>"0.00", "cost"=>"48.00", "uploaded_on"=>"Wed Feb 03 04:32:39 +1100 2016", "last_update"=>"Wed Mar 23 01:40:20 +1100 2016", "tags"=>"clean, clear shop, clothing, creative design, fashion, home furniture, joomla 3 theme, lifestyle, modern, online shop, professional joomla template", "category"=>"cms-themes/joomla/retail/fashion", "live_preview_url"=>"https://0.s3.envato.com/files/169212284/01_preview.__large_preview.png"}, "featured_author"=>{"id"=>"2016597", "user"=>"DigitalAtelier", "url"=>"http://themeforest.net/user/digitalatelier", "thumbnail"=>"https://0.s3.envato.com/files/50767715/logo.png"}, "free_file"=>{"id"=>"11403244", "item"=>"Melica – Responsive WordPress Blog Theme", "url"=>"http://themeforest.net/item/melica-responsive-wordpress-blog-theme/11403244", "user"=>"wphunters", "thumbnail"=>"https://0.s3.envato.com/files/174945675/thumbnail.png", "sales"=>"52", "rating"=>"5.0", "rating_decimal"=>"5.00", "cost"=>"44.00", "uploaded_on"=>"Fri May 22 05:00:32 +1000 2015", "last_update"=>"Wed Mar 02 00:53:28 +1100 2016", "tags"=>"blog, blogger, clean, creative, fashion, food, instagram, minimal, modern, music, personal,slider, travel, video", "category"=>"wordpress/blog-magazine/personal", "live_preview_url"=>"https://0.s3.envato.com/files/174945678/preview_wp.__large_preview.jpg"}}
81
- ```
82
-
83
- - [`random_new_items_by_site`](https://build.envato.com/api/#market_RandomNewFiles)
84
-
85
- ```rb
86
- client.random_new_items_by_site('themeforest')
87
- # => [{"id"=>"15345030", "item"=>"Legal justice - HTML Template", "url"=>"http://themeforest.net/item/legal-justice-html-template/15345030", "user"=>"Xstyler", "thumbnail"=>"https://0.s3.envato.com/files/176988930/Thumbnail.png", "sales"=>"0", "rating"=>"0.0", "rating_decimal"=>"0.00", "cost"=>"15.00"}, {"id"=>"15346859", "item"=>"Gear — Automotive Business/Auto Parts Store PSD Template", "url"=>"http://themeforest.net/item/gear-automotive-businessauto-parts-store-psd-template/15346859", "user"=>"torbara", "thumbnail"=>"https://0.s3.envato.com/files/177009058/Gear_Icon.png", "sales"=>"0", "rating"=>"0.0", "rating_decimal"=>"0.00", "cost"=>"12.00"}, {"id"=>"15343695", "item"=>"Noren - Multi Store Responsive HTML Template","url"=>"http://themeforest.net/item/noren-multi-store-responsive-html-template/15343695", "user"=>"EngoTheme", "thumbnail"=>"https://0.s3.envato.com/files/178795450/80x80.jpg", "sales"=>"0", "rating"=>"0.0", "rating_decimal"=>"0.00", "cost"=>"17.00"}, {"id"=>"14770935", "item"=>"Outlaw - Stylish WooCommerce WordPress Theme", "url"=>"http://themeforest.net/item/outlaw-stylish-woocommerce-wordpress-theme/14770935", "user"=>"elusivethemes", "thumbnail"=>"https://0.s3.envato.com/files/178441822/thumb.jpg", "sales"=>"0", "rating"=>"0.0", "rating_decimal"=>"0.00", "cost"=>"59.00"}, {"id"=>"15101532", "item"=>"Ri Quartz - Responsive Multipurpose WooCommerce Theme", "url"=>"http://themeforest.net/item/ri-quartz-responsive-multipurpose-woocommerce-theme/15101532", "user"=>"CleverSoft", "thumbnail"=>"https://0.s3.envato.com/files/174287786/quartz.jpg", "sales"=>"1", "rating"=>"0.0", "rating_decimal"=>"0.00", "cost"=>"59.00"}, {"id"=>"15332367", "item"=>"Highstand - Responsive MultiPurpose HTML5 Template ", "url"=>"http://themeforest.net/item/highstand-responsive-multipurpose-html5-template-/15332367", "user"=>"gsrthemes9", "thumbnail"=>"https://0.s3.envato.com/files/178795406/thumb.jpg", "sales"=>"1", "rating"=>"0.0", "rating_decimal"=>"0.00", "cost"=>"17.00"}, {"id"=>"15156133", "item"=>"James - Responsive WooCommerce Shoes Theme", "url"=>"http://themeforest.net/item/james-responsive-woocommerce-shoes-theme/15156133", "user"=>"roadthemes", "thumbnail"=>"https://0.s3.envato.com/files/178879482/thumbnail.png", "sales"=>"0", "rating"=>"0.0", "rating_decimal"=>"0.00", "cost"=>"59.00"}, {"id"=>"15319096", "item"=>"Mozar - Fashion Clothing Bootstrap Template", "url"=>"http://themeforest.net/item/mozar-fashion-clothing-bootstrap-template/15319096", "user"=>"BootExperts", "thumbnail"=>"https://0.s3.envato.com/files/176721976/thumbnail.png", "sales"=>"0", "rating"=>"0.0", "rating_decimal"=>"0.00", "cost"=>"17.00"}, {"id"=>"14752612", "item"=>"Hash - Responsive WordPress Magazine Theme", "url"=>"http://themeforest.net/item/hash-responsive-wordpress-magazine-theme/14752612", "user"=>"PremiumLayers", "thumbnail"=>"https://0.s3.envato.com/files/178438623/80x80.jpg", "sales"=>"0", "rating"=>"0.0", "rating_decimal"=>"0.00", "cost"=>"49.00"}, {"id"=>"15079135", "item"=>"BlueMed - Health and Medical WordPress Theme", "url"=>"http://themeforest.net/item/bluemed-health-and-medical-wordpress-theme/15079135", "user"=>"happy_robot", "thumbnail"=>"https://0.s3.envato.com/files/178384359/icon.png", "sales"=>"1", "rating"=>"0.0", "rating_decimal"=>"0.00", "cost"=>"49.00"}]
88
- ```
89
-
90
- #### User
91
-
92
- - [`account_details`](https://build.envato.com/api/#market_Account)
93
-
94
- ```rb
95
- client.account_details
96
- # => {"image"=>"https://0.s3.envato.com/files/144155428/avatar.jpg", "firstname"=>"Jacob", "surname"=>"Bednarz", "available_earnings"=>"0.00", "total_deposits"=>"0.00", "balance"=>"0.00", "country"=>"Australia"}
97
- ```
98
-
99
- - [`username`](https://build.envato.com/api/#market_Username)
100
-
101
- ```rb
102
- client.username
103
- # => 'jacobbednarz'
104
- ```
105
-
106
- - [`email_address`](https://build.envato.com/api/#market_Email)
107
-
108
- ```rb
109
- client.email_address
110
- # => 'jacob@envato.com'
111
- ```
112
-
113
- - [`user_information`](https://build.envato.com/api/#market_User)
114
-
115
- ```rb
116
- client.user_information('jacobbednarz')
117
- # => {"username"=>"jacobbednarz", "country"=>"Australia", "sales"=>"0", "location"=>"", "image" => "https://0.s3.envato.com/files/144155428/avatar.jpg", "followers"=>"4"}
118
- ```
119
-
120
- - [`badges_for_user`](https://build.envato.com/api/#market_UserBadges)
121
-
122
- ```rb
123
- client.badges_for_user('jacobbednarz')
124
- # => [{"name"=>"country_au", "label"=>"Australia", "image"=>"https://dmypbau5frl9g.cloudfront.net/assets/badges/country_au-53dc340a932f5b9f1d1db574fb6712b4.svg"}, {"name"=>"envato_team", "label"=>"Envato Team", "image"=>"https://dmypbau5frl9g.cloudfront.net/assets/badges/envato_team-ac987db51c92549046fa25dfb7259bf9.svg"}, {"name"=>"exclusive", "label"=>"Exclusive Author", "image"=>"https://dmypbau5frl9g.cloudfront.net/assets/badges/exclusive-f7d9bbcda891f9ad25f00da4ea099435.svg"}]
125
- ```
126
-
127
- - [`user_items_by_site`](https://build.envato.com/api/#market_UserItemsBySite)
128
-
129
- ```rb
130
- client.user_items_by_site('collis')
131
- # => [{"site"=>"ThemeForest", "items"=>"1"}, {"site"=>"Tuts+ Marketplace", "items"=>"2"}]
132
- ```
133
-
134
- - [`new_items_for_user`](https://build.envato.com/api/#market_NewFilesFromUser)
135
-
136
- ```rb
137
- client.new_items_for_user('collis', 'themeforest')
138
- # => [{"id"=>"22705", "item"=>"Black + White Simple Theme", "url"=>"http://themeforest.net/item/black-white-simple-theme/22705", "user"=>"collis", "thumbnail"=>"https://preview-tf.s3.envato.com/files/60223.jpg", "sales"=>"916", "rating"=>"4.5", "rating_decimal"=>"4.32", "cost"=>"8.00", "uploaded_on"=>"Tue Dec 02 04:01:12 +1100 2008", "last_update"=>"", "tags"=>"clean", "category"=>"psd-templates/creative", "live_preview_url"=>"https://0.s3.envato.com/files/60224/1_home.__large_preview.jpg"}]
139
- ```
140
-
141
- - [`sales_per_month`](https://build.envato.com/api/#market_EarningsAndSalesByMonth)
142
-
143
- ```rb
144
- client.sales_per_month
145
- # => [{"month"=>"Mon Jun 01 00:00:00 +1000 2009", "sales"=>"10", "earnings"=>"120.60"} ... ]
146
- ```
147
-
148
- - [`user_statement`](https://build.envato.com/api/#market_Statement)
149
-
150
- ```rb
151
- client.user_statement
152
- # => [{"kind"=>"Author Fee", "amount"=>"-1.00", "description"=>"Author Fee for included support sale IVIP1234", "occured_at"=>"Sat Apr 09 05:11:49 +1000 2014"} ... ]
153
- ```
154
-
155
- - [`sales`](https://build.envato.com/api/#market_0_Author_Sales)
156
-
157
- ```rb
158
- client.sales
159
- # => [{"amount"=>"20.00", "sold_at"=>"2016-04-09T05:19:48+10:00", "item"=>{"id"=>123456, "name"=>"A cool theme - WordPress","description"=>"This is a theme I made and looks good!", "summary"=>"Widget Ready: Yes" ... ]
160
- ```
161
-
162
- - [`sale_by_purchase_code`](https://build.envato.com/api/#market_0_Author_Sale)
163
-
164
- ```rb
165
- client.sale_by_purchase_code('1234-5678')
166
- # => {"amount" => "5.40", "sold_at" => "2009-11-13T19:28:25+11:00", "item" => {"id":1234, "name":"Test theme - HTML","description":"Test description" ... }
167
- ```
168
-
169
- #### Marketplace Stats
170
-
171
- - [`total_items`](https://build.envato.com/api/#market_TotalItems)
172
-
173
- ```rb
174
- client.total_items
175
- # => 12345
176
- ```
177
-
178
- - [`total_users`](https://build.envato.com/api/#market_TotalUsers)
179
-
180
- ```rb
181
- client.total_users
182
- # => 23456
183
- ```
184
-
185
- - [`category_information_by_site`](https://build.envato.com/api/#market_NumberOfFiles)
186
-
187
- ```rb
188
- client.category_information_by_site('themeforest')
189
- # => [{"category"=>"Site Templates","number_of_files"=>"6551","url"=>"http://themeforest.net/category/site-templates"}, ... ]
190
- ```
191
-
192
32
  ## Testing
193
33
 
194
34
  RSpec is the testing tool of choice and you can kick off the test suite by
@@ -33,17 +33,20 @@ module Envato
33
33
  inspected
34
34
  end
35
35
 
36
- # Public: Conceal a sensitive string.
36
+ # Conceal a sensitive string.
37
37
  #
38
38
  # This conceals everything in a string except for the first and last 4
39
39
  # characters. Useful to hide sensitive data without removing it completely.
40
40
  #
41
- # Examples
42
- #
41
+ # @example Concealing a string over 8 characters.
43
42
  # conceal('secretstring')
44
43
  # # => 'secr****ring'
44
+ # @example Concealing a string under 8 characters.
45
+ # conceal('tester')
46
+ # # => '****'
45
47
  #
46
- # Returns a String.
48
+ # @param string [String] String you wish to conceal.
49
+ # @return [String] Concealed version of the string.
47
50
  def conceal(string)
48
51
  if string.length < 8
49
52
  '****'
@@ -56,10 +59,16 @@ module Envato
56
59
 
57
60
  private
58
61
 
62
+ # All 'known' marketplace names we wish to allow querying via.
63
+ #
64
+ # @return [Array] Marketplace names we wish to whitelist.
59
65
  def marketplace_names
60
66
  %w(graphicriver themeforest activeden codecanyon videohive audiojungle photodune 3docean)
61
67
  end
62
68
 
69
+ # Domain versions of the marketplace names.
70
+ #
71
+ # @return [Array] Marketplace domains including the TLD.
63
72
  def marketplace_domains
64
73
  marketplace_names.map { |domain| "#{domain}.net" }
65
74
  end
@@ -1,46 +1,115 @@
1
1
  module Envato
2
2
  class Client
3
3
  module Catalog
4
+ # Fetch a public collection based on a collection ID.
5
+ #
6
+ # @see https://build.envato.com/api/#market_0_Catalog_Collection
7
+ #
8
+ # @example Finding public collection 12345
9
+ # @client.get_public_collection(12345)
10
+ #
11
+ # @param collection_id [Integer] Collection ID.
12
+ # @return [Hash] Collection information.
4
13
  def get_public_collection(collection_id)
5
14
  response = get "v3/market/catalog/collection?id=#{collection_id}"
6
- response['collection']
15
+ response[:collection]
7
16
  end
8
17
 
18
+ # Find an item based on ID.
19
+ #
20
+ # @see https://build.envato.com/api/#market_0_Catalog_Item
21
+ #
22
+ # @example Getting item with ID 1234.
23
+ # @client.get_item(1234)
24
+ #
25
+ # @param item_id [Integer] Item ID.
26
+ # @return [Hash] Item details.
9
27
  def get_item(item_id)
10
28
  get "v3/market/catalog/item?id=#{item_id}"
11
29
  end
12
30
 
31
+ # Get all popular items based on a site.
32
+ #
33
+ # @see https://build.envato.com/api/#market_Popular
34
+ #
35
+ # @example Popular item from themeforest.net
36
+ # @client.popular_items_by_site('themeforest')
37
+ #
38
+ # @param sitename [String] Marketplace domain to look up.
39
+ # @raise [Envato::InvalidSiteName] If marketplace name is not valid.
40
+ # @return [Hash] All items which have been marked as popular for the
41
+ # requested marketplace.
13
42
  def popular_items_by_site(sitename)
14
43
  raise Envato::InvalidSiteName unless marketplace_names.include? sitename
15
44
 
16
45
  response = get "v1/market/popular:#{sitename}.json"
17
- response['popular']
46
+ response[:popular]
18
47
  end
19
48
 
49
+ # Returns all categories for a marketplace.
50
+ #
51
+ # @see https://build.envato.com/api/#market_Categories
52
+ #
53
+ # @example Find all categories for themeforest.net
54
+ # @client.categories_by_site('themeforest')
55
+ #
56
+ # @param sitename [String] Marketplace name.
57
+ # @raise [Envato::InvalidSiteName] If marketplace name is not valid.
58
+ # @return [Hash] All categories for the requested marketplace.
20
59
  def categories_by_site(sitename)
21
60
  raise Envato::InvalidSiteName unless marketplace_names.include? sitename
22
61
 
23
62
  response = get "v1/market/categories:#{sitename}.json"
24
- response['categories']
63
+ response[:categories]
25
64
  end
26
65
 
66
+ # Get all pricing types for a single item.
67
+ #
68
+ # @see https://build.envato.com/api/#market_ItemPrices
69
+ #
70
+ # @example Find all prices for item 1234.
71
+ # @client.prices_for_item(1234)
72
+ #
73
+ # @param item_id [Integer] Item ID.
74
+ # @return [Hash] Keyed by license type and price for that license.
27
75
  def prices_for_item(item_id)
28
76
  response = get "v1/market/item-prices:#{item_id}.json"
29
- response['item-prices']
77
+ response[:'item-prices']
30
78
  end
31
79
 
80
+ # Get featured item and author by site.
81
+ #
82
+ # @see https://build.envato.com/api/#market_Features
83
+ #
84
+ # @example See all featured items for themeforest.net
85
+ # @cilent.featured_by_site('themeforest')
86
+ #
87
+ # @param sitename [String] Name of marketplace.
88
+ # @raise [Envato::InvalidSiteName] If marketplace name is not valid.
89
+ # @return [Hash] Includes the 'featured_author' and 'featured_file' keys
90
+ # which have the associated inner details of the respective information.
32
91
  def featured_by_site(sitename)
33
92
  raise Envato::InvalidSiteName unless marketplace_names.include? sitename
34
93
 
35
94
  response = get "v1/market/features:#{sitename}.json"
36
- response['features']
95
+ response[:features]
37
96
  end
38
97
 
98
+ # Retrieve random new files based on marketplace.
99
+ #
100
+ # @see https://build.envato.com/api/#market_RandomNewFiles
101
+ #
102
+ # @example Random new files for themeforest.net
103
+ # @client.random_new_items_by_site('themeforest')
104
+ #
105
+ # @param sitename [String] Marketplace name.
106
+ # @raise [Envato::InvalidSiteName] If marketplace name is not valid.
107
+ # @return [Array] With inner hashes of the item information.
39
108
  def random_new_items_by_site(sitename)
40
109
  raise Envato::InvalidSiteName unless marketplace_names.include? sitename
41
110
 
42
111
  response = get "v1/market/random-new-files:#{sitename}.json"
43
- response['random-new-files']
112
+ response[:'random-new-files']
44
113
  end
45
114
  end
46
115
  end
@@ -1,21 +1,48 @@
1
1
  module Envato
2
2
  class Client
3
3
  module Stats
4
+ # Get a total user count across all the marketplaces.
5
+ #
6
+ # @see https://build.envato.com/api/#market_TotalUsers
7
+ #
8
+ # @example Finding all users.
9
+ # @client.total_users
10
+ #
11
+ # @return [Integer] Total count of all users.
4
12
  def total_users
5
13
  response = get 'v1/market/total-users.json'
6
- response['total-users']['total_users'].to_i
14
+ response[:'total-users'][:total_users].to_i
7
15
  end
8
16
 
17
+ # Get a total item count across all the marketplaces.
18
+ #
19
+ # @see https://build.envato.com/api/#market_TotalItems
20
+ #
21
+ # @example Finding all items.
22
+ # @client.total_items
23
+ #
24
+ # @return [Integer] Total count of all items.
9
25
  def total_items
10
26
  response = get 'v1/market/total-items.json'
11
- response['total-items']['total_items'].to_i
27
+ response[:'total-items'][:total_items].to_i
12
28
  end
13
29
 
30
+ # Retrieve category information for a marketplace.
31
+ #
32
+ # @see https://build.envato.com/api/#market_NumberOfFiles
33
+ #
34
+ # @example Getting all category information for themeforest.net
35
+ # @client.category_information_by_site('themeforest')
36
+ #
37
+ # @param sitename [String] Marketplace name.
38
+ # @raise [Envato::InvalidSiteName] If marketplace name is not valid.
39
+ # @return [Array] With inner hashes containing all the specific category
40
+ # information for the requested marketplace.
14
41
  def category_information_by_site(sitename)
15
42
  raise Envato::InvalidSiteName unless marketplace_names.include? sitename
16
43
 
17
44
  response = get "v1/market/number-of-files:#{sitename}.json"
18
- response['number-of-files']
45
+ response[:'number-of-files']
19
46
  end
20
47
  end
21
48
  end
@@ -1,58 +1,157 @@
1
1
  module Envato
2
2
  class Client
3
3
  module User
4
+ # Get current logged in user account information.
5
+ #
6
+ # @see https://build.envato.com/api/#market_Account
7
+ #
8
+ # @example Fetching account details.
9
+ # @client.account_details
10
+ #
11
+ # @return [Hash] User details.
4
12
  def account_details
5
13
  response = get 'v1/market/private/user/account.json'
6
- response['account']
14
+ response[:account]
7
15
  end
8
16
 
17
+ # Return the current logged in username.
18
+ #
19
+ # @see https://build.envato.com/api/#market_Username
20
+ #
21
+ # @example Get logged in user username.
22
+ # @client.username
23
+ #
24
+ # @return [String] Current logged in username.
9
25
  def username
10
26
  response = get 'v1/market/private/user/username.json'
11
- response['username']
27
+ response[:username]
12
28
  end
13
29
 
30
+ # Return the current logged in email address.
31
+ #
32
+ # @see https://build.envato.com/api/#market_Email
33
+ #
34
+ # @example Get logged in user email address.
35
+ # @client.email_address
36
+ #
37
+ # @return [String] Current logged in email address.
14
38
  def email_address
15
39
  response = get 'v1/market/private/user/email.json'
16
- response['email']
40
+ response[:email]
17
41
  end
18
42
 
43
+ # Retrieve information about a user.
44
+ #
45
+ # @see https://build.envato.com/api/#market_User
46
+ #
47
+ # @example Getting information about a username 'jacob'.
48
+ # @client.user_information('jacob')
49
+ # @param username [String] Username of the user.
50
+ # @return [Hash] Information about the requested username.
19
51
  def user_information(username)
20
52
  response = get "v1/market/user:#{username}.json"
21
- response['user']
53
+ response[:user]
22
54
  end
23
55
 
56
+ # Find badges for a user.
57
+ #
58
+ # @see https://build.envato.com/api/#market_UserBadges
59
+ #
60
+ # @example Retrieving badges for user 'jacob'.
61
+ # @client.badges_for_user('jacob')
62
+ #
63
+ # @param username [String] Username of the user.
64
+ # @return [Array] Hashes of badge data for the user.
24
65
  def badges_for_user(username)
25
66
  response = get "v1/market/user-badges:#{username}.json"
26
- response['user-badges']
67
+ response[:'user-badges']
27
68
  end
28
69
 
70
+ # Find items by a single user based on marketplace.
71
+ #
72
+ # @see https://build.envato.com/api/#market_UserItemsBySite
73
+ #
74
+ # @example Finding items by username 'jacob'.
75
+ # @client.user_items_by_site('jacob')
76
+ #
77
+ # @param username [String] Username of the user.
78
+ # @return [Array] Hashes of marketplace => item count for all
79
+ # marketplaces.
29
80
  def user_items_by_site(username)
30
81
  response = get "v1/market/user-items-by-site:#{username}.json"
31
- response['user-items-by-site']
82
+ response[:'user-items-by-site']
32
83
  end
33
84
 
85
+ # Find all new items for user based on a marketplace.
86
+ #
87
+ # @see https://build.envato.com/api/#market_NewFilesFromUser
88
+ #
89
+ # @example Finding new items for username 'jacob' on themeforest.net.
90
+ # @client.new_items_for_user('jacob', 'themeforest')
91
+ #
92
+ # @param username [String] Username of the user.
93
+ # @param sitename [String] Marketplace name.
94
+ # @raise [Envato::InvalidSiteName] If marketplace name is not valid.
95
+ # @return [Array] Inner hashes of the item information.
34
96
  def new_items_for_user(username, sitename)
35
97
  raise Envato::InvalidSiteName unless marketplace_names.include? sitename
36
98
 
37
99
  response = get "v1/market/new-files-from-user:#{username},#{sitename}.json"
38
- response['new-files-from-user']
100
+ response[:'new-files-from-user']
39
101
  end
40
102
 
103
+ # Breakdown a users sales based on month.
104
+ #
105
+ # @see https://build.envato.com/api/#market_EarningsAndSalesByMonth
106
+ #
107
+ # @example Getting sales per month.
108
+ # @client.sales_per_month
109
+ #
110
+ # @return [Hash] Month => value of sales.
41
111
  def sales_per_month
42
112
  response = get 'v1/market/private/user/earnings-and-sales-by-month.json'
43
- response['earnings-and-sales-by-month']
113
+ response[:'earnings-and-sales-by-month']
44
114
  end
45
115
 
116
+ # Get the current user statement.
117
+ #
118
+ # @see https://build.envato.com/api/#market_Statement
119
+ #
120
+ # @example Fetching user statement.
121
+ # @client.user_statement
122
+ #
123
+ # @return [Array] Individual hashes of line entries for each type of
124
+ # activity.
46
125
  def user_statement
47
126
  response = get 'v1/market/private/user/statement.json'
48
- response['statement']
127
+ response[:statement]
49
128
  end
50
129
 
130
+ # Retrieve logged in author sales.
131
+ #
132
+ # @see https://build.envato.com/api/#market_0_Author_Sales
133
+ #
134
+ # @example Finding sales data on page 2.
135
+ # @client.sales(2)
136
+ #
137
+ # @param page [Integer] Page number to view sales data for.
138
+ # @raise [TypeError] If the reqested page number is not an integer.
139
+ # @return [Array] With inner hashes of sales data based on months.
51
140
  def sales(page = 1)
52
141
  raise TypeError unless page.is_a? Integer
53
142
  get "v3/market/author/sales?page=#{page}"
54
143
  end
55
144
 
145
+ # Get sale based on purchase code.
146
+ #
147
+ # @see https://build.envato.com/api/#market_0_Author_Sale
148
+ #
149
+ # @example Retrieving sale by purchase code '1234-5678-90ab-cdef'
150
+ # @client.sale_by_purchase_code('1234-5678-90ab-cdef')
151
+ #
152
+ # @param purchase_code [String] Purchase code of the sale.
153
+ # @raise [ArgumentError] If the purchase code isn't provided.
154
+ # @return [Hash] Purchase information.
56
155
  def sale_by_purchase_code(purchase_code)
57
156
  raise ArgumentError if purchase_code.nil?
58
157
  get "v3/market/author/sale?code=#{purchase_code}"
@@ -3,14 +3,27 @@ require 'json'
3
3
 
4
4
  module Envato
5
5
  module Connection
6
+ # Make a raw HTTP GET request.
7
+ #
8
+ # @example Perform a request for logged in username.
9
+ # @client.get 'v1/market/private/user/username.json'
10
+ #
11
+ # @param url [String] The URL relative to the base domain.
12
+ # @return [Hash] Response from HTTP endpoint.
6
13
  def get(url)
7
- request :get, url
14
+ request(:get, url)
8
15
  end
9
16
 
17
+ # Definition of all SSL options.
18
+ #
19
+ # @return [Hash] SSL connection options to be used on all connections.
10
20
  def ssl_opts
11
21
  { verify: true }
12
22
  end
13
23
 
24
+ # The API host we are connecting to.
25
+ #
26
+ # @return [String] Full hostnme to perform connections to.
14
27
  def api_host
15
28
  'https://api.envato.com'
16
29
  end
@@ -38,25 +51,72 @@ module Envato
38
51
  end
39
52
 
40
53
  begin
41
- JSON.parse(response.body)
54
+ symbolize(JSON.parse(response.body))
42
55
  rescue JSON::ParserError
43
56
  response.body
44
57
  end
45
58
  end
46
59
 
60
+ # Extract correct message for 'forbidden' requests.
61
+ #
62
+ # @param response [Faraday::Response] Endpoint response.
63
+ # @return [String] Error message returned from the request payload.
47
64
  def extract_forbidden_message(response)
48
- body = JSON.parse(response.body)
49
- body['error_description'] if body['error_description']
65
+ begin
66
+ body = JSON.parse(response.body)
67
+ body['error_description'] if body['error_description']
68
+ rescue JSON::ParserError
69
+ response.body
70
+ end
50
71
  end
51
72
 
73
+ # Extract correct message for 'not found' requests.
74
+ #
75
+ # @param response [Faraday::Response] Endpoint response.
76
+ # @return [String] Error message returned from the request payload.
52
77
  def extract_not_found_message(response)
53
- body = JSON.parse(response.body)
54
- body['description'] if body['description']
78
+ begin
79
+ body = JSON.parse(response.body)
80
+ body['description'] if body['description']
81
+ rescue JSON::ParserError
82
+ response.body
83
+ end
55
84
  end
56
85
 
86
+ # Extract correct message for 'server error' requests.
87
+ #
88
+ # @param response [Faraday::Response] Endpoint response.
89
+ # @return [String] Error message returned from the request payload.
57
90
  def extract_server_error_message(response)
58
- body = JSON.parse(response.body)
59
- body['message'] if body['message']
91
+ begin
92
+ body = JSON.parse(response.body)
93
+ body['message'] if body['message']
94
+ rescue JSON::ParserError
95
+ response.body
96
+ end
97
+ end
98
+
99
+ # Recursively convert strings to symbols.
100
+ #
101
+ # @example Symbolizing hash.
102
+ # symbolize({'test' => 'value'})
103
+ # # => { :test => 'value' }
104
+ # @example Symbolizing nested hash.
105
+ # symbolize({'test' => 'value', 'another' => {'value' => 'example'}})
106
+ # # => { :test => 'value', :another => { :value => 'example' } }
107
+ #
108
+ # @return [Hash] Converted hash using symbols instead of strings for the
109
+ # keys.
110
+ def symbolize(obj)
111
+ return obj.reduce({}) do |memo, (k, v)|
112
+ memo.tap { |m| m[k.to_sym] = symbolize(v) }
113
+ end if obj.is_a? Hash
114
+
115
+ return obj.reduce([]) do |memo, v|
116
+ memo << symbolize(v); memo
117
+ end if obj.is_a? Array
118
+
119
+ obj
60
120
  end
61
121
  end
62
122
  end
@@ -4,13 +4,21 @@ module Envato
4
4
  # User is missing the required API token.
5
5
  class MissingAPITokenError < ArgumentError; end
6
6
 
7
- # Handle the HTTP statuses correctly.
7
+ # Request received a HTTP 403 response.
8
8
  class ForbiddenError < Error; end
9
+
10
+ # Request received a HTTP 404 response.
9
11
  class NotFoundError < Error; end
12
+
13
+ # Request received a HTTP 4xx response.
10
14
  class ClientError < Error; end
15
+
16
+ # Request received a HTTP 5xx response.
11
17
  class ServerError < Error; end
12
18
 
13
- # Validation of Envato marketplaces.
19
+ # Validation against whitelisted marketplace names.
14
20
  class InvalidSiteName < Error; end
21
+
22
+ # Validation against whitelisted marketplace domains.
15
23
  class InvalidSiteDomain < Error; end
16
24
  end
@@ -1,6 +1,6 @@
1
1
  module Envato
2
2
  MAJOR = 0
3
- MINOR = 3
3
+ MINOR = 4
4
4
  PATCH = 0
5
5
  VERSION = [MAJOR, MINOR, PATCH].join '.'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: envato-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacob Bednarz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-22 00:00:00.000000000 Z
11
+ date: 2016-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler