feedupdater 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +3 -0
- data/config/feed_updater.yml +7 -0
- data/lib/feed_updater/version.rb +1 -1
- data/lib/feed_updater.rb +219 -28
- metadata +2 -4
- data/config/feed_updater.pid +0 -1
    
        data/CHANGELOG
    CHANGED
    
    
    
        data/config/feed_updater.yml
    CHANGED
    
    | @@ -5,8 +5,15 @@ start_delay: false | |
| 5 5 | 
             
            # See the documentation for details.
         | 
| 6 6 | 
             
            load_script: example/custom_updater.rb
         | 
| 7 7 |  | 
| 8 | 
            +
            # Keep this set to 1 unless you're certain you need to set it higher.
         | 
| 9 | 
            +
            # Never set it higher than 1 if you're on a shared server.
         | 
| 10 | 
            +
            threads: 5
         | 
| 11 | 
            +
             | 
| 8 12 | 
             
            # This is the path to store the pid files.
         | 
| 9 13 | 
             
            pid_file_path: config
         | 
| 10 14 |  | 
| 11 15 | 
             
            # This is the path to store the log files.
         | 
| 12 16 | 
             
            log_file_path: log
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            # Log level
         | 
| 19 | 
            +
            log_level: 0
         | 
    
        data/lib/feed_updater/version.rb
    CHANGED
    
    
    
        data/lib/feed_updater.rb
    CHANGED
    
    | @@ -55,6 +55,41 @@ if !defined?(FeedTools::FEED_TOOLS_VERSION) | |
| 55 55 | 
             
            end
         | 
| 56 56 |  | 
| 57 57 | 
             
            require 'benchmark'
         | 
| 58 | 
            +
            require 'thread'
         | 
| 59 | 
            +
            require 'logger'
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            class FeedUpdaterLogger < Logger
         | 
| 62 | 
            +
              attr_accessor :prefix
         | 
| 63 | 
            +
              
         | 
| 64 | 
            +
              alias_method :old_log, :log
         | 
| 65 | 
            +
              def log(level, message)
         | 
| 66 | 
            +
                if defined?(@prefix) && @prefix != nil
         | 
| 67 | 
            +
                  self.old_log(level, self.prefix + message)
         | 
| 68 | 
            +
                else
         | 
| 69 | 
            +
                  self.old_log(level, message)
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              def debug(message)
         | 
| 74 | 
            +
                self.log(0, message)
         | 
| 75 | 
            +
              end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
              def info(message)
         | 
| 78 | 
            +
                self.log(1, message)
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
              def warn(message)
         | 
| 82 | 
            +
                self.log(2, message)
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
              def error(message)
         | 
| 86 | 
            +
                self.log(3, message)
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
              def fatal(message)
         | 
| 90 | 
            +
                self.log(4, message)
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
            end
         | 
| 58 93 |  | 
| 59 94 | 
             
            module FeedTools
         | 
| 60 95 | 
             
              # A simple daemon for scheduled updating of feeds.
         | 
| @@ -127,7 +162,11 @@ module FeedTools | |
| 127 162 | 
             
                # Returns the logger object.
         | 
| 128 163 | 
             
                def logger()
         | 
| 129 164 | 
             
                  if !defined?(@logger) || @logger.nil?
         | 
| 130 | 
            -
                    @logger =  | 
| 165 | 
            +
                    @logger = FeedUpdaterLogger.new(self.log_file)
         | 
| 166 | 
            +
                    @logger.level = self.updater_options[:log_level]
         | 
| 167 | 
            +
                    @logger.datetime_format = nil
         | 
| 168 | 
            +
                    @logger.progname = nil
         | 
| 169 | 
            +
                    @logger.prefix = "FeedUpdater".ljust(20)
         | 
| 131 170 | 
             
                  end
         | 
| 132 171 | 
             
                  return @logger
         | 
| 133 172 | 
             
                end
         | 
| @@ -139,7 +178,11 @@ module FeedTools | |
| 139 178 | 
             
                    self.logger.close()
         | 
| 140 179 | 
             
                  rescue IOError
         | 
