moogle 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +35 -0
- data/Gemfile.lock +148 -0
- data/LICENSE.txt +202 -0
- data/NOTICE.txt +4 -0
- data/README.md +33 -0
- data/Rakefile +44 -0
- data/fixtures/vcr_cassettes/push_blog_entry.yml +48 -0
- data/fixtures/vcr_cassettes/push_webhook_ping.yml +41 -0
- data/lib/moogle/commands/create_link.rb +45 -0
- data/lib/moogle/commands/create_target.rb +46 -0
- data/lib/moogle/commands/destroy_link.rb +37 -0
- data/lib/moogle/commands/destroy_target.rb +37 -0
- data/lib/moogle/commands/find_targets.rb +31 -0
- data/lib/moogle/commands/push_blog_entry.rb +54 -0
- data/lib/moogle/commands/push_email.rb +60 -0
- data/lib/moogle/commands/push_webhook_ping.rb +58 -0
- data/lib/moogle/commands/update_target.rb +44 -0
- data/lib/moogle/commands.rb +9 -0
- data/lib/moogle/error.rb +6 -0
- data/lib/moogle/events/blog_entry_pushed.rb +34 -0
- data/lib/moogle/events/email_pushed.rb +36 -0
- data/lib/moogle/events/error.rb +24 -0
- data/lib/moogle/events/link_created.rb +21 -0
- data/lib/moogle/events/link_destroyed.rb +21 -0
- data/lib/moogle/events/target_created.rb +21 -0
- data/lib/moogle/events/target_destroyed.rb +21 -0
- data/lib/moogle/events/target_updated.rb +21 -0
- data/lib/moogle/events/webhook_ping_pushed.rb +34 -0
- data/lib/moogle/handlers/accept_notification.rb +96 -0
- data/lib/moogle/messages/notification.rb +34 -0
- data/lib/moogle/models/blog_target.rb +29 -0
- data/lib/moogle/models/email_target.rb +16 -0
- data/lib/moogle/models/facebook_target.rb +14 -0
- data/lib/moogle/models/link.rb +20 -0
- data/lib/moogle/models/post_log.rb +21 -0
- data/lib/moogle/models/target.rb +22 -0
- data/lib/moogle/models/twitter_target.rb +14 -0
- data/lib/moogle/models/webhook_target.rb +18 -0
- data/lib/moogle/models.rb +9 -0
- data/lib/moogle/representers/link_representer.rb +23 -0
- data/lib/moogle/representers/target_representer.rb +34 -0
- data/lib/moogle/requests/create_link.rb +24 -0
- data/lib/moogle/requests/create_target.rb +40 -0
- data/lib/moogle/requests/destroy_link.rb +22 -0
- data/lib/moogle/requests/destroy_target.rb +22 -0
- data/lib/moogle/requests/find_targets.rb +21 -0
- data/lib/moogle/requests/push_blog_entry.rb +67 -0
- data/lib/moogle/requests/push_email.rb +46 -0
- data/lib/moogle/requests/push_webhook_ping.rb +49 -0
- data/lib/moogle/requests/update_target.rb +22 -0
- data/lib/moogle/requests.rb +6 -0
- data/lib/moogle/version.rb +11 -0
- data/lib/moogle.rb +5 -0
- data/moogle.gemspec +160 -0
- data/spec/commands/find_targets_spec.rb +32 -0
- data/spec/commands/links_spec.rb +92 -0
- data/spec/commands/push_blog_entry_spec.rb +33 -0
- data/spec/commands/push_email_spec.rb +44 -0
- data/spec/commands/push_webhook_ping_spec.rb +30 -0
- data/spec/commands/targets_spec.rb +165 -0
- data/spec/handlers/accept_notification_spec.rb +55 -0
- data/spec/moogle_spec.rb +1 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/dependencies.rb +10 -0
- data/spec/support/vcr.rb +6 -0
- metadata +326 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'aequitas'
|
2
|
+
require 'serf/message'
|
3
|
+
require 'serf/more/uuid_fields'
|
4
|
+
require 'virtus'
|
5
|
+
|
6
|
+
module Moogle
|
7
|
+
module Messages
|
8
|
+
|
9
|
+
class Notification
|
10
|
+
include Virtus
|
11
|
+
include Aequitas
|
12
|
+
include Serf::Message
|
13
|
+
include Serf::More::UuidFields
|
14
|
+
|
15
|
+
# Targets
|
16
|
+
attribute :receiver_refs, Array[String], default: []
|
17
|
+
attribute :message_kind, String
|
18
|
+
|
19
|
+
# Email
|
20
|
+
attribute :subject, String
|
21
|
+
attribute :text_body, String
|
22
|
+
attribute :html_body, String
|
23
|
+
attribute :html_content_type, String, default: 'text/html; charset=UTF-8'
|
24
|
+
attribute :categories, Array[String], default: []
|
25
|
+
|
26
|
+
# Tweet
|
27
|
+
attribute :short_body, String
|
28
|
+
|
29
|
+
# Webhook
|
30
|
+
attribute :data, String
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'active_support/core_ext/object/blank'
|
2
|
+
require 'addressable/uri'
|
3
|
+
require 'moogle/models/target'
|
4
|
+
|
5
|
+
module Moogle
|
6
|
+
|
7
|
+
class BlogTarget < Target
|
8
|
+
|
9
|
+
validates_with_method :options, method: :validate_options
|
10
|
+
|
11
|
+
def validate_options
|
12
|
+
uri = Addressable::URI.parse options['rpc_uri']
|
13
|
+
return false, 'options rpc_uri not set' if uri.nil?
|
14
|
+
return false, 'options rpc_uri must be absolute URI' if uri.relative?
|
15
|
+
|
16
|
+
uri = Addressable::URI.parse options['blog_uri']
|
17
|
+
return false, 'options blog_uri not set' if uri.nil?
|
18
|
+
return false, 'options blog_uri must be absolute URI' if uri.relative?
|
19
|
+
|
20
|
+
return false, 'options blog_id is blank' if options['blog_id'].blank?
|
21
|
+
return false, 'options username is blank' if options['username'].blank?
|
22
|
+
return false, 'options password is blank' if options['password'].blank?
|
23
|
+
return false, 'options publish_immediately is blank' if(
|
24
|
+
options['publish_immediately'].blank?)
|
25
|
+
return true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'moogle/models/target'
|
2
|
+
|
3
|
+
module Moogle
|
4
|
+
|
5
|
+
class EmailTarget < Moogle::Target
|
6
|
+
|
7
|
+
validates_with_method :options, method: :validate_options
|
8
|
+
|
9
|
+
def validate_options
|
10
|
+
return false, 'options "to" is blank' if options['to'].blank?
|
11
|
+
return false, 'options "from" is blank' if options['from'].blank?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'data_mapper'
|
2
|
+
|
3
|
+
module Moogle
|
4
|
+
|
5
|
+
class Link
|
6
|
+
include DataMapper::Resource
|
7
|
+
|
8
|
+
def self.default_repository_name
|
9
|
+
:moogle_db
|
10
|
+
end
|
11
|
+
|
12
|
+
property :id, Serial
|
13
|
+
property :receiver_ref, String, length: 255
|
14
|
+
property :message_kind, String, length: 255
|
15
|
+
timestamps :at
|
16
|
+
|
17
|
+
belongs_to :target
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'data_mapper'
|
2
|
+
|
3
|
+
module Moogle
|
4
|
+
|
5
|
+
class PostLog
|
6
|
+
include DataMapper::Resource
|
7
|
+
|
8
|
+
def self.default_repository_name
|
9
|
+
:moogle_db
|
10
|
+
end
|
11
|
+
|
12
|
+
property :id, Serial
|
13
|
+
property :message_kind, String, length: 255
|
14
|
+
property :message_ref, String, length: 255
|
15
|
+
property :post_ref, String, length: 255
|
16
|
+
timestamps :at
|
17
|
+
|
18
|
+
belongs_to :target
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'data_mapper'
|
2
|
+
|
3
|
+
module Moogle
|
4
|
+
|
5
|
+
class Target
|
6
|
+
include DataMapper::Resource
|
7
|
+
|
8
|
+
def self.default_repository_name
|
9
|
+
:moogle_db
|
10
|
+
end
|
11
|
+
|
12
|
+
property :id, Serial
|
13
|
+
property :type, Discriminator
|
14
|
+
property :owner_ref, String, length: 255
|
15
|
+
property :options, Json, default: {}
|
16
|
+
timestamps :at
|
17
|
+
|
18
|
+
has n, :links
|
19
|
+
has n, :post_logs
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
require 'moogle/models/target'
|
3
|
+
|
4
|
+
module Moogle
|
5
|
+
|
6
|
+
class WebhookTarget < Target
|
7
|
+
|
8
|
+
validates_with_method :options, method: :validate_options
|
9
|
+
|
10
|
+
def validate_options
|
11
|
+
uri = Addressable::URI.parse options['webhook_uri']
|
12
|
+
return false, 'options webhook_uri not set' if uri.nil?
|
13
|
+
return false, 'options webhook_uri must be absolute URI' if uri.relative?
|
14
|
+
return true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'moogle/models/link'
|
2
|
+
require 'moogle/models/post_log'
|
3
|
+
require 'moogle/models/target'
|
4
|
+
|
5
|
+
require 'moogle/models/blog_target'
|
6
|
+
require 'moogle/models/email_target'
|
7
|
+
require 'moogle/models/facebook_target'
|
8
|
+
require 'moogle/models/twitter_target'
|
9
|
+
require 'moogle/models/webhook_target'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'roar/representer/json'
|
2
|
+
|
3
|
+
module Moogle
|
4
|
+
|
5
|
+
module LinkRepresenter
|
6
|
+
include Roar::Representer::JSON
|
7
|
+
|
8
|
+
property :kind
|
9
|
+
property :id
|
10
|
+
property :receiver_ref
|
11
|
+
property :message_kind
|
12
|
+
property :render_options
|
13
|
+
property :suspended
|
14
|
+
property :created_at
|
15
|
+
property :updated_at
|
16
|
+
|
17
|
+
def kind
|
18
|
+
'moogle/domain/link'
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
require 'roar/representer/json'
|
3
|
+
|
4
|
+
require 'moogle/representers/link_representer'
|
5
|
+
|
6
|
+
module Moogle
|
7
|
+
|
8
|
+
module TargetRepresenter
|
9
|
+
include Roar::Representer::JSON
|
10
|
+
|
11
|
+
property :kind
|
12
|
+
property :id
|
13
|
+
property :translated_type, from: :type
|
14
|
+
property :owner_ref
|
15
|
+
property :options
|
16
|
+
property :created_at
|
17
|
+
property :updated_at
|
18
|
+
|
19
|
+
collection(
|
20
|
+
:links,
|
21
|
+
extend: Moogle::LinkRepresenter)
|
22
|
+
|
23
|
+
def kind
|
24
|
+
'moogle/domain/target'
|
25
|
+
end
|
26
|
+
|
27
|
+
def translated_type
|
28
|
+
return $1.to_s.tableize if /^Moogle::(.+)Target$/ === self.type.to_s
|
29
|
+
return nil
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'aequitas'
|
2
|
+
require 'serf/message'
|
3
|
+
require 'serf/more/uuid_fields'
|
4
|
+
require 'virtus'
|
5
|
+
|
6
|
+
module Moogle
|
7
|
+
module Requests
|
8
|
+
|
9
|
+
class CreateLink
|
10
|
+
include Virtus
|
11
|
+
include Aequitas
|
12
|
+
include Serf::Message
|
13
|
+
include Serf::More::UuidFields
|
14
|
+
|
15
|
+
attribute :target_id, Integer
|
16
|
+
attribute :receiver_ref, String
|
17
|
+
attribute :message_kind, String
|
18
|
+
|
19
|
+
validates_presence_of :target_id, :receiver_ref, :message_kind
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'aequitas'
|
2
|
+
require 'serf/message'
|
3
|
+
require 'serf/more/uuid_fields'
|
4
|
+
require 'virtus'
|
5
|
+
|
6
|
+
module Moogle
|
7
|
+
module Requests
|
8
|
+
|
9
|
+
class CreateTarget
|
10
|
+
include Virtus
|
11
|
+
include Aequitas
|
12
|
+
include Serf::Message
|
13
|
+
include Serf::More::UuidFields
|
14
|
+
|
15
|
+
attribute :type, String
|
16
|
+
attribute :owner_ref, String
|
17
|
+
attribute :options, Hash, default: lambda { |obj,attr| Hash.new }
|
18
|
+
|
19
|
+
validates_with_method :type, method: :has_valid_type?
|
20
|
+
validates_presence_of :owner_ref
|
21
|
+
|
22
|
+
TYPES = [
|
23
|
+
'blog',
|
24
|
+
'email',
|
25
|
+
'facebook',
|
26
|
+
'twitter',
|
27
|
+
'webhook'
|
28
|
+
]
|
29
|
+
|
30
|
+
def has_valid_type?
|
31
|
+
if TYPES.include? type
|
32
|
+
return true, 'Valid'
|
33
|
+
else
|
34
|
+
return false, "'#{type}' is invalid type. Must be in #{TYPES}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'aequitas'
|
2
|
+
require 'serf/message'
|
3
|
+
require 'serf/more/uuid_fields'
|
4
|
+
require 'virtus'
|
5
|
+
|
6
|
+
module Moogle
|
7
|
+
module Requests
|
8
|
+
|
9
|
+
class DestroyLink
|
10
|
+
include Virtus
|
11
|
+
include Aequitas
|
12
|
+
include Serf::Message
|
13
|
+
include Serf::More::UuidFields
|
14
|
+
|
15
|
+
attribute :link_id, Integer
|
16
|
+
|
17
|
+
validates_presence_of :link_id
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'aequitas'
|
2
|
+
require 'serf/message'
|
3
|
+
require 'serf/more/uuid_fields'
|
4
|
+
require 'virtus'
|
5
|
+
|
6
|
+
module Moogle
|
7
|
+
module Requests
|
8
|
+
|
9
|
+
class DestroyTarget
|
10
|
+
include Virtus
|
11
|
+
include Aequitas
|
12
|
+
include Serf::Message
|
13
|
+
include Serf::More::UuidFields
|
14
|
+
|
15
|
+
attribute :target_id, Integer
|
16
|
+
|
17
|
+
validates_presence_of :target_id
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'aequitas'
|
2
|
+
require 'serf/message'
|
3
|
+
require 'serf/more/uuid_fields'
|
4
|
+
require 'virtus'
|
5
|
+
|
6
|
+
module Moogle
|
7
|
+
module Requests
|
8
|
+
|
9
|
+
class FindTargets
|
10
|
+
include Virtus
|
11
|
+
include Aequitas
|
12
|
+
include Serf::Message
|
13
|
+
include Serf::More::UuidFields
|
14
|
+
|
15
|
+
attribute :owner_ref, String
|
16
|
+
|
17
|
+
validates_presence_of :owner_ref
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
require 'aequitas'
|
3
|
+
require 'serf/message'
|
4
|
+
require 'serf/more/uuid_fields'
|
5
|
+
require 'virtus'
|
6
|
+
|
7
|
+
module Moogle
|
8
|
+
module Requests
|
9
|
+
|
10
|
+
##
|
11
|
+
# A request to create a blog entry at a target blog supporting
|
12
|
+
# the 'metaWeblog.newPost' api.
|
13
|
+
class PushBlogEntry
|
14
|
+
include Virtus
|
15
|
+
include Aequitas
|
16
|
+
include Serf::Message
|
17
|
+
include Serf::More::UuidFields
|
18
|
+
|
19
|
+
##
|
20
|
+
## House Keeping fields
|
21
|
+
##
|
22
|
+
|
23
|
+
attribute :target_id, Integer
|
24
|
+
attribute :message_origin, String
|
25
|
+
|
26
|
+
##
|
27
|
+
## Parameters that make up the BlogEntry.
|
28
|
+
##
|
29
|
+
|
30
|
+
attribute :subject, String
|
31
|
+
attribute :html_body, String
|
32
|
+
attribute :categories, Array[String], default: []
|
33
|
+
|
34
|
+
##
|
35
|
+
## Parameters used to post the BlogEntry.
|
36
|
+
##
|
37
|
+
|
38
|
+
# XML-RPC server rpc_uri.
|
39
|
+
# http://my_block.wordpress.com/xmlrpc.php'
|
40
|
+
attribute :rpc_uri, String
|
41
|
+
attribute :blog_id, String
|
42
|
+
# The username password authentication
|
43
|
+
attribute :username, String
|
44
|
+
attribute :password, String
|
45
|
+
# Display URI
|
46
|
+
attribute :blog_uri, String
|
47
|
+
# Publish Immediately
|
48
|
+
attribute :publish_immediately, Boolean
|
49
|
+
|
50
|
+
def host
|
51
|
+
uri = Addressable::URI.parse rpc_uri
|
52
|
+
return uri.host
|
53
|
+
end
|
54
|
+
|
55
|
+
def path
|
56
|
+
uri = Addressable::URI.parse rpc_uri
|
57
|
+
return uri.path
|
58
|
+
end
|
59
|
+
|
60
|
+
def port
|
61
|
+
uri = Addressable::URI.parse rpc_uri
|
62
|
+
return uri.port
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'aequitas'
|
2
|
+
require 'serf/message'
|
3
|
+
require 'serf/more/uuid_fields'
|
4
|
+
require 'virtus'
|
5
|
+
|
6
|
+
module Moogle
|
7
|
+
module Requests
|
8
|
+
|
9
|
+
##
|
10
|
+
# Request to email a message to a recipient
|
11
|
+
#
|
12
|
+
class PushEmail
|
13
|
+
include Virtus
|
14
|
+
include Aequitas
|
15
|
+
include Serf::Message
|
16
|
+
include Serf::More::UuidFields
|
17
|
+
|
18
|
+
##
|
19
|
+
## House Keeping fields
|
20
|
+
##
|
21
|
+
|
22
|
+
attribute :target_id, Integer
|
23
|
+
attribute :message_origin, String
|
24
|
+
|
25
|
+
##
|
26
|
+
## Parameters that make up the BlogEntry.
|
27
|
+
##
|
28
|
+
|
29
|
+
attribute :subject, String
|
30
|
+
attribute :text_body, String
|
31
|
+
attribute :html_body, String
|
32
|
+
attribute :html_content_type, String, default: 'text/html; charset=UTF-8'
|
33
|
+
attribute :categories, Array[String], default: []
|
34
|
+
|
35
|
+
##
|
36
|
+
## Parameters used to send the email.
|
37
|
+
##
|
38
|
+
|
39
|
+
attribute :to, String
|
40
|
+
attribute :from, String
|
41
|
+
|
42
|
+
validates_presence_of :to, :from, :subject, :text_body
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
require 'aequitas'
|
3
|
+
require 'serf/message'
|
4
|
+
require 'serf/more/uuid_fields'
|
5
|
+
require 'virtus'
|
6
|
+
|
7
|
+
module Moogle
|
8
|
+
module Requests
|
9
|
+
|
10
|
+
##
|
11
|
+
# A request to send a webhook post.
|
12
|
+
class PushWebhookPing
|
13
|
+
include Virtus
|
14
|
+
include Aequitas
|
15
|
+
include Serf::Message
|
16
|
+
include Serf::More::UuidFields
|
17
|
+
|
18
|
+
##
|
19
|
+
## House Keeping fields
|
20
|
+
##
|
21
|
+
|
22
|
+
attribute :target_id, Integer
|
23
|
+
attribute :message_origin, String
|
24
|
+
|
25
|
+
##
|
26
|
+
## Set by Kind Specific Renderer
|
27
|
+
##
|
28
|
+
|
29
|
+
attribute :data, String
|
30
|
+
|
31
|
+
##
|
32
|
+
## Set by Target's Options
|
33
|
+
##
|
34
|
+
|
35
|
+
attribute :webhook_uri, String
|
36
|
+
attribute :secret, String
|
37
|
+
|
38
|
+
validates_with_method :valid_webhook_uri?
|
39
|
+
|
40
|
+
def valid_webhook_uri?
|
41
|
+
uri = Addressable::URI.parse webhook_uri
|
42
|
+
return false, "webhook_uri not set" if uri.nil?
|
43
|
+
return false, "webhook_uri must be an absolute URI" if uri.relative?
|
44
|
+
return true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'aequitas'
|
2
|
+
require 'serf/message'
|
3
|
+
require 'serf/more/uuid_fields'
|
4
|
+
require 'virtus'
|
5
|
+
|
6
|
+
module Moogle
|
7
|
+
module Requests
|
8
|
+
|
9
|
+
class UpdateTarget
|
10
|
+
include Virtus
|
11
|
+
include Aequitas
|
12
|
+
include Serf::Message
|
13
|
+
include Serf::More::UuidFields
|
14
|
+
|
15
|
+
attribute :target_id, String
|
16
|
+
attribute :options, Hash, default: lambda { |obj,attr| Hash.new }
|
17
|
+
|
18
|
+
validates_presence_of :target_id
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|