#
#--
#
# $Id: download.rb 563 2006-12-29 08:59:41Z thomas $
#
# webgen: template based static website generator
# Copyright (C) 2004 Thomas Leitner
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#++
#
load_plugin 'webgen/plugins/tags/tag_processor'
load_plugin 'webgen/plugins/coreplugins/resourcemanager'
require 'yaml'
require 'uri'
require 'open-uri'
module Tags
class DownloadTag < DefaultTag
infos( :name => 'Tag/Download',
:author => Webgen::AUTHOR,
:summary => "Provides a nice download link and, optional, image "
)
param 'url', nil, 'The URL to the file. Can be a local file or one referenced via HTTP/FTP.'
param 'icon', nil, 'The URL to an icon which will be shown next to the name.'
param 'alwaysShowDownloadIcon', false, 'Specifies if the download icon should always be shown, or only ' +
'when no icon is available for the file type.'
param 'mappingFile', nil, 'An additional mapping file used for mapping extensions to icons.'
set_mandatory 'url', true
depends_on 'Core/ResourceManager'
register_tag 'download'
def initialize( plugin_manager )
super
@plugin_manager['Core/ResourceManager'].append_data( 'webgen-css', '
/* START webgen download tag */
.webgen-file-icon, .webgen-download-icon { vertical-align: middle; }
/* STOP webgen download tag */
' )
@default_mapping = load_mapping( File.join( Webgen.data_dir, 'icon_mapping.yaml' ) )
end
def process_tag( tag, chain )
url = param( 'url' )
return '' if url.nil?
mapping = @default_mapping.dup
mapping.update( load_mapping( param( 'mappingFile' ) ) ) if File.exists?( param( 'mappingFile' ) || '' )
icon = file_icon( File.extname( url ), mapping, chain.last )
output = ''
output << download_icon if param( 'alwaysShowDownloadIcon' ) || icon.nil?
output << icon unless icon.nil?
output << file_link( url, chain.last, chain.first )
output << file_size( url, chain.first )
end
#######
private
#######
def download_icon
""
end
def file_icon( ext, mapping, node )
data = mapping[ext]
src = param( 'icon' )
if src.nil? && !data.nil?
if data[0] == :resource
src = "{resource: #{data[1]}}"
else
icon_node = Node.root( node ).node_for_string( data[1] )
src = node.route_to( icon_node ) unless icon_node.nil?
end
end
(src.nil? ? nil : "")
end
def file_link( url, node, ref_node )
link = if URI.parse( url ).absolute?
url
else
file_node = ref_node.resolve_node( url )
(file_node.nil? ? '' : node.route_to( file_node ))
end
"#{File.basename( url )}"
end
UNIT_NAMES = ['Byte', 'KiB', 'MiB', 'GiB', 'TiB']
def file_size( url, ref_node )
size = nil
catch :size do
begin
if URI.parse( url ).absolute?
open( url, :content_length_proc => proc {|size| throw :size} ) {|f| }
else
file_node = ref_node.resolve_node( url )
size = File.size( file_node.node_info[:src] )
end
rescue
end
end
if size.nil?
log(:warn) { "Could not get file size information for file <#{url}>" }
''
else
size, unit = [size.to_f, 0]
size, unit = [size / 1024, unit + 1] while size > 1024
format_str = if unit == 0
" (%d %s)"
else
" (%.2f %s)"
end
format_str % [size, UNIT_NAMES[unit]]
end
end
def load_mapping( file )
data = YAML::load( File.read( file ) )
mapping = {}
if data['resource-mapping']
data['resource-mapping'].each do |icon, exts|
exts.each {|ext| mapping[ext] = [:resource, icon]}
end
end
if data['file-mapping']
data['file-mapping'].each do |icon, exts|
exts.each {|ext| mapping[ext] = [:file, icon]}
end
end
mapping
end
end
end