Class: WCC::Prog
- Inherits:
-
Object
- Object
- WCC::Prog
- Defined in:
- lib/wcc.rb
Class Method Summary collapse
- .checkForUpdate(site) ⇒ Object
-
.exit(errno) ⇒ Object
Central exit function, allows wcc a clean shutdown.
-
.load_template(name) ⇒ ERB
Attempts to read the named template file from template.d and converts it into ERB.
-
.run! ⇒ Object
main.
-
.save_template(name, raw_content) ⇒ Object
Attempts to write the given raw content to the named template file in template.d.
Class Method Details
.checkForUpdate(site) ⇒ Object
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 |
# File 'lib/wcc.rb', line 344 def self.checkForUpdate(site) WCC.logger.info "Requesting '#{site.uri.to_s}'" begin res = site.fetch rescue Timeout::Error => ex # don't claim on this return false rescue => ex WCC.logger.error "Cannot connect to #{site.uri.to_s} : #{ex.to_s}" return false end if res.kind_of?(Net::HTTPOK) # be happy! elsif res.kind_of?(Net::HTTPMovedPermanently) loc = res['Location'] if loc.nil? WCC.logger.error "Site #{site.uri.to_s} moved permanently, skippong it - no new location given." else WCC.logger.error "Site #{site.uri.to_s} moved permanently to '#{loc}', skipping it - please update your conf.yml adequately!" end return false elsif res.kind_of?(Net::HTTPSeeOther) or res.kind_of?(Net::HTTPTemporaryRedirect) loc = URI.parse(res['Location']) WCC.logger.warn "Redirect: requesting '#{loc.to_s}'" res = site.fetch_redirect(loc) if not res.kind_of?(Net::HTTPOK) WCC.logger.error "Redirected site #{loc.to_s} returned #{res.code} code, skipping it." WCC.logger.error "Headers: #{res.to_hash.inspect}" return false end elsif res.kind_of?(Net::HTTPUnauthorized) WCC.logger.error "Site #{site.uri.to_s} demands authentication for '#{res['www-authenticate']}', skipping it - consider using 'auth:' option in your conf.yml." return false elsif res.kind_of?(Net::HTTPNotFound) WCC.logger.error "Site #{site.uri.to_s} not found, skipping it." return false elsif res.kind_of?(Net::HTTPForbidden) WCC.logger.error "Site #{site.uri.to_s} forbids access, skipping it." return false elsif res.kind_of?(Net::HTTPInternalServerError) WCC.logger.error "Site #{site.uri.to_s} has internal errors, skipping it." return false elsif res.kind_of?(Net::HTTPServiceUnavailable) #retry_after = res['Retry-After'] WCC.logger.warn "Site #{site.uri.to_s} currently not available, skipping it." return false else WCC.logger.error "Site #{site.uri.to_s} returned #{res.code} code, skipping it." WCC.logger.error "Headers: #{res.to_hash.inspect}" return false end new_content = res.body # detect encoding from http header, meta element, default utf-8 # do not use utf-8 regex because it will fail on non utf-8 pages encoding = (res['content-type'].to_s.match(/;\s*charset=([A-Za-z0-9-]*)/i).to_a[1] || new_content.match(/<meta.*charset=([a-zA-Z0-9-]*).*/i).to_a[1]).to_s.downcase || 'utf-8' WCC.logger.info "Encoding is '#{encoding}'" # convert to utf-8 begin new_content = Iconv.conv('utf-8', encoding, new_content) rescue => ex WCC.logger.error "Cannot convert site from '#{encoding}': #{ex.to_s}" return false end # strip html new_content = new_content.strip_html if site.strip_html? new_hash = Digest::MD5.hexdigest(new_content) WCC.logger.debug "Compare hashes\n old: #{site.hash.to_s}\n new: #{new_hash.to_s}" return false if new_hash == site.hash # do not try diff or anything if site was never checked before if site.new? site.hash, site.content = new_hash, new_content # signal that no diff was posible diff = nil else # save old site to tmp file old_site_file = Tempfile.new("wcc-#{site.id}-") old_site_file.write(site.content) old_site_file.close # calculate labels before updating old_label = "OLD (%s)" % File.mtime(Conf.file(site.id + ".md5")).strftime(DIFF_TIME_FMT) new_label = "NEW (%s)" % Time.now.strftime(DIFF_TIME_FMT) site.hash, site.content = new_hash, new_content # diff between OLD and NEW diff = %x[diff -U 1 --label "#{old_label}" --label "#{new_label}" #{old_site_file.path} #{Conf.file(site.id + '.site')}] end # construct the data made available to filters and templates data = OpenStruct.new data.site = site data.diff = diff.nil? ? nil : WCC::Differ.new(diff) data.tag = Conf[:tag] # HACK: there *was* an update but no notification is required return false if not Filters.accept(data, site.filters) site.notify.each do |name| rec = Conf.recipients[name] if rec.nil? WCC.logger.error "Could not notify recipient #{name} - not found!" else rec.each { |way| way.notify!(data) } end end true end |
.exit(errno) ⇒ Object
Central exit function, allows wcc a clean shutdown.
564 565 566 |
# File 'lib/wcc.rb', line 564 def self.exit(errno) Kernel::exit errno end |
.load_template(name) ⇒ ERB
Attempts to read the named template file from template.d and converts it into ERB.
536 537 538 539 540 541 542 543 544 545 |
# File 'lib/wcc.rb', line 536 def self.load_template(name) t_path = File.join(Conf[:template_dir], name) if File.exists?(t_path) WCC.logger.debug "Load template '#{name}'" t = File.open(t_path, 'r') { |f| f.read } # <> omit newline for lines starting with <% and ending in %> return ERB.new(t, 0, "<>") end nil end |
.run! ⇒ Object
main
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 |
# File 'lib/wcc.rb', line 464 def self.run! # first use of Conf initializes it WCC.logger = Logger.new(STDOUT) # make sure logger is correctly configured Conf.instance # create cache dir for hash and diff files Dir.mkdir(Conf[:cache_dir]) unless File.directory?(Conf[:cache_dir]) if(Conf[:clean]) WCC.logger.warn "Removing hash and diff files..." Dir.foreach(Conf[:cache_dir]) do |f| File.delete(Conf.file(f)) if f =~ /^.*\.(md5|site)$/ end cache_file = Conf.file('cache.yml') WCC.logger.warn "Removing timestamp cache..." File.delete(cache_file) if File.exists?(cache_file) Prog.exit 1 end # read filter.d Dir[File.join(Conf[:filter_dir], '*.rb')].each { |file| require file } # timestamps cache_file = Conf.file('cache.yml') if File.exists?(cache_file) WCC.logger.debug "Load timestamps from '#{cache_file}'" # may be *false* if file is empty yaml = YAML.load_file(cache_file) if not yaml WCC.logger.info "No timestamps loaded" else @@timestamps = yaml['timestamps'] end else @@timestamps = {} end Conf.sites.each do |site| ts_old = (site) ts_new = Time.now.to_i if (ts_new-ts_old) < site.check_interval*60 ts_diff = (ts_new-ts_old)/60 WCC.logger.info "Skipping check for #{site.uri.host.to_s} due to check #{ts_diff} minute#{ts_diff == 1 ? '' : 's'} ago." next end if checkForUpdate(site) WCC.logger.warn "#{site.uri.host.to_s} has an update!" else WCC.logger.info "#{site.uri.host.to_s} is unchanged" end (site, ts_new) end # save timestamps File.open(cache_file, 'w+') do |f| YAML.dump({"timestamps" => @@timestamps}, f) end # shut down notificators Notificators.mappings.each do |name,klass| WCC.logger.debug "Shut down #{klass}" klass.shut_down end end |
.save_template(name, raw_content) ⇒ Object
Attempts to write the given raw content to the named template file in template.d. This should be used to create initial template files on demand and will work only when file does not already exist.
553 554 555 556 557 558 559 560 561 |
# File 'lib/wcc.rb', line 553 def self.save_template(name, raw_content) t_path = File.join(Conf[:template_dir], name) if File.exists?(t_path) WCC.logger.warn "Trying to save template '#{name}' which already exists!" return end WCC.logger.info "Save template '#{name}' to #{t_path}" File.open(t_path, 'w') { |f| f.write(raw_content) } end |