mingle 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/mingle/facebook.rb +13 -1
  3. data/app/models/mingle/facebook/post.rb +1 -34
  4. data/app/models/mingle/instagram.rb +12 -0
  5. data/app/models/mingle/instagram/photo.rb +1 -26
  6. data/app/models/mingle/twitter.rb +15 -2
  7. data/app/models/mingle/twitter/tweet.rb +1 -24
  8. data/db/migrate/20140403083806_add_url_to_mingle_twitter_tweets.rb +5 -0
  9. data/lib/generators/mingle/install/USAGE +9 -0
  10. data/lib/generators/mingle/install/install_generator.rb +7 -0
  11. data/lib/generators/mingle/install/templates/mingle_config.rb +8 -0
  12. data/lib/mingle.rb +16 -0
  13. data/lib/mingle/concerns.rb +3 -0
  14. data/lib/mingle/concerns/models.rb +5 -0
  15. data/lib/mingle/concerns/models/facebook.rb +3 -0
  16. data/lib/mingle/concerns/models/facebook/post.rb +40 -0
  17. data/lib/mingle/concerns/models/instagram.rb +3 -0
  18. data/lib/mingle/concerns/models/instagram/photo.rb +20 -0
  19. data/lib/mingle/concerns/models/twitter.rb +3 -0
  20. data/lib/mingle/concerns/models/twitter/tweet.rb +26 -0
  21. data/lib/mingle/configuration.rb +28 -5
  22. data/lib/mingle/engine.rb +4 -0
  23. data/lib/mingle/version.rb +1 -1
  24. data/spec/dummy/db/development.sqlite3 +0 -0
  25. data/spec/dummy/db/test.sqlite3 +0 -0
  26. data/spec/dummy/log/test.log +6458 -0
  27. data/spec/lib/mingle/configuration_spec.rb +28 -5
  28. data/spec/lib/mingle_spec.rb +15 -0
  29. data/spec/models/mingle/facebook_spec.rb +12 -0
  30. data/spec/models/mingle/instagram_spec.rb +15 -6
  31. data/spec/models/mingle/twitter/tweet_spec.rb +8 -0
  32. data/spec/models/mingle/twitter_spec.rb +20 -2
  33. metadata +66 -54
  34. data/MIT-LICENSE +0 -20
  35. data/app/assets/javascripts/mingle/application.js +0 -13
  36. data/app/assets/stylesheets/mingle/application.css +0 -15
  37. data/app/controllers/mingle/application_controller.rb +0 -4
  38. data/app/helpers/mingle/application_helper.rb +0 -4
  39. data/app/views/layouts/mingle/application.html.erb +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 60949a367f442c1a324c904715cb48d88576f599
4
- data.tar.gz: 17e07f3a27586fd103fb98e379b52d6f40726753
3
+ metadata.gz: a9065eee4fcbf4cf798b08a052c87c209a8d4518
4
+ data.tar.gz: e050a6a2d566384473405ed4545a1fd5474caaa2
5
5
  SHA512:
6
- metadata.gz: 1cb632bf16a925ea6efc6749b8da84d70e27c66ba1b76cb8bce68b92fd018abce8551c5d60673ecb1eef47b1fa80d1bdc350038fd2fd32dd8eb8a92c8d9e2cb8
7
- data.tar.gz: ab1d144d20d2949589e8e244668c66ead49c9d90f692d55ba49b848c108fc9dfeca7ca048042565828bdcb12bbb620f79a136270d77f13059caa64f2941229e7
6
+ metadata.gz: 6d6b77c34319be35a94a15273f6857d6d869c5d50bbb45c609f93e3ff2cbd93cc992746c57e30390867955217a6ec50b25df741344cc37e1239a164e6b5ff2e2
7
+ data.tar.gz: 80b26d770497904a3ed85ca7ba28060b7f04a42c784f9766c773911c3dd3b3221b49dcdd854d8e8bbcc66c4489dd9cc5f6e0476940ebaa0029411707904cdfb9
@@ -8,7 +8,15 @@ module Mingle::Facebook
8
8
  end
9
9
 
10
10
  # Fetch posts since given date/timestamp, last post's creation date or beginning of time
11
- def fetch(hashtags = Mingle::Hashtag.all, since = Mingle::Facebook::Post.ordered.last.try(:created_at))
11
+ def fetch(hashtags = Mingle::Hashtag.all, since = nil)
12
+ unless since
13
+ if Post.any?
14
+ since = Post.ordered.last.created_at
15
+ else
16
+ since = Mingle.config.since
17
+ end
18
+ end
19
+
12
20
  hashtags = Array(hashtags)
13
21
 
14
22
  posts = []
@@ -23,6 +31,10 @@ module Mingle::Facebook
23
31
 
24
32
  # Retrieves posts through given search query
25
33
  def posts_through_search hashtag, since
