Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- #############################
- #
- # pk3filter script by joki ( #racenet @ quakenet )
- # version 0.5
- #
- # use at your own risk!
- #
- # usage: pk3filter [files]
- #
- # directories can be setup inside the script
- #
- # required tools: bash, zipinfo, unzip, zip, sort (should be included in most linux distributions)
- #
- # bash version info: GNU bash, Version 4.1.5(1)-release (x86_64-pc-linux-gnu)
- #
- #
- #
- # use this script with a bunch of pk3 files. It will detect duplicate files inside the packages and put them into another package inside the package.
- # packages will be sorted in reversed alphabetical order.
- #
- # packages without duplicates will be copied to packageroot
- # packages with duplicates will be repacked and put to packageroot/incomplete
- #
- #############################
- # you may edit the following variables to your needs
- # set directories. they can also be relative
- # tmpdir: any directory you want the temporary files to be stored
- tmpdir="/media/tmpfs" # a tmpfs (ramdisk) might improve performance
- # contentroot: the contents of the packages will be stored here. delete this directory, if you want to start a fresh run.
- # this can also be on a tmpfs, because there will be only empty files inside
- contentroot="/media/tmpfs/content"
- # packageroot: the new ( repacked or copied ) packages will be stored here. repacked packages are in the "incomplete" directory.
- packageroot="/tmp/pk3filter/packages"
- # prefix and suffix for repacked packages. leave empty to use the original filename.
- prefix=""
- # suffix will be added BEFORE file extension
- suffix="_repack"
- # do not edit below ( you may, if you know what you are doing ;)
- oldwd="$PWD"
- newline="
- ";
- failed=0
- empty=0
- complete=0
- incomplete=0
- mkdir -p "$contentroot"
- mkdir -p "$packageroot/incomplete"
- function process_package
- {
- local pk3file="$1"
- local pk3name=`basename "${pk3file}"`
- filename="${pk3name%.*}"
- fileext="${pk3name##*.}"
- if [ "${fileext}" = "${pk3name}" ] ; then
- fileext=""
- else
- fileext=".${fileext}"
- fi
- echo -n "[${filename}] "
- unzipstr=`zipinfo -1 "$pk3file" 2>/dev/null`
- if [ "${unzipstr}" = "" ] ; then
- echo "zipinfo failed. Aborting!"
- let failed++
- return
- fi
- # files: array of files inside the package (including path)
- local files=()
- local f=0 # f: pointer for files array
- # get files and directories and store them in arrays
- # IFS is still newline (required for this for-loop to work)
- for str in $unzipstr ; do
- # zip directory entries are strange, dont use them
- if [ "${str:(-1)}" = "/" ] ; then
- continue;
- fi
- files[$f]="$str"
- let f++
- # strip filename
- local directory="$contentroot/$str"
- directory="${directory%/*}"
- # convert directory to lowercase
- directory="${directory,,}"
- # not really necessary, but nicer to skip root and multiple directories
- case "$directory" in
- "$oldDirectory" ) continue;;
- "$contentroot" ) continue;;
- esac
- oldDirectory="$directory"
- if [ ! -d "${directory}" ] ; then
- mkdir -p "${directory}"
- fi
- done
- # conversion to lowercase
- # str="${str,,}"
- # all filesystem operations are to be lowercase.
- # valid and invalid: arrays of filenames
- local iv=0
- local invalid=()
- # valid is not needed
- #local v=0
- #local valid=()
- # filter valid / invalid files, add valid files to filesystem
- for file in ${files[*]}
- do
- # convert to lowercase for filesystem
- fsFile="$contentroot/${file,,}"
- if [ -f "${fsFile}" ] ; then
- #echo "file already exists: ${file}"
- invalid[$iv]="${file}"
- let iv++
- else
- #echo "touching file: ${fsFile}"
- echo "" > "${fsFile}" # this is a little faster than `touch $fsFile`
- #valid[$v]="${file}"
- #let v++
- fi
- done
- # decide what to do with this package
- if [ ${#files[*]} -eq ${#invalid[*]} ] ; then # all files are duplicate, package will still be created
- echo "duplicate files: all"
- let empty++
- # run repacking in background
- repack_package "${pk3file}" "${filename}" "${fileext}" "${invalid[@]}" &
- return
- elif [ ${#invalid[*]} -gt 0 ] ; then # some files are duplicate
- echo "duplicate files: ${#invalid[*]}"
- let incomplete++
- # run repacking in background
- repack_package "${pk3file}" "${filename}" "${fileext}" "${invalid[@]}" &
- return
- else # all files are unique
- echo "all files are unique!"
- let complete++
- keep_package "${pk3file}" &
- return
- fi
- }
- #####
- # repack_package
- # $1 = pk3file
- # $2 = file name without extension
- # $3 = file extension
- # $4, $5, ... = content files to be renamed in package
- #####
- function repack_package
- {
- local pkgfile="$1"
- shift
- local pkgname="$1"
- shift
- local pkgext="$1"
- shift
- local newpkg="${prefix}${pkgname}${suffix}${pkgext}"
- local insidepkg="${pkgname}_missingfiles${pkgext}"
- # setup temporary directory
- pkgtemp=`mktemp -d "${tmpdir}/pkg_XXXXX"`
- cp "${pkgfile}" "${pkgtemp}/${newpkg}"
- cd "${pkgtemp}"
- # extract duplicates from zipfile
- unzip -qq "${newpkg}" $@
- # create inside package with duplicate files
- zip -qq "${insidepkg}" $@
- # delete old duplicates from zipfile
- zip -qq -d "${newpkg}" $@
- # create dupelist
- local dupelist="${pkgname}_missingfiles.txt"
- # IFS=newline tricking again
- echo "$*" > "${dupelist}"
- # add dupelist and inside package to package
- zip -qq "${newpkg}" "${dupelist}" "${insidepkg}"
- # save repacked package and clean up
- mv "${newpkg}" "$packageroot/incomplete"
- cd "$oldwd"
- rm -rf "${pkgtemp}"
- }
- #####
- # keep_package
- # $1 = pk3file
- #####
- function keep_package
- {
- # copy package to packageroot
- cp "${1}" "${packageroot}"
- }
- oldtime=`date +%s`
- filecount=$#
- oldifs="$IFS"
- IFS="${newline}"
- filelist=`echo "${*}" | sort -r`
- # check if file exists and process it
- for pkg in ${filelist} ; do
- if [ -f "${pkg}" ] ; then
- process_package "${pkg}"
- else
- let filecount--
- fi
- done
- IFS="${oldifs}"
- wait
- newtime=`date +%s`
- #rm -rf "$packageroot" "$contentroot"
- echo ""
- echo "Took $[ $newtime - $oldtime ] seconds for $filecount files"
- echo "Failed to unzip: $failed"
- echo "Empty packages left out: $empty"
- echo "Repacked packages: $incomplete"
- echo "Original packages: $complete"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement