distribution_wrappers 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +102 -0
  3. data/Gemfile.lock +295 -0
  4. data/README.md +22 -0
  5. data/Rakefile +53 -0
  6. data/VERSION +1 -0
  7. data/distribution_wrappers.gemspec +173 -0
  8. data/lib/config/key_chain.yml +70 -0
  9. data/lib/config/key_chain_dev.yml +71 -0
  10. data/lib/distribution_wrappers.rb +64 -0
  11. data/lib/distribution_wrappers/_base.rb +68 -0
  12. data/lib/distribution_wrappers/backstitch/backstitch.rb +267 -0
  13. data/lib/distribution_wrappers/email/_email.rb +48 -0
  14. data/lib/distribution_wrappers/email/template.html.haml +29 -0
  15. data/lib/distribution_wrappers/google/google.rb +129 -0
  16. data/lib/distribution_wrappers/hipchat/hipchat.rb +80 -0
  17. data/lib/distribution_wrappers/office365/office365.rb +51 -0
  18. data/lib/distribution_wrappers/sendgrid/sendgrid.rb +35 -0
  19. data/lib/distribution_wrappers/slack/slack.rb +87 -0
  20. data/lib/helpers/keys.rb +10 -0
  21. data/lib/helpers/text_helper.rb +9 -0
  22. data/lib/models/device_session_distro.rb +5 -0
  23. data/lib/models/distribution_channel_distro.rb +4 -0
  24. data/lib/models/feed_distro.rb +11 -0
  25. data/lib/models/organization_admin_distro.rb +5 -0
  26. data/lib/models/organization_distro.rb +10 -0
  27. data/lib/models/studio_post_version_contact_distro.rb +5 -0
  28. data/lib/models/studio_post_version_distro.rb +5 -0
  29. data/lib/models/team_distro.rb +13 -0
  30. data/lib/models/team_feed_distro.rb +5 -0
  31. data/lib/models/team_member_distro.rb +6 -0
  32. data/lib/models/topic_distro.rb +11 -0
  33. data/lib/models/topic_feed_distro.rb +5 -0
  34. data/lib/models/topic_subscription_distro.rb +9 -0
  35. data/lib/models/user_distro.rb +34 -0
  36. data/test/helper.rb +34 -0
  37. data/test/test_distribution_wrappers.rb +7 -0
  38. 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
@@ -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("&amp;", "&")
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ class DeviceSessionDistro < ActiveRecord::Base
2
+ self.table_name = "device_sessions"
3
+
4
+ belongs_to :user, :class_name => "UserDistro", :foreign_key => :user_id
5
+ end
@@ -0,0 +1,4 @@
1
+ class DistributionChannelDistro < ActiveRecord::Base
2
+ self.table_name = 'distribution_channels'
3
+ belongs_to :owner, polymorphic: true
4
+ 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,5 @@
1
+ class OrganizationAdminDistro < ActiveRecord::Base
2
+ self.table_name = 'organization_admins'
3
+ belongs_to :organization, :class_name => "OrganizationDistro", :foreign_key => :organization_id
4
+ belongs_to :user, :class_name => "UserDistro", :foreign_key => :user_id
5
+ 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,5 @@
1
+ class PostVersionContactDistro < ActiveRecord::Base
2
+ self.table_name = "studio_post_version_contacts"
3
+
4
+ belongs_to :version, :foreign_key => "studio_post_version_id", :class_name => "PostVersionDistro"
5
+ end
@@ -0,0 +1,5 @@
1
+ class PostVersionDistro < ActiveRecord::Base
2
+ self.table_name = "studio_post_versions"
3
+
4
+ has_many :contacts, :foreign_key => 'studio_post_version_id', :class_name => "PostVersionContact"
5
+ 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,5 @@
1
+ class TeamFeedDistro < ActiveRecord::Base
2
+ self.table_name = 'team_feeds'
3
+ belongs_to :team, :class_name => "TeamDistro", :foreign_key => :team_id
4
+ belongs_to :feed, :class_name => "FeedDistro", :foreign_key => :feed_id
5
+ 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,5 @@
1
+ class TopicFeedDistro < ActiveRecord::Base
2
+ self.table_name = "topic_feeds"
3
+ belongs_to :topic, :class_name => "TopicDistro", :foreign_key => :topic_id
4
+ belongs_to :feed, :class_name => "FeedDistro", :foreign_key => :feed_id
5
+ 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
@@ -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