#!/usr/bin/env ruby # # Copyright (c) Perforce Software, Inc., 2014. All rights reserved # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE # SOFTWARE, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH # DAMAGE. # # Triggers: # CreateThumbnails change-commit ... "/path/to/file/CreateThumbnails.rb # %serverport% %change%" # # Usage: CreateThumbnails.rb serverport change [-r] # # # Description: # Goes through the changelist looking for files that can be given a # thumbnail. Creates the PNG thumbnails using imagemagick, then sends # the thumbnail to the server as a hex string. # # By default this trigger will attempt to make a thumbnail of any file # that has an extension. For instance, it will try and fail to make a # thumbnail for .txt and .sh files. If you would like to restrict the # file types that this trigger will attempt to make thumbnails for, use # the '-r' option, and add the extension to the 'exts' array. The case of # the extensions does not matter. # SET THESE OR TRIGGER WILL NOT WORK p4bin = '/usr/local/bin/p4' convertbin = '/usr/local/bin/convert' user = 'example' client = 'example-ws' passwd = 'secret' # ALL SET exts = [] exts << 'ppm' << 'bmp' << 'jpg' << 'jpeg' << 'bpm'<< 'gif' << 'pgm' << 'png' exts << 'xbm' << 'xpm' << 'tga' << 'psd' << 'ai' describe_regex = /^.+(\/\/[^\/]+[^\.]*?([^\/]+)(\.([^#]+)){1}#[0-9]+).+$/ # With the example string '... //depot/images/flower.png#1 add' # '//depot/images/flower.png#1' = '\1' # 'flower' = '\2' # 'png' = '\4' lbrFile_regex = /\A.*lbrFile\s+\/\/([^\n]+).*\z/m #'\1' = file lbrRev_regex = /\A.*lbrRev\s+([^\n]+).*\z/m #'\1' = rev lbrType_regex = /\A.*lbrType\s+([^\n]+).*\z/m #'\1' = type require 'zlib' require 'tempfile' def bin_to_hex(s) s.each_byte.map {|b| b.to_s(16).rjust(2, '0')}.join end def valid_ext?(extension, exts) exts.each do |ext| return true if (0 == extension.casecmp(ext)) end return false end begin if ARGV.length < 2 || ARGV.length > 3 puts 'Usage: CreateThumbnails.rb serverport change [-r]' exit 1 end if ARGV.length == 3 if (ARGV[2] != '-r') puts 'Usage: CreateThumbnails.rb serverport change [-r]' exit 1 end end serverport = ARGV[0] change = ARGV[1] opt3 = ARGV[2] p4 = "#{p4bin} -p #{serverport} -u #{user} -c #{client} -P #{passwd}" # Filter changed files and add them to files list files = [] describe_output = `#{p4} describe -s #{change}` describe_output.each_line do |line| if line =~ describe_regex valid_ext = true if ('-r' == opt3) extension = line.gsub(describe_regex, '\4').chomp valid_ext = valid_ext?(extension, exts) end files << line if (valid_ext) end end # Try to make a thumbnail for each file in list files.each do |file| begin depot_file_full = file.gsub(describe_regex, '\1').chomp file_name = file.gsub(describe_regex, '\2').chomp fstat_output = `#{p4} fstat -Oc #{depot_file_full}` lbrFile = fstat_output.gsub(lbrFile_regex, '\1') lbrRev = fstat_output.gsub(lbrRev_regex, '\1') lbrType = fstat_output.gsub(lbrType_regex, '\1') if ('binary' == lbrType || 'ubinary' == lbrType) lbr_file_full = "#{lbrFile.downcase},d/#{lbrRev}" # Binary files must be decompressed and contents stored in temp file if (lbrType == 'binary') lbr_file_gz = "#{lbr_file_full}.gz" temp_file = Tempfile.new(file_name) temp_file.write(Zlib::GzipReader.open(lbr_file_gz) {|gz| gz.read}) lbr_file_full = temp_file.path end thumb_name = "#{file_name}_CreateThumbnails_thumb.png" if system("#{convertbin} #{lbr_file_full} \ -thumbnail 240x240^ #{thumb_name} 2>/dev/null") thumb_string = File.read(thumb_name) hex_image = bin_to_hex(thumb_string) File.open(thumb_name, "w") {|f| f.write(hex_image)} `cat #{thumb_name} | #{p4} attribute -e -f -n thumb -i \ #{depot_file_full}` File.delete(thumb_name) end temp_file.unlink if (lbrType == 'binary') end rescue Zlib::GzipReader::Error end end end exit 0