34
+ warn "DEPRECATION WARNING: Facebook has deprecated searching for posts. It is no " +
35
+ "longer available for new applications and will cease to work for existing " +
36
+ "applications in April 2015."
37
+
26
38
  posts = FbGraph::Post.search(hashtag.tag_name_with_hash, since: since.to_i, return_ssl_resources: 1, access_token: config.access_token)
27
39
 
28
40
  # Facebook search is fairly unpredictable, so ensure the query is actually mentioned
@@ -1,36 +1,3 @@
1
1
  class Mingle::Facebook::Post < ActiveRecord::Base
2
- has_many :hashtaggings, class_name: 'Mingle::Hashtagging', as: :hashtaggable,
3
- dependent: :destroy
4
-
5
- has_many :hashtags, through: :hashtaggings
6
-
7
- validates :post_id, :user_id, :user_name, presence: true
8
-
9
- scope :ordered, lambda { order('created_at ASC') }
10
-
11
- # Prevent Rails from assuming :type is STI-related
12
- # See: http://stackoverflow.com/questions/7134559/rails-use-type-column-without-sti
13
- self.inheritance_column = nil
14
-
15
- # Large pictures are not directly provided through the Graph API
16
- # Note: Not a documented Facebook feature and may potentially break in the future
17
- def large_picture
18
- picture.gsub(/_(?:s|t)\.(jpg|jpeg|png|gif)$/, '_b.\1') if picture.present?
19
- end
20
-
21
- def profile_url
22
- "https://www.facebook.com/#{user_id}" if user_id.present?
23
- end
24
-
25
- def profile_image_url
26
- "https://graph.facebook.com/#{user_id}/picture" if user_id.present?
27
- end
28
-
29
- def author
30
- user_name
31
- end
32
-
33
- def avatar
34
- profile_image_url
35
- end
2
+ include Mingle::Concerns::Models::Facebook::Post
36
3
  end
@@ -26,6 +26,8 @@ module Mingle::Instagram
26
26
 
27
27
  photo.hashtags << hashtag unless photo.hashtags.include? hashtag
28
28
 
29
+ next if ignore? photo
30
+
29
31
  photo.save!
30
32
  photo
31
33
  end
@@ -33,4 +35,14 @@ module Mingle::Instagram
33
35
  end.flatten
34
36
  end
35
37
 
38
+ private
39
+
40
+ # Determine whether the given photo should be ignored.
41
+ #
42
+ # photo - A Photo instance.
43
+ #
44
+ # Returns a Boolean.
45
+ def self.ignore? photo
46
+ Mingle.config.since && photo.created_at < Mingle.config.since
47
+ end
36
48
  end
@@ -1,28 +1,3 @@
1
1
  class Mingle::Instagram::Photo < ActiveRecord::Base
