#!/usr/bin/ruby # # artspots-update downloads the latest submissions to Artspots and Jaxpad # to a local directory. The intention is to combine this script with # standard Linux applications to get a dynamically updated wallpaper or # screensaver. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # Copyright 2007, Nocte # There are some extra requires here for rubyscript2exe require 'rexml/document' require 'net/http' require 'tempfile' require 'open-uri' require 'optparse' require 'time' begin exit if RUBYSCRIPT2EXE.is_compiling? rescue nil end use_jaxpad = false prune_nr = 0 ARGV.options do |o| o.set_summary_indent(' ') o.banner = 'Usage: artspots-update [options]' o.on('-j', '--jaxpad', 'Download from Jaxpad instead of Artspots') { |use_jaxpad| } o.on('-p', '--prune=N', Integer, 'Keep only the newest N images') { |prune_nr| } o.on('-v', '--version', 'Print version information') { puts 'artspots-update 1.1'; exit } o.on('-h', '--help', 'Show this help message') { puts o; exit } o.parse! end prune = (prune_nr.nil? == false and prune_nr > 0) site = (use_jaxpad ? 'jaxpad' : 'artspots') if prune and prune_nr < 1 puts "--prune must be a positive number" exit end dest_dir = File.join(ENV['HOME'] || ENV['USERPROFILE'], ".#{site}-cache") src = "http://#{site}.com/rss" iurl = "http://#{site}.com/image/" if not File.directory?(dest_dir) begin Dir.mkdir(dest_dir) rescue puts "Error: cannot create directory '#{dest_dir}'" exit end end Dir.chdir(dest_dir) available = Dir.glob("*.title").map!{|x| x.split('.')[0]}.sort downloaded = [] #---------------------------------------------------------------------------- begin xml = REXML::Document.new(open(src){|f|f.read}) rescue puts "Cannot retrieve data from #{src}" exit end xml.elements.each('rss/channel/item') do |item| title = item.elements['title'].text id = item.elements['link'].text.split('/')[-1] url = item.elements['enclosure'].text pubd = item.elements['pubDate'].text ext = url.split('.')[-1] timestamp = Time.parse(pubd).to_i.to_s filename = File.join(dest_dir, timestamp + '.' + ext) fileinfo = File.join(dest_dir, timestamp + '.title') next if not available.empty? and timestamp.to_i <= available[-1].to_i break if prune and downloaded.length == prune_nr begin open(filename, "wb") { |file| file.write(open(url){|f|f.read}) } open(fileinfo, "w") { |file| file.write("#{title} (#{iurl}#{id})") } downloaded.push(timestamp) rescue puts "Failed to download #{url}" end end #---------------------------------------------------------------------------- if prune available = (available + downloaded).sort available[0,available.length - prune_nr].each { |id| ['.title', '.jpg', '.png', '.gif'].each { |ext| File.unlink(File.join(dest_dir, id + ext)) rescue nil } } unless available.length <= prune_nr end