envato 0.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0803d16509a393c20d289dad31220711faccadd9cc5b03821d0c6a24f297fa33'
4
- data.tar.gz: 7439e670daa5fb74d6c96809ea72772c0acec9acb90d5dff797f6d360e2e1374
3
+ metadata.gz: ca318d16d398b0a77237e559d9f021fb3b16ca50bc323c280440ad6b467a968a
4
+ data.tar.gz: 8fb7c7d0744fae188d2c3e29187c0373de1991adc29d33d04d105ed707b93bcd
5
5
  SHA512:
6
- metadata.gz: 5f4b0c6b832f601d7e4bc5be400b3382a31e1be402119f12794ec8de37f57fd173edc8566175a3a6e25886d039b3481c64dd51f2efc30c063afa7c033f866660
7
- data.tar.gz: 436335c438e3842e1c5b3930de468669496a4a28a5a7d17444d5f5fd8ad161c6f9b2ffabab1617fbce790de2c2ef7b4064e1deb8e4b881f90f3b395640498b58
6
+ metadata.gz: b0fe756e6317f1edd3eb27153b0b3e886b0f98cb45bf9f4613d61386f7d7f9aa9a118f9f207fb9c401182f914a20bae04fa53d4c1e9c34feeecf095b00d1e321
7
+ data.tar.gz: a7051264e17963184e5f14a6810989261251ab89c96dee004b4597c006af17fb8669b746a4b152996fabf192b30b6e638967b579167b43ac48394b83f7d8f952
@@ -0,0 +1,12 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: /
5
+ schedule:
6
+ interval: daily
7
+ open-pull-requests-limit: 20
8
+ - package-ecosystem: "github-actions"
9
+ directory: "/"
10
+ schedule:
11
+ interval: "weekly"
12
+ open-pull-requests-limit: 20
@@ -0,0 +1,51 @@
1
+ name: Ruby specs
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ name: tests
6
+ strategy:
7
+ fail-fast: false
8
+ matrix:
9
+ os: [ubuntu-latest, macos-latest]
10
+ ruby: ['2.6', '2.7', '3.0', '3.1', head, truffleruby, truffleruby-head]
11
+ runs-on: ${{ matrix.os }}
12
+ continue-on-error: true
13
+ steps:
14
+ - uses: actions/checkout@v3
15
+ - uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: ${{ matrix.ruby }}
18
+ bundler-cache: true
19
+
20
+ - name: Get the newest rubygems version to rid ourselves of warnings
21
+ run: gem update --system --no-document
22
+
23
+ - name: Install bundler
24
+ run: gem i bundler --no-document
25
+
26
+ - name: Install dependencies
27
+ run: |
28
+ bundle config set --local without benchmark
29
+ bundle install --jobs=3
30
+ - name: RSpec testing
31
+ run: |
32
+ JRUBY_OPTS="--dev --debug" bundle exec rspec --color --format documentation
33
+ - name: Coveralls Parallel
34
+ uses: coverallsapp/github-action@1.1.3
35
+ with:
36
+ github-token: ${{ secrets.github_token }}
37
+ flag-name: run-${{ matrix.ruby-version }}
38
+ path-to-lcov: ./coverage/lcov/envato.lcov
39
+ parallel: true
40
+
41
+ coverage:
42
+ name: Coverage
43
+ needs: test
44
+ runs-on: ubuntu-latest
45
+ steps:
46
+ - name: Coveralls Finished
47
+ uses: coverallsapp/github-action@1.1.3
48
+ with:
49
+ github-token: ${{ secrets.github_token }}
50
+ path-to-lcov: ${{ github.workspace }}/coverage/lcov.info
51
+ parallel-finished: true
data/.gitignore ADDED
@@ -0,0 +1,47 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ # Gemfile.lock
30
+ # .ruby-version
31
+ # .ruby-gemset
32
+
33
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
+ .rvmrc
35
+
36
+ ## macos
37
+ .DS_Store
38
+ dev
39
+
40
+ # TODO: remove from ignore list
41
+ api_endpoints.json
42
+ api.sh
43
+
44
+ fixtures
45
+ .rspec_status
46
+ Gemfile.lock
47
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ --tty
2
+ --color
3
+ --format documentation # progress
4
+ --backtrace
5
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,142 @@
1
+ ---
2
+ AllCops:
3
+ NewCops: disable # TODO: change to enable after refactoring
4
+
5
+ # Commonly used screens these days easily fit more than 80 characters.
6
+ Layout/LineLength:
7
+ Max: 120
8
+
9
+ # Too short methods lead to extraction of single-use methods, which can make
10
+ # the code easier to read (by naming things), but can also clutter the class
11
+ Metrics/MethodLength:
12
+ Max: 20
13
+
14
+ # The guiding principle of classes is SRP, SRP can't be accurately measured by LoC
15
+ Metrics/ClassLength:
16
+ Max: 1500
17
+
18
+ # No space makes the method definition shorter and differentiates
19
+ # from a regular assignment.
20
+ Layout/SpaceAroundEqualsInParameterDefault:
21
+ EnforcedStyle: no_space
22
+
23
+ # Single quotes being faster is hardly measurable and only affects parse time.
24
+ # Enforcing double quotes reduces the times where you need to change them
25
+ # when introducing an interpolation. Use single quotes only if their semantics
26
+ # are needed.
27
+ Style/StringLiterals:
28
+ EnforcedStyle: double_quotes
29
+
30
+ # We do not need to support Ruby 1.9, so this is good to use.
31
+ Style/SymbolArray:
32
+ Enabled: true
33
+
34
+ # Most readable form.
35
+ Style/OptionHash:
36
+ # A list of parameter names that will be flagged by this cop.
37
+ SuspiciousParamNames:
38
+ - options
39
+ - opts
40
+ - args
41
+ - paramsgit sttus
42
+ - parameters
43
+
44
+ # Mixing the styles looks just silly.
45
+ Style/HashSyntax:
46
+ EnforcedStyle: ruby19_no_mixed_keys
47
+
48
+ # has_key? and has_value? are far more readable than key? and value?
49
+ Style/PreferredHashMethods:
50
+ Enabled: false
51
+
52
+ # String#% is by far the least verbose and only object oriented variant.
53
+ Style/FormatString:
54
+ EnforcedStyle: percent
55
+
56
+ Style/CollectionMethods:
57
+ Enabled: true
58
+ PreferredMethods:
59
+ # inject seems more common in the community.
60
+ reduce: "inject"
61
+
62
+
63
+ # Either allow this style or don't. Marking it as safe with parenthesis
64
+ # is silly. Let's try to live without them for now.
65
+ Style/ParenthesesAroundCondition:
66
+ AllowSafeAssignment: false
67
+ Lint/AssignmentInCondition:
68
+ AllowSafeAssignment: false
69
+
70
+ # A specialized exception class will take one or more arguments and construct the message from it.
71
+ # So both variants make sense.
72
+ Style/RaiseArgs:
73
+ Enabled: false
74
+
75
+ # Indenting the chained dots beneath each other is not supported by this cop,
76
+ # see https://github.com/bbatsov/rubocop/issues/1633
77
+ Layout/MultilineOperationIndentation:
78
+ Enabled: false
79
+
80
+ # Fail is an alias of raise. Avoid aliases, it's more cognitive load for no gain.
81
+ # The argument that fail should be used to abort the program is wrong too,
82
+ # there's Kernel#abort for that.
83
+ Style/SignalException:
84
+ EnforcedStyle: only_raise
85
+
86
+ # Suppressing exceptions can be perfectly fine, and be it to avoid to
87
+ # explicitly type nil into the rescue since that's what you want to return,
88
+ # or suppressing LoadError for optional dependencies
89
+ Lint/SuppressedException:
90
+ Enabled: false
91
+
92
+ Layout/SpaceInsideBlockBraces:
93
+ # The space here provides no real gain in readability while consuming
94
+ # horizontal space that could be used for a better parameter name.
95
+ # Also {| differentiates better from a hash than { | does.
96
+ SpaceBeforeBlockParameters: false
97
+
98
+ # No trailing space differentiates better from the block:
99
+ # foo} means hash, foo } means block.
100
+ Layout/SpaceInsideHashLiteralBraces:
101
+ EnforcedStyle: no_space
102
+
103
+ # { ... } for multi-line blocks is okay, follow Weirichs rule instead:
104
+ # https://web.archive.org/web/20140221124509/http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc
105
+ Style/BlockDelimiters:
106
+ Enabled: false
107
+
108
+ # do / end blocks should be used for side effects,
109
+ # methods that run a block for side effects and have
110
+ # a useful return value are rare, assign the return
111
+ # value to a local variable for those cases.
112
+ Style/MethodCalledOnDoEndBlock:
113
+ Enabled: true
114
+
115
+ # Enforcing the names of variables? To single letter ones? Just no.
116
+ Style/SingleLineBlockParams:
117
+ Enabled: false
118
+
119
+ # Shadowing outer local variables with block parameters is often useful
120
+ # to not reinvent a new name for the same thing, it highlights the relation
121
+ # between the outer variable and the parameter. The cases where it's actually
122
+ # confusing are rare, and usually bad for other reasons already, for example
123
+ # because the method is too long.
124
+ Lint/ShadowingOuterLocalVariable:
125
+ Enabled: false
126
+
127
+ # Check with yard instead.
128
+ Style/Documentation:
129
+ Enabled: false
130
+
131
+ # This is just silly. Calling the argument `other` in all cases makes no sense.
132
+ Naming/BinaryOperatorParameterName:
133
+ Enabled: false
134
+
135
+ # There are valid cases, for example debugging Cucumber steps,
136
+ # also they'll fail CI anyway
137
+ Lint/Debugger:
138
+ Enabled: false
139
+
140
+ # Style preference
141
+ Style/MethodDefParentheses:
142
+ Enabled: false
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2022 Ilya Brin
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # Envato API - Ruby client ([gem](https://rubygems.org/gems/envato))
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/envato.svg)](https://badge.fury.io/rb/envato)
4
+ ![Gem](https://shields.api-test.nl/gem/dt/envato)
5
+ [![Ruby specs](https://github.com/ruby-api-client/envato/actions/workflows/ci.yml/badge.svg)](https://github.com/ruby-api-client/envato/actions/workflows/ci.yml)
6
+ [![Coverage Status](https://coveralls.io/repos/github/ruby-api-client/envato/badge.svg?branch=master)](https://coveralls.io/github/ruby-api-client/envato?branch=master)
7
+
8
+ ## TODO
9
+
10
+ - examples
11
+ - document methods
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << "test"
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
+ end
11
+
12
+ task default: :test
13
+
14
+ task :console do
15
+ exec "irb -I lib -r envato.rb"
16
+ end
data/envato.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require "envato/version"
7
+
8
+ Gem::Specification.new do |s|
9
+ s.name = "envato"
10
+ s.version = Envato::VERSION
11
+ s.summary = "WIP - Envato API client"
12
+ s.description = "WIP - Envato API wrapper written in Ruby"
13
+ s.authors = ["Ilya Brin"]
14
+ s.email = "ilya@codeplay.ru"
15
+ s.files = `git ls-files`.split($RS).reject {|fn| fn.start_with? "spec" }
16
+ s.executables = s.files.grep(%r{^bin/}) {|f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+ s.homepage = "https://github.com/ruby-api-client/envato"
19
+ s.license = "MIT"
20
+
21
+ s.required_ruby_version = ">= 2.6"
22
+
23
+ s.metadata["rubygems_mfa_required"] = "true"
24
+
25
+ s.add_dependency "faraday", "~> 1.7"
26
+
27
+ s.add_development_dependency "bundler"
28
+ s.add_development_dependency "rake", "~> 12.3"
29
+ s.add_development_dependency "rspec", "~> 3.0"
30
+ s.add_development_dependency "simplecov", "~> 0.9"
31
+ s.add_development_dependency "simplecov-lcov", "~> 0.7.0"
32
+ s.add_development_dependency "vcr", "~> 6.1"
33
+ s.add_development_dependency "webmock", "~> 3.18"
34
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Envato
4
+ class Client
5
+ BASE_URL = "https://api.envato.com"
6
+
7
+ attr_reader :token, :adapter
8
+
9
+ def initialize(token:, adapter: Faraday.default_adapter, stubs: nil)
10
+ @token = token
11
+ @adapter = adapter
12
+ @stubs = stubs # Test stubs for requests
13
+ end
14
+
15
+ def user
16
+ UserResource.new(self)
17
+ end
18
+
19
+ def users
20
+ UsersResource.new(self)
21
+ end
22
+
23
+ def search
24
+ SearchResource.new(self)
25
+ end
26
+
27
+ def market
28
+ MarketResource.new(self)
29
+ end
30
+
31
+ def markets
32
+ MarketsResource.new(self)
33
+ end
34
+
35
+ def bookmarks
36
+ BookmarksResource.new(self)
37
+ end
38
+
39
+ def item
40
+ ItemResource.new(self)
41
+ end
42
+
43
+ def connection
44
+ @connection ||= Faraday.new(BASE_URL) do |conn|
45
+ conn.request :authorization, :Bearer, token
46
+ conn.request :json
47
+ conn.request :url_encoded
48
+
49
+ conn.response :json, content_type: "application/json"
50
+
51
+ conn.adapter adapter, @stubs
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Envato
4
+ class Collection
5
+ # TODO: links: { next_page_url, prev_page_url, first_page_url, last_page_url }
6
+ # TODO: total_hits:
7
+ # TODO: took:
8
+ attr_reader :data, :items, :total
9
+
10
+ def self.from_response(response, key:, type:)
11
+ body = response.body
12
+ new(
13
+ data: body[key].map {|attrs| type.new(attrs) },
14
+ items: body["items"],
15
+ total: body["total"]
16
+ )
17
+ end
18
+
19
+ def initialize(data:, items:, total:)
20
+ @data = data
21
+ @items = items
22
+ @total = total
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Envato
4
+ class Error < StandardError
5
+ end
6
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ostruct"
4
+
5
+ module Envato
6
+ class Object < OpenStruct
7
+ def initialize(attributes)
8
+ super to_ostruct(attributes)
9
+ end
10
+
11
+ # Convert Array or Hash to OpenStruct
12
+ def to_ostruct(obj)
13
+ case obj
14
+ when Hash
15
+ # rubocop:disable Style/HashTransformValues
16
+ OpenStruct.new(obj.map {|key, val| [key, to_ostruct(val)] }.to_h)
17
+ # rubocop:enable Style/HashTransformValues
18
+ when Array
19
+ obj.map {|o| to_ostruct(o) }
20
+ else
21
+ obj
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Envato
4
+ class User < Object; end
5
+ class Users < Object; end
6
+ class UsersTotal < Object; end
7
+ class UserSale < Object; end
8
+ class UserAccount < Object; end
9
+ class UserStatement < Object; end
10
+ class UserCollection < Object; end
11
+ class UserBookmark < Object; end
12
+ class UserBadge < Object; end
13
+ class Item < Object; end
14
+ class ItemPrice < Object; end
15
+ class ItemVersion < Object; end
16
+ class CollectionItem < Object; end
17
+ class Comment < Object; end
18
+ class Category < Object; end
19
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Envato
4
+ class Resource
5
+ attr_reader :client
6
+
7
+ def initialize(client)
8
+ @client = client
9
+ end
10
+
11
+ private
12
+
13
+ def get(url, params: {}, headers: {})
14
+ handle_response client.connection.get(url, params, headers)
15
+ end
16
+
17
+ def post(url, body:, headers: {})
18
+ handle_response client.connection.post(url, body, headers)
19
+ end
20
+
21
+ def patch(url, body:, headers: {})
22
+ handle_response client.connection.patch(url, body, headers)
23
+ end
24
+
25
+ def put(url, body:, headers: {})
26
+ handle_response client.connection.put(url, body, headers)
27
+ end
28
+
29
+ def delete(url, params: {}, headers: {})
30
+ handle_response client.connection.delete(url, params, headers)
31
+ end
32
+ alias delete_request delete
33
+
34
+ # rubocop:disable Metrics/CyclomaticComplexity
35
+ # rubocop:disable Metrics/AbcSize
36
+ def handle_response(response)
37
+ case response.status
38
+ when 400
39
+ raise Error, "Your request was malformed. #{response.body['error']}"
40
+ when 401
41
+ raise Error, "You did not supply valid authentication credentials. #{response.body['error']}"
42
+ when 403
43
+ raise Error, "You are not allowed to perform that action. #{response.body['error']}"
44
+ when 404
45
+ raise Error, "No results were found for your request. #{response.body['error']}"
46
+ when 429
47
+ raise Error, "Your request exceeded the API rate limit. #{response.body['error']}"
48
+ when 500
49
+ raise Error, "We were unable to perform the request due to server-side problems. #{response.body['error']}"
50
+ when 503
51
+ raise Error, "You have been rate limited for sending more requests per second. #{response.body['error']}"
52
+ end
53
+
54
+ response
55
+ end
56
+ # rubocop:enable Metrics/AbcSize
57
+ # rubocop:enable Metrics/CyclomaticComplexity
58
+ end
59
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Envato
4
+ class BookmarksResource < Resource
5
+ def list
6
+ resp = get("v3/market/user/bookmarks")
7
+ Collection.from_response(resp, key: "bookmarks", type: UserBookmark)
8
+ end
9
+
10
+ # TODO: API error: "reason": "not-found"
11
+ def add(collection_id:, item_id:)
12
+ put("v3/market/user/bookmark_add?collection_id=#{collection_id}&item_id=#{item_id}")
13
+ end
14
+
15
+ def remove(id:)
16
+ delete("v3/market/user/bookmark_remove?id=#{id}")
17
+ end
18
+
19
+ # TODO: bookmarks_for_items
20
+ # TODO: item_ids: comma separated "12312312,123123123,12312312"
21
+ def for_items(item_ids:)
22
+ Object.new get("v3/market/user/bookmarks_for_items?item_ids=#{item_ids}").body
23
+ end
24
+
25
+ # TODO: add to CollectionResource
26
+ # TODO: API error: "reason": "not-found"
27
+ def collection_create(name:, site:, description:, is_public: false)
28
+ Object.new post("v3/market/user/collection_create \
29
+ ?name=#{name}&site=#{site} \
30
+ &public=#{is_public} \
31
+ &description=#{description}".gsub(/\s+/, "")).body
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Envato
4
+ class ItemResource < Resource
5
+ def prices(item_id:)
6
+ resp = get("v1/market/item-prices:#{item_id}.json")
7
+ Collection.from_response(resp, key: "item-prices", type: ItemPrice)
8
+ end
9
+
10
+ def download(item_id:, purchase_code:, shorten_url: true)
11
+ Object.new get("v3/market/buyer/download \
12
+ ?item_id=#{item_id} \
13
+ &purchase_code=#{purchase_code} \
14
+ &shorten_url=#{shorten_url}".gsub(/\s+/, "")).body
15
+ end
16
+
17
+ # TODO: filter_by: wordpress-plugins | wordpress-themes
18
+ def list_purchases(filter_by: "wordpress-themes", page: 1, details: false)
19
+ resp = get("v3/market/buyer/list-purchases \
20
+ ?filter_by=#{filter_by} \
21
+ &page=#{page} \
22
+ &details=#{details}".gsub(/\s+/, ""))
23
+ Collection.from_response(resp, key: "results", type: Item)
24
+ end
25
+
26
+ def purchase(code:)
27
+ Object.new get("v3/market/buyer/purchase?code=#{code}").body
28
+ end
29
+
30
+ def purchases
31
+ resp = get("v3/market/buyer/purchases")
32
+ Collection.from_response(resp, key: "purchases", type: Item)
33
+ end
34
+
35
+ def version(id:)
36
+ ItemVersion.new get("v3/market/catalog/item-version?id=#{id}").body
37
+ end
38
+
39
+ def info(id:)
40
+ Item.new get("v3/market/catalog/item?id=#{id}").body
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Envato
4
+ class MarketResource < Resource
5
+ def user(username:)
6
+ Object.new get("v1/market/user:#{username}").body
7
+ end
8
+
9
+ # TODO: move methods to CategoriesResource
10
+ def categories(site:)
11
+ resp = get("v1/market/categories:#{site}.json")
12
+ Collection.from_response(resp, key: "categories", type: Category)
13
+ end
14
+
15
+ def categories_themeforest
16
+ categories(site: "themeforest")
17
+ end
18
+
19
+ def categories_photodune
20
+ categories(site: "photodune")
21
+ end
22
+
23
+ def categories_codecanyon
24
+ categories(site: "codecanyon")
25
+ end
26
+
27
+ def categories_videohive
28
+ categories(site: "videohive")
29
+ end
30
+
31
+ def categories_audiojungle
32
+ categories(site: "audiojungle")
33
+ end
34
+
35
+ def categories_graphicriver
36
+ categories(site: "graphicriver")
37
+ end
38
+
39
+ def categories_3docean
40
+ categories(site: "3docean")
41
+ end
42
+
43
+ # TODO: Features.new
44
+ def features(site:)
45
+ Object.new get("v1/market/features:#{site}.json").body
46
+ end
47
+
48
+ def features_themeforest
49
+ features(site: "themeforest")
50
+ end
51
+
52
+ def features_photodune
53
+ features(site: "photodune")
54
+ end
55
+
56
+ def features_codecanyon
57
+ features(site: "codecanyon")
58
+ end
59
+
60
+ def features_videohive
61
+ features(site: "videohive")
62
+ end
63
+
64
+ def features_audiojungle
65
+ features(site: "audiojungle")
66
+ end
67
+
68
+ def features_graphicriver
69
+ features(site: "graphicriver")
70
+ end
71
+
72
+ def features_3docean
73
+ features(site: "3docean")
74
+ end
75
+
76
+ def popular_items(site:)
77
+ Object.new get("v1/market/popular:#{site}.json").body
78
+ end
79
+
80
+ def popular_items_themeforest
81
+ popular_items(site: "themeforest")
82
+ end
83
+
84
+ def popular_items_photodune
85
+ popular_items(site: "photodune")
86
+ end
87
+
88
+ def popular_items_codecanyon
89
+ popular_items(site: "codecanyon")
90
+ end
91
+
92
+ def popular_items_videohive
93
+ popular_items(site: "videohive")
94
+ end
95
+
96
+ def popular_items_audiojungle
97
+ popular_items(site: "audiojungle")
98
+ end
99
+
100
+ def popular_items_graphicriver
101
+ popular_items(site: "graphicriver")
102
+ end
103
+
104
+ def popular_items_3docean
105
+ popular_items(site: "3docean")
106
+ end
107
+
108
+ # TODO: add themeforest, graphicriver, etc.
109
+ def new_files(site:, category:)
110
+ resp = get("v1/market/new-files:#{site},#{category}.json")
111
+ Collection.from_response(resp, key: "new-files", type: Item)
112
+ end
113
+
114
+ # TODO: add themeforest, etc.
115
+ def new_files_graphicriver(category:)
116
+ new_files(site: "graphicriver", category: category)
117
+ end
118
+
119
+ def new_files_from_user(username:, site:)
120
+ Object.new get("v1/market/new-files-from-user:#{username},#{site}.json")
121
+ end
122
+
123
+ def random_new_files(site:)
124
+ Object.new get("v1/market/random-new-files:#{site}.json")
125
+ end
126
+
127
+ def collection(id:, page: 1)
128
+ Object.new get("v3/market/catalog/collection?id=#{id}&page=#{page}").body
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Envato
4
+ class MarketsResource < Resource
5
+ def number_of_files(site:)
6
+ Object.new get("v1/market/number-of-files:#{site}.json").body
7
+ end
8
+
9
+ def total_themeforest
10
+ number_of_files(site: "themeforest")
11
+ end
12
+
13
+ def total_photodune
14
+ number_of_files(site: "photodune")
15
+ end
16
+
17
+ def total_codecanyon
18
+ number_of_files(site: "codecanyon")
19
+ end
20
+
21
+ def total_videohive
22
+ number_of_files(site: "videohive")
23
+ end
24
+
25
+ def total_audiojungle
26
+ number_of_files(site: "audiojungle")
27
+ end
28
+
29
+ def total_graphicriver
30
+ number_of_files(site: "graphicriver")
31
+ end
32
+
33
+ def total_3docean
34
+ number_of_files(site: "3docean")
35
+ end
36
+
37
+ def total_items
38
+ Object.new get("v1/market/total-items.json").body
39
+ end
40
+ alias total total_items
41
+ end
42
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Envato
4
+ class SearchResource < Resource
5
+ def more_like_this(item_id:, page: 1, page_size: 10)
6
+ resp = get("v1/discovery/search/search/more_like_this?item_id=#{item_id}&page=#{page}&page_size=#{page_size}")
7
+ Collection.from_response(resp, key: "matches", type: Item)
8
+ end
9
+ alias like more_like_this
10
+
11
+ def comments(item_id:, page: 1, page_size: 10)
12
+ resp = get("v1/discovery/search/search/comment?item_id=#{item_id}&page=#{page}&page_size=#{page_size}")
13
+ Collection.from_response(resp, key: "matches", type: Comment)
14
+ end
15
+
16
+ def item
17
+ resp = get("v1/discovery/search/search/item")
18
+ Collection.from_response(resp, key: "matches", type: Item)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Envato
4
+ class UserResource < Resource
5
+ def statement
6
+ UserStatement.new get("v3/market/user/statement").body
7
+ end
8
+
9
+ def collections
10
+ resp = get("v3/market/user/collections")
11
+ Collection.from_response(resp, key: "collections", type: UserCollection)
12
+ end
13
+
14
+ def collection(id:)
15
+ resp = get("v3/market/user/collection?id=#{id}")
16
+ Collection.from_response(resp, key: "items", type: CollectionItem)
17
+ end
18
+
19
+ def items(username:)
20
+ resp = get("v1/market/user-items-by-site:#{username}.json")
21
+ Collection.from_response(resp, key: "user-items-by-site", type: Item)
22
+ end
23
+
24
+ def badges(username:)
25
+ resp = get("v1/market/user-badges:#{username}.json")
26
+ Collection.from_response(resp, key: "user-badges", type: UserBadge)
27
+ end
28
+
29
+ def earnings_and_sales
30
+ Object.new get("v1/market/private/user/earnings-and-sales-by-month.json").body
31
+ end
32
+ alias sales_and_earnings earnings_and_sales
33
+
34
+ def account
35
+ UserAccount.new get("/v1/market/private/user/account.json").body
36
+ end
37
+
38
+ def name
39
+ Object.new get("v1/market/private/user/username.json").body
40
+ end
41
+ alias username name
42
+
43
+ def email
44
+ Object.new get("v1/market/private/user/email.json").body
45
+ end
46
+
47
+ def sales
48
+ Object.new get("v1/market/private/author/sales").body
49
+ end
50
+
51
+ def sale(code:)
52
+ UserSale.new get("v3/market/author/sale?code=#{code}").body
53
+ end
54
+
55
+ # TODO: rename and move to CollectionResource
56
+ def add_to_favorite(item_id:)
57
+ put("v3/market/user/favourite_collection_add?item_id=#{item_id}")
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Envato
4
+ class UsersResource < Resource
5
+ def total
6
+ UsersTotal.new get("v1/market/total-users.json").body
7
+ end
8
+ alias totat_users total
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Envato
4
+ major = 1
5
+ minor = 0
6
+ patch = 1
7
+ VERSION = "#{major}.#{minor}.#{patch}"
8
+ end
data/lib/envato.rb ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday"
4
+ require "envato/version"
5
+
6
+ module Envato
7
+ autoload :Client, "envato/client"
8
+ autoload :Object, "envato/object"
9
+ autoload :Resource, "envato/resource"
10
+ autoload :Collection, "envato/collection"
11
+ autoload :Error, "envato/error"
12
+
13
+ # resources
14
+ autoload :UserResource, "envato/resources/user"
15
+ autoload :UsersResource, "envato/resources/users"
16
+ autoload :MarketResource, "envato/resources/market"
17
+ autoload :MarketsResource, "envato/resources/markets"
18
+ autoload :SearchResource, "envato/resources/search"
19
+ autoload :BookmarksResource, "envato/resources/bookmarks"
20
+ autoload :ItemResource, "envato/resources/item"
21
+
22
+ # objects
23
+ autoload :User, "envato/objects/types"
24
+ autoload :UserAccount, "envato/objects/types"
25
+ autoload :UserStatement, "envato/objects/types"
26
+ autoload :UserList, "envato/objects/types"
27
+ autoload :UserStatement, "envato/objects/types"
28
+ autoload :UserCollection, "envato/objects/types"
29
+ autoload :UserBookmark, "envato/objects/types"
30
+ autoload :UsersTotal, "envato/objects/types"
31
+ autoload :SearchMatch, "envato/objects/types"
32
+ autoload :CollectionItem, "envato/objects/types"
33
+ autoload :Item, "envato/objects/types"
34
+ autoload :ItemPrice, "envato/objects/types"
35
+ autoload :ItemVersion, "envato/objects/types"
36
+ end
metadata CHANGED
@@ -1,61 +1,164 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: envato
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilya Brin
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-08 00:00:00.000000000 Z
11
+ date: 2022-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: addressable
14
+ name: faraday
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.3'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 2.3.7
19
+ version: '1.7'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '2.3'
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
30
31
  - - ">="
31
32
  - !ruby/object:Gem::Version
32
- version: 2.3.7
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
33
41
  - !ruby/object:Gem::Dependency
34
- name: faraday
42
+ name: rake
35
43
  requirement: !ruby/object:Gem::Requirement
36
44
  requirements:
37
45
  - - "~>"
38
46
  - !ruby/object:Gem::Version
39
- version: '1.7'
40
- type: :runtime
47
+ version: '12.3'
48
+ type: :development
41
49
  prerelease: false
42
50
  version_requirements: !ruby/object:Gem::Requirement
43
51
  requirements:
44
52
  - - "~>"
45
53
  - !ruby/object:Gem::Version
46
- version: '1.7'
54
+ version: '12.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.9'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov-lcov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.7.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.7.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: vcr
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '6.1'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '6.1'
111
+ - !ruby/object:Gem::Dependency
112
+ name: webmock
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.18'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.18'
47
125
  description: WIP - Envato API wrapper written in Ruby
48
126
  email: ilya@codeplay.ru
49
127
  executables: []
50
128
  extensions: []
51
129
  extra_rdoc_files: []
52
- files: []
130
+ files:
131
+ - ".github/dependabot.yml"
132
+ - ".github/workflows/ci.yml"
133
+ - ".gitignore"
134
+ - ".rspec"
135
+ - ".rubocop.yml"
136
+ - Gemfile
137
+ - LICENSE
138
+ - README.md
139
+ - Rakefile
140
+ - envato.gemspec
141
+ - lib/envato.rb
142
+ - lib/envato/client.rb
143
+ - lib/envato/collection.rb
144
+ - lib/envato/error.rb
145
+ - lib/envato/object.rb
146
+ - lib/envato/objects/types.rb
147
+ - lib/envato/resource.rb
148
+ - lib/envato/resources/bookmarks.rb
149
+ - lib/envato/resources/item.rb
150
+ - lib/envato/resources/market.rb
151
+ - lib/envato/resources/markets.rb
152
+ - lib/envato/resources/search.rb
153
+ - lib/envato/resources/user.rb
154
+ - lib/envato/resources/users.rb
155
+ - lib/envato/version.rb
53
156
  homepage: https://github.com/ruby-api-client/envato
54
157
  licenses:
55
158
  - MIT
56
159
  metadata:
57
160
  rubygems_mfa_required: 'true'
58
- post_install_message:
161
+ post_install_message:
59
162
  rdoc_options: []
60
163
  require_paths:
61
164
  - lib
@@ -70,8 +173,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
173
  - !ruby/object:Gem::Version
71
174
  version: '0'
72
175
  requirements: []
73
- rubygems_version: 3.0.3.1
74
- signing_key:
176
+ rubygems_version: 3.2.3
177
+ signing_key:
75
178
  specification_version: 4
76
179
  summary: WIP - Envato API client
77
180
  test_files: []