posty_client 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in posty_client.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Thomas Steinhausen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ posty_client
2
+ ============
3
+
4
+ Client library for the post_api server: https://github.com/posty/posty_api
5
+
6
+ Install
7
+ -------
8
+
9
+ gem install posty_client
10
+
11
+ Usage
12
+ -----
13
+
14
+ Create at least a configuration file at ~/.posty-cli.yml
15
+
16
+ Cli:
17
+
18
+ ```
19
+ $ posty-client help
20
+ ```
21
+
22
+ Library:
23
+
24
+ ```
25
+ require 'pp'
26
+
27
+ ENV['RESTCLIENT_LOG'] = 'stdout'
28
+
29
+ $: << '.'
30
+ require 'lib/posty_client.rb'
31
+
32
+ d = PostyClient::Resources::Domain.new('posty-soft1.org')
33
+ puts d.name, d.primary_key
34
+ pp d.attributes
35
+
36
+ unless d.save
37
+ pp d.errors
38
+ end
39
+
40
+ d = PostyClient::Resources::Domain.new('posty-soft.org')
41
+ unless d.save
42
+ pp d.errors
43
+ end
44
+
45
+ puts '--'*10
46
+
47
+ pp d.users
48
+
49
+ puts '*'*20
50
+
51
+ u = PostyClient::Resources::User.new(d, 'to')
52
+ u.attributes['password'] = 'lalalala'
53
+ unless u.save
54
+ pp u.errors
55
+ exit
56
+ end
57
+
58
+ a = PostyClient::Resources::UserAlias.new(u, 'tommy')
59
+ a.attributes['destination'] = 'bheller'
60
+ unless a.save
61
+ pp a.errors
62
+ exit
63
+ end
64
+
65
+ puts '--'*10
66
+ pp u.aliases
67
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/posty-client ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/posty_client'
4
+ require 'posty_client/cli'
5
+
6
+ PostyClient::CLI.start
@@ -0,0 +1,11 @@
1
+ development:
2
+ # this is the posty Url put here your url where the posty-api is stored
3
+ api_url: http://posty-api.herokuapp.com/api/
4
+ # this is the version from the posty api
5
+ api_version: v1
6
+ access_token: ask your admin
7
+
8
+ production:
9
+ api_url: http://posty-api.herokuapp.com/api/
10
+ api_version: v1
11
+ access_token: ask your admin
@@ -0,0 +1,53 @@
1
+ require "logger"
2
+ require "active_support/all"
3
+ require "readwritesettings"
4
+ require "rest_client"
5
+
6
+ $: << File.expand_path(File.dirname(__FILE__)+'/../lib')
7
+
8
+ require "posty_client/version"
9
+
10
+ module PostyClient
11
+ def self.settings_file
12
+ default_file = File.expand_path('~/.posty_client.yml')
13
+
14
+ @settings_file ||= if File.exists?(default_file)
15
+ default_file
16
+ else
17
+ # this is set to make the cli not bark on missing settings
18
+ PostyClient.root + '/config/posty_client.yml.dist'
19
+ end
20
+ end
21
+
22
+ def self.settings_file=(file_path)
23
+ @settings_file = file_path
24
+ Settings.source(@settings_file)
25
+ end
26
+
27
+ def self.env
28
+ 'development' || ENV['POSTY_ENV']
29
+ end
30
+
31
+ def self.root
32
+ File.expand_path(File.dirname(__FILE__)+'/../')
33
+ end
34
+
35
+ mattr_accessor :logger
36
+ self.logger = Logger.new(STDOUT)
37
+ end
38
+
39
+ RestClient.add_before_execution_proc do |req, params|
40
+ req['auth_token'] = PostyClient::Settings.access_token
41
+ end
42
+
43
+
44
+ require "posty_client/settings"
45
+
46
+ require "posty_client/resources/base"
47
+ require "posty_client/resources/domain"
48
+ require "posty_client/resources/user"
49
+ require "posty_client/resources/domain_alias"
50
+ require "posty_client/resources/user_alias"
51
+ require "posty_client/resources/transport"
52
+ require "posty_client/resources/api_key"
53
+ require "posty_client/resources/summary"
@@ -0,0 +1,78 @@
1
+ require 'thor'
2
+ require 'posty_client/command/domain_command'
3
+ require 'posty_client/command/user_command'
4
+ require 'posty_client/command/domain_alias_command'
5
+ require 'posty_client/command/user_alias_command'
6
+ require 'posty_client/command/transport_command'
7
+ require 'posty_client/command/api_key_command'
8
+
9
+
10
+ module PostyClient
11
+ class CLI < Thor
12
+ map "-v" => "version"
13
+ map "--version" => "version"
14
+
15
+ desc "--version", "print version"
16
+ long_desc "Print the Posty CLI tool version"
17
+ def version
18
+ puts "version %s" % [PostyClient::VERSION]
19
+ end
20
+
21
+ desc "create_config", "create a configuration file at ~/.posty-client.yml"
22
+ def create_config
23
+ require 'fileutils'
24
+
25
+ user_config_file = File.expand_path('~/.posty_client.yml')
26
+ if File.exists?(user_config_file)
27
+ say("File #{user_config_file} already exists! Nothing created.", :red)
28
+ exit 1
29
+ end
30
+
31
+ FileUtils.cp(PostyClient.root + '/config/posty_client.yml.dist', user_config_file)
32
+ say("File #{user_config_file} created. Please customize.", :green)
33
+ end
34
+
35
+ desc "summary", "Returns a summary of all Resources"
36
+ def summary
37
+ print_table(PostyClient::Resources::Summary.get)
38
+ end
39
+
40
+ desc "domain [SUBCOMMAND]", "perform an action on a domain"
41
+ long_desc <<-D
42
+ Perform an action on a domain. To see available subcommands use 'posty domain help'
43
+ D
44
+ subcommand "domain", PostyClient::Command::DomainCommand
45
+
46
+ desc "user [SUBCOMMAND]", "perform an action on a user"
47
+ long_desc <<-D
48
+ Perform an action on a User. To see available subcommands use 'posty user help'
49
+ D
50
+ subcommand "user", PostyClient::Command::UserCommand
51
+
52
+ desc "domain_alias [SUBCOMMAND]", "perform an action on a domain_alias"
53
+ long_desc <<-D
54
+ Perform an action on a domain_alias. To see available subcommands use 'posty domain_alias help'
55
+ D
56
+ subcommand "domain_alias", PostyClient::Command::DomainAliasCommand
57
+
58
+ desc "user_alias [SUBCOMMAND]", "perform an action on a user_alias"
59
+ long_desc <<-D
60
+ Perform an action on a user_alias. To see available subcommands use 'posty user_alias help'
61
+ D
62
+ subcommand "user_alias", PostyClient::Command::UserAliasCommand
63
+
64
+ desc "transport [SUBCOMMAND]", "perform an action on a transport"
65
+ long_desc <<-D
66
+ Perform an action on a transport. To see available subcommands use 'posty transport help'
67
+ D
68
+ subcommand "transport", PostyClient::Command::TransportCommand
69
+
70
+ desc "api_key [SUBCOMMAND]", "perform an action on a api_key"
71
+ long_desc <<-D
72
+ Perform an action on a api_key. To see available subcommands use 'posty api_key help'
73
+ D
74
+ subcommand "api_key", PostyClient::Command::ApiKeyCommand
75
+ end
76
+ end
77
+
78
+
@@ -0,0 +1,61 @@
1
+ module PostyClient
2
+ module Command
3
+ class ApiKeyCommand < Thor
4
+ include PostyClient::Resources
5
+
6
+ desc "list", "list all api keys"
7
+ def list
8
+ api_keys = PostyClient::Resources::ApiKey.all.map {|d| [d.attributes["access_token"], set_color(d.attributes["expires_at"], d.expired? ? :red : :green), set_color(d.attributes["active"], d.active? ? :green : :red)]}
9
+ api_keys.unshift(["API Key", "Expires at", "Active"])
10
+ print_table(api_keys)
11
+ end
12
+
13
+ desc "add", "add a api key"
14
+ def add
15
+ api_key = PostyClient::Resources::ApiKey.new("")
16
+ api_key.create
17
+ end
18
+
19
+ desc "expire [TOKEN]", "expires the given token"
20
+ def expire(token)
21
+ api_key = PostyClient::Resources::ApiKey.new(token)
22
+ api_key.attributes['expires_at'] = DateTime.now
23
+ unless api_key.save
24
+ say api_key.errors.inspect, :red
25
+ exit 1
26
+ end
27
+ end
28
+
29
+ desc "disable [TOKEN]", "disables the given token"
30
+ def disable(token)
31
+ api_key = PostyClient::Resources::ApiKey.new(token)
32
+ api_key.attributes['active'] = false
33
+ unless api_key.save
34
+ say api_key.errors.inspect, :red
35
+ exit 1
36
+ end
37
+ end
38
+
39
+ desc "enable [TOKEN]", "enables the given token"
40
+ def enable(token)
41
+ api_key = PostyClient::Resources::ApiKey.new(token)
42
+ api_key.attributes['active'] = true
43
+ unless api_key.save
44
+ say api_key.errors.inspect, :red
45
+ exit 1
46
+ end
47
+ end
48
+
49
+ desc "delete [TOKEN]", "delete a specified token"
50
+ def delete(token)
51
+ if yes?("Delete #{name}?")
52
+ transport = PostyClient::Resources::Transport.new(token)
53
+ unless transport.delete
54
+ say transport.errors.inspect, :red
55
+ exit 1
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,43 @@
1
+ require 'posty_client/command/finder_concerns'
2
+
3
+ module PostyClient
4
+ module Command
5
+ class DomainAliasCommand < Thor
6
+ include PostyClient::Resources
7
+ include PostyClient::Command::FinderConcerns
8
+
9
+ desc "list [DOMAIN]", "list all domain aliases of given domain"
10
+ def list(domain)
11
+ domain = find_domain_by_name(domain)
12
+ domain_aliases = domain.aliases
13
+ puts domain_aliases.map(&:name)
14
+ end
15
+
16
+ desc "add [DOMAIN] [DOMAIN_ALIAS]", "add a domain alias"
17
+ def add(domain_name, alias_name)
18
+ domain = find_domain_by_name(domain_name)
19
+
20
+ ali = DomainAlias.new(domain, alias_name)
21
+
22
+ unless ali.save
23
+ say("#{alias_name} save failed: #{ali.errors}", :red)
24
+ exit 1
25
+ end
26
+ end
27
+
28
+ desc "delete [DOMAIN] [DOMAIN_ALIAS]", "delete the specified domain alias"
29
+ def delete(domain_name, name)
30
+ ali = find_domain_alias_by_domain_and_name(domain_name, name)
31
+ if ali.new_resource?
32
+ say("#{name} unknown", :red)
33
+ exit 1
34
+ end
35
+
36
+ unless ali.delete
37
+ say("#{name} delete failed: #{ali.errors}", :red)
38
+ exit 1
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,41 @@
1
+ module PostyClient
2
+ module Command
3
+ class DomainCommand < Thor
4
+ desc "list", "list all domains"
5
+ def list
6
+ domains = PostyClient::Resources::Domain.all.map {|d| [d.name]}
7
+ print_table(domains)
8
+ end
9
+
10
+ desc "add [DOMAIN]", "add a domain"
11
+ def add(name)
12
+ domain = PostyClient::Resources::Domain.new(name)
13
+ unless domain.save
14
+ say domain.errors.inspect, :red
15
+ exit 1
16
+ end
17
+ end
18
+
19
+ desc "rename [DOMAIN] [NEW_DOMAIN]", "rename specified domain"
20
+ def rename(name, new_name)
21
+ domain = PostyClient::Resources::Domain.new(name)
22
+ domain.attributes['name'] = new_name
23
+ unless domain.save
24
+ say domain.errors.inspect, :red
25
+ exit 1
26
+ end
27
+ end
28
+
29
+ desc "delete [DOMAIN]", "delete a specified domain"
30
+ def delete(name)
31
+ if yes?("Delete #{name}?")
32
+ domain = PostyClient::Resources::Domain.new(name)
33
+ unless domain.delete
34
+ say domain.errors.inspect, :red
35
+ exit 1
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,47 @@
1
+ module PostyClient
2
+ module Command
3
+ module FinderConcerns
4
+ include PostyClient::Resources
5
+
6
+ def user_and_domain_from_email(email)
7
+ parts = email.split("\@")
8
+
9
+ unless parts.size == 2
10
+ say("#{email} not an email address", :red)
11
+ exit 1
12
+ end
13
+
14
+ return *parts
15
+ end
16
+
17
+ def find_domain_by_name(name)
18
+ domain = Domain.new(name)
19
+ if domain.new_resource?
20
+ say("Unknown domain #{name}", :red)
21
+ exit 1
22
+ end
23
+
24
+ domain
25
+ end
26
+
27
+ def find_user_by_email(name)
28
+ user_name, domain_name = user_and_domain_from_email(name)
29
+ domain = find_domain_by_name(domain_name)
30
+
31
+ User.new(domain, user_name)
32
+ end
33
+
34
+ def find_user_alias_by_email_and_name(email, name)
35
+ user = find_user_by_email(email)
36
+
37
+ UserAlias.new(user, name)
38
+ end
39
+
40
+ def find_domain_alias_by_domain_and_name(domain_name, name)
41
+ domain = find_domain_by_name(domain_name)
42
+
43
+ DomainAlias.new(domain, name)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,44 @@
1
+ module PostyClient
2
+ module Command
3
+ class TransportCommand < Thor
4
+ desc "list", "list all transports"
5
+ def list
6
+ transports = PostyClient::Resources::Transport.all.map {|d| [d.name]}
7
+ print_table(transports)
8
+ end
9
+
10
+ desc "add [DOMAIN] [DESTINATION]", "add a transport"
11
+ def add(name, destination)
12
+ transport = PostyClient::Resources::Transport.new(name)
13
+ transport.attributes['destination'] = destination
14
+
15
+ unless transport.save
16
+ say transport.errors.inspect, :red
17
+ exit 1
18
+ end
19
+ end
20
+
21
+ desc "rename [DOMAIN] [NEW_DOMAIN]", "rename specified transport"
22
+ def rename(name, new_name)
23
+ transport = PostyClient::Resources::Transport.new(name)
24
+ transport.attributes['name'] = new_name
25
+
26
+ unless transport.save
27
+ say transport.errors.inspect, :red
28
+ exit 1
29
+ end
30
+ end
31
+
32
+ desc "delete [DOMAIN]", "delete a specified transport"
33
+ def delete(name)
34
+ if yes?("Delete #{name}?")
35
+ transport = PostyClient::Resources::Transport.new(name)
36
+ unless transport.delete
37
+ say transport.errors.inspect, :red
38
+ exit 1
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ require 'posty_client/command/finder_concerns'
2
+
3
+ module PostyClient
4
+ module Command
5
+ class UserAliasCommand < Thor
6
+ include PostyClient::Resources
7
+ include PostyClient::Command::FinderConcerns
8
+
9
+ desc "list [USER]@[DOMAIN]", "list all user aliases of given user"
10
+ def list(name)
11
+ user = find_user_by_email(name)
12
+ users = user.aliases
13
+ puts users.map(&:name)
14
+ end
15
+
16
+ desc "add [USER]@[DOMAIN] [USER_ALIAS]", "add a user alias"
17
+ def add(email, alias_name)
18
+ user = find_user_by_email(email)
19
+
20
+ ali = UserAlias.new(user, alias_name)
21
+
22
+ unless ali.save
23
+ say("#{alias_name} save failed: #{ali.errors}", :red)
24
+ exit 1
25
+ end
26
+ end
27
+
28
+ desc "delete [ALIAS]@[DOMAIN] [USER_ALIAS]", "delete the specified user alias"
29
+ def delete(email, alias_name)
30
+ ali = find_user_alias_by_email_and_name(email, alias_name)
31
+
32
+ if ali.new_resource?
33
+ say("#{alias_name} unknown", :red)
34
+ exit 1
35
+ end
36
+
37
+ unless ali.delete
38
+ say("#{alias_name} delete failed: #{ali.errors}", :red)
39
+ exit 1
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,61 @@
1
+ require 'posty_client/command/finder_concerns'
2
+
3
+ module PostyClient
4
+ module Command
5
+ class UserCommand < Thor
6
+ include PostyClient::Resources
7
+ include PostyClient::Command::FinderConcerns
8
+
9
+ desc "list [DOMAIN]", "list all users of given domain"
10
+ def list(domain)
11
+ domain = Domain.new(domain)
12
+ users = domain.users
13
+ puts users.map(&:name)
14
+ end
15
+
16
+ desc "add [USER]@[DOMAIN]", "add a user"
17
+ def add(name)
18
+ user = find_user_by_email(name)
19
+
20
+ password = ask('Password?')
21
+ unless password.blank?
22
+ user.attributes['password'] = password
23
+ end
24
+
25
+ unless user.save
26
+ say("#{name} save failed: #{user.errors}", :red)
27
+ exit 1
28
+ end
29
+ end
30
+
31
+ desc "rename [USER]@[DOMAIN] [NEW_USER]", "rename a specified user"
32
+ def rename(name, new_name)
33
+ user = find_user_by_email(name)
34
+ if user.new_resource?
35
+ say("#{name} unknown", :red)
36
+ exit 1
37
+ end
38
+
39
+ user.attributes['name'] = new_name
40
+ unless user.save
41
+ say("#{name} save failed: #{user.errors}", :red)
42
+ exit 1
43
+ end
44
+ end
45
+
46
+ desc "delete [USER]@[DOMAIN]", "delete a specified user from the given domain"
47
+ def delete(name)
48
+ user = find_user_by_email(name)
49
+ if user.new_resource?
50
+ say("#{name} unknown", :red)
51
+ exit 1
52
+ end
53
+
54
+ unless user.delete
55
+ say("#{name} delete failed: #{user.errors}", :red)
56
+ exit 1
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,47 @@
1
+ module PostyClient
2
+ module Resources
3
+ class ApiKey < Base
4
+
5
+ attr_reader :access_token
6
+
7
+ self.primary_key = 'access_token'
8
+
9
+ def self.all
10
+ response = RestClient.get([base_uri, resource_name].join('/'))
11
+
12
+ return nil unless response.code == 200
13
+
14
+ data = JSON.parse(response)
15
+
16
+ data.collect do |datum|
17
+ model = self.new
18
+ model.attributes = datum.flatten.last
19
+ model.new_resource = false
20
+
21
+ model
22
+ end
23
+ end
24
+
25
+ def initialize(name=nil)
26
+ @name = name
27
+ load if name
28
+ end
29
+
30
+ def expired?
31
+ attributes['expires_at'].to_time <= DateTime.now
32
+ end
33
+
34
+ def active?
35
+ attributes['active']
36
+ end
37
+
38
+ def slug
39
+ [resource_slug, name].join('/')
40
+ end
41
+
42
+ def resource_slug
43
+ [base_uri, 'api_keys'].join('/')
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,140 @@
1
+ require 'uri'
2
+
3
+ module PostyClient
4
+ module Resources
5
+ class Base
6
+ cattr_accessor :logger do
7
+ PostyClient.logger
8
+ end
9
+
10
+ cattr_accessor :rejected_attributes do
11
+ [:id, :virtual_domain_id, :created_at, :updated_at, :password]
12
+ end
13
+
14
+ cattr_accessor :base_uri do
15
+ URI.join(Settings.api_url, Settings.api_version)
16
+ end
17
+
18
+ class_attribute :primary_key
19
+ self.primary_key = 'name'
20
+
21
+ attr_reader :name
22
+ attr_reader :attributes
23
+ attr_reader :errors
24
+
25
+ attr_accessor :new_resource
26
+
27
+ def new_resource?
28
+ @new_resource
29
+ end
30
+
31
+ def attributes=(attributes)
32
+ @attributes = attributes.reject {|k,v| rejected_attributes.include?(k.to_sym)} # we only want the value
33
+ @name ||= @attributes[primary_key]
34
+ @attributes
35
+ end
36
+
37
+ def load
38
+ @new_resource = true
39
+ @attributes = {}
40
+
41
+ response = begin
42
+ RestClient.get(slug)
43
+ rescue RestClient::Exception => e
44
+ e.response
45
+ end
46
+
47
+ if response.code == 404
48
+ logger.debug("#{self.class.name} :: load non existing object (#{response.code}) '#{response}'")
49
+ return
50
+ elsif response.code != 200
51
+ logger.error("#{self.class.name} :: load failed with (#{response.code}) '#{response}'")
52
+ return
53
+ end
54
+
55
+ @new_resource = false
56
+ self.attributes = JSON.parse(response).flatten.last
57
+
58
+ @name = attributes[primary_key]
59
+
60
+ self
61
+ end
62
+
63
+ def save
64
+ if new_resource?
65
+ self.attributes[primary_key] = @name
66
+ if create
67
+ @new_resource = false
68
+ return true
69
+ end
70
+ else
71
+ if update
72
+ load
73
+ return true
74
+ end
75
+ end
76
+
77
+ return false
78
+ end
79
+
80
+ def update
81
+ logger.debug("update #{self.class.name} : #{name}")
82
+ request_with_error_handling do
83
+ RestClient.put(slug, attributes)
84
+ end
85
+ end
86
+
87
+ def create
88
+ logger.debug("create #{self.class.name} : #{name}")
89
+ request_with_error_handling do
90
+ RestClient.post(resource_slug, attributes, :content_type => :json, :accept => :json)
91
+ end
92
+ end
93
+
94
+ def delete
95
+ logger.debug("delete #{self.class.name} : #{name}")
96
+ request_with_error_handling do
97
+ RestClient.delete(slug)
98
+ end
99
+ end
100
+
101
+ def request_with_error_handling(&block)
102
+ response = begin
103
+ block.call
104
+ rescue RestClient::Exception => e
105
+ e.response
106
+ end
107
+
108
+ case response.code
109
+ when 200..299
110
+ true
111
+ else
112
+ @errors = begin
113
+ JSON.parse(response)['error']
114
+ rescue => e
115
+ logger.error(e)
116
+ {'base' => "Unrecoverable error: #{response.code} (#{response})"}
117
+ end
118
+
119
+ false
120
+ end
121
+ end
122
+
123
+ def self.resource_name
124
+ self.name.demodulize.tableize
125
+ end
126
+
127
+ def resource_name
128
+ self.class.resource_name
129
+ end
130
+
131
+ def resource_slug
132
+ raise NotImplementedError
133
+ end
134
+
135
+ def slug
136
+ raise NotImplementedError
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,43 @@
1
+ module PostyClient
2
+ module Resources
3
+ class Domain < Base
4
+
5
+ def self.all
6
+ response = RestClient.get([base_uri, resource_name].join('/'))
7
+
8
+ return nil unless response.code == 200
9
+
10
+ data = JSON.parse(response)
11
+
12
+ data.collect do |datum|
13
+ model = self.new
14
+ model.attributes = datum.flatten.last
15
+ model.new_resource = false
16
+
17
+ model
18
+ end
19
+ end
20
+
21
+ def initialize(name=nil)
22
+ @name = name
23
+ load if name
24
+ end
25
+
26
+ def users
27
+ User.find_all_by_domain(self)
28
+ end
29
+
30
+ def aliases
31
+ DomainAlias.find_all_by_domain(self)
32
+ end
33
+
34
+ def slug
35
+ [resource_slug, name].join('/')
36
+ end
37
+
38
+ def resource_slug
39
+ [base_uri, 'domains'].join('/')
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,29 @@
1
+ require_relative 'finder_concern'
2
+
3
+ module PostyClient
4
+ module Resources
5
+ class DomainAlias < Base
6
+ extend FinderConcern
7
+
8
+ attr_reader :domain
9
+
10
+ def initialize(domain, name=nil)
11
+ @domain = domain
12
+ @name = name
13
+ load if name
14
+ end
15
+
16
+ def slug
17
+ [resource_slug, name].join('/')
18
+ end
19
+
20
+ def resource_slug
21
+ [domain.slug, 'aliases'].join('/')
22
+ end
23
+
24
+ def self.resource_name
25
+ :aliases
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,49 @@
1
+ module PostyClient
2
+ module Resources
3
+ module FinderConcern
4
+ def find_all_by_domain(domain)
5
+ response = RestClient.get([domain.slug, resource_name].join('/'))
6
+
7
+ if response.code == 404
8
+ logger.debug("#{self.class.name} :: load non existing object (#{response.code}) '#{response}'")
9
+ return []
10
+ elsif response.code != 200
11
+ logger.error("#{self.class.name} :: load failed with (#{response.code}) '#{response}'")
12
+ return nil
13
+ end
14
+
15
+ data = JSON.parse(response)
16
+
17
+ data.collect do |datum|
18
+ model = self.new(domain)
19
+ model.attributes = datum.flatten.last
20
+ model.new_resource = false
21
+
22
+ model
23
+ end
24
+ end
25
+
26
+ def find_all_by_user(user)
27
+ response = RestClient.get([user.slug, resource_name].join('/'))
28
+
29
+ if response.code == 404
30
+ logger.debug("#{self.class.name} :: load non existing object (#{response.code}) '#{response}'")
31
+ return []
32
+ elsif response.code != 200
33
+ logger.error("#{self.class.name} :: load failed with (#{response.code}) '#{response}'")
34
+ return nil
35
+ end
36
+
37
+ data = JSON.parse(response)
38
+
39
+ data.collect do |datum|
40
+ model = self.new(user)
41
+ model.attributes = datum.flatten.last
42
+ model.new_resource = false
43
+
44
+ model
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,15 @@
1
+ module PostyClient
2
+ module Resources
3
+ class Summary < Base
4
+ def self.get
5
+ response = RestClient.get([base_uri, resource_name].join('/'))
6
+
7
+ data = JSON.parse(response)
8
+ end
9
+
10
+ def self.resource_name
11
+ :summary
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ module PostyClient
2
+ module Resources
3
+ class Transport < Base
4
+
5
+ def self.all
6
+ response = RestClient.get([base_uri, resource_name].join('/'))
7
+
8
+ return nil unless response.code == 200
9
+
10
+ data = JSON.parse(response)
11
+
12
+ data.collect do |datum|
13
+ model = self.new
14
+ model.attributes = datum.flatten.last
15
+ model.new_resource = false
16
+
17
+ model
18
+ end
19
+ end
20
+
21
+ def initialize(name=nil)
22
+ @name = name
23
+ load if name
24
+ end
25
+
26
+ def slug
27
+ [resource_slug, name].join('/')
28
+ end
29
+
30
+ def resource_slug
31
+ [base_uri, 'transports'].join('/')
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,29 @@
1
+ require_relative 'finder_concern'
2
+
3
+ module PostyClient
4
+ module Resources
5
+ class User < Base
6
+ extend FinderConcern
7
+
8
+ attr_reader :domain
9
+
10
+ def initialize(domain, name=nil)
11
+ @name = name
12
+ @domain = domain
13
+ load if name
14
+ end
15
+
16
+ def aliases
17
+ UserAlias.find_all_by_user(self)
18
+ end
19
+
20
+ def slug
21
+ [resource_slug, name].join('/')
22
+ end
23
+
24
+ def resource_slug
25
+ [domain.slug, 'users'].join('/')
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ require_relative 'finder_concern'
2
+
3
+ module PostyClient
4
+ module Resources
5
+ class UserAlias < Base
6
+ extend FinderConcern
7
+
8
+ attr_reader :user
9
+
10
+ def initialize(user, name=nil)
11
+ @user = user
12
+ @name = name
13
+ load if name
14
+ end
15
+
16
+ def slug
17
+ [resource_slug, name].join('/')
18
+ end
19
+
20
+ def resource_slug
21
+ [user.slug, 'aliases'].join('/')
22
+ end
23
+
24
+ def self.resource_name
25
+ :aliases
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+ module PostyClient
2
+ class Settings < ReadWriteSettings
3
+ source PostyClient.settings_file
4
+ namespace PostyClient.env
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module PostyClient
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'posty_client/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "posty_client"
8
+ spec.version = PostyClient::VERSION
9
+ spec.authors = ["Thomas Steinhausen"]
10
+ spec.email = ["ts@image-addicts.de"]
11
+ spec.description = %q{A library and a command line tool to use the post api.}
12
+ spec.summary = %q{Library and cli for the post api.}
13
+ spec.homepage = "https://github.com/iaddict/posty_client"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_runtime_dependency "thor"
25
+ spec.add_runtime_dependency "json"
26
+ spec.add_runtime_dependency "rest-client"
27
+ spec.add_runtime_dependency "readwritesettings"
28
+ spec.add_runtime_dependency "activesupport"
29
+ end
metadata ADDED
@@ -0,0 +1,193 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: posty_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Thomas Steinhausen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: thor
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: json
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rest-client
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: readwritesettings
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: activesupport
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: A library and a command line tool to use the post api.
127
+ email:
128
+ - ts@image-addicts.de
129
+ executables:
130
+ - posty-client
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - .gitignore
135
+ - Gemfile
136
+ - LICENSE.txt
137
+ - README.md
138
+ - Rakefile
139
+ - bin/posty-client
140
+ - config/posty_client.yml.dist
141
+ - lib/posty_client.rb
142
+ - lib/posty_client/cli.rb
143
+ - lib/posty_client/command/api_key_command.rb
144
+ - lib/posty_client/command/domain_alias_command.rb
145
+ - lib/posty_client/command/domain_command.rb
146
+ - lib/posty_client/command/finder_concerns.rb
147
+ - lib/posty_client/command/transport_command.rb
148
+ - lib/posty_client/command/user_alias_command.rb
149
+ - lib/posty_client/command/user_command.rb
150
+ - lib/posty_client/resources/api_key.rb
151
+ - lib/posty_client/resources/base.rb
152
+ - lib/posty_client/resources/domain.rb
153
+ - lib/posty_client/resources/domain_alias.rb
154
+ - lib/posty_client/resources/finder_concern.rb
155
+ - lib/posty_client/resources/summary.rb
156
+ - lib/posty_client/resources/transport.rb
157
+ - lib/posty_client/resources/user.rb
158
+ - lib/posty_client/resources/user_alias.rb
159
+ - lib/posty_client/settings.rb
160
+ - lib/posty_client/version.rb
161
+ - posty_client.gemspec
162
+ homepage: https://github.com/iaddict/posty_client
163
+ licenses:
164
+ - MIT
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ none: false
171
+ requirements:
172
+ - - ! '>='
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ segments:
176
+ - 0
177
+ hash: 3693208534755418150
178
+ required_rubygems_version: !ruby/object:Gem::Requirement
179
+ none: false
180
+ requirements:
181
+ - - ! '>='
182
+ - !ruby/object:Gem::Version
183
+ version: '0'
184
+ segments:
185
+ - 0
186
+ hash: 3693208534755418150
187
+ requirements: []
188
+ rubyforge_project:
189
+ rubygems_version: 1.8.24
190
+ signing_key:
191
+ specification_version: 3
192
+ summary: Library and cli for the post api.
193
+ test_files: []