distribution_wrappers 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +102 -0
- data/Gemfile.lock +295 -0
- data/README.md +22 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/distribution_wrappers.gemspec +173 -0
- data/lib/config/key_chain.yml +70 -0
- data/lib/config/key_chain_dev.yml +71 -0
- data/lib/distribution_wrappers.rb +64 -0
- data/lib/distribution_wrappers/_base.rb +68 -0
- data/lib/distribution_wrappers/backstitch/backstitch.rb +267 -0
- data/lib/distribution_wrappers/email/_email.rb +48 -0
- data/lib/distribution_wrappers/email/template.html.haml +29 -0
- data/lib/distribution_wrappers/google/google.rb +129 -0
- data/lib/distribution_wrappers/hipchat/hipchat.rb +80 -0
- data/lib/distribution_wrappers/office365/office365.rb +51 -0
- data/lib/distribution_wrappers/sendgrid/sendgrid.rb +35 -0
- data/lib/distribution_wrappers/slack/slack.rb +87 -0
- data/lib/helpers/keys.rb +10 -0
- data/lib/helpers/text_helper.rb +9 -0
- data/lib/models/device_session_distro.rb +5 -0
- data/lib/models/distribution_channel_distro.rb +4 -0
- data/lib/models/feed_distro.rb +11 -0
- data/lib/models/organization_admin_distro.rb +5 -0
- data/lib/models/organization_distro.rb +10 -0
- data/lib/models/studio_post_version_contact_distro.rb +5 -0
- data/lib/models/studio_post_version_distro.rb +5 -0
- data/lib/models/team_distro.rb +13 -0
- data/lib/models/team_feed_distro.rb +5 -0
- data/lib/models/team_member_distro.rb +6 -0
- data/lib/models/topic_distro.rb +11 -0
- data/lib/models/topic_feed_distro.rb +5 -0
- data/lib/models/topic_subscription_distro.rb +9 -0
- data/lib/models/user_distro.rb +34 -0
- data/test/helper.rb +34 -0
- data/test/test_distribution_wrappers.rb +7 -0
- metadata +556 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
module DistributionWrappers
|
2
|
+
class HipChatWrapper < DistributionWrappers::Base
|
3
|
+
|
4
|
+
def send_message(recipient)
|
5
|
+
super
|
6
|
+
client = get_access(@auth[:key])
|
7
|
+
|
8
|
+
case recipient['contact_type']
|
9
|
+
when 'channel'
|
10
|
+
client[recipient['identifier']].send('backstitch', @message, :color => "purple", :message_format => "html")
|
11
|
+
when 'user'
|
12
|
+
client.user(recipient['identifier']).send(@message, :color => "purple", :message_format => "html")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_contacts
|
17
|
+
client = get_access(@auth[:key])
|
18
|
+
rooms = client.rooms
|
19
|
+
|
20
|
+
users = client.users
|
21
|
+
|
22
|
+
return nil if (rooms.nil? || rooms.length == 0) && (users.nil? || users.length == 0)
|
23
|
+
|
24
|
+
csv_sting = ""
|
25
|
+
|
26
|
+
# Loop through the channels just grabbing the names of them (that's all we need for the user)
|
27
|
+
rooms.each_with_index do |room, index|
|
28
|
+
csv_sting += CSV.generate_line [room.name, room.name, '{"url": null}', 'channel', @params[:channel_id]]
|
29
|
+
|
30
|
+
if index % 100 == 0
|
31
|
+
@params[:temp_file].write(csv_sting)
|
32
|
+
csv_sting = ""
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
@params[:temp_file].write(csv_sting)
|
37
|
+
|
38
|
+
csv_sting = ""
|
39
|
+
|
40
|
+
users.each_with_index do |user, index|
|
41
|
+
icon_url = user.photo_url ? user.photo_url : "null"
|
42
|
+
csv_sting += CSV.generate_line [user.name, user.user_id, "{\"url\": \"#{icon_url}\"}", 'user', @params[:channel_id]]
|
43
|
+
|
44
|
+
if index % 100 == 0
|
45
|
+
@params[:temp_file].write(csv_sting)
|
46
|
+
csv_sting = ""
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
@params[:temp_file].write(csv_sting)
|
51
|
+
|
52
|
+
return true
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def prepare(identifier=nil)
|
58
|
+
base_url = ""
|
59
|
+
if ENV['ENVIRONMENT'] == "development"
|
60
|
+
base_url = "http://localhost:3000"
|
61
|
+
else
|
62
|
+
base_url = "https://studio.backstit.ch"
|
63
|
+
end
|
64
|
+
|
65
|
+
params = "contact_id=#{@version_contact.id}&version_id=#{@version_contact.studio_post_version_id}&organization_id=#{@params[:organization_id]}"
|
66
|
+
|
67
|
+
body_text = "<a href='#{base_url}/posts/#{@params[:post].id}?#{params}'><strong>#{@params[:post].title}</strong></a>"
|
68
|
+
body_text += "<br><br>#{TextHelper.clean_text(@params[:post].draft_content)[0..280]}..."
|
69
|
+
body_text += "<br><br><a href='#{base_url}/posts/#{@params[:post].id}?#{params}'><img src='#{@params[:post].screenshot_url}'/></a>"
|
70
|
+
body_text += "<br><a href='#{base_url}/posts/#{@params[:post].id}?#{params}'><strong>Read More...</strong></a>"
|
71
|
+
|
72
|
+
return body_text
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_access(key)
|
76
|
+
client = HipChat::Client.new(key, :api_version => 'v2')
|
77
|
+
client
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module DistributionWrappers
|
2
|
+
class Office365 < DistributionWrappers::Email
|
3
|
+
|
4
|
+
def send_message(email)
|
5
|
+
super
|
6
|
+
key = @auth[:key]
|
7
|
+
recipients = []
|
8
|
+
|
9
|
+
# Office 365's API takes addresses in a specific way, so we have to build up an array
|
10
|
+
# of recipients before we hit their API
|
11
|
+
recipients << {'emailAddress' => {"address" => email['identifier']}}
|
12
|
+
|
13
|
+
message = {
|
14
|
+
'subject' => @params[:subject],
|
15
|
+
'body' => {
|
16
|
+
'contentType' => 'HTML',
|
17
|
+
'content' => @message
|
18
|
+
},
|
19
|
+
"toRecipients" => recipients,
|
20
|
+
"sender" => {
|
21
|
+
"emailAddress" => {
|
22
|
+
"address" => @params[:custom_opts]['send_from']
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
send_response = Curl.post('https://graph.microsoft.com/v1.0/me/sendMail', {"Message" => message}.to_json) do |http|
|
28
|
+
http.headers['Authorization'] = "Bearer #{key}"
|
29
|
+
http.headers['Content-Type'] = 'application/json'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_contacts
|
34
|
+
key = @auth[:key]
|
35
|
+
results = []
|
36
|
+
|
37
|
+
response = RestClient.get('https://graph.microsoft.com/v1.0/me/contacts', {"Authorization" => "Bearer #{key}"})
|
38
|
+
contacts = JSON.parse(response.body)
|
39
|
+
|
40
|
+
csv_string = ""
|
41
|
+
|
42
|
+
contacts['value'].each do |contact|
|
43
|
+
csv_string += CSV.generate_line [contact['displayName'], contact['emailAddresses'].first['address'], '{"url": null}', 'email', @params[:channel_id]]
|
44
|
+
end
|
45
|
+
|
46
|
+
@params[:temp_file].write(csv_string)
|
47
|
+
|
48
|
+
return true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module DistributionWrappers
|
2
|
+
class Sendgrid < DistributionWrappers::Email
|
3
|
+
include SendGrid
|
4
|
+
|
5
|
+
def send_message(recipient)
|
6
|
+
super
|
7
|
+
email = recipient['identifier']
|
8
|
+
metadata = {}
|
9
|
+
metadata["user_id"] = @params[:user].id if @params[:user]
|
10
|
+
|
11
|
+
### Send Sendgrid Email ###
|
12
|
+
|
13
|
+
# Build request
|
14
|
+
data = {"metadata" => metadata}
|
15
|
+
|
16
|
+
# Post to SendGrid
|
17
|
+
api_key = Keys.sendgrid.studio.api_key
|
18
|
+
client = SendGrid::API.new(:api_key => api_key)
|
19
|
+
|
20
|
+
send_from = {
|
21
|
+
:email => "#{@params[:custom_opts]['send_from']}@#{Keys.sendgrid.studio.send_from_domain}",
|
22
|
+
:name => @params[:user].display_name
|
23
|
+
}
|
24
|
+
|
25
|
+
from = SendGrid::Email.new(send_from)
|
26
|
+
subject = @params[:subject]
|
27
|
+
to = SendGrid::Email.new(email: email)
|
28
|
+
content = SendGrid::Content.new(type: 'text/html', value: @message)
|
29
|
+
mail = Mail.new(from, subject, to, content)
|
30
|
+
|
31
|
+
|
32
|
+
response = client.client.mail._('send').post(request_body: mail.to_json)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module DistributionWrappers
|
2
|
+
class SlackWrapper < DistributionWrappers::Base
|
3
|
+
|
4
|
+
def send_message(recipient)
|
5
|
+
super
|
6
|
+
client = get_access(@auth[:key])
|
7
|
+
|
8
|
+
client.chat_postMessage(channel: recipient['identifier'], attachments: [@message], as_user: true)
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_contacts
|
12
|
+
url = "https://slack.com/api/channels.list?token=#{@auth[:key]}"
|
13
|
+
channels = JSON.parse(RestClient.get(url))['channels']
|
14
|
+
|
15
|
+
url = "https://slack.com/api/users.list?token=#{@auth[:key]}"
|
16
|
+
members = JSON.parse(RestClient.get(url))["members"]
|
17
|
+
|
18
|
+
return nil if (channels.nil? || channels.length == 0) && (members.nil? || members.length == 0)
|
19
|
+
|
20
|
+
csv_sting = ""
|
21
|
+
|
22
|
+
# Loop through the channels just grabbing the names of them (that's all we need for the user)
|
23
|
+
channels.each_with_index do |channel, index|
|
24
|
+
csv_sting += CSV.generate_line [channel["name"], channel["name"], '{"url": null}', 'channel', @params[:channel_id]]
|
25
|
+
|
26
|
+
if index % 100 == 0
|
27
|
+
@params[:temp_file].write(csv_sting)
|
28
|
+
csv_sting = ""
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
@params[:temp_file].write(csv_sting)
|
33
|
+
|
34
|
+
csv_sting = ""
|
35
|
+
|
36
|
+
members.each_with_index do |member, index|
|
37
|
+
icon_url = member['profile']['image_192'] ? member['profile']['image_192'] : "null"
|
38
|
+
csv_sting += CSV.generate_line [member["real_name"], member["id"], "{\"url\": #{icon_url}}", 'user', @params[:channel_id]]
|
39
|
+
|
40
|
+
if index % 100 == 0
|
41
|
+
@params[:temp_file].write(csv_sting)
|
42
|
+
csv_sting = ""
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
@params[:temp_file].write(csv_sting)
|
47
|
+
|
48
|
+
return true
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def prepare(identifier=nil)
|
54
|
+
base_url = ""
|
55
|
+
if ENV['ENVIRONMENT'] == "development"
|
56
|
+
base_url = "http://localhost:3000"
|
57
|
+
else
|
58
|
+
base_url = "https://studio.backstit.ch"
|
59
|
+
end
|
60
|
+
|
61
|
+
params = "contact_id=#{@version_contact.id}&version_id=#{@version_contact.studio_post_version_id}&organization_id=#{@params[:organization].id}"
|
62
|
+
|
63
|
+
return {
|
64
|
+
title: @params[:post].title,
|
65
|
+
title_link: "#{base_url}/posts/#{@params[:post].id}?#{params}",
|
66
|
+
author_name: @params[:user].display_name,
|
67
|
+
color: @params[:organization].highlight_color,
|
68
|
+
fallback: @params[:post].title,
|
69
|
+
image_url: @params[:post].screenshot_url,
|
70
|
+
fields: [
|
71
|
+
{
|
72
|
+
value: "#{TextHelper.clean_text(@params[:post].draft_content)[0..280]}...",
|
73
|
+
short: false
|
74
|
+
}
|
75
|
+
]
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_access(key)
|
80
|
+
Slack.configure do |config|
|
81
|
+
config.token = key
|
82
|
+
end
|
83
|
+
|
84
|
+
return Slack::Web::Client.new
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/helpers/keys.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'settingslogic'
|
2
|
+
module DistributionWrappers
|
3
|
+
class Keys < Settingslogic
|
4
|
+
if ENV['RAILS_ENV'] == 'production'
|
5
|
+
source File.join(File.dirname(__FILE__), '..', 'config/key_chain.yml')
|
6
|
+
else
|
7
|
+
source File.join(File.dirname(__FILE__), '..', 'config/key_chain_dev.yml')
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class TextHelper
|
2
|
+
def self.clean_text(text)
|
3
|
+
clean_text = Sanitize.clean(text)
|
4
|
+
clean_text.gsub!("\n", " ")
|
5
|
+
clean_text.gsub!("\t", " ")
|
6
|
+
clean_text.gsub!(/((http|https|ftp|ftps):\/\/)?([a-zA-Z0-9\-]*\.)+[a-zA-Z0-9]{2,4}(\/[a-zA-Z0-9=.?&-]*)?/i, "")
|
7
|
+
return clean_text.strip.gsub("&", "&")
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class FeedDistro < ActiveRecord::Base
|
2
|
+
self.table_name = "feeds"
|
3
|
+
serialize :params, JSON
|
4
|
+
|
5
|
+
belongs_to :owner, polymorphic: true
|
6
|
+
|
7
|
+
has_many :team_feeds, :class_name => "TeamFeedDistro", :foreign_key => :feed_id
|
8
|
+
has_many :teams, :through => :team_feeds
|
9
|
+
|
10
|
+
has_many :topic_feeds, :class_name => "TopicFeedDistro", :foreign_key => :feed_id
|
11
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class OrganizationDistro < ActiveRecord::Base
|
2
|
+
self.table_name = 'organizations'
|
3
|
+
|
4
|
+
has_many :feeds, :as => :owner, :class_name => "FeedDistro"
|
5
|
+
has_many :topics, :as => :owner, :class_name => "TopicDistro"
|
6
|
+
|
7
|
+
has_many :teams, -> { order("is_primary DESC, name") }, :class_name => "TeamDistro", :foreign_key => :organization_id
|
8
|
+
has_many :team_members, :through => :teams
|
9
|
+
has_many :members, :through => :team_members
|
10
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class TeamDistro < ActiveRecord::Base
|
2
|
+
self.table_name = "teams"
|
3
|
+
belongs_to :organization, :class_name => "OrganizationDistro", :foreign_key => :organization_id
|
4
|
+
|
5
|
+
has_many :team_members, :class_name => "TeamMemberDistro", :foreign_key => :team_id
|
6
|
+
has_many :members, :through => :team_members
|
7
|
+
|
8
|
+
has_many :team_feeds, :class_name => "TeamFeedDistro", :foreign_key => :team_id
|
9
|
+
has_many :feeds, :through => :team_feeds
|
10
|
+
|
11
|
+
has_many :owned_feeds, :class_name => 'FeedDistro', :as => :owner
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
class TeamMemberDistro < ActiveRecord::Base
|
2
|
+
self.table_name = "team_members"
|
3
|
+
belongs_to :team, :class_name => "TeamDistro", :foreign_key => :team_id
|
4
|
+
delegate :organization, :to => :team
|
5
|
+
belongs_to :member, :class_name => "UserDistro", :foreign_key => :user_id
|
6
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class TopicDistro < ActiveRecord::Base
|
2
|
+
self.table_name = "topics"
|
3
|
+
serialize :icon, JSON
|
4
|
+
serialize :banner, JSON
|
5
|
+
serialize :serialized_alias, JSON
|
6
|
+
serialize :serialized_promoted_alias, JSON
|
7
|
+
|
8
|
+
belongs_to :owner, polymorphic: true
|
9
|
+
has_many :topic_feeds, :class_name => "TopicFeedDistro", :foreign_key => :topic_id
|
10
|
+
has_many :feeds, :through => :topic_feeds
|
11
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class TopicSubscriptionDistro < ActiveRecord::Base
|
2
|
+
self.table_name = "topic_subscriptions"
|
3
|
+
|
4
|
+
serialize :serialized_alias, JSON
|
5
|
+
serialize :serialized_promoted_alias, JSON
|
6
|
+
|
7
|
+
belongs_to :user, :foreign_key => "user_id", :class_name => "UserDistro"
|
8
|
+
belongs_to :topic, :foreign_key => "topic_id", :class_name => "TopicDistro"
|
9
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class UserDistro < ActiveRecord::Base
|
2
|
+
self.table_name = "users"
|
3
|
+
|
4
|
+
has_many :team_memberships, :foreign_key => "user_id", :class_name => "TeamMemberDistro"
|
5
|
+
has_many :teams, :through => :team_memberships
|
6
|
+
|
7
|
+
has_many :organizations, :through => :teams
|
8
|
+
|
9
|
+
has_many :organization_admins, :foreign_key => "user_id", :class_name => "OrganizationAdminDistro"
|
10
|
+
has_many :managed_organizations, :through => :organization_admins, :source => :organization
|
11
|
+
|
12
|
+
has_many :topic_subscriptions, :class_name => 'TopicSubscriptionDistro', :foreign_key => "user_id"
|
13
|
+
has_many :topics, :through => :topic_subscriptions
|
14
|
+
has_many :owned_topics, :class_name => 'TopicDistro', :as => :owner
|
15
|
+
|
16
|
+
def managed_feeds
|
17
|
+
self.managed_organizations
|
18
|
+
.select("team_feeds.id, feeds.id AS feed_id, teams.id AS team_id, organizations.id AS organization_id, feeds.name, organizations.highlight_color, team_feeds.feed_type")
|
19
|
+
.joins({:teams => {:team_feeds => :feed}}).where("team_feeds.feed_type = 'manual'").uniq
|
20
|
+
end
|
21
|
+
|
22
|
+
def avatar_url
|
23
|
+
avatar = ""
|
24
|
+
if self.avatar != nil
|
25
|
+
avatar = self.avatar
|
26
|
+
else
|
27
|
+
hash = Digest::MD5.hexdigest(self.email)
|
28
|
+
default = "https://images-backstitch.s3.amazonaws.com/next/logos/backstitch_purple_icon.png"
|
29
|
+
avatar = "https://www.gravatar.com/avatar/#{hash}?d=#{default}"
|
30
|
+
# "http://unicornify.appspot.com/avatar/#{hash}?s=128"
|
31
|
+
end
|
32
|
+
avatar
|
33
|
+
end
|
34
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
|
3
|
+
module SimpleCov::Configuration
|
4
|
+
def clean_filters
|
5
|
+
@filters = []
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
SimpleCov.configure do
|
10
|
+
clean_filters
|
11
|
+
load_adapter 'test_frameworks'
|
12
|
+
end
|
13
|
+
|
14
|
+
ENV["COVERAGE"] && SimpleCov.start do
|
15
|
+
add_filter "/.rvm/"
|
16
|
+
end
|
17
|
+
require 'rubygems'
|
18
|
+
require 'bundler'
|
19
|
+
begin
|
20
|
+
Bundler.setup(:default, :development)
|
21
|
+
rescue Bundler::BundlerError => e
|
22
|
+
$stderr.puts e.message
|
23
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
24
|
+
exit e.status_code
|
25
|
+
end
|
26
|
+
require 'test/unit'
|
27
|
+
require 'shoulda'
|
28
|
+
|
29
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
30
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
31
|
+
require 'distribution_wrappers'
|
32
|
+
|
33
|
+
class Test::Unit::TestCase
|
34
|
+
end
|