sppmg

sl-nethack.sh

Feb 6th, 2014
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 14.26 KB | None | 0 0
  1. #!/bin/bash
  2. # set -x
  3. # trap read debug
  4. version="2.5.140207"
  5. comment_file="comment.txt"
  6. ######## database var ########
  7. declare -A db_backup_file_dir db_game_files
  8. db_backup_file_dir["nethack"]="${HOME}/nethack"
  9. db_game_files["nethack"]="/var/games/nethack/save/${{UID}${USER}.gz"
  10. #db_backup_file_dir["test"]="/tmp/sppmg/test"
  11. #db_game_files["test"]="/home/sppmg/prog/nethack/test.txt"
  12. ######## program var ########
  13. game_name="`basename $0 |sed -r 's/^sl-(.*).sh$/\1/'`"
  14. backup_file_dir="${db_backup_file_dir["${game_name}"]}"
  15. game_files="${db_game_files["${game_name}"]}"
  16. trash_dir="${backup_file_dir}/trash"
  17.  
  18. game_dir=`dirname "${game_files}"`
  19. game_target=`basename "${game_files}"`
  20.  
  21.  
  22. get_fid_last(){
  23.     # This function will get last ID and check exist.
  24.     # The input is number save in $fid. Length of fid will <= 10+1. If length != 10+1(count by wc) then search file.
  25.     # And function will check it.
  26.     local fid_old=$fid
  27.     echo $(echo "$fid" | wc -m )
  28.     case $(echo "$fid" | wc -m ) in # here don't chenge to " wc -m <<< $fid " , because busybox can't run
  29.         1 ) # For no fid
  30.             fid=$( ls -1r "${backup_file_dir}" | sed -nr '/^([0-9]{10})\.tar\.gz$/ {s/\.tar\.gz//p;q}' )
  31.             ;;
  32.         11 )    # Do nothing for correct length
  33.             ;;
  34.         * ) # less then 8 char , arg only pass 1 to 8 number to here . (1 to 9 of wc output)
  35.             fid=$(ls -1r "${backup_file_dir}" | sed -nr '/^[0-9]*'$fid'\.tar\.gz$/{s/\.tar\.gz//p;q}' )
  36.             ;;
  37.     esac
  38.     if [ -z "$fid" ] ; then
  39.         echo "Error: No file can be load."
  40.         exit 1
  41.     elif ! [ -a "${backup_file_dir}/${fid}.tar.gz" ] ; then
  42.         echo "Error: No search file ID similar to $fid_old in ${backup_file_dir}"
  43.         exit 1
  44.     fi
  45.  
  46. }
  47.  
  48. get_fid_new(){
  49.     # This function will get a new ID.
  50.     # if no search last ID, It will give a new id too.
  51.     #local fid_last=( $(ls -1 "${backup_file_dir}" |sed -nr 's/([0-9]{8})([0-9]{2})\.tar.gz$/\1 \2/p'|tail -n 1) )
  52.     local fid_last=( $(ls -1r "${backup_file_dir}" | sed -nr '0,/^([0-9]{10})\.tar\.gz$/{s/([0-9]{8})([0-9]{2})\.tar\.gz$/\1 \2/p}') )
  53.    
  54.     if [ "${fid_last[1]}" -ge 99 ] ; then
  55.         echo "Warn: Today had 99 records, please take a rest.  :)"
  56.         exit 1
  57.     fi
  58.    
  59.     if [ "$(date +%Y%m%d)" == "${fid_last[0]}" ] ; then
  60.         fid=$( printf "%d%02d\n" ${fid_last[0]} $((10#${fid_last[1]}+1)) )  # base is 10
  61.     else
  62.         fid="$(date +%Y%m%d)01"
  63.     fi
  64. }
  65.  
  66. mk_comment_header(){
  67.     # header for txt2tags
  68.     echo "${game_name} backup comment. support txt2tags format." > "${backup_file_dir}/${comment_file}"
  69.     echo "${USER}" >> "${backup_file_dir}/${comment_file}"
  70.     echo '%%date' >> "${backup_file_dir}/${comment_file}"
  71.     # setting of txt2tags
  72.     echo "" >> ${backup_file_dir}/${comment_file}
  73. }
  74. write_comment(){    # usage : write_comment $fid $title
  75.     [ -s "${backup_file_dir}/${comment_file}" ] || mk_comment_header
  76.     echo "==${1} ${2}==" >> "${backup_file_dir}/${comment_file}"
  77.     echo "" >> "${backup_file_dir}/${comment_file}"
  78. }
  79.  
  80. read_comment(){     # usage : read_comment $fid
  81.    
  82.     if [ -a "${backup_file_dir}/${comment_file}" ] ; then
  83.         sed -nr '/^=='${1}' .*==$/,/^==[0-9]{10} .*==$/ {s/^=='${1}' (.*)==$/\1/; /^==[0-9]{10} .*==$/b; p}' "${backup_file_dir}/${comment_file}"
  84.         return 0
  85.     else
  86.         echo "Error : There is no ${comment_file} in ${backup_file_dir}"
  87.         return 1
  88.     fi
  89.    
  90. }
  91. delete_comment(){   # usage : delete_comment $fid
  92.    
  93.     # delete title to next title
  94.     sed -ri '/^=='${1}' .*==$/,/^==[0-9]{10} .*==$/ {/^=='${1}' .*==$/d; /^==[0-9]{10} .*==$/b; d}' "${comment_file}"
  95.    
  96.    
  97. }
  98. print_comment(){    # usage : print_comment $fid
  99.     echo "_____ ${1} _____"                                                                                                              
  100.     local cmt="$(read_comment ${1} )"
  101.     echo "<<< $(echo "$cmt" | sed -n '1p' ) >>>"    # Title
  102.     echo "$(echo "$cmt" | sed -n '2,$p' )"
  103. }
  104. mv_trash(){     # usage : mv_trash $fid
  105.     [ -d "${trash_dir}" ] || `mkdir "${trash_dir}"`
  106.     if [ "$1" != "tmp" ] ; then
  107.         read_comment ${1} >  "${backup_file_dir}/comment_${1}.txt"
  108.         delete_comment ${1}
  109.         gzip -d "${backup_file_dir}/${1}.tar.gz"
  110.         tar -rf "${backup_file_dir}/${1}.tar" -C "${backup_file_dir}" "comment_${1}.txt"
  111.         gzip "${backup_file_dir}/${1}.tar"
  112.         rm "${backup_file_dir}/comment_${1}.txt"
  113.     fi
  114.     # add delete date and id before original file name
  115.    
  116.     #local fid_last=( $(ls -1 "${trash_dir}" |sed -nr 's/([0-9]{8})([0-9]{2})-.*\.tar.gz$/\1 \2/p'|tail -n 1) )
  117.     local fid_last=( $(ls -1r "${trash_dir}" | sed -nr '0,/^([0-9]{10})-.*\.tar\.gz$/{s/([0-9]{8})([0-9]{2})-.*\.tar\.gz$/\1 \2/p}') )
  118.     if [ "$(date +%Y%m%d)" == "${fid_last[0]}" ] ; then
  119.         local fid_del="$( printf "%d%02d\n" ${fid_last[0]} $((10#${fid_last[1]}+1)) )-${1}"
  120.     else
  121.         local fid_del="$(date +%Y%m%d)01-${1}"
  122.     fi
  123.    
  124.     mv "${backup_file_dir}/${1}.tar.gz" "${trash_dir}/${fid_del}.tar.gz"
  125.     # Check trash file number
  126.     # it's will rm more then 30 (write after sed). find for send absolute path of file to xargs.
  127.     find "${trash_dir}" -regextype posix-extended -regex '.*[0-9]{10}-.*.tar.gz'|sort -r |sed -n '31,$ p' | xargs --no-run-if-empty rm
  128.    
  129. }
  130.  
  131.  
  132. # Parsing command line arguments
  133. fid=""
  134. op=""
  135. set -o noglob   # for "*" in $* , if no add this line , * will expansion.
  136. while [ $# -gt 0 ]
  137. do
  138.     case "$1" in
  139.         -sn)    op="save_to_new"    ;;
  140.         -st)    op="save_to_tmp"    ;;
  141.         -ln)    op="load_normal"
  142.             if [[ "$2" =~ [0-9]{1,10} ]] ; then
  143.                 fid=$2
  144.                 shift
  145.             fi
  146.             ;;
  147.         -lt)    op="load_tmp"       ;;
  148.         -dn)    op="delete_normal"
  149.             if [[ "$2" =~ [0-9]{1,10} ]] ; then
  150.                 fid=$2
  151.                 shift
  152.             fi
  153.             ;;
  154.         -dt)    op="delete_tmp"     ;;
  155.         -mt)    op="move_tmp"       ;;
  156.         -lc)    op="list_comment"  
  157.             if [[ "$2" =~ [0-9]{1,10} ]] ; then
  158.                 fid=$2
  159.                 shift
  160.             fi
  161.             ;;
  162.         -ec)    op="edit_comment"
  163.             if [[ "$2" =~ [0-9]{1,10} ]] ; then
  164.                 fid=$2
  165.                 shift
  166.             else
  167.                 echo "Plese select a file ID"
  168.                 op="list_comment"
  169.             fi
  170.             ;;
  171.         -h )    op="help-short"
  172.             ;;
  173.         -hf )   op="help-full"
  174.             ;;
  175.         -xch )  op="export_comment_html"
  176.             ;;
  177.         *)      arg=( ${arg[*]} $1)
  178.             ;;
  179.     esac
  180.     shift
  181. done
  182. comment_title="${arg[*]}"
  183. #set +o noglob
  184.  
  185. if [ -z "$op" ] ; then
  186.     echo "Error : Invalid option."
  187.     op="help-short"
  188. elif [ "$op" == "list_comment" -o "$op" == "edit_comment" -o "$op" == "export_comment_html" ] ; then
  189.     if ! [ -a "${backup_file_dir}/${comment_file}" ] ; then
  190.         echo "Error : There is no ${comment_file} in ${backup_file_dir}"
  191.         exit 1
  192.     fi
  193. fi
  194.  
  195. # check folder
  196. if [ "$op" != "help-short" ] && [ "$op" != "help-full" ] ; then
  197.     if ! [ -a "${game_files}" ] ; then
  198.         echo -e "Error: Backup target not found. please check config in script. \\n"
  199.         op="help-full"
  200.     elif [ ! -d "${backup_file_dir}" ] ; then
  201.         read -p "There is no backup folder ( ${backup_file_dir} ), make new one? [y/n] " -t 10 ans
  202.         if [[ "$ans" =~ [yY] ]] ; then
  203.             mkdir -p "${backup_file_dir}" || { echo "Error: Can't make folder in  ${backup_file_dir}"; exit 1 ;}
  204.         else
  205.             echo "Error : This script need a backup folder !"
  206.             echo "Please use \"$(basename $0) -hf\" to get more infomation."
  207.             exit 1
  208.         fi
  209.     fi
  210. fi
  211.  
  212.  
  213.  
  214. # check fid is number only
  215.  
  216. case "${op}" in
  217.     "help-short" )
  218.     echo "
  219. Option:
  220.     -sn [Title] Save to new backup.
  221.     -st     Save to temporary backup. Can't add comment
  222.     -ln [ID]    Load backup file from (normal) backup
  223.     -lt     Load backup file from temporary backup
  224.     -dn [ID]    Delete normal backup file
  225.     -dt     Delete temporary backup file
  226.     -mt [Title] Move temporary to normal
  227.     -lc [ID]    List comment titles or watch special comment
  228.     -ec ID      Edit special comment
  229.     -h      Show short help message.
  230.     -hf     Show full help message.(include how to install)
  231.     -xch        Export to HTML file by txt2tags
  232. "
  233.     ;;
  234.     "help-full" )
  235.     echo "
  236. Introduction:
  237.     This script can help you backup/restore file.
  238.     Aim for game record, but not only game.
  239.     In Taiwan, we call this \"SL magic\".
  240.    
  241.     Feature :
  242.     1. Easy backup and restore
  243.     2. Comment each backup. You can edit later and export by txt2tags.
  244.     3. Backup is compressd.
  245.     4. Portable, backup files and comment in same folder.
  246.     5. One script for different game.
  247.  
  248. Synopsis:
  249.     $(basename $0) [OPTION] [BACKUP ID | COMMENT TITLE]
  250.  
  251. Option:
  252.     -sn [Title] Save to new backup.
  253.     -st     Save to temporary backup. Can't add comment
  254.     -ln [ID]    Load backup file from (normal) backup
  255.     -lt     Load backup file from temporary backup
  256.     -dn [ID]    Delete normal backup file
  257.     -dt     Delete temporary backup file
  258.     -mt [Title] Move temporary to normal
  259.     -lc [ID]    List comment titles or watch special comment
  260.     -ec ID      Edit special comment
  261.     -h      Show short help message.
  262.     -hf     Show full help message.(include how to install)
  263.     -xch        Export to HTML file by txt2tags
  264.    
  265.     ID format is YYYYMMDDNN. (Year,Month,Date,Number[max=99])
  266.     You can only use partial ID, It can be identify. If you
  267.     don't special ID, default is last.
  268.    
  269. Example:
  270.     Backup files
  271.         $(basename $0) -sn
  272.         $(basename $0) -sn It\'s a big step.
  273.         (You nees add \ before ' \" * because shell )
  274.    
  275.     Load backup file
  276.         $(basename $0) -ln
  277.         $(basename $0) -ln 2013112201
  278.         $(basename $0) -ln 1
  279.         (Use partial ID)
  280.  
  281. Configure:
  282.     This script can backup single path (include file and folder),
  283.     You need special which is backup target and where is backup folder.
  284.     Please edit \"database var\" section in this script. Change the game
  285.     name and path.
  286.     eg:db_game_files[\"gamename\"]=\"path\"
  287.  
  288.     For more backup target,add path variable pair to \"database var\"
  289.     section. Change the name of script to sl-gamename.sh
  290.     (replace gamename to what you want.)
  291.     You can use (hard) links to save space by different link name.
  292.    
  293.     The default editor is vi. If you don't like it, please change code
  294.     by replace 'vi' word. (I want use eval, but busybox no eval ... )
  295.  
  296. Author:
  297.     Written by sppmg ( https://github.com/sppmg )
  298.     Version = ${version}
  299.  
  300. Copyright:
  301.     This is free software: you are free to change and redistribute it.
  302.     There is NO WARRANTY, to the extent permitted by law.
  303. "
  304.         ;;
  305.     "save_to_new" )
  306.         get_fid_new
  307.         tar -czf "${backup_file_dir}/${fid}.tar.gz" -C "${game_dir}" "${game_target}" || { echo "Error: Can't save file to ${backup_file_dir}/${fid}.tar.gz" ; exit 1 ; }
  308.         write_comment $fid "$comment_title"
  309.         echo Saved to ${fid}
  310.         ;;
  311.     "save_to_tmp" )
  312.         # No check overwrite here.
  313.         tar -czf "${backup_file_dir}/tmp.tar.gz" -C "${game_dir}" "${game_target}" ||  { echo "Error: Can't save file to ${backup_file_dir}/tmp.tar.gz" ; exit 1 ; }
  314.         echo Saved to tmp
  315.         ;;
  316.     "load_normal" )
  317.         get_fid_last
  318.         print_comment $fid
  319.         read -p "Overwrite \"${game_files}\" by $fid ? [y/n] " -t 10 ans
  320.         if [[ "$ans" =~ [yY] ]] ; then
  321.             tar -xzf "${backup_file_dir}/${fid}.tar.gz" -C "${game_dir}" || { echo "Error: Can't load file from ${backup_file_dir}/${fid}.tar.gz" ; exit 1 ; }
  322.             echo loaded ${fid}
  323.         else
  324.             echo Canceled
  325.         fi
  326.         ;;
  327.     "load_tmp" )
  328.         [ -a "${backup_file_dir}/tmp.tar.gz" ] || { echo "Error: There is no tmp file in ${backup_file_dir}" ; exit 1 ; }
  329.         read -p "Overwrite \"${game_files}\" by tmp ? [y/n] " -t 10 ans
  330.         if [[ "$ans" =~ [yY] ]] ; then
  331.             tar -xzf "${backup_file_dir}/tmp.tar.gz" -C "${game_dir}" || { echo "Error: Can't load file from ${backup_file_dir}/tmp.tar.gz" ; exit 1 ; }
  332.             echo Loaded tmp
  333.         else
  334.             echo Canceled
  335.         fi
  336.        
  337.         ;;
  338.     "delete_normal" )
  339.         get_fid_last
  340.         print_comment $fid
  341.         echo ----------------------
  342.         read -p "Delete $fid ? [y/n] " -t 10 ans
  343.         if [[ "$ans" =~ [yY] ]] ; then
  344.             mv_trash "${fid}"
  345.             echo Deleted
  346.         else
  347.             echo Canceled
  348.         fi
  349.        
  350.         ;;
  351.     "delete_tmp" )
  352.         [ -a "${backup_file_dir}/tmp.tar.gz" ] || { echo "Error: There is no tmp file in ${backup_file_dir}" ; exit 1 ; }
  353.         read -p "Delete tmp file? [y/n] " -t 10 ans
  354.         if [[ "$ans" =~ [yY] ]] ; then
  355.             mv_trash "tmp"
  356.             echo Deleted
  357.         else
  358.             echo Canceled
  359.         fi
  360.         ;;
  361.     "move_tmp" )
  362.         [ -a "${backup_file_dir}/tmp.tar.gz" ] || { echo "Error: There is no tmp file in ${backup_file_dir}" ; exit 1 ; }
  363.         get_fid_new
  364.         cp "${backup_file_dir}"/{tmp.tar.gz,"${fid}".tar.gz} || { echo "Error: Can't load file from ${backup_file_dir}/tmp.tar.gz" ; exit 1 ; }
  365.         # add comment
  366.         echo "Created new file $fid from tmp"
  367.         # Don't add this check to -sn because speed.
  368.         if [ -z "$comment_title" ] ; then
  369.             read -p "Type a title of comment? [y/n] " -t 10 ans
  370.             if [[ "$ans" =~ [yY] ]] ; then
  371.                 read -p "Title > " comment_title
  372.             fi
  373.         fi
  374.         write_comment "$fid" "$comment_title"
  375.         ;;
  376.     "list_comment" )
  377.         if [ -z "$fid" ] ; then
  378.             sed -nr -e 's/^==([0-9]{10}) (.*)==$/\1 -> \2/gp' "${backup_file_dir}/${comment_file}" |sort
  379.             echo "Comment in ${backup_file_dir}/${comment_file}"
  380.         else
  381.             get_fid_last
  382.             print_comment $fid
  383.         fi
  384.         ;;
  385.     "edit_comment" )
  386.         # get title and content and save to tmp file
  387.         # this tmp file formated (delete txt2tags title mark '= = ' and last blank line)
  388.         get_fid_last
  389.         read -p "Edit comment of ${fid} ? [y/n] " -t 10 ans
  390.         if [[ "$ans" =~ [nN] ]] ; then
  391.             echo Canceled
  392.             exit 0
  393.         fi
  394.        
  395.         read_comment ${fid} >  "${backup_file_dir}/comment_new_${fid}.txt"
  396.         vi "${backup_file_dir}/comment_new_${fid}.txt"
  397.        
  398.         # format new text file
  399.             # translate first line to title form (can't use -ir , only -ri ??? )
  400.         sed -ri '1 {s/(.*)/=='${fid}' \1==/}' "${backup_file_dir}/comment_new_${fid}.txt"
  401.             # make sure last line is blank (I don't know how to combine to 1 line command.)
  402.         last_line=$(sed -nr '$ {/^$/!p}' "${backup_file_dir}/comment_new_${fid}.txt")
  403.         [ -n "$last_line" ] && $(echo "" >> "${backup_file_dir}/comment_new_${fid}.txt")
  404.        
  405.         # inster new comment text. inster mark line -> delete fid's comment -> inster new comment -> delete mark word.
  406.        
  407.         random_str="$(dd if=/dev/urandom bs=100 count=1 2>/dev/null | base64 |sed ':a;N;$!ba;s/[\n/+=]//g')" # include [a-Z,0-9],sed removed "\n" "/" "+" "="
  408.        
  409.         # random_str_int=${RANDOM}${RANDOM}${RANDOM}${RANDOM}${RANDOM}  # 0-32767 for each $RANDOM
  410.         mark_line="comment_tmp_mark_${random_str}"
  411.        
  412.         sed -r -e '/^=='${fid}' .*==$/i '${mark_line} -e '/^=='${fid}' .*==$/,/^==[0-9]{10} .*==$/ {/^=='${fid}' .*==$/d; /^==[0-9]{10} .*==$/b; d}' "${backup_file_dir}/${comment_file}" | sed -r -e '/^'${mark_line}'$/r '"${backup_file_dir}/comment_new_${fid}.txt" -e '/^'${mark_line}'$/d' > "${backup_file_dir}/${comment_file}.tmp"
  413.        
  414.         mv "${backup_file_dir}"/{"${comment_file}.tmp","${comment_file}"}
  415.         # delete temporary file
  416.         rm "${backup_file_dir}/comment_new_${fid}.txt"
  417.         ;;
  418.     "export_comment_html" )
  419.         txt2tags -q -t html -i "${backup_file_dir}/${comment_file}" -o "${backup_file_dir}/${comment_file}.html" && echo "Exported comments to ${backup_file_dir}/${comment_file}.html"
  420.         ;;
  421.        
  422. esac
Advertisement
Add Comment
Please, Sign In to add comment