Class: EntryManager

Inherits:
Object
  • Object
show all
Defined in:
lib/entry_manager.rb

Overview

Class to save or update in the database a collection of entries fetched from a feed.

Class Method Summary collapse

Class Method Details

.save_new_entries(feed, entries, encoding) ⇒ Object

Save new feed entries in the database.

For each entry passed, if an entry with the same guid for the same feed already exists in the database, ignore it. Also, if an entry with the same guid for the same feed has been deleted in the past, indicated by a record in the deleted_entries table, ignore it. Otherwise save it as a new entry in the database.

The argument passed are:

  • the feed to which the entries belong (an instance of the Feed model)

  • an Enumerable with the feed entries to save.

  • encoding of the feed. Necessary because Feedjira sometimes receives a non-utf8 feed as input and returns a parsed

feed object with e.g. entry titles incorrectly marked as utf-8, when actually the internal representation is in the same encoding as the input. This makes necessary converting Feedjira outputs to the input encoding.

If during processing there is a problem with an entry, it is skipped and the next one is processed, instead of failing the whole process.


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/entry_manager.rb', line 27

def self.save_new_entries(feed, entries, encoding)
  entries.reverse_each do |entry|

    begin
      set_entry_encoding entry, encoding
      guid = entry.entry_id || entry.url
      if guid.blank?
        Rails.logger.warn "Received entry without guid or url for feed #{feed.id} - #{feed.title}. Skipping it."
        next
      end

      # Sanitize and trim guid; necessary to check if the entry already exists, because the Entry model
      # changes the guid this way before saving.
      guid = Sanitizer.sanitize_plaintext guid

      if Entry.exists? guid: guid, feed_id: feed.id
        Rails.logger.debug "Already existing entry fetched for feed #{feed.fetch_url} - title: #{entry.title} - guid: #{entry.entry_id}. Ignoring it"
      elsif DeletedEntry.exists? guid: guid, feed_id: feed.id
        Rails.logger.debug "Already deleted entry fetched for feed #{feed.fetch_url} - title: #{entry.title} - guid: #{entry.entry_id}. Ignoring it"
      else
        Rails.logger.debug "Saving in the database new entry for feed #{feed.fetch_url} - title: #{entry.title} - guid: #{entry.entry_id}"
        entry_hash = entry_to_hash entry, guid
        feed.entries.create! entry_hash
      end

    rescue => e
      Rails.logger.error "There's been a problem processing a fetched entry from feed #{feed.id} - #{feed.title}. Skipping entry."
      Rails.logger.error e.message
      # Do not print backtrace for AR validation errors, it's just white noise
      Rails.logger.error e.backtrace unless e.is_a? ActiveRecord::RecordInvalid
      next
    end
  end
end