| 141 180 | 
             
                  end
         | 
| 142 | 
            -
                  @logger =  | 
| 181 | 
            +
                  @logger = FeedUpdaterLogger.new(self.log_file)
         | 
| 182 | 
            +
                  @logger.level = self.updater_options[:log_level]
         | 
| 183 | 
            +
                  @logger.datetime_format = nil
         | 
| 184 | 
            +
                  @logger.progname = nil
         | 
| 185 | 
            +
                  @logger.prefix = "FeedUpdater".ljust(20)
         | 
| 143 186 | 
             
                end
         | 
| 144 187 |  | 
| 145 188 | 
             
                # Returns a list of feeds to be updated.
         | 
| @@ -174,7 +217,9 @@ module FeedTools | |
| 174 217 | 
             
                def updater_options()
         | 
| 175 218 | 
             
                  if !defined?(@updater_options) || @updater_options.nil?
         | 
| 176 219 | 
             
                    @updater_options = {
         | 
| 177 | 
            -
                      :start_delay => true
         | 
| 220 | 
            +
                      :start_delay => true,
         | 
| 221 | 
            +
                      :thread => 1,
         | 
| 222 | 
            +
                      :log_level => 0
         | 
| 178 223 | 
             
                    }
         | 
| 179 224 | 
             
                  end
         | 
| 180 225 | 
             
                  return @updater_options
         | 
| @@ -234,6 +279,7 @@ module FeedTools | |
| 234 279 |  | 
| 235 280 | 
             
                # Starts the daemon.
         | 
| 236 281 | 
             
                def start()
         | 
| 282 | 
            +
                  self.logger.prefix = "FeedUpdater".ljust(20)
         | 
| 237 283 | 
             
                  if !defined?(@@on_update) || @@on_update.nil?
         | 
| 238 284 | 
             
                    raise "No on_update handler block given."
         | 
| 239 285 | 
             
                  end
         | 
| @@ -241,6 +287,9 @@ module FeedTools | |
| 241 287 | 
             
                    puts "FeedUpdater is already running."
         | 
| 242 288 | 
             
                    return self.pid
         | 
| 243 289 | 
             
                  end
         | 
| 290 | 
            +
                  if defined?(ActiveRecord)
         | 
| 291 | 
            +
                    ActiveRecord::Base.allow_concurrency = true
         | 
| 292 | 
            +
                  end
         | 
| 244 293 |  | 
| 245 294 | 
             
                  @initial_directory = File.expand_path(".")
         | 
| 246 295 |  | 
| @@ -280,9 +329,13 @@ module FeedTools | |
| 280 329 | 
             
                          self.update_feeds()
         | 
| 281 330 | 
             
                        end
         | 
| 282 331 | 
             
                        self.logger.info(
         | 
| 283 | 
            -
                          "#{@feed_href_list.size}  | 
| 332 | 
            +
                          "#{@feed_href_list.size} feed(s) updated " +
         | 
| 284 333 | 
             
                          "in #{result.real.round} seconds.")
         | 
| 285 | 
            -
                         | 
| 334 | 
            +
                        if !defined?(@feed_href_list_override) ||
         | 
| 335 | 
            +
                            !@feed_href_list_override
         | 
| 336 | 
            +
                          @feed_href_list = nil
         | 
| 337 | 
            +
                        end
         | 
| 338 | 
            +
                        ObjectSpace.garbage_collect()
         | 
| 286 339 | 
             
                        sleepy_time = 1.hour - result.real.round
         | 
| 287 340 | 
             
                        if sleepy_time > 0
         | 
