freefeed-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 51d600de0410a6c2e6341267d64986af26b39add
4
+ data.tar.gz: 2c3b31d286d4b5cb477d38389b00306cb973540e
5
+ SHA512:
6
+ metadata.gz: a1aed947a23f1fcc9b9ae852841ecc72688455e0ae499cd504b05a510a823edf3cd0e0a762c8d5cad748673be74d0958824e5c0451628c5a6e4a2469eb81d174
7
+ data.tar.gz: 2f6299a90a0d4e7e783604d2c7d27f00fcc917ce9ac7f212c6303826231aa31727be25bcac965fe3bb4f134738a86bcd14d8f16a20deca7cd248c8a09a7a0e73
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.13.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in freefeed.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Ilia Zemskov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # freefeed-client
2
+
3
+ Ruby wrapper for [Freefeed API](https://fetsh.github.io/freefeed-api).
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/feefeed-client.svg)](http://badge.fury.io/rb/freefeed-client)
6
+
7
+ ## Installation
8
+
9
+ Add following line to your Gemfile:
10
+
11
+ ```ruby
12
+ gem 'freefeed-client'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ ```shell
18
+ $ bundle
19
+ ```
20
+
21
+ Or install it system-wide:
22
+
23
+ ```shell
24
+ $ gem install freefeed-client
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ First things first, you need to [obtain a token](https://fetsh.github.io/freefeed-api/#authentication) for your user. Then create your api client like this:
30
+
31
+ ```ruby
32
+ require 'freefeed'
33
+
34
+ client = Freefeed::Client.new('yourFreefeedAPIToken')
35
+
36
+ post = Freefeed::Types::PostCreate.new(
37
+ {
38
+ post: {
39
+ body: 'Hello World!'
40
+ },
41
+ meta: {
42
+ feeds: ['yourusername']
43
+ }
44
+ }
45
+ )
46
+
47
+ post_resource = Freefeed::Post.new(client: client)
48
+
49
+ post_resource.create(post)
50
+ ```
51
+
52
+ You can skip instantiating resource, but I'm not sure if this is a good practice:
53
+
54
+ ```ruby
55
+ require 'freefeed'
56
+
57
+ client = Freefeed::Client.new('yourFreefeedAPIToken')
58
+
59
+ post = Freefeed::Types::PostCreate.new(
60
+ {
61
+ post: {
62
+ body: 'Hello World!'
63
+ },
64
+ meta: {
65
+ feeds: ['yourusername']
66
+ }
67
+ }
68
+ )
69
+
70
+ client.posts.create(post)
71
+ ```
72
+
73
+ You can even skip instantiating post type, but you will lose some validation:
74
+
75
+
76
+ ```ruby
77
+ require 'freefeed'
78
+
79
+ client = Freefeed::Client.new('yourFreefeedAPIToken')
80
+
81
+ client.posts.create({post: {body: 'Hello World!'}, meta: {feeds: ['yourusername']}})
82
+ ```
83
+
84
+ ## Logging
85
+
86
+ By default, `freefeed-client` logs everything to STDOUT. You can change this behavior and provide your own logger class with someo ptions. See example below:
87
+
88
+ ```ruby
89
+ client = Freefeed::Client.new(
90
+ 'yourFreefeedAPIToken',
91
+ logger: Logger.new('log.txt'),
92
+ logger_options: {bodies: false, headers: false}
93
+ )
94
+ ```
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "freefeed"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/freefeed.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'freefeed/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'freefeed-client'
8
+ spec.version = Freefeed::VERSION
9
+ spec.authors = ['Ilia Zemskov']
10
+ spec.email = ['me@fetsh.me']
11
+
12
+ spec.summary = 'Ruby wrapper for FreeFeed API.'
13
+ spec.homepage = 'https://github.com/fetsh/freefeed-client'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = 'bin'
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_dependency 'faraday'
24
+ spec.add_dependency 'faraday_middleware'
25
+ spec.add_dependency 'multi_json'
26
+ spec.add_dependency 'dry-types'
27
+ spec.add_dependency 'dry-struct'
28
+ spec.add_dependency 'activesupport'
29
+
30
+
31
+ spec.add_development_dependency 'bundler', '~> 1.13'
32
+ spec.add_development_dependency 'rake'
33
+ spec.add_development_dependency 'rspec', '~> 3.0'
34
+ end
@@ -0,0 +1,90 @@
1
+ module Freefeed
2
+ class Client
3
+ HOST = 'freefeed.net'.freeze
4
+
5
+ attr_accessor :api_token, :faraday_options, :resources
6
+
7
+ def initialize(api_token = nil, faraday_options = {})
8
+ @api_token = api_token
9
+ @faraday_options = faraday_options
10
+ end
11
+
12
+ def authenticate(username:, password:)
13
+ Session.new(client: self)
14
+ .create(username: username, password: password).tap do |re|
15
+ @api_token = re.fetch('authToken')
16
+ end
17
+ end
18
+
19
+ def call(endpoint, params = {}, headers = {})
20
+ guard_wrong_endpoint(endpoint)
21
+ call!(
22
+ ENDPOINTS[endpoint][:method], path(endpoint),
23
+ build_options(endpoint, params), headers
24
+ )
25
+ end
26
+
27
+ def call!(verb, endpoint, params = {}, headers = {})
28
+ response = conn.send(
29
+ verb, endpoint, params, auth_header.merge(headers)
30
+ )
31
+ handle_erros(response)
32
+ prepare_response(response)
33
+ end
34
+
35
+ private
36
+
37
+ def conn
38
+ @conn ||= Faraday.new(url: "https://#{HOST}") do |faraday|
39
+ faraday.request :multipart
40
+ faraday.response(
41
+ :logger,
42
+ (faraday_options[:logger] || Logger.new(STDOUT)),
43
+ (faraday_options[:logger_options] || { bodies: true, headers: true })
44
+ )
45
+ faraday.request :json
46
+ faraday.adapter faraday_options[:adapter] || Faraday.default_adapter
47
+ end
48
+ end
49
+
50
+ def guard_wrong_endpoint(endpoint)
51
+ raise Exceptions::WrongEndpoint unless ENDPOINTS.keys.include?(endpoint)
52
+ end
53
+
54
+ def build_options(endpoint, params)
55
+ default_params(endpoint).merge(sanitize_params(endpoint, params))
56
+ end
57
+
58
+ def path(endpoint)
59
+ (endpoint.start_with?('/') ? '' : BASE_PATH) + endpoint.split('#').first
60
+ end
61
+
62
+ def default_params(endpoint)
63
+ {}.merge(ENDPOINTS[endpoint][:default_params] || {})
64
+ end
65
+
66
+ def sanitize_params(endpoint, params)
67
+ return {} unless ENDPOINTS[endpoint][:params]
68
+ params.delete_if do |key, _|
69
+ !ENDPOINTS[endpoint][:params].include?(key.to_s)
70
+ end
71
+ end
72
+
73
+ def handle_erros(response)
74
+ raise(
75
+ Exceptions::ResponseError.new(response),
76
+ 'Freefeed API has returned the error'
77
+ ) unless response.status == 200
78
+ end
79
+
80
+ def prepare_response(response)
81
+ MultiJson.load(response.body.to_s)
82
+ rescue MultiJson::LoadError
83
+ response.body
84
+ end
85
+
86
+ def auth_header
87
+ api_token.nil? ? {} : { 'x-authentication-token': api_token }
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,27 @@
1
+ module Freefeed
2
+ module Exceptions
3
+ class ResponseError < StandardError
4
+ attr_reader :response
5
+
6
+ def initialize(response)
7
+ @response = response
8
+ end
9
+
10
+ def to_s
11
+ super + format(' (%s)', data.map { |k, v| %(#{k}: "#{v}") }.join(', '))
12
+ end
13
+
14
+ private
15
+
16
+ def data
17
+ @data ||= begin
18
+ MultiJson.load(response.body)
19
+ rescue MultiJson::DecodeError
20
+ { uri: response.env.url.to_s, errors: response.body.to_s }
21
+ end.merge(code: response.status)
22
+ end
23
+ end
24
+ class WrongEndpoint < StandardError
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ module Freefeed
2
+ class Archive < ResourceKitling::Resource
3
+ actions do
4
+ action :restoration do
5
+ verb :post
6
+ version :v2
7
+ path '/archives/restoration'
8
+ end
9
+ action :activities do
10
+ verb :put
11
+ version :v2
12
+ path '/archives/activities'
13
+ end
14
+ action :post_by_old_name do
15
+ verb :get
16
+ version :v2
17
+ path '/archives/post-by-old-name/:name'
18
+ end
19
+ action :stats do
20
+ verb :get
21
+ version :v2
22
+ path '/archives-stats'
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ module Freefeed
2
+ class Attachment < ResourceKitling::Resource
3
+ actions do
4
+ action :create do
5
+ verb :post
6
+ version :v1
7
+ path '/attachments'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Freefeed
2
+ class Bookmarklet < ResourceKitling::Resource
3
+ actions do
4
+ action :create do
5
+ verb :post
6
+ version :v1
7
+ path '/bookmarklet'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,36 @@
1
+ module Freefeed
2
+ class Comment < ResourceKitling::Resource
3
+ actions do
4
+ action :create do
5
+ verb :post
6
+ version :v1
7
+ path '/comments'
8
+ end
9
+ action :update do
10
+ verb :put
11
+ version :v1
12
+ path '/comments/:id'
13
+ end
14
+ action :destroy do
15
+ verb :delete
16
+ version :v1
17
+ path '/comments/:id'
18
+ end
19
+ action :like do
20
+ verb :post
21
+ version :v2
22
+ path '/comments/:id/like'
23
+ end
24
+ action :unlike do
25
+ verb :post
26
+ version :v2
27
+ path '/comments/:id/unlike'
28
+ end
29
+ action :likes do
30
+ verb :get
31
+ version :v2
32
+ path '/comments/:id/likes'
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,61 @@
1
+ module Freefeed
2
+ class Group < ResourceKitling::Resource
3
+ actions do
4
+ action :create do
5
+ verb :post
6
+ version :v1
7
+ path '/groups'
8
+ end
9
+ action :sudo_create do
10
+ verb :post
11
+ version :v1
12
+ path '/groups/sudo'
13
+ end
14
+ action :update_profile_picture do
15
+ verb :post
16
+ version :v1
17
+ path '/groups/:name/updateProfilePicture'
18
+ end
19
+ action :admin do
20
+ verb :post
21
+ version :v1
22
+ path '/groups/:name/subscribers/:username/admin'
23
+ end
24
+ action :unadmin do
25
+ verb :post
26
+ version :v1
27
+ path '/groups/:name/subscribers/:username/unadmin'
28
+ end
29
+ action :send_request do
30
+ verb :post
31
+ version :v1
32
+ path '/groups/:name/sendRequest'
33
+ end
34
+ action :accept_request do
35
+ verb :post
36
+ version :v1
37
+ path '/groups/:name/acceptRequest/:username'
38
+ end
39
+ action :reject_request do
40
+ verb :post
41
+ version :v1
42
+ path '/groups/:name/rejectRequest/:username'
43
+ end
44
+ action :unsubscribe_from_group do
45
+ verb :post
46
+ version :v1
47
+ path '/groups/:name/unsubscribeFromGroup/:username'
48
+ end
49
+ action :manage do
50
+ verb :get
51
+ version :v2
52
+ path '/managedGroups'
53
+ end
54
+ action :all do
55
+ verb :get
56
+ version :v2
57
+ path '/allGroups'
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,16 @@
1
+ module Freefeed
2
+ class Invitation < ResourceKitling::Resource
3
+ actions do
4
+ action :create do
5
+ verb :post
6
+ version :v2
7
+ path '/invitations'
8
+ end
9
+ action :get do
10
+ verb :get
11
+ version :v2
12
+ path '/invitations/:id'
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module Freefeed
2
+ class Notification < ResourceKitling::Resource
3
+ actions do
4
+ action :all do
5
+ verb :get
6
+ version :v2
7
+ path '/notifications'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ module Freefeed
2
+ class Password < ResourceKitling::Resource
3
+ actions do
4
+ action :create do
5
+ verb :post
6
+ version :v1
7
+ path '/passwords'
8
+ end
9
+ action :update do
10
+ verb :put
11
+ version :v1
12
+ path '/passwords/:token'
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,61 @@
1
+ module Freefeed
2
+ class Post < ResourceKitling::Resource
3
+ actions do
4
+ action :create do
5
+ verb :post
6
+ version :v1
7
+ path '/posts'
8
+ end
9
+ action :get do
10
+ verb :get
11
+ version :v2
12
+ path '/posts/:id'
13
+ end
14
+ action :update do
15
+ verb :put
16
+ version :v1
17
+ path '/posts/:id'
18
+ end
19
+ action :destroy do
20
+ verb :delete
21
+ version :v1
22
+ path '/posts/:id'
23
+ end
24
+ action :like do
25
+ verb :post
26
+ version :v1
27
+ path '/posts/:id/like'
28
+ end
29
+ action :unlike do
30
+ verb :post
31
+ version :v1
32
+ path '/posts/:id/unlike'
33
+ end
34
+ action :hide do
35
+ verb :post
36
+ version :v1
37
+ path '/posts/:id/hide'
38
+ end
39
+ action :unhide do
40
+ verb :post
41
+ version :v1
42
+ path '/posts/:id/unhide'
43
+ end
44
+ action :disable_comments do
45
+ verb :post
46
+ version :v1
47
+ path '/posts/:id/disableComments'
48
+ end
49
+ action :enable_comments do
50
+ verb :post
51
+ version :v1
52
+ path '/posts/:id/enableComments'
53
+ end
54
+ action :opengraph do
55
+ verb :get
56
+ version :v2
57
+ path '/posts-opengraph/:id'
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,11 @@
1
+ module Freefeed
2
+ class Request < ResourceKitling::Resource
3
+ actions do
4
+ action :revoke do
5
+ verb :post
6
+ version :v2
7
+ path '/requests/:username/revoke'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Freefeed
2
+ class Search < ResourceKitling::Resource
3
+ actions do
4
+ action :search do
5
+ verb :get
6
+ version :v2
7
+ path '/search'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Freefeed
2
+ class Session < ResourceKitling::Resource
3
+ actions do
4
+ action :create do
5
+ verb :post
6
+ version :v1
7
+ path '/session'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Freefeed
2
+ class Stat < ResourceKitling::Resource
3
+ actions do
4
+ action :stats do
5
+ verb :get
6
+ version :v2
7
+ path '/stats'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ module Freefeed
2
+ class Summary < ResourceKitling::Resource
3
+ actions do
4
+ action :general do
5
+ verb :get
6
+ version :v2
7
+ path '/summary/:days'
8
+ end
9
+ action :by_user do
10
+ verb :get
11
+ version :v2
12
+ path '/summary/:username/:days'
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,41 @@
1
+ module Freefeed
2
+ class Timeline < ResourceKitling::Resource
3
+ actions do
4
+ action :bestof do
5
+ verb :get
6
+ version :v2
7
+ path '/bestof'
8
+ end
9
+ action :home do
10
+ verb :get
11
+ version :v2
12
+ path '/timelines/home'
13
+ end
14
+ action :discussions do
15
+ verb :get
16
+ version :v2
17
+ path '/timelines/filter/discussions'
18
+ end
19
+ action :directs do
20
+ verb :get
21
+ version :v2
22
+ path '/timelines/filter/directs'
23
+ end
24
+ action :posts do
25
+ verb :get
26
+ version :v2
27
+ path '/timelines/:username'
28
+ end
29
+ action :likes do
30
+ verb :get
31
+ version :v2
32
+ path '/timelines/:username/likes'
33
+ end
34
+ action :comments do
35
+ verb :get
36
+ version :v2
37
+ path '/timelines/:username/comments'
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,121 @@
1
+ module Freefeed
2
+ class User < ResourceKitling::Resource
3
+ actions do
4
+ action :create do
5
+ verb :post
6
+ version :v1
7
+ path '/users'
8
+ end
9
+ action :sudo_create do
10
+ verb :post
11
+ version :v1
12
+ path '/users/sudo'
13
+ end
14
+ action :send_request do
15
+ verb :post
16
+ version :v1
17
+ path '/users/:username/sendRequest'
18
+ end
19
+ action :revoke_request do
20
+ verb :post
21
+ version :v2
22
+ path '/requests/:username/revoke'
23
+ end
24
+ action :accept_request do
25
+ verb :post
26
+ version :v1
27
+ path '/users/acceptRequest/:username'
28
+ end
29
+ action :reject_request do
30
+ verb :post
31
+ version :v1
32
+ path '/users/rejectRequest/:username'
33
+ end
34
+ action :unsubscribe_from_me do
35
+ verb :post
36
+ version :v1
37
+ path '/users/:username/unsubscribeFromMe'
38
+ end
39
+ action :show do
40
+ verb :get
41
+ version :v1
42
+ path '/users/:username'
43
+ end
44
+ action :update_password do
45
+ verb :put
46
+ version :v1
47
+ path '/users/updatePassword'
48
+ end
49
+ action :update_profile_picture do
50
+ verb :post
51
+ version :v1
52
+ path '/users/updateProfilePicture'
53
+ end
54
+ action :update do
55
+ verb :put
56
+ version :v1
57
+ path '/users/:id'
58
+ end
59
+ action :ban do
60
+ verb :post
61
+ version :v1
62
+ path '/users/:username/ban'
63
+ end
64
+ action :unban do
65
+ verb :post
66
+ version :v1
67
+ path '/users/:username/unban'
68
+ end
69
+ action :subscribe do
70
+ verb :post
71
+ version :v1
72
+ path '/users/:username/subscribe'
73
+ end
74
+ action :unsubscribe do
75
+ verb :post
76
+ version :v1
77
+ path '/users/:username/unsubscribe'
78
+ end
79
+ action :subscribers do
80
+ verb :get
81
+ version :v1
82
+ path '/users/:username/subscribers'
83
+ end
84
+ action :subscriptions do
85
+ verb :get
86
+ version :v1
87
+ path '/users/:username/subscriptions'
88
+ end
89
+ action :blocked do
90
+ verb :get
91
+ version :v2
92
+ path '/users/blockedByMe'
93
+ end
94
+ action :unread_directs_number do
95
+ verb :get
96
+ version :v2
97
+ path '/users/getUnreadDirectsNumber'
98
+ end
99
+ action :unread_notifications_number do
100
+ verb :get
101
+ version :v2
102
+ path '/users/getUnreadNotificationsNumber'
103
+ end
104
+ action :mark_all_directs_as_read do
105
+ verb :get
106
+ version :v2
107
+ path '/users/markAllDirectsAsRead'
108
+ end
109
+ action :mark_all_notifications_as_read do
110
+ verb :post
111
+ version :v2
112
+ path '/users/markAllNotificationsAsRead'
113
+ end
114
+ action :whoami do
115
+ verb :get
116
+ version :v2
117
+ path '/users/whoami'
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,17 @@
1
+ require 'dry-types'
2
+ require 'dry-struct'
3
+ module Freefeed
4
+ module Types
5
+ class Bookmarklet < Dry::Struct
6
+ attribute :title, Types::Body
7
+ attribute :comment, Types::Strict::String.meta(omittable: true)
8
+ attribute :image, Types::Strict::String.meta(omittable: true)
9
+ attribute :images, Types::Strict::Array.of(
10
+ Types::Strict::String
11
+ ).meta(omittable: true)
12
+ attribute :meta, Types::Hash.schema(
13
+ feeds: Types::AccountName | Types::Feeds
14
+ ).meta(omittable: true)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ require 'dry-types'
2
+ require 'dry-struct'
3
+ module Freefeed
4
+ module Types
5
+ class CommentCreate < Dry::Struct
6
+ attribute :comment, Types::Hash.schema(
7
+ body: Types::Body,
8
+ postId: Types::UID
9
+ )
10
+ end
11
+
12
+ class CommentUpdate < Dry::Struct
13
+ attribute :comment, Types::Hash.schema(body: Types::Body)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ require 'dry-types'
2
+ require 'dry-struct'
3
+ module Freefeed
4
+ module Types
5
+ class PostCreate < Dry::Struct
6
+ attribute :post, Types::Hash.schema(
7
+ body: Types::Body,
8
+ attachments: Types::Attachments.meta(omittable: true)
9
+ )
10
+ attribute :meta, Types::Hash.schema(
11
+ commentsDisabled: Types::Strict::Bool.default(false),
12
+ feeds: Types::AccountName | Types::Feeds
13
+ )
14
+ end
15
+
16
+ class PostUpdate < Dry::Struct
17
+ attribute :post, Types::Hash.schema(
18
+ body: Types::Body.meta(omittable: true),
19
+ attachments: Types::Attachments.meta(omittable: true),
20
+ feeds: Types::Feeds.meta(omittable: true)
21
+ )
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ require 'dry-types'
2
+ require 'dry-struct'
3
+ module Freefeed
4
+ module Types
5
+ include Dry::Types.module
6
+
7
+ Body = Types::Strict::String.constrained(min_size: 1, format: %r{\S+})
8
+ UID = Types::Strict::String.constrained(
9
+ format: %r{^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$}
10
+ )
11
+ UserName = Types::Strict::String.constrained(
12
+ min_size: 3, max_size: 25, format: %r{^[A-Za-z0-9]+$}
13
+ )
14
+ GroupName = Types::Strict::String.constrained(
15
+ min_size: 3, max_size: 25, format: %r{^[A-Za-z0-9]+(-[a-zA-Z0-9]+)*$}
16
+ )
17
+ AccountName = UserName | GroupName
18
+ Attachments = Types::Strict::Array.of(UID)
19
+ Feeds = Types::Strict::Array.of(AccountName)
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module Freefeed
2
+ VERSION = '0.1.0'.freeze
3
+ end
data/lib/freefeed.rb ADDED
@@ -0,0 +1,46 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+ require 'logger'
4
+ require 'multi_json'
5
+ require 'resource_kitling'
6
+ require 'freefeed/version'
7
+ require 'freefeed/exceptions'
8
+ require 'freefeed/client'
9
+ require 'active_support/inflector'
10
+
11
+ require 'freefeed/resources/archive'
12
+ require 'freefeed/resources/attachment'
13
+ require 'freefeed/resources/bookmarklet'
14
+ require 'freefeed/resources/comment'
15
+ require 'freefeed/resources/group'
16
+ require 'freefeed/resources/invitation'
17
+ require 'freefeed/resources/notification'
18
+ require 'freefeed/resources/password'
19
+ require 'freefeed/resources/post'
20
+ require 'freefeed/resources/request'
21
+ require 'freefeed/resources/search'
22
+ require 'freefeed/resources/session'
23
+ require 'freefeed/resources/stat'
24
+ require 'freefeed/resources/summary'
25
+ require 'freefeed/resources/timeline'
26
+ require 'freefeed/resources/user'
27
+
28
+ require 'freefeed/types'
29
+ require 'freefeed/types/bookmarklet'
30
+ require 'freefeed/types/comment'
31
+ require 'freefeed/types/post'
32
+
33
+ ResourceKitling::Resource.subclasses.each do |sc|
34
+ mn = sc.to_s.downcase.split('::').last.pluralize
35
+ if Freefeed::Client.method_defined?(mn)
36
+ raise(
37
+ ArgumentError,
38
+ "Method '#{mn}' is already defined on Freefeed::Client"
39
+ )
40
+ end
41
+ Freefeed::Client.send(:define_method, mn) do
42
+ instance_variable_get("@#{mn}") || instance_variable_set(
43
+ "@#{mn}", sc.new(client: self)
44
+ )
45
+ end
46
+ end
@@ -0,0 +1,101 @@
1
+ module ResourceKitling
2
+ require 'forwardable'
3
+ class ActionCollection
4
+ extend Forwardable
5
+ def_delegators :@collection, :find, :<<, :each, :include?
6
+ def initialize
7
+ @collection = []
8
+ end
9
+
10
+ def action(name, &block)
11
+ action = Action.new(name)
12
+ action.instance_eval(&block) if block_given?
13
+ action.tap { |a| @collection << a }
14
+ end
15
+ end
16
+
17
+ class Action
18
+ attr_reader :name
19
+
20
+ def initialize(name)
21
+ @name = name
22
+ @verb = :get
23
+ @version = 'v1'
24
+ @path = path
25
+ end
26
+
27
+ def verb(v = nil)
28
+ @verb = v if v
29
+ @verb
30
+ end
31
+
32
+ def version(v = nil)
33
+ @version = v if v
34
+ @version
35
+ end
36
+
37
+ def path(path = nil, &block)
38
+ raise "You must pass either a block or a string for paths" if path and block_given?
39
+ @path = path if path
40
+ @path = block if block_given?
41
+ @path
42
+ end
43
+
44
+ def generated_path(values = {})
45
+ values.inject("/#{version}/#{path}") do |np, (key, value)|
46
+ np.gsub(":#{key}", value.to_s)
47
+ end
48
+ end
49
+ end
50
+ class Resource
51
+ class << self
52
+ attr_accessor :_actions
53
+ attr_reader :subclasses
54
+ def inherited(subclass)
55
+ superclass.inherited(subclass) if superclass.respond_to?(:inherited)
56
+ @subclasses ||= []
57
+ @subclasses << subclass
58
+ end
59
+ end
60
+
61
+ def self.actions(&block)
62
+ self._actions ||= ActionCollection.new
63
+ if block_given?
64
+ self._actions.instance_eval(&block)
65
+ # MethodFactory.construct(self, self._actions)
66
+ self._actions.each do |action|
67
+ if method_defined?(action.name)
68
+ raise(
69
+ ArgumentError,
70
+ "Action '#{action.name}' is already defined on `#{self}`"
71
+ )
72
+ end
73
+ method_block = method_for_action(action)
74
+ send(:define_method, action.name, &method_block)
75
+ end
76
+ end
77
+ self._actions
78
+ end
79
+
80
+ def self.method_for_action(action)
81
+ Proc.new do |*args|
82
+ pathopts = action.path.include?(':') ? args.shift : {}
83
+ payload = args.shift
84
+ payload = payload.to_h if payload.respond_to?(:to_h)
85
+ client.call!(
86
+ action.verb, action.generated_path(pathopts), payload, *args
87
+ )
88
+ end
89
+ end
90
+
91
+ def actions
92
+ self.class.actions
93
+ end
94
+
95
+ attr_reader :client
96
+
97
+ def initialize(client: nil)
98
+ @client = client
99
+ end
100
+ end
101
+ end
metadata ADDED
@@ -0,0 +1,207 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: freefeed-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ilia Zemskov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-10-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: multi_json
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: dry-types
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: dry-struct
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activesupport
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.13'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.13'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '3.0'
139
+ description:
140
+ email:
141
+ - me@fetsh.me
142
+ executables:
143
+ - console
144
+ - setup
145
+ extensions: []
146
+ extra_rdoc_files: []
147
+ files:
148
+ - ".gitignore"
149
+ - ".rspec"
150
+ - ".travis.yml"
151
+ - Gemfile
152
+ - LICENSE.txt
153
+ - README.md
154
+ - Rakefile
155
+ - bin/console
156
+ - bin/setup
157
+ - freefeed.gemspec
158
+ - lib/freefeed.rb
159
+ - lib/freefeed/client.rb
160
+ - lib/freefeed/exceptions.rb
161
+ - lib/freefeed/resources/archive.rb
162
+ - lib/freefeed/resources/attachment.rb
163
+ - lib/freefeed/resources/bookmarklet.rb
164
+ - lib/freefeed/resources/comment.rb
165
+ - lib/freefeed/resources/group.rb
166
+ - lib/freefeed/resources/invitation.rb
167
+ - lib/freefeed/resources/notification.rb
168
+ - lib/freefeed/resources/password.rb
169
+ - lib/freefeed/resources/post.rb
170
+ - lib/freefeed/resources/request.rb
171
+ - lib/freefeed/resources/search.rb
172
+ - lib/freefeed/resources/session.rb
173
+ - lib/freefeed/resources/stat.rb
174
+ - lib/freefeed/resources/summary.rb
175
+ - lib/freefeed/resources/timeline.rb
176
+ - lib/freefeed/resources/user.rb
177
+ - lib/freefeed/types.rb
178
+ - lib/freefeed/types/bookmarklet.rb
179
+ - lib/freefeed/types/comment.rb
180
+ - lib/freefeed/types/post.rb
181
+ - lib/freefeed/version.rb
182
+ - lib/resource_kitling.rb
183
+ homepage: https://github.com/fetsh/freefeed-client
184
+ licenses:
185
+ - MIT
186
+ metadata: {}
187
+ post_install_message:
188
+ rdoc_options: []
189
+ require_paths:
190
+ - lib
191
+ required_ruby_version: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ required_rubygems_version: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ requirements: []
202
+ rubyforge_project:
203
+ rubygems_version: 2.5.2.1
204
+ signing_key:
205
+ specification_version: 4
206
+ summary: Ruby wrapper for FreeFeed API.
207
+ test_files: []