2
- has_many :hashtaggings, class_name: 'Mingle::Hashtagging', as: :hashtaggable, dependent: :destroy
3
- has_many :hashtags, through: :hashtaggings
4
-
5
- validates :link, :photo_id, :url, :user_handle, :user_image_url, presence: true
6
-
7
- scope :ordered, lambda { order('created_at ASC') }
8
-
9
- before_save :ensure_https_urls
10
-
11
- def author
12
- user_handle
13
- end
14
-
15
- def avatar
16
- user_image_url
17
- end
18
-
19
- private
20
-
21
- def ensure_https_urls
22
- self.link = link.sub(/http:/, 'https:')
23
- self.url = url.sub(/http:/, 'https:')
24
- self.user_image_url = user_image_url.sub(%r(http://images\.ak\.instagram\.com),
25
- 'https://distillery.s3.amazonaws.com')
26
- end
27
-
2
+ include Mingle::Concerns::Models::Instagram::Photo
28
3
  end
@@ -9,8 +9,11 @@ module Mingle::Twitter
9
9
  def fetch hashtags = Mingle::Hashtag.all, since_id = Mingle::Twitter::Tweet.ordered.last.try(:tweet_id)
10
10
  hashtags = Array(hashtags)
11
11
 
12
+ options = { since_id: since_id }
13
+ options[:exclude] = 'retweets' if Mingle.config.twitter_ignore_retweets
14
+
12
15
  hashtags.map do |hashtag|
13
- client.search(hashtag.tag_name_with_hash, since_id: since_id).collect do |data|
16
+ client.search(hashtag.tag_name_with_hash, options).collect do |data|
14
17
  tweet = Tweet.find_or_initialize_by tweet_id: data.id.to_s
15
18
 
16
19
  tweet.attributes = {
@@ -25,9 +28,11 @@ module Mingle::Twitter
25
28
 
26
29
  tweet.hashtags << hashtag unless tweet.hashtags.include? hashtag
27
30
 
31
+ next if ignore? tweet
32
+
28
33
  tweet.save!
29
34
  tweet
30
- end
35
+ end.compact
31
36
  end.flatten
32
37
  end
33
38
 
@@ -43,6 +48,14 @@ module Mingle::Twitter
43
48
  end
44
49
  end
45
50
 
51
+ # Determine whether the given tweet should be ignored.
52
+ #
53
+ # tweet - A Tweet instance.
54
+ #
55
+ # Returns a Boolean.
56
+ def ignore? tweet
57
+ Mingle.config.since && tweet.created_at < Mingle.config.since
58
+ end
46
59
  end
47
60
 
48
61
  end
@@ -1,26 +1,3 @@
1
1
  class Mingle::Twitter::Tweet < ActiveRecord::Base
2
- has_many :hashtaggings, class_name: 'Mingle::Hashtagging', as: :hashtaggable,
3
- dependent: :destroy
4
-
5
- has_many :hashtags, through: :hashtaggings
6
-
7
- validates :text, :tweet_id, :user_handle, :user_image_url, :user_name, presence: true
8
-
9
- scope :ordered, lambda { order('created_at ASC') }
10
-
11
- before_save :ensure_https_urls
12
-
13
- def author
14
- user_handle
15
- end
16
-
17
- def avatar
18
- user_image_url
19
- end
20
-
21
- private
22
-
23
- def ensure_https_urls
24
- self.user_image_url = user_image_url.sub(/http:/, 'https:')
25
- end
2
+ include Mingle::Concerns::Models::Twitter::Tweet
26
3
  end
@@ -0,0 +1,5 @@
1
+ class AddUrlToMingleTwitterTweets < ActiveRecord::Migration
2
+ def change
3
+ add_column :mingle_twitter_tweets, :url, :string
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ Description:
2
+ Copies over a default configuration file for Mingle into your application's
3
+ initializer directory.
4
+
5
+ Example:
6
+ rails generate mingle:install
7
+
8
+ This will create:
9
+ config/initializers/mingle.rb
@@ -0,0 +1,7 @@
1
+ class Mingle::InstallGenerator < Rails::Generators::Base
2
+ source_root File.expand_path('../templates', __FILE__)
3
+
4
+ def copy_config_file
5
+ copy_file 'mingle_config.rb', 'config/initializers/mingle.rb'
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ Mingle.configure do |config|
2
+ config.facebook_access_token = ENV['FACEBOOK_ACCESS_TOKEN']
3
+ config.twitter_api_key = ENV['TWITTER_API_KEY']
4
+ config.twitter_api_secret = ENV['TWITTER_API_SECRET']
5
+ config.twitter_access_token = ENV['TWITTER_ACCESS_TOKEN']
6
+ config.twitter_access_token_secret = ENV['TWITTER_ACCESS_TOKEN_SECRET']
7
+ config.instagram_client_id = ENV['INSTAGRAM_CLIENT_ID']
8
+ end
@@ -1,5 +1,6 @@
1
1
  require 'mingle/engine'
2
2
  require 'mingle/configuration'
3
+ require "mingle/concerns"
3
4
 
4
5
  require 'twitter'
5
6
  require 'fb_graph'
@@ -14,5 +15,20 @@ module Mingle
14
15
  def config
15
16
  @config ||= Mingle::Configuration.new
16
17
  end
18
+
19
+ # Set temporary configuration options for the duration of the given block.
20
+ #
21
+ # options - A Hash describing temporary configuration options.
22
+ def temporarily options = {}
23
+ original = @config.dup
24
+
25
+ options.each do |key, value|
26
+ @config.send "#{key}=", value
27
+ end
28
+
29
+ yield
30
+ ensure
31
+ @config = original
32
+ end
17
33
  end
18
34
  end
@@ -0,0 +1,3 @@
1
+ module Mingle::Concerns
2
+ require 'mingle/concerns/models'
3
+ end
@@ -0,0 +1,5 @@
1
+ module Mingle::Concerns::Models
2
+ require 'mingle/concerns/models/facebook'
3
+ require 'mingle/concerns/models/instagram'
4
+ require 'mingle/concerns/models/twitter'
5
+ end
@@ -0,0 +1,3 @@
1
+ module Mingle::Concerns::Models::Facebook
2
+ require 'mingle/concerns/models/facebook/post'
3
+ end
@@ -0,0 +1,40 @@
1
+ module Mingle::Concerns::Models::Facebook::Post
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ has_many :hashtaggings, class_name: 'Mingle::Hashtagging', as: :hashtaggable,
6
+ dependent: :destroy
7
+
8
+ has_many :hashtags, through: :hashtaggings
9
+
10
+ validates :post_id, :user_id, :user_name, presence: true
11
+
12
+ scope :ordered, lambda { order('created_at ASC') }
13
+
14
+ # Prevent Rails from assuming :type is STI-related
15
+ # See: http://stackoverflow.com/questions/7134559/rails-use-type-column-without-sti
16
+ self.inheritance_column = nil
17
+
18
+ # Large pictures are not directly provided through the Graph API
19
+ # Note: Not a documented Facebook feature and may potentially break in the future
20
+ def large_picture
21
+ picture.gsub(/_(?:s|t)\.(jpg|jpeg|png|gif)$/, '_b.\1') if picture.present?
22
+ end
23
+
24
+ def profile_url
25
+ "https://www.facebook.com/#{user_id}" if user_id.present?
26
+ end
27
+
28
+ def profile_image_url
29
+ "https://graph.facebook.com/#{user_id}/picture" if user_id.present?
30
+ end
31
+
32
+ def author
33
+ user_name
34
+ end
35
+
36
+ def avatar
37
+ profile_image_url
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module Mingle::Concerns::Models::Instagram
2
+ require 'mingle/concerns/models/instagram/photo'
3
+ end
@@ -0,0 +1,20 @@
1
+ module Mingle::Concerns::Models::Instagram::Photo
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ has_many :hashtaggings, class_name: 'Mingle::Hashtagging', as: :hashtaggable, dependent: :destroy
6
+ has_many :hashtags, through: :hashtaggings
7
+
8
+ validates :link, :photo_id, :url, :user_handle, :user_image_url, presence: true
9
+
10
+ scope :ordered, lambda { order('created_at ASC') }
11
+
12
+ def author
13
+ user_handle
14
+ end
15
+
16
+ def avatar
17
+ user_image_url
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module Mingle::Concerns::Models::Twitter
2
+ require 'mingle/concerns/models/twitter/tweet'
3
+ end
@@ -0,0 +1,26 @@
1
+ module Mingle::Concerns::Models::Twitter::Tweet
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ has_many :hashtaggings, class_name: 'Mingle::Hashtagging', as: :hashtaggable,
6
+ dependent: :destroy
7
+
8
+ has_many :hashtags, through: :hashtaggings
9
+
10
+ validates :text, :tweet_id, :user_handle, :user_image_url, :user_name, presence: true
11
+
12
+ scope :ordered, lambda { order('created_at ASC') }
13
+
14
+ def author
15
+ user_handle
16
+ end
17
+
18
+ def avatar
19
+ user_image_url
20
+ end
21
+
22
+ def url
23
+ "https://twitter.com/#{user_handle}/status/#{tweet_id}"
24
+ end
25
+ end
26
+ end
@@ -2,15 +2,38 @@ module Mingle
2
2
  class Configuration
3
3
  configs = [
4
4
  :facebook_access_token, :twitter_api_key, :twitter_api_secret,
5
- :twitter_access_token, :twitter_access_token_secret, :instagram_client_id
5
+ :twitter_access_token, :twitter_access_token_secret,
6
+ :twitter_ignore_retweets, :instagram_client_id, :since
6
7
  ]
7
8
 
8
9
  attr_accessor *configs
9
10
 
10
- configs.each do |config|
11
- define_method config do
12
- instance_variable_get("@#{config}") || ENV[config.upcase.to_s]
13
- end
11
+ def initialize
12
+ @twitter_ignore_retweets = false
13
+ end
14
+
15
+ def facebook_access_token
16
+ @facebook_access_token || ENV['FACEBOOK_ACCESS_TOKEN']
17
+ end
18
+
19
+ def twitter_api_key
20
+ @twitter_api_key || ENV['TWITTER_API_KEY']
21
+ end
22
+
23
+ def twitter_api_secret
24
+ @twitter_api_secret || ENV['TWITTER_API_SECRET']
25
+ end
26
+
27
+ def twitter_access_token
28
+ @twitter_access_token || ENV['TWITTER_ACCESS_TOKEN']
29
+ end
30
+
31
+ def twitter_access_token_secret
32
+ @twitter_access_token_secret || ENV['TWITTER_ACCESS_TOKEN_SECRET']
33
+ end
34
+
35
+ def instagram_client_id
36
+ @instagram_client_id || ENV['INSTAGRAM_CLIENT_ID']
14
37
  end
15
38
  end
16
39
  end
@@ -7,6 +7,10 @@ module Mingle
7
7
  class Engine < ::Rails::Engine
8
8
  isolate_namespace Mingle
9
9
 
10
+ initializer 'mingle.factories', after: 'factory_girl.set_factory_paths' do
11
+ FactoryGirl.definition_file_paths << File.expand_path('../../../spec/factories', __FILE__) if defined?(FactoryGirl)
12
+ end
13
+
10
14
  config.eager_load_paths.delete_if do |path|
11
15
  Pathname.new(path).split.last.to_s == 'jobs' && !defined? Sidekiq
12
16
  end
@@ -1,3 +1,3 @@
1
1
  module Mingle
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end