| 288 341 | 
             
                          self.logger.info(
         | 
| @@ -304,11 +357,16 @@ module FeedTools | |
| 304 357 | 
             
                  else
         | 
| 305 358 | 
             
                    @application.start()
         | 
| 306 359 | 
             
                  end
         | 
| 360 | 
            +
                  self.logger.prefix = nil
         | 
| 361 | 
            +
                  self.logger.level = 0
         | 
| 307 362 | 
             
                  self.logger.info("-" * 79)
         | 
| 308 363 | 
             
                  self.logger.info("Daemon started, " +
         | 
| 309 364 | 
             
                    "FeedUpdater #{FeedTools::FEED_UPDATER_VERSION::STRING} / " +
         | 
| 310 365 | 
             
                    "FeedTools #{FeedTools::FEED_TOOLS_VERSION::STRING}")
         | 
| 311 366 | 
             
                  self.logger.info(" @ #{Time.now.utc.to_s}")
         | 
| 367 | 
            +
                  self.logger.info("-" * 79)
         | 
| 368 | 
            +
                  self.logger.level = self.updater_options[:log_level]
         | 
| 369 | 
            +
                  self.logger.prefix = "FeedUpdater".ljust(20)
         | 
| 312 370 | 
             
                  @status = :running
         | 
| 313 371 | 
             
                  return self.pid
         | 
| 314 372 | 
             
                end
         | 
| @@ -340,7 +398,10 @@ module FeedTools | |
| 340 398 | 
             
                    end
         | 
| 341 399 | 
             
                  rescue Exception
         | 
| 342 400 | 
             
                  end
         | 
| 401 | 
            +
                  self.logger.prefix = "FeedUpdater".ljust(20)
         | 
| 402 | 
            +
                  self.logger.level = 0
         | 
| 343 403 | 
             
                  self.logger.info("Daemon stopped.")
         | 
| 404 | 
            +
                  self.logger.level = self.updater_options[:log_level]
         | 
| 344 405 | 
             
                  @status = :stopped
         | 
| 345 406 | 
             
                  return nil if self.application.nil?
         | 
| 346 407 | 
             
                  begin
         | 
| @@ -358,40 +419,170 @@ module FeedTools | |
| 358 419 |  | 
| 359 420 | 
             
                # Updates all of the feeds.
         | 
| 360 421 | 
             
                def update_feeds()
         | 
| 422 | 
            +
                  self.logger.prefix = "FeedUpdater".ljust(20)
         | 
| 423 | 
            +
                  ObjectSpace.garbage_collect()
         | 
| 361 424 | 
             
                  if defined?(@feed_href_list_override) && @feed_href_list_override
         | 
| 362 425 | 
             
                    self.feed_href_list()
         | 
| 363 426 | 
             
                  else
         | 
| 427 | 
            +
                    self.logger.info("Loading default feed list...")
         | 
| 364 428 | 
             
                    @feed_href_list =
         | 
| 365 | 
            -
             | 
| 366 | 
            -
             | 
| 429 | 
            +
                      (FeedTools.feed_cache.find(:all).collect do |cache_object|
         | 
| 430 | 
            +
                        cache_object.href
         | 
| 431 | 
            +
                      end)
         | 
| 432 | 
            +
                  end
         | 
| 433 | 
            +
                  self.logger.info("Updating #{@feed_href_list.size} feed(s)...")
         | 
| 434 | 
            +
                  ObjectSpace.garbage_collect()
         | 
| 435 | 
            +
                  
         | 
| 436 | 
            +
                  threads = []
         | 
| 437 | 
            +
                  thread_slices = []
         | 
| 438 | 
            +
                  thread_slice_size =
         | 
| 439 | 
            +
                    (@feed_href_list.size / self.updater_options[:threads])
         | 
| 440 | 
            +
             | 
| 441 | 
            +
                  for i in 0...self.updater_options[:threads]
         | 
| 442 | 
            +
                    if i != self.updater_options[:threads] - 1
         | 
| 443 | 
            +
                      thread_slices << @feed_href_list[
         | 
| 444 | 
            +
                        (i * thread_slice_size)...((i + 1) * thread_slice_size)]
         | 
| 445 | 
            +
                    else
         | 
| 446 | 
            +
                      thread_slices << @feed_href_list[
         | 
| 447 | 
            +
                        (i * thread_slice_size)..-1]
         | 
| 367 448 | 
             
                    end
         | 
| 368 449 | 
             
                  end
         | 
| 369 | 
            -
                   | 
| 370 | 
            -
             | 
| 371 | 
            -
             | 
| 372 | 
            -
             | 
| 373 | 
            -
             | 
| 374 | 
            -
             | 
| 375 | 
            -
             | 
| 376 | 
            -
             | 
| 377 | 
            -
             | 
| 378 | 
            -
             | 
| 379 | 
            -
             | 
| 380 | 
            -
             | 
| 381 | 
            -
                       | 
| 382 | 
            -
             | 
| 383 | 
            -
                           | 
| 384 | 
            -
                         | 
| 385 | 
            -
             | 
| 450 | 
            +
                  ObjectSpace.garbage_collect()
         | 
| 451 | 
            +
             | 
| 452 | 
            +
                  begin_updating = false
         | 
| 453 | 
            +
                  self.logger.info(
         | 
| 454 | 
            +
                    "Starting up #{self.updater_options[:threads]} thread(s)...")
         | 
| 455 | 
            +
                  
         | 
| 456 | 
            +
                  mutex = Mutex.new
         | 
| 457 | 
            +
                  for i in 0...self.updater_options[:threads]
         | 
| 458 | 
            +
                    updater_thread = Thread.new do
         | 
| 459 | 
            +
                      self.logger.level = self.updater_options[:log_level]
         | 
| 460 | 
            +
                      self.logger.datetime_format = "%s"
         | 
| 461 | 
            +
                      self.logger.progname = "FeedUpdater".ljust(20)
         | 
| 462 | 
            +
                      
         | 
| 463 | 
            +
                      while !Thread.current.respond_to?(:thread_id) &&
         | 
| 464 | 
            +
                          begin_updating == false
         | 
| 465 | 
            +
                        Thread.pass
         | 
| 466 | 
            +
                      end
         | 
| 467 | 
            +
                      mutex.synchronize do
         | 
| 468 | 
            +
                        self.logger.prefix = "Thread #{Thread.current.thread_id} ".ljust(20)
         | 
| 469 | 
            +
                        self.logger.info("Thread started.")
         | 
| 470 | 
            +
                        
         | 
| 471 | 
            +
                        begin
         | 
| 472 | 
            +
                          FeedTools.feed_cache.initialize_cache()
         | 
| 473 | 
            +
                          if !FeedTools.feed_cache.set_up_correctly?
         | 
| 474 | 
            +
                            self.logger.info("Problem with cache connection...")
         | 
| 475 | 
            +
                          end
         | 
| 476 | 
            +
                        rescue Exception => error
         | 
| 386 477 | 
             
                          self.logger.info(error)
         | 
| 387 478 | 
             
                        end
         | 
| 479 | 
            +
                      
         | 
| 480 | 
            +
                        self.logger.info(
         | 
| 481 | 
            +
                          "Thread ##{Thread.current.thread_id} handling " +
         | 
| 482 | 
            +
                          "#{thread_slices[Thread.current.thread_id].size} feeds...")
         | 
| 388 483 | 
             
                      end
         | 
| 389 | 
            -
             | 
| 390 | 
            -
                       | 
| 391 | 
            -
                       | 
| 392 | 
            -
                       | 
| 484 | 
            +
                      
         | 
| 485 | 
            +
                      ObjectSpace.garbage_collect()
         | 
| 486 | 
            +
                      Thread.pass
         | 
| 487 | 
            +
                      href_list = thread_slices[Thread.current.thread_id]
         | 
| 488 | 
            +
             | 
| 489 | 
            +
                      for i in 0...href_list.size
         | 
| 490 | 
            +
                        href = nil
         | 
| 491 | 
            +
                        progress = nil
         | 
| 492 | 
            +
                        mutex.synchronize do
         | 
| 493 | 
            +
                          href = href_list[i]
         | 
| 494 | 
            +
                          Thread.current.progress =
         | 
| 495 | 
            +
                            (href_list.index(href).to_f / href_list.size.to_f) * 100
         | 
| 496 | 
            +
                          progress = sprintf("%.2f", Thread.current.progress)
         | 
| 497 | 
            +
                        end
         | 
| 498 | 
            +
                        begin
         | 
| 499 | 
            +
                          begin
         | 
| 500 | 
            +
                            feed = nil
         | 
| 501 | 
            +
                            feed_load_benchmark = Benchmark.measure do
         | 
| 502 | 
            +
                              feed = FeedTools::Feed.open(href)
         | 
| 503 | 
            +
                            end
         | 
| 504 | 
            +
                            Thread.pass
         | 
| 505 | 
            +
                            if feed.live?
         | 
| 506 | 
            +
                              unless @@on_update.nil?
         | 
| 507 | 
            +
                                mutex.synchronize do
         | 
| 508 | 
            +
                                  progress = sprintf("%.2f", Thread.current.progress)
         | 
| 509 | 
            +
                                  self.logger.prefix = ("Thread #{Thread.current.thread_id} " +
         | 
| 510 | 
            +
                                    "(#{progress}%)"
         | 
| 511 | 
            +
                                    ).ljust(20)
         | 
| 512 | 
            +
                                  self.cloaker(&(@@on_update)).bind(self).call(
         | 
| 513 | 
            +
                                    feed, feed_load_benchmark.real)
         | 
| 514 | 
            +
                                end
         | 
| 515 | 
            +
                              end
         | 
| 516 | 
            +
                            else
         | 
| 517 | 
            +
                              mutex.synchronize do
         | 
| 518 | 
            +
                                progress = sprintf("%.2f", Thread.current.progress)
         | 
| 519 | 
            +
                                self.logger.prefix = ("Thread #{Thread.current.thread_id} " +
         | 
| 520 | 
            +
                                  "(#{progress}%)"
         | 
| 521 | 
            +
                                  ).ljust(20)
         | 
| 522 | 
            +
                                self.logger.info(
         | 
| 523 | 
            +
                                  "'#{href}' unchanged, skipping.")
         | 
| 524 | 
            +
                              end
         | 
| 525 | 
            +
                            end
         | 
| 526 | 
            +
                          rescue Exception => error
         | 
| 527 | 
            +
                            mutex.synchronize do
         | 
| 528 | 
            +
                              progress = sprintf("%.2f", Thread.current.progress)
         | 
| 529 | 
            +
                              self.logger.prefix = ("Thread #{Thread.current.thread_id} " +
         | 
| 530 | 
            +
                                "(#{progress}%)"
         | 
| 531 | 
            +
                                ).ljust(20)
         | 
| 532 | 
            +
                              if @@on_error != nil
         | 
| 533 | 
            +
                                self.cloaker(&(@@on_error)).bind(self).call(href, error)
         | 
| 534 | 
            +
                              else
         | 
| 535 | 
            +
                                self.logger.error("Error updating '#{href}':")
         | 
| 536 | 
            +
                                self.logger.error(error.class.name + ": " + error.message)
         | 
| 537 | 
            +
                                self.logger.error(error.class.backtrace)
         | 
| 538 | 
            +
                              end
         | 
| 539 | 
            +
                            end
         | 
| 540 | 
            +
                          end
         | 
| 541 | 
            +
                        rescue Exception => error
         | 
| 542 | 
            +
                          mutex.synchronize do
         | 
| 543 | 
            +
                            progress = sprintf("%.2f", Thread.current.progress)
         | 
| 544 | 
            +
                            self.logger.prefix = ("Thread #{Thread.current.thread_id} " +
         | 
| 545 | 
            +
                              "(#{progress}%)"
         | 
| 546 | 
            +
                              ).ljust(20)
         | 
| 547 | 
            +
                            self.logger.fatal("Critical unhandled error.")
         | 
| 548 | 
            +
                            self.logger.fatal("Error updating '#{href}':")
         | 
| 549 | 
            +
                            self.logger.fatal(error.class.name + ": " + error.message)
         | 
| 550 | 
            +
                            self.logger.fatal(error.class.backtrace)
         | 
| 551 | 
            +
                          end
         | 
| 552 | 
            +
                        end
         | 
| 553 | 
            +
                        ObjectSpace.garbage_collect()
         | 
| 554 | 
            +
                        Thread.pass
         | 
| 555 | 
            +
                      end          
         | 
| 556 | 
            +
                    end
         | 
| 557 | 
            +
                    threads << updater_thread        
         | 
| 558 | 
            +
                    class <<updater_thread
         | 
| 559 | 
            +
                      attr_accessor :thread_id
         | 
| 560 | 
            +
                      attr_accessor :progress
         | 
| 561 | 
            +
                    end
         | 
| 562 | 
            +
                    updater_thread.thread_id = i
         | 
| 563 | 
            +
                  end
         | 
| 564 | 
            +
                  mutex.synchronize do
         | 
| 565 | 
            +
                    self.logger.prefix = "FeedUpdater".ljust(20)
         | 
| 566 | 
            +
                    self.logger.info(
         | 
| 567 | 
            +
                      "#{threads.size} thread(s) successfully started...")
         | 
| 568 | 
            +
                    begin_updating = true
         | 
| 569 | 
            +
                  end
         | 
| 570 | 
            +
                  Thread.pass
         | 
| 571 | 
            +
                  
         | 
| 572 | 
            +
                  ObjectSpace.garbage_collect()
         | 
| 573 | 
            +
                  Thread.pass
         | 
| 574 | 
            +
                  for i in 0...threads.size
         | 
| 575 | 
            +
                    mutex.synchronize do
         | 
| 576 | 
            +
                      self.logger.prefix = "FeedUpdater".ljust(20)
         | 
| 577 | 
            +
                      self.logger.info(
         | 
| 578 | 
            +
                        "Joining on thread #{threads[i].thread_id}...")
         | 
| 393 579 | 
             
                    end
         | 
| 580 | 
            +
                    threads[i].join
         | 
| 394 581 | 
             
                  end
         | 
| 582 | 
            +
                  self.logger.prefix = "FeedUpdater".ljust(20)
         | 
| 583 | 
            +
                  ObjectSpace.garbage_collect()
         | 
| 584 | 
            +
                  
         | 
| 585 | 
            +
                  self.logger.progname = nil
         | 
| 395 586 | 
             
                  unless @@on_complete.nil?
         | 
| 396 587 | 
             
                    self.cloaker(&(@@on_complete)).bind(self).call(@feed_href_list)
         | 
| 397 588 | 
             
                  end
         | 
    
        metadata
    CHANGED
    
    | @@ -3,8 +3,8 @@ rubygems_version: 0.8.11 | |
| 3 3 | 
             
            specification_version: 1
         | 
| 4 4 | 
             
            name: feedupdater
         | 
| 5 5 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 6 | 
            -
              version: 0. | 
| 7 | 
            -
            date: 2006-04- | 
| 6 | 
            +
              version: 0.2.0
         | 
| 7 | 
            +
            date: 2006-04-17 00:00:00 -07:00
         | 
| 8 8 | 
             
            summary: Automatic feed updater daemon.
         | 
| 9 9 | 
             
            require_paths: 
         | 
| 10 10 | 
             
              - lib
         | 
| @@ -32,7 +32,6 @@ files: | |
| 32 32 | 
             
              - bin
         | 
| 33 33 | 
             
              - CHANGELOG
         | 
| 34 34 | 
             
              - config
         | 
| 35 | 
            -
              - doc
         | 
| 36 35 | 
             
              - example
         | 
| 37 36 | 
             
              - lib
         | 
| 38 37 | 
             
              - log
         | 
| @@ -55,7 +54,6 @@ files: | |
| 55 54 | 
             
              - lib/feed_updater/vendor/daemons/pid.rb
         | 
| 56 55 | 
             
              - lib/feed_updater/vendor/daemons/pidfile.rb
         | 
| 57 56 | 
             
              - lib/feed_updater/vendor/daemons/pidmem.rb
         | 
| 58 | 
            -
              - config/feed_updater.pid
         | 
| 59 57 | 
             
              - config/feed_updater.yml
         | 
| 60 58 | 
             
              - example/custom_updater.rb
         | 
| 61 59 | 
             
            test_files: []
         | 
    
        data/config/feed_updater.pid
    DELETED
    
    | @@ -1 +0,0 @@ | |
| 1 | 
            -
            617
         |