grab_feed (Raggle::Engine)

    # File raggle, line 5298
        def Engine::grab_feed(feed)
          meth = 'Engine.grab_feed'
          t = Time.now

          # set the name and priority of the current thread
          Thread::current['feed'] = feed
          Thread::current.priority = $config['thread_priority_feed']

          msg = _("Checking feed")
          $new_status = " #{msg} \"#{feed['title']}\"..."
          $log.info(meth) { "#{msg} \"#{feed['title']}\"" }
          return unless feed['refresh'] > 0 &&
            feed['updated'] + (feed['refresh'] * 60) < t.to_i

          # update statusbar and grab log
          msg, src_msg = _("Updating feed"), _('from')
          $new_status = " #{msg} \"#{feed['title']}\"..."
          $log.info(meth) { "#{msg} \"#{feed['title']}\" #{src_msg} \"#{feed['url']}\"" }

          # get channel
          begin
            chan = Raggle::Feed::Channel.new(feed['url'], feed['last_modified'])
            feed.delete 'error'
          rescue
            err_msg = _('Error updating')
            err = feed['error'] = "#$!"

            if $config['mode'] == 'view'
              Raggle::Interfaces::NcursesInterface::set_status "#{err_msg} \"#{feed['title']}\"."
            end
            $log.error(meth) { "#{err_msg}: #{err}" }

            # mark this feed as updated so it doesn't get constantly polled
            feed['updated'] = t.to_i
            return
          end

          # update feed attributes
          if !chan.last_modified ||
             chan.last_modified != feed['last_modified']
            Thread::critical = $config['use_critical_regions']
            feed['title'] = chan.title unless $config['lock_feed_title'] ||
                                              feed['lock_title?'] == true
            feed['desc'] = chan.desc
            feed['site'] = chan.link
            feed['image'] = chan.image
            feed['updated'] = t.to_i

            # Note: last_modified is slightly different than modified,
            # because we're using it as a token, not as a timestamp
            # -- paul
            feed['last_modified'] = chan.last_modified

            # hash the urls, save the read and visibility status
            status = {}
            feed['items'].each { |item| status[item['url']] = { :read => item['read?'], :visible => item['visible'] } }

            # clear the list if we're not saving feed items
            Thread::critical = $config['use_critical_regions']
            feed['items'].clear unless $config['save_feed_items'] ||
                                       feed['save_items?']
            Thread::critical = false

            # insert new items
            new_items = []
            chan.items.each { |item|
              unless (($config['save_feed_items'] ||
                       feed['save_items?']) &&
                      status.has_key?(item.link))
                if status.has_key?(item.link)
                  was_read = status[item.link][:read]
                  is_visible = status[item.link][:visible]
                else  # new item
                  was_read = false; is_visible = true
                end
                new_items << {
                  'title'   => item.title,
                  'date'    => item.date,
                  'url'     => item.link,
                  'desc'    => item.desc,
                  'read?'   => was_read,
                  'visible' => is_visible,
                  'added'   => Time.now.to_i,
                }
              end
            }

            # if we're saving old items, then prepend the new items
            # otherwise, replace the old list
            Thread::critical = $config['use_critical_regions']
            if $config['save_feed_items'] || feed['save_items?']
              feed['items'] = new_items + feed['items']

              max = $config['max_feed_items'] || feed['max_items']
              if max && max > 0
                old = (feed['items'].slice!(max .. -1) || []).size
                rm_msg = _('Removing %d old items.')
                $log.info(meth) { rm_msg % [old] }
              end
            else
              feed['items'] = new_items
            end

            if $config['do_beep']
              print "\a"
            end

            Thread::critical = false
          else
            feed['updated'] = t.to_i
            same_msg = _("Feed \"%s\" hasn't changed.")
            $log.info(meth) { same_msg % [feed['title']] }
          end

          # if this is the currently selected feed, then re-select it
          # so it's contents are updated
          # TODO: make this select the currently selected item again
          # (assuming it still exists)
          if $config['mode'] == 'view' &&
            !$config['run_http_server'] && !$config['run_drb_server'] &&
             $config['feeds'].get($a_feed)['url'] == feed['url']
             feed_win_id = Raggle::Interfaces::NcursesInterface::get_win_id('feed')
            $wins[feed_win_id].select_win_item
          end

          # redraw feed / item windows
          $update_wins = true
        end