envato-sdk 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -162
- data/lib/envato/client.rb +13 -4
- data/lib/envato/client/catalog.rb +75 -6
- data/lib/envato/client/stats.rb +30 -3
- data/lib/envato/client/user.rb +108 -9
- data/lib/envato/connection.rb +68 -8
- data/lib/envato/errors.rb +10 -2
- data/lib/envato/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76873a2b09a7a9b82211f2abe8ecc4cfd84df4f7
|
4
|
+
data.tar.gz: bb2df3c454b56c01de0a664a6b2dec21f13dbcd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
# => {
|
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
|
data/lib/envato/client.rb
CHANGED
@@ -33,17 +33,20 @@ module Envato
|
|
33
33
|
inspected
|
34
34
|
end
|
35
35
|
|
36
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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[
|
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[
|
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[
|
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[
|
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
|
data/lib/envato/client/stats.rb
CHANGED
@@ -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'][
|
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'][
|
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
|
data/lib/envato/client/user.rb
CHANGED
@@ -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[
|
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[
|
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[
|
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[
|
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[
|
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}"
|
data/lib/envato/connection.rb
CHANGED
@@ -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
|
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
|
-
|
49
|
-
|
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
|
-
|
54
|
-
|
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
|
-
|
59
|
-
|
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
|
data/lib/envato/errors.rb
CHANGED
@@ -4,13 +4,21 @@ module Envato
|
|
4
4
|
# User is missing the required API token.
|
5
5
|
class MissingAPITokenError < ArgumentError; end
|
6
6
|
|
7
|
-
#
|
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
|
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
|
data/lib/envato/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2016-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|