divx118

Download_handle

Apr 4th, 2016
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 12.18 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. #
  4. # Synology Download station file handling
  5. #
  6. # This script will look in the database if a download has finished and then extract, move the file(s) to the desired location.
  7. # It will auto delete files so be very carefull when use it. You may loose data.
  8. # Usage: ./download_handle.pl
  9. #
  10. #
  11. # DISCLAIMER:
  12. #
  13. # (C) 2013 by Maurice van Kruchten ([email protected])
  14. #
  15. # 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;
  16. # either version 3 of the License, or (at your option) any later version.
  17. #
  18. # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  19. # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  20. # See the GNU General Public License for more details.
  21. #
  22. # http://www.gnu.org/licenses/gpl-3.0.txt
  23.  
  24. ############### Commandline arguments check if they are valid.
  25. # You can add more arguments. arguments_value[x] is set to 1 if an argument is passed. Where x is the position in the arguments array starting at 0.
  26. # If an invalid argument is passed help screen will be printed and the script will exit.
  27. @arguments_info = ("show this help","remove all paused items from the database if the download, extraction and moving the files is completed",
  28.         "extra debug info in the log file");
  29. @arguments = ("-help","-remove-paused","-debug");
  30.  
  31. for ($i=0;$i<=$#ARGV;$i++) {
  32.     $p = 0;
  33.     for ($j=0;$j<=$#arguments;$j++) {
  34.         if ($ARGV[$i] eq $arguments[$j]) {
  35.             $arguments_value[$j] = 1;
  36.         }
  37.         else {
  38.             $arguments_value[$j] = 0;
  39.             $p++;
  40.         }
  41.     }
  42.     # check if the argument is valid, else print the help.
  43.     if ($p > $#arguments) {
  44.         $arguments_value[0] = 1;
  45.     }
  46. }
  47.  
  48. if ($arguments_value[0]) {
  49.     print "\nArgument list info download.pl:\n\n";
  50.     print "Usage: ./download.pl argument1 argument2 ...\n\n";
  51.     for ($i=0;$i<=$#arguments;$i++) {
  52.         print "$arguments[$i] --> $arguments_info[$i]\n";
  53.     }
  54.     exit 1;
  55. }
  56. ############### begin of declaring arrays for where to move what, just add more if you want. Note the trailing "/" for the paths.
  57. # Don't change mode 0 except for the path. It is used as a fallback when no mode is found or if there is mixed content.
  58. # change the script_path below for where you have the script.
  59. $script_path =  "/volume1/Extensions/scripts/";
  60.  
  61.  
  62. $exclude_file_path = $script_path . "exclude";
  63. @exclude_array = ("*.[n,N][f,F][o,O]","*.[s,S][f,F][v,V]");
  64. @exclude_rar_array = ("*\.[r,R][0-9]","*\.[r,R][0-9][0-9]","*\.[r,R][0-9][0-9][0-9]","*\.[r,R][a,A][r,R]");
  65. $include_file_path = $script_path . "include";
  66. @include_array = ();
  67.  
  68. $mode = -1;
  69.  
  70. ### mixed --> 0
  71. $dest_array[0] = "/volume1/movie/ready/";
  72. $file_ext_array[0] = "";
  73.  
  74. ### video --> 1
  75. $dest_array[1] = "/volume1/video/3000GbXBMC/tempvideo/";
  76. $file_ext_array[1] = "mpg,avi,mkv,mp4,mov";
  77.  
  78. ### music --> 2
  79. $dest_array[2] = "/volume1/music/";
  80. $file_ext_array[2] = "mp3,flac,ogg";
  81.  
  82. ### iso --> 3
  83. $dest_array[3] = "/volume1/video/3000GbXBMC/games/";
  84. $file_ext_array[3] = "iso";
  85.  
  86. ############### end of declaring arrays for where to move what
  87.  
  88. print "#################### Starting download_handle script ###########################";
  89.  
  90. ### Set global variable paths, database stuff etc
  91.  
  92. $base_path = '/volume1/';
  93. $unrar = '/bin/unrar';
  94. $psql_path = '/bin/psql';
  95. $DB_user = 'admin';
  96. $DB_pwd = '';
  97. $DB_name = 'download';
  98.  
  99. ### Read seeding downloads
  100. @result_array = split(';', read_database(8));
  101. print "Status 8 result @result_array\n";
  102. extract_move_files(8);
  103. ### Read completed downloads
  104. @result_array = split(";", read_database(5));
  105. print "Status 5 result @result_array\n";
  106. extract_move_files(5);
  107. ### Read paused downloads
  108. if ($arguments_value[1]) {
  109.     @result_array = split(";", read_database(3));
  110.     print "Status 3 result @result_array\n";
  111.     extract_move_files(3);
  112. }
  113. ### extract and move the files to the required location.
  114.  
  115. sub extract_move_files {
  116. for ( $i=1 ;$i < $#result_array ; $i++ ) {
  117. $mode = -1;
  118. my @temp = split ('/', $result_array[$i]);
  119. my $file_name = @temp[$#temp];
  120. my $download_path = $base_path . @result_array[$i];
  121. my $file_done = $download_path . "/done";
  122. my $rsync_path = $download_path . "/";
  123.  
  124. ### check if it is a file or dir
  125. if (-f $download_path) {
  126.     print "yes it is a file\n";
  127.     }
  128.     else
  129.     {
  130.     print "nope it is a directory\n";
  131.     }
  132.  
  133.  
  134. ### check if it is already extracted or copied to the new location
  135. if (-f $file_done) {
  136.     print "YES\n";
  137.     if (@_[0] == 5 || @_[0] == 3) {
  138.         # Status completed time to remove everything.
  139.         delete_database($file_name);
  140.         if (system("rm -rf '$download_path'") != 0) {
  141.             print "Failed to remove $download_path\n";
  142.             }
  143.         }
  144.     next;
  145.     }
  146.  
  147. ### make a list of all the files(extensions) so we can see what type we are dealing with and which files need to be extracted
  148. @norar_files=();
  149. if (-e $download_path) {
  150.     ### First see if we have rar files
  151.     @rarlist_array = check_for_rar($download_path);
  152.     @files = ();
  153.     if ($rarlist_array[0] ne "") {
  154.         my $rar_file = "";
  155.         my $j = 0;
  156.         while ($j<=$#rarlist_array) {
  157.             # TODO: what happens if the rar contains a directory with the files inside? if "lb" will list all files following should work.
  158.  
  159.             $rar_file = `$unrar lb '$rarlist_array[$j]'`;
  160.             @rar_file_array = split("\n",$rar_file);
  161.             my @already_exists = grep {/$rar_file_array[0]/} @files; #check if the file already exists, another tricky thing. TODO: improve
  162.             if ($rar_file_array[0] ne "" && $#already_exists == -1) {
  163.                 push(@files, @rar_file_array);
  164.                 $j++;
  165.             }
  166.             else {
  167.             # cleanup the rarlist so we only keep files that can be extracted keep track of the list of files that can not be extracted.
  168.                 if ($#already_exists == -1) {
  169.                     push(@norar_files, $rarlist_array[$j]);
  170.                 }
  171.             splice(@rarlist_array, $j, 1);
  172.             }
  173.         }
  174.        
  175.         if ($files[0] ne "") {
  176.             check_files_ext();
  177.         }
  178.  
  179.     }
  180.     }
  181.     else {
  182.     print "Directory $download_path does not exist\n";
  183.     print "Files don't exist. We are going to delete the entry $file_name in the database\n";
  184.     delete_database($file_name);
  185.     next;
  186.     }
  187.    
  188.  
  189. if ($mode !=0 ) {
  190.     @files = ();
  191.     my $result = `find "$download_path" -type f |grep -Eiv '\\.r[0-9]\$|\\.r[0-9][0-9]\$|\\.r[0-9][0-9][0-9]\$|\\.rar\$'`;
  192.     print "Other files then rar --> $result\n";
  193.     @files = split ("\n",$result);
  194.     check_files_ext();
  195.     }  
  196. if ($mode < 0) {
  197.     # We don't know what it is so make it mixed mode.
  198.     $mode = 0;
  199.     }
  200.  
  201. print "mode = $mode\n";
  202.  
  203.  
  204. my $dest_path = $dest_array[$mode] . $file_name;
  205. if (system("mkdir -p '$dest_path'") != 0 ) {
  206.     print "mkdir -p '$dest_path' Failed\n";
  207.     }
  208.  
  209. if ($rarlist_array[0] ne "") {
  210.     for ($j=0;$j<=$#rarlist_array;$j++) {
  211.         if (system("$unrar e '$rarlist_array[$j]' '$dest_path'" ) != 0) {
  212.             print "unrar failed $dest_path $rarlist_array[$j]\n";
  213.             # Push the failed rar files to the include array so we can rsync them.
  214.             push(@norar_files,$rarlist_array[$j]);
  215.  
  216.         }
  217.         else {
  218.             @exclude_rar_array = ("*\.[r,R][0-9]","*\.[r,R][0-9][0-9]","*\.[r,R][0-9][0-9][0-9]","*\.[r,R][a,A][r,R]");
  219.             print "unrar successfull $dest_path $rarlist_array[$j]\n";
  220.         }
  221.     } #end of for loop $j
  222. }
  223.  
  224.  
  225. ### NOTE: below is not perfect, because we include and exclude based on filename expressions. It could also match a subfolder or if duplicate filenames are used in subfolders.
  226. ### Include will have the upper hand. So what is included with the include file will not be excluded with the exclude file.
  227.  
  228. # Clean up norar_files array by removing paths and replace extension with ".*"
  229. for ($j=0;$j<=$#norar_files;$j++) {
  230.     my @temp1_array = split ("\/",$norar_files[$j]);
  231.     # split the filename to remove the extension.
  232.     my @temp_array = split(/\./,$temp1_array[$#temp1_array]);
  233.     $norar_files[$j] = join("\.",@temp_array[0 .. $#temp_array-1]) . "\.*";
  234. }
  235. # push the arrays to include and exclude array for writing the files.
  236. push (@include_array,@norar_files);
  237. print "include_array = @include_array\n";
  238. push (@exclude_array,@exclude_rar_array);
  239. print "exclude_array = @exclude_array\n";
  240.  
  241. # write the include file.
  242. @write_line = ();
  243. @write_line = @include_array;
  244. write_file($include_file_path);
  245. # write the exclude file.
  246. @write_line = ();
  247. @write_line = @exclude_array;
  248. write_file($exclude_file_path);
  249.        
  250. # using rsync for the rest of the files -extracted archives and -predefined files to skip. @norar_files include
  251. if ( system("rsync -ar --progress --include-from='$include_file_path' --exclude-from='$exclude_file_path' '$rsync_path' '$dest_path'") != 0 ) {
  252.         print "rsync -ar --include-from='$include_file_path' --exclude-from='$exclude_file_path' $rsync_path $dest_path failed\n";
  253.     }
  254.     else {
  255.         print "rsync -ar --include-from='$include_file_path' --exclude-from='$exclude_file_path' $rsync_path $dest_path succesfull\n";
  256.         if ( system("touch '$file_done'") != 0 ) {
  257.             print "touch $file_done failed\n";
  258.             next;
  259.         }
  260.         else {
  261.             print "touch $file_done succesfull for $rsync_path\n";
  262.             next;
  263.         }
  264.     }
  265.  
  266. }
  267.  
  268. } # end sub extract_move_files
  269.  
  270. ### Read database returns a list with full path from the torrents downloading depending on which state is passed. For reference the states are listed below.
  271. # states = {1:'WAITING', 2:'ACTIVE', 3:'PAUSED', 4:'COMPLETING', 5:'COMPLETE', 6:'CHECKING', 8:'SEEDING', 101:'ERROR', 107:'TIMEOUT'}
  272. sub read_database {
  273. my $result  = `$psql_path -d $DB_name $DB_user -c "SELECT destination,filename FROM download_queue where status=@_[0]" -P format=unaligned -R "\;"`;
  274. $result =~ s/\|/\//g;
  275. return $result;
  276. }
  277.  
  278. ### Delete an entry from the database. Filename must be passed. Note that if there are 2 or more entries with the same filename ie from different users all will be deleted.
  279. # For me this is not a problem, but if you don't want this to happen you will need to also keep track of the user instead of only the filenames.
  280. sub delete_database {
  281. my $result  = `$psql_path -d $DB_name $DB_user -c "DELETE FROM download_queue WHERE filename = '@_[0]'" -P format=unaligned -R "\;"`;
  282. # Log the output to see if it was succesfull
  283. print "Deleting '@_[0]' from database --> $result\n";
  284. return $result;
  285. }
  286.  
  287. ### Check the file extensions to set mode from the global array @files.
  288.  
  289. sub check_files_ext {
  290.  
  291.         for ($j=0;$j <= $#files;$j++) {
  292.         my @temp = split(/\./,$files[$j]);
  293.         my $ext = $temp[$#temp];
  294.         if ($arguments_value[2]) {
  295.             print "ext= $ext\n";
  296.         }
  297.         for ($k=1;$k <= $#file_ext_array;$k++) {
  298.             if ($file_ext_array[$k] =~ /$ext/i) {
  299.                 if ($mode > 0 && $mode != $k) {
  300.                     # We have a mixed mode
  301.                     $mode = 0;
  302.                     return;
  303.                     }
  304.                 $mode = $k;
  305.             }
  306.        
  307.        
  308.         }  
  309.     }
  310.     }
  311. ### Check for rar files.
  312. sub check_for_rar {
  313.         # only get files with extension .r1 or .r12 or .r123 or .rar case is ignored
  314.         my $result = `find "@_[0]" -type f |grep -Ei '\\.r[0-9]\$|\\.r[0-9][0-9]\$|\\.r[0-9][0-9][0-9]\$|\\.rar\$'`;
  315.         my @resultrar_array = split("\n",$result);
  316.         my @rarlist_sub_array = ();
  317.         my @rarlist_array1 = ();
  318.         # make an array of the different rar files.
  319.         for ($k=0;$k<=$#resultrar_array;$k++) {
  320.             # first split the path to get the filename so we are sure we don't have problems when a "." exists in the dir name.
  321.             my @temp1_array = split ("\/",$resultrar_array[$k]);
  322.             # split the filename so we can cut off the extension.
  323.             my @temp_array = split(/\./,$temp1_array[$#temp1_array]);
  324.             print "THIS $temp1_array[$#temp1_array]\n";
  325.             my $temp = join("\.",@temp_array[0 .. $#temp_array-1]);
  326.             $same_file = 0;
  327.             for ($j=0;$j<=$#rarlist_array1;$j++) {
  328.                 if ($temp eq $temprarlist_array[$j]) {
  329.                     $same_file = 1;
  330.                     last;
  331.                     }
  332.                     else {
  333.                     $same_file = 0;
  334.                     }
  335.                 }
  336.             if (!$same_file) {
  337.                 my $temp1 = join("\/",@temp1_array[0 .. $#temp1_array-1]);
  338.                 push(@rarlist_array1,$temp1 . "/" . $temp . "\." . @temp_array[$#temparray]);
  339.                 push(@temprarlist_array, $temp);               
  340.                 }
  341.             }
  342.         print "Rar file list from @_[0] --> @rarlist_array1\n";
  343.         return @rarlist_array1;
  344.     }
  345. ### Write file from a global array @write_line, full path filename of the file to write is passed in the function. 
  346. sub write_file {
  347.     unlink @_[0];
  348.     open (MY_FILE, ">>@_[0]");
  349.     for ($j=0;$j<=$#write_line;$j++) {
  350.  
  351.         print MY_FILE "$write_line[$j]\n";
  352.    
  353.     }  
  354.     close MY_FILE;
  355. }  
  356. print "#################### Stopping download_handle script ###########################\n";
Advertisement
Add Comment
Please, Sign In to add comment