Advertisement
Guest User

fapomatic.pl

a guest
Apr 8th, 2014
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env perl
  2. #
  3. # MPlayer wrapper to select and play random video file(s)
  4. #
  5.  
  6. # TODO: incorporate history-cleanse ?
  7.  
  8. use strict;
  9. use warnings;
  10.  
  11. use File::Find;
  12. use File::stat;
  13.  
  14. #-------------------------------------------------------------------------------------------------------#
  15. ## BEGIN CONFIGURABLE OPTIONS :
  16. #-------------------------------------------------------------------------------------------------------#
  17.  
  18. # Configure your video 'collection' locations here. This is probably the only thing you need to change.
  19. our @Collections=(
  20.     "/Volumes/ENCRYPTED",
  21.     #"/mnt/pr0n",
  22. );
  23.  
  24. # Specify Alternate image viewer, it will take one argument - related filename(s)
  25. our $image_viewer="";
  26.  
  27. # Otherwise the defaults:
  28. our $def_image_viewer_osx="open";
  29. our $def_image_viewer_linux="eog";
  30.  
  31. # Autoplay the files, or give a y/n prompt? 1 = auto, 0 = prompt
  32. our $autoplay="0";
  33.  
  34. # Path to mplayer, and any default options you want to pass along
  35. our $mplayer="mplayer";
  36. our $mplayer_opts="";
  37. #our $mplayer_opts="-display :0";
  38.  
  39. # Supported file types mplayer can handle - if it's not in this list, it won't be played, even though mplayer probably supports it
  40. our @Supported_videos=("mpg","mpeg","avi","wmv","asf","mov","mp4","mkv","m4v","rmvb","flv");
  41.  
  42. # Cover images - some filetypes that may exist in your collection that mplayer should ignore / will not play
  43. our @Supported_images=(".jpg",".png",".gif",".bmp");
  44.  
  45. # Volume Suppression. use Negative integer to decrease mplayer's volume.
  46. our $volume_suppression="-25";
  47. our $volume_mods="";
  48. #our $volume_mods="-af volume=$volume_suppression:0";
  49.  
  50. # Set some default behavior switches; alter for desired behavior
  51. my $version="3.1";      # Current Version.
  52. our $file_info_banner="1";  # Display info about the selected file ?
  53. our $use_colors="1";        # Colorize output ?
  54. our $verbose="0";       # Verbose by default ?
  55. our $very_verbose="0";      # Even more info ?
  56. our $fullscreen="0";        # Fullscreen mplayer ?
  57. our $sort_order="0";        # Sort by mtime (1), vs alphabetical (0)?
  58. our $cover="0";         # Open related images ?
  59. our $nosound="0";       # Nosound (unrecoverable stream) ?     
  60. our $search="0";        # Jump to search prompt ?
  61. our $test_exists="0";       # Simple test for existance of file
  62. our $listing="0";       # List files by default ?
  63. our $list_everything="0";   # List videos, images, and unrelated files ?
  64. our $list_full_paths="0";   # Display full paths for files ?
  65. our $mplayer_output="0";    # Attach to mplayer output ?
  66. our $search_char_min="2";   # Minimum search characters ?
  67. our $specific_result="0";   # Selected file number to play ?
  68. our $debug = "0";       # Debug info by default ?
  69. our $pretend="0";       # No Exec ?
  70. our $auto_sort="1";     # 1 implies -o with -t
  71. our $fork_bomb_protect="1"; # Prevent fork bombing the system with mplayer calls
  72. our $do_exec="0";       # Probably never need to change this.
  73. our $search_char="0";       # Probably never need to change this.
  74. our $custom_dir="0";        # Probably never need to change this.
  75. our $total_videos="0";      # Probably never need to change this.
  76. our $total_images="0";      # Probably never need to change this.
  77. our $total_rejected="0";    # Probably never need to change this.
  78. our $search_term="";        # Probably never need to change this.
  79. our $search_input;      # Probably never need to change this.
  80. our $search_request;        # Probably never need to change this.
  81. our $limit_recent="0";      # Probably never need to change this.
  82. our $limit_time="0";        # Probably never need to change this.
  83. our $old_or_new;        # Probably never need to change this.
  84. our $repeat="0";        # Repeat / Range
  85. our $default_repeat="5";    # Default repeat range
  86. our $repeat_range="0";
  87. our $range_request;
  88. our $repetition;
  89. our $mplayer_max="10";      # Maximum amount of mplayer windows before limiting spawn
  90. our $video_width="0";
  91. our $video_height="0";
  92. our $target_x="0";
  93. our $target_y="0";
  94. our $screen_res_x="0";
  95. our $screen_res_y="0";
  96. our $resolution="";
  97. our $mplayer_opts_geo="";
  98. our $kill_players="0";
  99. our $kill_signal="hup";
  100. our $user_ok="";
  101. our $null_term="0";
  102. our $exclude_term="";
  103.  
  104. # Define highlight color codes
  105. my $color_bold = "\033[0;1m";
  106. my $color_white = "\033[0m";
  107. my $color_black = "\033[1;30m";
  108. my $color_red = "\033[1;31m";
  109. my $color_green = "\033[1;32m";
  110. my $color_blue = "\033[1;34m";
  111. my $color_yellow = "\033[1;33m";
  112. my $color_cyan = "\033[1;36m";
  113. my $color_purple = "\033[1;35m";
  114. my $color_dark_blue = "\033[0;34m";
  115. my $color_dark_red = "\033[0;31m";
  116. my $color_dark_green = "\033[0;32m";
  117. my $color_dark_yellow = "\033[0;33m";
  118. my $color_dark_cyan = "\033[0;36m";
  119. my $color_dark_purple = "\033[0;35m";
  120. my $color_dark_black = "\033[0;30m";
  121.  
  122. # Set which color to actually use for various 'tags'
  123. our $colortag_name = $color_red;
  124. our $colortag_search = $color_cyan;
  125. our $colortag_number = $color_dark_yellow;
  126. our $colortag_mtime = $color_dark_blue;
  127. our $colortag_default = $color_white;
  128. our $colortag_online = $color_bold;
  129. our $colortag_offline = $color_bold;
  130. our $colortag_warning = $color_bold;
  131. our $colortag_error = $color_bold;
  132. our $colortag_pretend = $color_dark_purple;
  133. our $colortag_exec = $color_bold;
  134. our $colortag_vidlabel = $color_bold;
  135. our $colortag_abort = $color_yellow;
  136. our $colortag_category = $color_blue;
  137. our $colortag_imgname = $color_purple;
  138. our $colortag_selection = $color_dark_red;
  139.  
  140. # Text used for the static variable tags;
  141. our $online_label = "AVAILABLE";
  142. our $offline_label = "UNAVAILABLE";
  143. our $warning_label = "WARNING";
  144. our $error_label = "ERROR";
  145. our $pretend_label = "PRETEND";
  146. our $exists_label = "FOUND";
  147. our $exec_label = "EXEC";
  148. our $abort_label = "ABORT";
  149. our $yes_label = "y";
  150. our $no_label = "n";
  151. our $category_label = "CATEGORY";
  152. our $vid_label = "VID FILE";
  153.  
  154. # Initial self awareness for this script
  155. my @ScriptPath=split(/\//,$0);
  156. our $script_name=$ScriptPath[$#ScriptPath];
  157.  
  158. # Required commands used by this script
  159. our @Required=("$mplayer","grep");
  160.  
  161. #-------------------------------------------------------------------------------------------------------#
  162. &Init; ## END CONFIGURABLE OPTIONS : YOU SHOULDN'T NEED TO EDIT ANYTHING BELOW THIS POINT
  163. #-------------------------------------------------------------------------------------------------------#
  164.  
  165. sub GlobalVars {
  166.  
  167.     if ($debug == 1) {
  168.         print qq| <Enter Sub> GlobalVars\n|;
  169.     }
  170.  
  171.     our $mplayer = $main::mplayer;
  172.     our $mplayer_opts = $main::mplayer_opts;
  173.     our $volume_suppression = $main::volume_suppression;
  174.     our $volume_mods = $main::volume_mods;
  175.     our $image_viewer = $main::image_viewer;
  176.     our $version = $main::version;
  177.     our @Collections = @main::Collections;
  178.     our @Videos = @main::Videos;
  179.     our @Images = @main::Images;
  180.     our @Rejected = @main::Rejected;
  181.     our @Supported_videos = @main::Supported_videos;
  182.     our @Supported_images = @main::Supported_images;
  183.     our @AlreadyPicked=@main::AlreadyPicked;
  184. }
  185.  
  186. sub Init {
  187.  
  188.     # Set & Get some initial requirements
  189.     &GlobalVars;
  190.  
  191.     print qq|\n|;
  192.  
  193.     if (@ARGV) {
  194.         &CheckArgs;
  195.     }
  196.    
  197.     if ($debug == 1) {
  198.         print qq| <Enter Sub> Init\n|;
  199.     }
  200.  
  201.     # swap out colors
  202.     if ($use_colors == 1) {
  203.         $online_label = $colortag_online . "$online_label" . $colortag_default;
  204.         $offline_label = $colortag_offline . "$offline_label" . $colortag_default;
  205.         $warning_label = $colortag_error . "$warning_label" . $colortag_default;
  206.         $error_label = $colortag_error . "$error_label" . $colortag_default;
  207.         $pretend_label = $colortag_pretend . "$pretend_label" . $colortag_default;
  208.         $exists_label = $colortag_pretend . "$exists_label" . $colortag_default;
  209.         $exec_label = $colortag_exec . "$exec_label" . $colortag_default;
  210.         $abort_label = $colortag_abort . "$abort_label" . $colortag_default;
  211.         $yes_label = $color_bold . "$yes_label" . $colortag_default;
  212.         $no_label = $color_bold . "$no_label" . $colortag_default;
  213.         $vid_label = $colortag_vidlabel . $vid_label . $colortag_default;
  214.         $script_name = $color_bold . $script_name . $colortag_default;
  215.         #$category_label = $colortag_category . "$category_label" . $colortag_default;
  216.     }
  217.    
  218.     if ($autoplay == 1) {
  219.         our $do_exec = 1;
  220.     }
  221.  
  222.     # Check some command dependancies
  223.     &DepCheck;
  224.    
  225.     # If one of the args is a directory, play file from requested dir
  226.     if ($custom_dir == 1) {
  227.         our $dir=$main::user_dir;
  228.        
  229.         my $dirlabel = $color_bold . "USING DIR" . $colortag_default;
  230.         print qq| [$dirlabel]: $dir\n\n|;
  231.        
  232.         if ($search == 1) {
  233.             &Search;
  234.         }
  235.         else {
  236.             #Draw random file from user dir (will inherit dir)
  237.             &BeginFlow;
  238.         }
  239.     }
  240.     else {
  241.         # Default Program flow; Play random file from collections
  242.         &BeginFlow;
  243.     }  
  244. }
  245.  
  246. sub CheckArgs {
  247.  
  248.     # Process arguments before action
  249.  
  250.     if ($debug == 1) {
  251.         print qq| <Enter Sub> CheckArgs\n|;
  252.     }
  253.  
  254.     my $args=0;
  255.     my $pass_opt_check=0;
  256.     my $next;
  257.    
  258.     foreach my $arg (@ARGV) {  
  259.        
  260.         if ($arg =~/^\-q$/) {
  261.             $nosound = 1;
  262.         }
  263.         elsif ($arg =~/^\-i$/) {
  264.             our $cover = 1;
  265.         }
  266.         elsif ($arg =~/^\-h$|^-{1,2}help$/) {
  267.             &Usage;
  268.         }
  269.         elsif ($arg =~/^\-v$/) {
  270.             our $verbose = 1;
  271.         }
  272.         elsif ($arg =~/^-vv$/) {
  273.             our $verbose = 1;
  274.             our $very_verbose = 1;
  275.         }
  276.         elsif ($arg =~/^-{1,2}debug$/) {
  277.             our $debug = 1;
  278.         }
  279.         elsif ($arg =~/^\-a$/) {
  280.             our $autoplay = 1;
  281.             our $do_exec = 1;
  282.         }
  283.         elsif ($arg =~/^\-l$/) {
  284.             our $listing = 1;
  285.         }
  286.         elsif ($arg =~/^\-z$/) {
  287.             our $list_everything = 1;
  288.             our $listing = 1;
  289.         }
  290.         elsif ($arg =~/^\-c$/) {
  291.            
  292.             if ($use_colors == 1) {
  293.                 our $use_colors = 0;
  294.             }
  295.             else {
  296.                 our $use_colors = 1;
  297.             }
  298.         }
  299.         elsif ($arg =~/^\-o$/) {
  300.            
  301.             if ($sort_order == 1) {
  302.                 our $sort_order = 0;
  303.             }
  304.             else {
  305.                 our $sort_order = 1;
  306.             }
  307.         }
  308.         elsif ($arg =~/^\-k$/) {
  309.             our $kill_players = 1;
  310.            
  311.             chomp(my $mplayer_pid=`pidof mplayer`);
  312.            
  313.             if ($mplayer_pid) {
  314.                 system("kill -s $kill_signal $mplayer_pid");
  315.             }
  316.         }
  317.         elsif ($arg =~/^\-p$/) {
  318.             our $pretend = 1;
  319.         }
  320.         elsif ($arg =~ /^\-fs$/) {
  321.             our $fullscreen = 1;
  322.         }
  323.         elsif ($arg =~ /^\-m$/) {
  324.             our $mplayer_output = 1;
  325.         }
  326.         elsif ($arg =~/^\-t$/) {
  327.            
  328.             # Limit results by time logic;
  329.  
  330.             our $limit_recent = 1;
  331.            
  332.             if ($auto_sort == 1) {
  333.                 our $sort_order = 1;
  334.             }
  335.  
  336.             my $next=$ARGV[$args+1];
  337.            
  338.             unless ($next) {
  339.                 print qq|[$error_label]: With -t, You must specify a time period.\n\n|;
  340.                 sleep 1;
  341.                 &Usage;
  342.             }      
  343.                    
  344.             unless ($next=~/^-(\w+)/) {
  345.                 $limit_time = $next;
  346.             }
  347.            
  348.             if ($limit_time=~/^(\+?)(\d+)(\w?)$/) {
  349.                
  350.                 $pass_opt_check=1;
  351.                
  352.                 our $old_or_new = $1;
  353.                 my $number = $2;
  354.                 my $amount = $3;
  355.                
  356.                 if ($amount) {
  357.                     if ($amount eq 'd') {
  358.                         if ($old_or_new) {
  359.                             $number = $number - 1; 
  360.                         }
  361.                         $limit_time = $number * 1;
  362.                     }
  363.                     elsif ($amount eq 'w') {
  364.                         $limit_time = $number * 7;
  365.                     }
  366.                     elsif ($amount eq 'm') {
  367.                         $limit_time = $number * 31;
  368.                     }
  369.                     elsif ($amount eq 'y') {
  370.                         $limit_time = $number * 365;
  371.                     }
  372.                     else {
  373.                         print qq|Recent Limit: $limit_time - "$amount" is not a valid time period... must be either d,w,m,y\n|;
  374.                         exit;
  375.                     }
  376.                 }
  377.             }
  378.         }
  379.         elsif (($arg =~ /^\-s$/) || ($arg=~ /^-e$/)) {
  380.  
  381.             # grab search term
  382.            
  383.             if ($arg =~/^\-s$/) {
  384.                 our $search = 1;
  385.             }
  386.             elsif ($arg =~/^\-e$/) {
  387.                 our $search = 1;
  388.                 our $listing = 1;
  389.                 our $test_exists = 1;
  390.             }
  391.            
  392.             my $next=$ARGV[$args+1];
  393.  
  394.             if ($next) {
  395.                
  396.                 unless ($next=~/^-(\w+)/) {
  397.                     $search_term = $next;
  398.                 }
  399.                 if ($search_term=~/^((\w+)|(\*)|(\.))/g) {
  400.                     $pass_opt_check=1;
  401.                 }
  402.             }
  403.             else {
  404.                 $search_term = "";
  405.             }
  406.         }
  407.         elsif ($arg =~ /^\-x$/) {
  408.  
  409.             our $null_term = 1;
  410.            
  411.             my $next=$ARGV[$args+1];
  412.  
  413.             if ($next) {    
  414.                 unless ($next=~/^-(\w+)/) {
  415.                     $exclude_term = $next;
  416.                 }
  417.                 if ($exclude_term=~/^((\w+)|(\*)|(\.))/g) {
  418.                     $pass_opt_check=1;
  419.                 }
  420.             }
  421.             else {
  422.                 $exclude_term = "";
  423.             }
  424.         }
  425.         elsif ($arg =~ /^\-n$/) {
  426.  
  427.             our $specific_result = 1;
  428.  
  429.             my $wrong_number="[$error_label]: With -n, You must specify the number of a search result to play.\n";
  430.             my $next = $ARGV[$args+1];
  431.  
  432.             if ($next) {
  433.                
  434.                 unless ($next=~/^(\d+)$/) {
  435.                     print qq|$wrong_number\n|;
  436.                     sleep 1;
  437.                     &Usage;
  438.                 }
  439.                 else {
  440.                     $search_request = $next;
  441.                 }
  442.                 if ($search_request=~/^(\d+)/) {
  443.                     $pass_opt_check=1;
  444.                 }
  445.             }
  446.             else {
  447.                 print qq|$wrong_number\n|;
  448.                 sleep 1;
  449.                 &Usage;
  450.             }
  451.         }  
  452.         elsif ($arg =~ /^\-r$/) {
  453.  
  454.             our $repeat = 1;           
  455.             $repeat_range = "$default_repeat";
  456.            
  457.             my $next=$ARGV[$args+1];
  458.  
  459.             if ($next) {
  460.                
  461.                 # unless next var is another option, assign it as a var
  462.                 unless ($next=~/^-(\w+)/) {
  463.                    
  464.                     unless (-d $next) {
  465.                         $repeat_range = $next;
  466.                     }
  467.                 }
  468.                
  469.                 if ($repeat_range=~/^((\d+)|all)$/g) {
  470.                    
  471.                     my $range_limit=$mplayer_max + $default_repeat;
  472.                    
  473.                     if (($repeat_range=~/^\d+/) && ($repeat_range > $range_limit)) {
  474.                        
  475.                         unless ($fork_bomb_protect == 1) {
  476.                        
  477.                             &PromptUser("WARNING: $repeat_range is over $range_limit processes. Continue?");
  478.                         }
  479.                     }
  480.                    
  481.                     $pass_opt_check=1;
  482.                 }
  483.             }
  484.  
  485.             $range_request = $repeat_range;
  486.         }
  487.         elsif ((-d "$arg")||(-l "$arg")) {
  488.             our $custom_dir = 1;
  489.             our $user_dir=$arg;
  490.             $user_dir=~s/\/$//;
  491.         }
  492.         else {
  493.             # if an option has been validated, don't complain
  494.             unless ($pass_opt_check == 1) {
  495.                
  496.                 print qq|[$error_label]: Unknown Argument: "$arg"\n\n|;
  497.                
  498.                 sleep 1;
  499.                
  500.                 &Usage;
  501.                 exit;
  502.             }
  503.             $pass_opt_check=0;
  504.         }
  505.         $args++;
  506.     }
  507.     return;
  508. }
  509.  
  510. sub BeginFlow {
  511.    
  512.     # Silence errors of subcommands, unless ...
  513.  
  514.     unless (($very_verbose == 1) || ($debug == 1)) {
  515.         open(STDERR, ">/dev/null") or die "Can't redirect stderr: $!";
  516.     }
  517.    
  518.     if ($debug == 1) {
  519.         print qq| <Enter Sub> BeginFlow\n|;
  520.     }
  521.    
  522.     &CheckStorage;     
  523.     &GetSysInfo;
  524.    
  525.     if (($search == 1) || ($test_exists == 1)) {
  526.         &Search;
  527.     }
  528.     else {
  529.         &SelectFile;
  530.     }
  531.  
  532.     print qq|OOPS! You should not be here.\n|;
  533.  
  534.     exit;
  535. }
  536.  
  537. sub GetSysInfo {
  538.  
  539.     # Alter commands per OS;
  540.     my $this_os="$^O";
  541.    
  542.     # MAC OSX
  543.     if ($this_os =~/^(darwin)$/i) {
  544.        
  545.         # grab default for image viewer
  546.         unless ($image_viewer) {
  547.             $image_viewer = $def_image_viewer_osx;
  548.         }
  549.        
  550.         # If repeating, and resolution hasn't been grabbed yet... we need it to determine window layouts
  551.         if ($repeat == 1) {
  552.            
  553.             unless ($resolution) {
  554.  
  555.                 my $getrez_cmd="system_profiler SPDisplaysDataType | grep Resolution";
  556.                 chomp($resolution=`$getrez_cmd`);
  557.                
  558.                 $resolution=~s/^\s+//g;
  559.                 $resolution=~s/Resolution: //g;
  560.                
  561.                 # Pull x & Y variables from result
  562.                 ($screen_res_x,$screen_res_y)=split(/\ x\ /,$resolution);
  563.             }
  564.         }
  565.     }
  566.     elsif ($this_os =~/^(linux)$/i) {
  567.        
  568.         # grab default for image viewer
  569.         unless ($image_viewer) {
  570.             $image_viewer = $def_image_viewer_linux;
  571.         }
  572.        
  573.         # Same process as above..
  574.         if ($repeat == 1) {
  575.             unless($resolution) {
  576.                
  577.                 my $getrez_cmd="xdpyinfo | grep dimensions | awk '{print \$2}' | awk -Fx '{print \$1, \$2}'";
  578.                 chomp($resolution=`$getrez_cmd`);
  579.                
  580.                 # Pull x & Y variables from result 
  581.                 ($screen_res_x,$screen_res_y)=split(/\ /,$resolution);
  582.             }
  583.         }
  584.     }
  585.     else {
  586.         print qq|Unsupported OS: some things may not work as expected.\n|;
  587.     }
  588.  
  589.     if ($debug == 1) { print qq| Screen Resolution: "$resolution"\n|; };
  590. }
  591.  
  592. sub CheckStorage {
  593.    
  594.     # Consider multiple sources, check for availability
  595.  
  596.     if ($debug == 1) {
  597.         print qq| <Enter Sub> CheckStorage\n|;
  598.     }
  599.    
  600.     our @Available;
  601.     our @Unavailable;
  602.  
  603.     my $count;
  604.  
  605.     # Check storage for availability   
  606.     foreach my $csellection (@Collections) {
  607.         $count++;
  608.         chomp $csellection;
  609.        
  610.         if (-d "$csellection") {
  611.             push(@Available,$csellection);
  612.         }
  613.         else {
  614.             push(@Unavailable,$csellection);
  615.         }
  616.     }
  617.    
  618.     # if no collections available, print error -- unless user specified a directory to use 
  619.     my $X;
  620.     my $Y;
  621.     my $storage_info="";
  622.    
  623.     unless ($#Available == -1) {
  624.  
  625.         if ($very_verbose == 1) {
  626.  
  627.             $storage_info .= qq| [COLLECTIONS]:\n\n|;
  628.  
  629.             foreach my $avail (@Available) {
  630.                 $storage_info .= qq|  [$online_label]: $avail\n|;
  631.             }
  632.             foreach my $unavail (@Unavailable) {
  633.                 $storage_info .= qq|  [$offline_label]: $unavail\n|;
  634.             }
  635.             print qq|$storage_info\n|;
  636.         }
  637.         else {
  638.             $Y=0;
  639.  
  640.             foreach my $unavail (@Unavailable) {
  641.                
  642.                 if ($verbose == 1) {
  643.                    
  644.                     print qq|[$warning_label]: $unavail is currently unavailable.\n\n|;
  645.                    
  646.                     if ($Y == $#Unavailable) {
  647.                         print qq|  Consider editing the \@Collections array.\n\n|;
  648.                     }
  649.                 }
  650.                 $Y++;
  651.             }
  652.             unless ($#Unavailable < 0) {
  653.                 #print qq|\n|;
  654.             }
  655.         }
  656.     }
  657.     else {
  658.         unless ($custom_dir == 1) {
  659.  
  660.             # Display this message if no available collections
  661.  
  662.             $storage_info .= qq|[$error_label]: No collections currently available?\n\n|;
  663.  
  664.             $X=0;
  665.  
  666.             foreach my $unavail (@Unavailable) {
  667.                 $X++;
  668.                 $storage_info .= qq|[$offline_label]: $unavail\n|;
  669.             }
  670.  
  671.             $storage_info .= qq|\n You may need to edit the list of \@Collections in this script,\n|;
  672.             $storage_info .= qq| or otherwise specify a directory to select a file from:\n|;
  673.             $storage_info .= qq|\n $script_name ~/path/to/videos\n|;
  674.  
  675.             print qq|$storage_info\n|;
  676.  
  677.             exit;
  678.         }
  679.     }
  680.     return;
  681. }
  682.  
  683. sub DepCheck {
  684.  
  685.     # Ensure required commands exist
  686.  
  687.     if ($debug == 1) {
  688.         print qq| <Enter Sub> DepCheck\n|;
  689.     }
  690.    
  691.     foreach my $command (@Required) {  
  692.        
  693.         chomp(my $which=`which $command`);     
  694.        
  695.         unless (-e "$which") {
  696.        
  697.             print qq|[$error_label]: "$command" command not found!\n\n|;
  698.            
  699.             if ($command =~/mplayer$/) {
  700.                 print qq|This script is just a wrapper for command line mplayer.\n|;
  701.                 print qq|Please ensure mplayer is compiled & installed properly.\n|;
  702.                 print qq|http://www.mplayerhq.hu/design7/dload.html\n\n|;
  703.             }
  704.  
  705.             exit;
  706.         }
  707.     }
  708. }
  709.  
  710. sub BuildLists {
  711.  
  712.     # Filter unsupported file types and build list of available files.
  713.  
  714.     if ($debug == 1) {
  715.         print qq| <Enter Sub> BuildLists\n|;
  716.     }
  717.    
  718.     our $location;
  719.     my $Y=0;
  720.  
  721.     my $mtime;
  722.     my %mtime;
  723.     my $supported_videos;
  724.     my $supported_images;
  725.     my @AllFiles;
  726.     my @FileList;
  727.        
  728.     # Build List from a collection directory, or user-specified path
  729.     if ($custom_dir == 1) {
  730.         $location = &PrepPath("$main::user_dir");
  731.         @main::Available = $main::user_dir;
  732.     }
  733.     else {
  734.        
  735.         $location="";
  736.        
  737.         foreach my $item (@main::Available) {
  738.        
  739.             chomp $item;
  740.            
  741.             $location .= &PrepPath("$item");
  742.  
  743.             if ($#main::Available > 0) {
  744.                 $location = $location . " ";
  745.             }
  746.         }
  747.     }
  748.    
  749.     if ($debug == 1) { print qq| <FIND AND SORT FILES>\n|; }
  750.    
  751.     # FILE FIND: IF sorting by oder, find files in all available paths & sort by mtime (-l -o)
  752.     if ($sort_order == 1 && $limit_recent == 0) {
  753.        
  754.         find(sub {$mtime{$File::Find::name} = -M _ if -f;}, @main::Available);
  755.         @AllFiles = sort {$mtime{$b} <=> $mtime{$a}} keys %mtime;
  756.        
  757.     }
  758.     # FILE FIND: (-l -o -t [x]): selective population of the $mtime{} hash for sorting, based on mtime vs $limit_time
  759.     elsif ($sort_order == 1 && $limit_recent == 1) {
  760.        
  761.         unless ($repetition) {
  762.        
  763.             unless ($old_or_new eq '+') {
  764.                 $old_or_new = "-";
  765.             }
  766.             $limit_time = $old_or_new . $limit_time;
  767.         }
  768.        
  769.         # File::Find in action;
  770.         find(
  771.             sub {  
  772.                 if ($old_or_new eq '+') {
  773.        
  774.                     if (-f && -M >= $limit_time) {
  775.                         $mtime{$File::Find::name} = -M _;
  776.                     }
  777.                 }
  778.                 elsif ($old_or_new eq '-') {
  779.        
  780.                     $limit_time=~s/\-//;
  781.        
  782.                     if (-f && $limit_time >= -M) {
  783.                         $mtime{$File::Find::name} = -M _;
  784.                     }
  785.                 }  
  786.             }, @main::Available);
  787.  
  788.         @AllFiles = sort { $mtime{$b} <=> $mtime{$a} } keys %mtime;
  789.        
  790.     }
  791.     # FIND FILE: Limit file list to time period (-l -t [x])
  792.     elsif ($sort_order == 0 && $limit_recent == 1) {
  793.        
  794.         # THIS CONDITION IS UNREACHABLE IF $sort_order =1 is defined under -t option -- or $auto_sort = 1|;
  795.         #@AllFiles=`find $location -type f -mtime $limit_time`;
  796.        
  797.         unless ($repetition) {
  798.        
  799.             unless ($old_or_new eq '+') {
  800.                 $old_or_new = "-";
  801.             }
  802.             $limit_time = $old_or_new . $limit_time;
  803.         }
  804.        
  805.         find(
  806.             sub {  
  807.                 if ($old_or_new eq '+') {
  808.                     if (-f && -M >= $limit_time) {
  809.                         push(@AllFiles, $File::Find::name); ### FIX THIS SHIT CONDITIONAL
  810.                     }
  811.                 }
  812.                 elsif ($old_or_new eq '-') {
  813.    
  814.                     $limit_time=~s/\-//;
  815.    
  816.                     if (-f && $limit_time >= -M) {
  817.                         push(@AllFiles, $File::Find::name);
  818.                     }
  819.                 }  
  820.             }, @main::Available);
  821.                            
  822.     }
  823.     # IF NOT sorting, no need for mtime check (just -l), slight speedup
  824.     else {
  825.         #@AllFiles=`find $location -type f`;
  826.         find(sub { push(@AllFiles, $File::Find::name) if -f }, @main::Available);
  827.     }
  828.    
  829.     # SEARCH FILTER: Now we'll use a secondary list for parsed search results
  830.     if ($search == 1) {
  831.                    
  832.         my @search_words=split(/\,/,$search_term);
  833.        
  834.         foreach my $search_word (@search_words) {
  835.  
  836.             $search_word=~s/\,\ /\,/g;
  837.             $search_word=~s/\./\(\\W+\)/g;
  838.             #$search_word=~s/\./\(\(\\W+\)|\(\\S+\)\)/g;
  839.            
  840.             # Must-have for simple search
  841.             $search_word=~s/\ /\./g;
  842.             #$search_word=~s/\ /\(\\W+\)/g;
  843.            
  844.             # Expand search if wildcard, else this will not split and var is still useable
  845.    
  846.             my @sub_words=(split(/\*/,"$search_word"));
  847.  
  848.             # Now, actually populate @FileList if file matches search terms
  849.             foreach my $sub_word (@sub_words) {
  850.                
  851.                 $sub_word=~s/^\.//g;
  852.  
  853.                 foreach my $item (@AllFiles) {
  854.                     chomp $item;
  855.                    
  856.                     # .. unless it matches an -x exclusion_term, put it in the list
  857.                     unless (($null_term == 1 )&& ($exclude_term ne "") && ($item=~/$exclude_term/ig)) {
  858.                        
  859.                         if ($item=~/$search_word/ig) {         
  860.                             push(@FileList,$item);
  861.                         }
  862.                    
  863.                         if ($item=~/$sub_word/ig) {
  864.                             push(@FileList,$item);
  865.                         }
  866.                     }
  867.                 }
  868.             }
  869.         }
  870.     }
  871.     else {
  872.         # If not searching, use the complete list
  873.         @FileList = @AllFiles;
  874.     }
  875.    
  876.     # Determine Supported file types by creating a filter
  877.  
  878.     $Y=0;
  879.  
  880.     foreach my $type (@Supported_videos) {
  881.  
  882.         $supported_videos .= "\.$type\$";
  883.  
  884.         unless ($Y == $#Supported_videos) {
  885.             $supported_videos .= "|";
  886.         }
  887.         $Y++;
  888.     }
  889.  
  890.     # Same style filter image types
  891.  
  892.     $Y=0;
  893.  
  894.     foreach my $type (@Supported_images) {
  895.  
  896.         $supported_images .= "\.$type\$";
  897.  
  898.         unless ($Y == $#Supported_images) {
  899.             $supported_images .= "|";
  900.         }
  901.         $Y++;
  902.     }
  903.  
  904.     # Isolate specific file types into arrays for later access
  905.  
  906.     foreach my $item (@FileList) {
  907.  
  908.         chomp $item;
  909.  
  910.         if ($item =~/$supported_videos/i) {
  911.             push (@main::Videos,$item);
  912.             our $total_videos++;
  913.         }
  914.         elsif ($item=~/$supported_images/i) {
  915.             push (@main::Images,$item);
  916.             our $total_images++;
  917.         }
  918.         else {
  919.             # Store all other files as rejected
  920.             push (@main::Rejected,$item);
  921.             our $total_rejected++;
  922.         }
  923.     }
  924.    
  925.     # Strip out duplicates.
  926.     my %unique;
  927.  
  928.     undef %unique;
  929.         @unique{@main::Videos} = ();
  930.  
  931.         my @Videos = keys %unique;
  932.    
  933.     unless ($sort_order == 1) {
  934.         #NOTE: Don't sort this list, it should already be sorted
  935.         @main::Videos=sort(@Videos);
  936.     }
  937.     else {
  938.         # Strip duplicates;
  939.         @main::Videos = grep(!$unique{$_}++, @main::Videos);       
  940.     }
  941.    
  942.         undef %unique;
  943.     @unique{@main::Images} = ();
  944.  
  945.     my @Images = keys %unique;
  946.  
  947.     @main::Images = sort(@Images);
  948.  
  949.     undef %unique;
  950.     @unique{@main::Rejected} = ();
  951.    
  952.     my @Rejected = keys %unique;
  953.     @main::Rejected =  sort(@Rejected);
  954.    
  955.     my $zero;
  956.  
  957.     if ($total_videos == 0) {
  958.         if ($use_colors == 1) {
  959.             $zero = $color_red . "0" . $colortag_default;
  960.         }
  961.         else {
  962.             $zero = "0";
  963.         }
  964.        
  965.         if ($search == 1 && $limit_recent == 0) {
  966.             print qq|[$error_label]: $zero results found for "$main::search_input" in: $location\n\n|;
  967.         }
  968.         elsif ($search == 1 && $limit_recent == 1) {
  969.    
  970.             my $result_text="";
  971.    
  972.             if ($limit_time =~/^\-/) {
  973.                 $result_text = "results NEWER than $limit_time days";
  974.             }
  975.             elsif ($limit_time =~/^\+/) {
  976.                 $result_text = "results OLDER than $limit_time days";
  977.             }
  978.    
  979.             print qq|[$error_label]: $zero $result_text found for "$main::search_input" in: $location\n\n|;
  980.         }
  981.         else {
  982.             print qq|[$error_label:] $zero results found in: $location\n\n|;
  983.         }  
  984.         exit;
  985.     }
  986.  
  987.     return;
  988. }
  989.  
  990. sub Search {
  991.  
  992.     if ($debug == 1) {
  993.         print qq| <Enter Sub> Search: \"$main::search_term\"\n|;
  994.     }
  995.    
  996.     # Gather Search input if not specified on the command line
  997.     unless ($main::search_term) {
  998.  
  999.         print qq|[SEARCH]: |;
  1000.  
  1001.         chomp($search_input=<STDIN>);
  1002.  
  1003.         print qq|\n|;
  1004.  
  1005.     }
  1006.     else {
  1007.         unless (-d "$main::search_term") {
  1008.             $search_input=$main::search_term;
  1009.         }
  1010.         else {
  1011.             if ($debug == 1) {
  1012.                 print qq|<DEBUG>Search $main::search_term is a dir.\n|;
  1013.             }
  1014.  
  1015.             $main::search_term = "";
  1016.  
  1017.             print qq|[SEARCH]: |;
  1018.  
  1019.             chomp($search_input=<STDIN>);
  1020.  
  1021.             print qq|\n|;
  1022.         }
  1023.     }
  1024.    
  1025.     my $search_char=length($search_input);
  1026.    
  1027.     # if empty search input, default to random selection, else format a regex based on input
  1028.     if ($search_char == 0) {
  1029.        
  1030.         print qq|[NOTICE]: No Search terms specified, selecting random file...\n\n|;
  1031.  
  1032.         $main::search = 0;
  1033.  
  1034.         &SelectFile;
  1035.         exit;
  1036.     }
  1037.     elsif ($search_char < $main::search_char_min ) {
  1038.         print qq|[$error_label]: $search_input is too short ($search_char of $main::search_char_min min).\n\n|;
  1039.         exit;  
  1040.     }
  1041.     else {
  1042.         # Now that input is validated, Search
  1043.         $search_term="$search_input";
  1044.  
  1045.         &SelectFile;
  1046.         exit;
  1047.     }
  1048. }
  1049.  
  1050. sub SelectFile {
  1051.  
  1052.     if ($debug == 1) {
  1053.         print qq| <Enter Sub> SelectFile\n|;
  1054.     }
  1055.  
  1056.     # Only build the list once
  1057.     unless ($repetition) {
  1058.         &BuildLists;   
  1059.     }
  1060.  
  1061.     my $count;
  1062.     my $display_name;
  1063.     my $selected;
  1064.     my $selected_movie_raw_path;
  1065.     my $unique_videos=$#main::Videos+1;
  1066.    
  1067.    
  1068.     # If the range is 'all', play in order (avoid dupes) by dropping to 1st request, and jumping back to top of &SelectFile for full increment
  1069.     if (($repeat == 1) && ($range_request =~/^all$/)) {
  1070.        
  1071.         $specific_result = 1;
  1072.         $search_request = 1;
  1073.        
  1074.         $range_request = $total_videos;
  1075.         $repeat_range = $range_request;
  1076.        
  1077.         # Reset counter    
  1078.         $total_videos = "";
  1079.        
  1080.         # Start over;      
  1081.         &SelectFile;
  1082.     }
  1083.    
  1084.     # If a user specifies the file from a list, we already know it's number. Else draw randomly.
  1085.     if ($specific_result == 1) {
  1086.    
  1087.         my $result_summary;
  1088.         my $req_orig = $search_request;
  1089.    
  1090.         $selected = $search_request;
  1091.        
  1092.         # Alter user request to align with array
  1093.         unless ($search_request == 0) {
  1094.             $search_request = ($search_request - 1);
  1095.         }
  1096.            
  1097.         if ($search_request > $#main::Videos) {
  1098.            
  1099.             if ($total_videos == 1) {
  1100.                 $result_summary = qq|only 1 result for "$search_term" ... |;
  1101.             }
  1102.             else {
  1103.                 $result_summary = qq|only $unique_videos Videos found |;
  1104.                 if ($search == 1) {
  1105.                     $result_summary .= qq|for "$search_term" |;
  1106.                 }
  1107.                 $result_summary .= qq |...|;
  1108.             }
  1109.            
  1110.             print qq|[$error_label]: $req_orig is out of bounds, $result_summary\n\n|;
  1111.             exit;
  1112.         }
  1113.         chomp($selected_movie_raw_path=$main::Videos[$search_request]);
  1114.     }
  1115.     else {
  1116.         # THE WHEEL OF FATE SPINS!
  1117.         my $rand=int rand ($#main::Videos+1);
  1118.         $selected = $rand;
  1119.        
  1120.         chomp($selected_movie_raw_path=$main::Videos[$rand]);
  1121.        
  1122.         unless ($selected == 0) {
  1123.             $selected = ($selected + 1);
  1124.         }
  1125.        
  1126.         # ..but try to avoid dupes
  1127.         if ($repeat == 1) {
  1128.            
  1129.             foreach my $past_select (@main::AlreadyPicked) {
  1130.                
  1131.                 # If this selection has been drawn before...
  1132.                 if ($past_select == $selected) {
  1133.                    
  1134.                     if ($debug == 1) {
  1135.                         print qq| PICKED $selected but ALREADY PLAYED $#main::AlreadyPicked $#main::Videos\n|;
  1136.                     }
  1137.                    
  1138.                     # exit if we've gone through the full list, else roll again
  1139.                     if ($#main::AlreadyPicked >= $#main::Videos) {
  1140.                         exit;
  1141.                     }
  1142.                     else {
  1143.                         &SelectFile;
  1144.                     }
  1145.                 }
  1146.             }
  1147.            
  1148.             # Keep track of drawn numbers
  1149.             push (@main::AlreadyPicked,$selected);
  1150.         }
  1151.     }
  1152.  
  1153.     if (($selected)&&($debug == 1)) {
  1154.         print qq| <SELECTED:> "$selected"\n|;
  1155.         print qq| <FILENAME: $selected_movie_raw_path\n|;
  1156.     }
  1157.  
  1158.     # Mangle the path to seperate the $file_name from the raw $file_folder_path
  1159.     my $playable_path=&PrepPath("$selected_movie_raw_path");   
  1160.     my $file_folder_path=$selected_movie_raw_path;
  1161.    
  1162.     foreach my $item (@main::Available) {
  1163.         $file_folder_path=~s/^$item//g;
  1164.     }
  1165.    
  1166.     # Extract file name from path and determine generic name of file (without extension)
  1167.        
  1168.     my $file_path=$file_folder_path;
  1169.     my @folders=split(/\//,$file_folder_path);
  1170.    
  1171.     our $file_name = $folders[$#folders];
  1172.        
  1173.     # if $file_name contains invalid characters it gets treated as a nested regex, escape, then replace
  1174.     $file_name =~s/\?/\\\?/g;
  1175.     $file_name =~s/\[/\\\[/g;
  1176.     $file_name =~s/\]/\\\]/g;
  1177.    
  1178.     $file_path=~s/$file_name//g;
  1179.    
  1180.     $file_name =~s/\\\?/\?/g;
  1181.     $file_name =~s/\\\[/\[/g;
  1182.     $file_name =~s/\\\]/\]/g;
  1183.  
  1184.     # Strip extension for a generic name to find images with
  1185.     our $generic_name = $file_name;
  1186.     $generic_name =~s/\.(\w{3})$//i;
  1187.    
  1188.     # Ok, NOW PRINT list if -l
  1189.     if ($listing == 1) {   
  1190.    
  1191.         if ($total_videos > 0) {
  1192.             print qq| [VIDEO FILES]:|;
  1193.    
  1194.             if ($search == 1) {
  1195.                 $total_videos = $unique_videos;
  1196.                 print qq| $total_videos results for "$search_input" ... \n\n|;
  1197.             }
  1198.             elsif ($limit_recent == 1) {
  1199.            
  1200.                 my $result_text="";
  1201.  
  1202.                 if ($limit_time =~/^\-/) {
  1203.                     $result_text = "results NEWER than $limit_time days";
  1204.                 }
  1205.                 elsif ($limit_time =~/^\+/) {
  1206.                     $result_text = "results OLDER than $limit_time days";
  1207.                 }
  1208.        
  1209.                 print qq| $total_videos $result_text\n\n|;
  1210.             }
  1211.             else {
  1212.                 print qq| $total_videos videos available.\n\n|;
  1213.             }
  1214.            
  1215.             $count=0;
  1216.            
  1217.             # Loop through and print list
  1218.             foreach my $item (@main::Videos) {
  1219.            
  1220.                 $count++;
  1221.                 $display_name=$item;
  1222.                    
  1223.                 # Strip source name from file to help categorize
  1224.                 unless ($list_full_paths == 1) {
  1225.                     foreach my $avail (@main::Available) {
  1226.                         $display_name=~s/^$avail\///g;
  1227.                     }
  1228.                 }
  1229.            
  1230.                 # Colorize search-term hits
  1231.                 if (($search == 1) && ($use_colors == 1)) {
  1232.            
  1233.                     my $search_word;
  1234.                    
  1235.                     # Split seperated terms
  1236.                     my @search_breakdown2=split(/\,/,$search_term);
  1237.            
  1238.                     foreach my $seperate_term (@search_breakdown2) {
  1239.                    
  1240.                         #$search_term=~s/\,\ /\,/g;
  1241.                         my @search_breakdown=split(/\ |\,|\.|\*/,$search_term);
  1242.                    
  1243.                         # Break the search phrase down into individual words for matching results
  1244.                         foreach my $search_word (@search_breakdown) {      
  1245.            
  1246.                             my @matches = $display_name =~/($search_word)/ig;
  1247.            
  1248.                             foreach my $match (@matches) {
  1249.                            
  1250.                                 my $highlighted=$colortag_search . "$match" . $colortag_default;
  1251.                                 $display_name=~s/$match/$highlighted/g;
  1252.                             }
  1253.                         }
  1254.                     }
  1255.                 }
  1256.                
  1257.                 # Include mtime info ?
  1258.                 my $mtime="";
  1259.                
  1260.                 if (($verbose == 1) || ($limit_recent == 1) || ($sort_order == 1)) {
  1261.  
  1262.                     $mtime = scalar localtime stat("$item")->mtime;
  1263.                    
  1264.                     # format only useful data
  1265.                     $mtime =~s/\ \ /\ /g;
  1266.                     (my $day,my $month,my $date,my $time,my $year)=split(/\ /,$mtime);
  1267.                     $mtime = "$year $month $date";
  1268.                     $mtime = " ($mtime)";
  1269.  
  1270.                     if ($use_colors == 1) {
  1271.                         $mtime = $colortag_mtime . $mtime . $colortag_default;
  1272.                     }
  1273.                 }
  1274.                 my $number;
  1275.                 if ($use_colors == 1) {
  1276.                     $number = $colortag_number . $count . $colortag_default;
  1277.                 }
  1278.                 else {
  1279.                     $number = $count;
  1280.                 }
  1281.                 # Finally display list item
  1282.                 print qq|  [$number]:$mtime $display_name \n|;
  1283.                
  1284.             }
  1285.             print qq|\n|;
  1286.         }
  1287.         $count=0;
  1288.     }
  1289.        
  1290.     if ($list_everything == 1) {
  1291.  
  1292.         print qq| [IMAGES]:\n\n|;
  1293.  
  1294.         foreach my $item (@main::Images) {
  1295.             $count++;
  1296.             print qq|  [$count]: $item\n|;
  1297.         }
  1298.  
  1299.         print qq|\n|;
  1300.         $count=0;
  1301.  
  1302.         print qq| [OTHER FILES]:\n\n|;
  1303.  
  1304.         foreach my $item (@main::Rejected) {
  1305.             $count++;
  1306.             print qq|  [$count]: $item\n|;
  1307.         }
  1308.  
  1309.         print qq|\n|;
  1310.         $count=0;
  1311.  
  1312.         print qq| [VIDEOS]: $total_videos\n|;
  1313.         print qq| [IMAGES]: $total_images\n|;
  1314.         print qq| [OTHER]: $total_rejected\n|;
  1315.  
  1316.         print qq|\n|;
  1317.         exit;
  1318.     }
  1319.    
  1320.     if ($test_exists == 1) {
  1321.  
  1322.         $pretend = 1;
  1323.  
  1324.         if ($total_videos > 1) {
  1325.             print qq| [$exists_label] $total_videos matches for "$search_term".\n\n|;
  1326.         }
  1327.         elsif ($total_videos == 1) {
  1328.             print qq| [$exists_label] File "$file_name" matches.\n\n|;
  1329.         }
  1330.         exit;      
  1331.     }
  1332.    
  1333.     # If repeating, report itteration
  1334.     if ($repeat == 1) {
  1335.                    
  1336.         #keep track of repetitions (after earlier reset)
  1337.         $repetition++;
  1338.  
  1339.         # If we've opened too many windows, bind to terminal to prevent fork bombing the system
  1340.         if ($fork_bomb_protect == 1) {
  1341.            
  1342.             if ($repetition > $mplayer_max) {
  1343.                
  1344.                 $target_x = 0;
  1345.                 $target_y = 0;
  1346.                 $mplayer_output = 1;
  1347.             }
  1348.         }
  1349.        
  1350.         # Turn off listing for repititions
  1351.         $listing = 0;
  1352.        
  1353.         #if user requests 4, but there's only 3 vids, drop range to match total_videos
  1354.         if ($range_request >= $total_videos) {
  1355.             $range_request = $total_videos;
  1356.         }
  1357.        
  1358.         print qq| [INSTANCE]: $repetition of $range_request\n|;
  1359.     }
  1360.    
  1361.     # Determine selection # of total
  1362.     if ($selected == 0) {
  1363.         $selected = 1;
  1364.     }
  1365.    
  1366.     my $file_info="";
  1367.     my $selected_label = $selected;
  1368.    
  1369.     if ($use_colors == 1) {
  1370.         $selected_label = $colortag_selection . $selected_label . $colortag_default;
  1371.     }
  1372.  
  1373.     $file_info .= qq| [SELECTED]: File \# $selected_label of $unique_videos\n|;
  1374.    
  1375.     # Display some useful info about the file if verbose
  1376.     if ($#Collections >= 1) {      
  1377.  
  1378.         foreach my $item (@main::Available) {
  1379.  
  1380.             if ($selected_movie_raw_path=~/^$item/) {
  1381.  
  1382.                 my $csellection = $item;
  1383.  
  1384.                 if ($use_colors == 1) {
  1385.                     #$csellection .= $colortag_category . $csellection . $colortag_default;
  1386.                 }
  1387.                 $file_info .= qq| [SOURCE]: $csellection\n|;
  1388.             }
  1389.         }
  1390.     }          
  1391.     # Unless custom dir, list some path info as 'category' - it's up to you to organize your files though
  1392.     unless (($custom_dir == 1) || ($#folders == 1)) {      
  1393.  
  1394.         $file_info .= qq| [$category_label]: |;
  1395.  
  1396.         if ($use_colors == 1) {
  1397.             $file_info .= $colortag_category;
  1398.         }
  1399.        
  1400.         for (my $i=0; $i < $#folders; $i++) {  
  1401.            
  1402.             unless ($folders[$i] =~"^\/") {
  1403.  
  1404.                 $file_info .= qq|$folders[$i]|;    
  1405.  
  1406.                 unless ($i == 0) {
  1407.                     $file_info .= qq|/ |;
  1408.                 }
  1409.             }
  1410.         }
  1411.         if ($use_colors == 1) {
  1412.             $file_info .= $colortag_default;
  1413.         }
  1414.         $file_info .= qq|\n|;      
  1415.     }
  1416.    
  1417.     if ($verbose == 1) {
  1418.  
  1419.         # Additional date
  1420.         my $mtime = scalar localtime stat("$selected_movie_raw_path")->mtime;
  1421.  
  1422.         # format only useful data
  1423.         $mtime =~s/\ \ /\ /g;
  1424.         (my $day,my $month,my $date,my $time,my $year)=split(/\ /,$mtime);
  1425.         $mtime = "$month $date $year";
  1426.    
  1427.         if ($use_colors == 1) {
  1428.             $mtime = $colortag_mtime . $mtime . $colortag_default;
  1429.         }
  1430.         $file_info .= qq| [VID DATE]: $mtime\n|;
  1431.     }
  1432.    
  1433.     # Color label for filename?
  1434.     my $filename_label = $file_name;
  1435.     my $orig_total = $total_videos;
  1436.  
  1437.     if ($use_colors == 1) {
  1438.         $filename_label = $colortag_name . $file_name . $colortag_default;
  1439.         $total_videos = $color_red . $total_videos . $colortag_default;
  1440.     }
  1441.     else {
  1442.         # Bold if no color
  1443.         $filename_label = $color_bold . $file_name . $colortag_default;
  1444.         $total_videos = $color_bold . $total_videos . $colortag_default;
  1445.     }
  1446.  
  1447.     $file_info .= qq| [$vid_label]: $filename_label\n\n|;
  1448.    
  1449.     # Finally print the $file_info we've formatted
  1450.     if (($file_info_banner == 1) || ($verbose == 1)) {
  1451.  
  1452.         unless (($#ARGV == 0)&&($listing == 1)) {
  1453.             print qq|$file_info|;
  1454.         }
  1455.         else {
  1456.             # Exit after -l is given
  1457.             print qq| $total_videos videos in your collection.\n\n|;
  1458.             exit;
  1459.         }
  1460.     }
  1461.    
  1462.     $total_videos = $orig_total;
  1463.        
  1464.     # Handle repitition requests
  1465.     if ($repeat == 1) {
  1466.        
  1467.         # Determine geometries for multiple window layouts, unless remaining attached
  1468.         unless ($mplayer_output == 1) {
  1469.        
  1470.             my $last_vid_x = $target_x;
  1471.             my $last_vid_y = $target_y;
  1472.        
  1473.             # Only move across if user has played previous file, or autoplay
  1474.             unless ($user_ok eq "n") {
  1475.                 $target_x=$target_x + $video_width;
  1476.             }
  1477.            
  1478.             #$target_y= $target_y + $video_height;
  1479.        
  1480.             # Get video resolution
  1481.             my $mplayer_info_cmd="mplayer -vo null -ao null -frames 0 -identify $playable_path 2>/dev/null | grep ^ID_VIDEO";
  1482.             my @vid_info=`$mplayer_info_cmd`;
  1483.            
  1484.             foreach my $info_line (@vid_info) {
  1485.  
  1486.                 chomp $info_line;
  1487.  
  1488.                 if ($info_line =~/^ID_VIDEO_WIDTH=/) {
  1489.                     $video_width=$info_line;
  1490.                     $video_width=~s/^ID_VIDEO_WIDTH=//;
  1491.                 }
  1492.                 if ($info_line =~/^ID_VIDEO_HEIGHT=/) {
  1493.                     $video_height=$info_line;
  1494.                     $video_height=~s/^ID_VIDEO_HEIGHT=//;
  1495.                 }
  1496.             };
  1497.        
  1498.             # Determine next geometry, and if breaching far edge, drop down to new row.
  1499.             my $next_x = $target_x + $video_width;
  1500.             my $next_y = $target_y + $video_height;
  1501.            
  1502.             if ($next_x >= $screen_res_x) {
  1503.                 $target_x = 0;
  1504.                 $target_y= $target_y + $video_height;
  1505.             }
  1506.            
  1507.             if ($next_y >= $screen_res_y) {
  1508.                 #$target_y = 0;
  1509.             }
  1510.        
  1511.             if ($debug == 1) {
  1512.                 print qq| vidX: $video_width : $target_x of $screen_res_x : $next_x ($resolution)\n|;
  1513.                 print qq| vidY: $video_height : $target_y of $screen_res_y : $next_y ($resolution)\n|;
  1514.             }
  1515.            
  1516.             # Set next windows' mplayer geometry
  1517.             $mplayer_opts_geo = " -geometry $target_x:$target_y";
  1518.            
  1519.         }
  1520.        
  1521.         # Return to center if we've stacked too many
  1522.         if ($repetition > $mplayer_max) {
  1523.             $mplayer_opts_geo = "";
  1524.         }
  1525.        
  1526.         ## IF -n $search_request, array needs alignment elsewhere (-1), so to increment the range to +1, we must actually +2
  1527.         if ($search_request) {
  1528.             $search_request = $search_request +2;
  1529.         }
  1530.         # If the file #1 is requested, var was = 0, so previous test fails, so we need to bump to 2 to equal back to 0 to allow file +1
  1531.         else {
  1532.             $search_request = 2;
  1533.         }
  1534.        
  1535.         # if repeat range has more cycles,
  1536.         if ($repeat_range > 1) {
  1537.  
  1538.             # remove a cycle from requested repetitions,
  1539.             $repeat_range--;
  1540.            
  1541.             # and unless this is the last cycle, spin another video
  1542.             unless ($repetition >= $total_videos) {
  1543.                 #sleep 1;
  1544.                 &PlayFile("$playable_path");
  1545.                 &SelectFile;
  1546.             }  
  1547.         }  
  1548.     }
  1549.    
  1550.     # Under regular operation, finally open file;
  1551.     &PlayFile("$playable_path");
  1552.    
  1553.     if (($verbose == 1) || ($debug == 1)) {
  1554.         &GetStats;
  1555.     }  
  1556.     exit;
  1557. }
  1558.  
  1559. sub PlayFile {
  1560.    
  1561.     chomp(my $play_file="$_[0]");
  1562.    
  1563.     if ($debug == 1) {
  1564.         print qq| <Enter Sub> PlayFile $play_file\n|;
  1565.     }  
  1566.    
  1567.     # Form the actual mplayer command
  1568.     my $cmd = "$mplayer $mplayer_opts -title \"$main::file_name\"";
  1569.     my $silent_output="1>/dev/null 2>&1";
  1570.    
  1571.     # Append mplayer options before command is formed
  1572.     if ($mplayer_opts_geo) {
  1573.         $cmd .= " $mplayer_opts_geo";
  1574.     }
  1575.     if ($fullscreen == 1)  {
  1576.         $cmd .=" -fs";
  1577.     }
  1578.     if ($nosound == 1) {
  1579.         $cmd .=" -nosound";
  1580.     }
  1581.     else {
  1582.         $cmd .= " $volume_mods";
  1583.     }
  1584.  
  1585.     # Feed file to command
  1586.     $cmd = $cmd . " $play_file";
  1587.    
  1588.     # Unless attaching, silence output
  1589.     unless ($mplayer_output == 1) {
  1590.         $cmd="$cmd $silent_output";    
  1591.     }
  1592.    
  1593.     # Added Ability to open an image, even if -p
  1594.     if ($cover == 1 && $pretend == 1) {
  1595.  
  1596.         &GetRelatedImages;
  1597.  
  1598.         if ($#main::Related_images >= 1) {
  1599.  
  1600.             &PromptUser("Open image only?");
  1601.  
  1602.             foreach my $item (@main::Related_images) {
  1603.                
  1604.                 # Possible to be called and return nothing, so only act on tangible items
  1605.                 unless ($item =~/^$/) {
  1606.                     &OpenImage("$item");
  1607.                 }
  1608.             }
  1609.         }
  1610.     }
  1611.  
  1612.     unless ($pretend == 1) {
  1613.  
  1614.         # Build a List
  1615.         if ($cover == 1) {
  1616.             &GetRelatedImages;
  1617.         }
  1618.        
  1619.         unless ($do_exec == 1) {
  1620.  
  1621.             # SAFETY; confirmation prompt before playing the video;
  1622.             print qq|[$warning_label]: Always wise to double-check before exec ... ('-a' to override)\n\n|;
  1623.  
  1624.             &PromptUser("Play file?");
  1625.         }
  1626.        
  1627.         # Now that a user will have confirmed, open all related images
  1628.         if ($cover == 1) {
  1629.             if ($do_exec == 1) {
  1630.                 foreach my $item (@main::Related_images) {
  1631.                    
  1632.                     # Possible to be called and return nothing, so only act on tangible items
  1633.                     unless ($item =~/^$/) {
  1634.                         &OpenImage("$item");
  1635.                     }
  1636.                 }
  1637.             }
  1638.         }
  1639.  
  1640.         # NOW we can finally launch mplayer
  1641.         unless ($mplayer_output == 1) {    
  1642.            
  1643.             if ($do_exec == 1) {   
  1644.                    
  1645.                 system("$cmd \&");
  1646.                
  1647.                 # Unless auto = 1, reset so it prompts again
  1648.                 unless ($autoplay == 1) {
  1649.                     $do_exec = 0;
  1650.                 }
  1651.             }
  1652.         }
  1653.         else {
  1654.             print qq|Mplayer output:\n--\n|;
  1655.             system("$cmd");
  1656.         }
  1657.     }
  1658.     else {
  1659.         print qq| [$pretend_label]: no exec ...\n\n|;
  1660.         unless ($repeat == 1) {
  1661.             exit;
  1662.         }
  1663.     }  
  1664.     if ($very_verbose == 1) {
  1665.         print qq|\n [$exec_label]: $cmd\n\n|;
  1666.     }
  1667.     return;
  1668. }
  1669.  
  1670. sub GetRelatedImages {
  1671.  
  1672.     # Find Associated Images;
  1673.    
  1674.     if ($debug == 1) {
  1675.         print qq| <Enter Sub> GetRelatedImages for "$main::generic_name" in $main::location\n|;
  1676.     }
  1677.    
  1678.     # Reset;
  1679.     our @Related_images="";
  1680.     our $path_to_image;
  1681.  
  1682.     my $image;
  1683.     my $image_file="";
  1684.     my $images_found="";
  1685.     my $generic_name=$main::generic_name;
  1686.    
  1687.     # strip non-word characters into regex, strip "part X" for multi-part video labels
  1688.     $generic_name =~s/part((\s+)*)(\d+)/\.\*/ig;
  1689.     $generic_name =~s/(\W+)/\.\*/g;
  1690.    
  1691.     # Go through all images we found and find matches for the selected video, set them aside
  1692.     foreach my $item (@main::Images) {
  1693.  
  1694.         chomp $item;
  1695.  
  1696.         if ($item=~/$generic_name/g) {
  1697.             push (@Related_images,$item);
  1698.            
  1699.         }
  1700.     }
  1701.  
  1702.     # If we have some related image results, make use of them - but don't pass to OpenImage yet
  1703.     unless ($#Related_images == -1) {
  1704.         my $X;
  1705.         foreach my $image (@Related_images) {
  1706.             $X++;
  1707.             chomp $image;
  1708.  
  1709.             my @image_path=split(/\//,$image);
  1710.             $image_file=$image_path[$#image_path];
  1711.            
  1712.             unless ($image =~/^$/) {
  1713.                
  1714.                 if ($use_colors == 1) {
  1715.                     $image_file = $colortag_imgname . $image_file . $colortag_default;
  1716.                 }
  1717.                 print qq| [IMAGE]: $image_file\n|;
  1718.                
  1719.                 # Format image file list correct, by adding space if it's the last one
  1720.                 if ($#Related_images < $X) {
  1721.                     print qq|\n|;
  1722.                 }
  1723.             }
  1724.         }  
  1725.        
  1726.     }
  1727.     else {
  1728.         print qq| [NOTICE]: No images found for "$generic_name"\n\n|;
  1729.     }
  1730.     return;
  1731. }
  1732.    
  1733. sub OpenImage {
  1734.  
  1735.     # Open Associated Image(s)
  1736.  
  1737.     chomp(my $imagepath=$_[0]);
  1738.     $imagepath=&PrepPath("$imagepath");
  1739.  
  1740.     my $image_command = "$image_viewer $imagepath 1>/dev/null 2>&1";
  1741.    
  1742.     my @image_path=split(/\//,$imagepath);
  1743.     my $image_name=$image_path[$#image_path];
  1744.    
  1745.     if ($debug == 1) {
  1746.         print qq| <OpenImageExec>: "$image_command"\n\n|;
  1747.     }
  1748.    
  1749.     unless (($main::user_ok eq 'n') || ($imagepath =~/^$/)) {
  1750.         system("$image_command \&");
  1751.     }
  1752.  
  1753.     return;
  1754. }
  1755.  
  1756. sub PromptUser {
  1757.  
  1758.     # Unless otherwise stated, prompt before blatantly opening a video.
  1759.    
  1760.     if ($debug == 1) {
  1761.         print qq| <PromptUser:>\n|;
  1762.     }
  1763.  
  1764.     my $prompt_msg = "$_[0]";
  1765.      
  1766.     unless ($autoplay == 1) {
  1767.  
  1768.         print qq|$prompt_msg [$yes_label/$no_label|;
  1769.         if ($repeat == 1) {
  1770.             print $color_bold . qq|/q| . $colortag_default;
  1771.         }
  1772.         print qq|] ($yes_label)|;
  1773.        
  1774.         chomp($main::user_ok=<STDIN>);
  1775.  
  1776.         if ($user_ok =~/^y$/i) {
  1777.             $do_exec = 1;
  1778.             #return;
  1779.         }
  1780.         elsif ($user_ok eq "") {
  1781.             $do_exec = 1;
  1782.             #return;
  1783.         }
  1784.         elsif ($user_ok =~/^n$/i) {
  1785.             print qq|\n [$abort_label]: Not Launching.\n\n|;
  1786.             #exit;
  1787.         }
  1788.         elsif ($user_ok =~/^q$|^quit$|^exit$/) {
  1789.             print qq|\n [$abort_label]: Aborted.\n\n|;
  1790.             exit;
  1791.         }
  1792.         else {
  1793.             &PromptUser("$prompt_msg");
  1794.         }
  1795.        
  1796.         print qq|\n|;
  1797.     }
  1798. }
  1799.  
  1800. sub PrepPath {
  1801.  
  1802.     # Sanitize path for command executions
  1803.  
  1804.     if ($debug == 1) {
  1805.         print qq| <PrepPath:> "$_[0]"\n|;
  1806.     }
  1807.    
  1808.     my $esc_path;
  1809.     chomp($esc_path=$_[0]);
  1810.    
  1811.     $esc_path=~s/\ /\\\ /g;
  1812.     $esc_path=~s/\&/\\&/g;
  1813.     $esc_path=~s/\[/\\[/g;
  1814.     $esc_path=~s/\]/\\]/g;
  1815.     $esc_path=~s/\(/\\(/g;
  1816.     $esc_path=~s/\)/\\)/g;
  1817.     $esc_path=~s/\'/\\'/g; 
  1818.     $esc_path=~s/\!/\\!/g;
  1819.     $esc_path=~s/\;/\\;/g;
  1820.     return $esc_path;
  1821. }
  1822.  
  1823. sub GetStats {
  1824.  
  1825.     # Time this scripts execution time
  1826.    
  1827.     if (($verbose == 1)||($debug == 1)) {  
  1828.    
  1829.         my $time = time - $^T;
  1830.         my $decimal=$time/60;
  1831.         my $minutes;
  1832.         my $fraction;
  1833.         my $time_report;
  1834.         ($minutes,$fraction)=split(/\./,$decimal);
  1835.  
  1836.         # Square off time into minutes, subtract from overall time to get additional seconds
  1837.         my $min_seconds=($minutes*60);
  1838.         my $seconds=($time-$min_seconds);
  1839.  
  1840.         # If over an hour, break down into additional minutes
  1841.         if ($minutes >= 60) {
  1842.             my $decimal2 = $minutes/60;
  1843.             my $hours;
  1844.             ($hours,$fraction)=split(/\./,$decimal2);
  1845.  
  1846.             my $hour_minutes=($hours*60);
  1847.             my $extramins=($minutes - $hour_minutes);
  1848.  
  1849.             $time_report = qq|$hours hours $extramins minutes $seconds seconds.\n|;
  1850.         }
  1851.         elsif ($minutes >= 1) {
  1852.             $time_report = qq|$minutes minutes $seconds seconds.\n|;
  1853.         }
  1854.         else {
  1855.             $time_report = qq|$seconds seconds.\n|;
  1856.         }
  1857.         print qq|$script_name runtime: $time_report|;
  1858.     }  
  1859. }
  1860.  
  1861. sub Usage {
  1862.    
  1863.     if ($debug == 1) {
  1864.         print qq| <Enter Sub> Usage\n|;
  1865.     }
  1866.    
  1867.     if ($use_colors == 1) {
  1868.         $script_name = $color_bold . $script_name . $colortag_default;
  1869.     }
  1870.    
  1871.     print qq| $script_name [options] [dir]\n (v.$version)\n\n|;
  1872.     print qq|   -h\t\tThis Help. \n|;
  1873.     print qq|   -p\t\tPretend Only. No execution.\n|;
  1874.     print qq|   -q\t\tNo Volume. Play Muted.\n|;
  1875.     print qq|   -a\t\tAutoplay. Bypass confirmation prompt.\n|;
  1876.     print qq|   -l\t\tList available videos.\n|;
  1877.     print qq|   -o\t\tSort listing by file modification times.\n|;
  1878.     print qq|   -n [#]\tPlay Nth numbered result. (As numbered by the "-l" option)\n|;
  1879.     print qq|   -e [TERM]\tQuick check against collection and exit. Shorter than '-s -p'\n|;
  1880.     print qq|   -s [TERM]\tSearch files using keywords.\n\t\t ("." = wildcard, "," = expanded search terms)\n|;
  1881.     print qq|   -x [TERM]\tExclude a term from search results.\n|;
  1882.     print qq|   -t [#x]\tOnly list files newer than [Xx]. +X for 'older than' X.\n\t\t x = (d/w/m/y). Ex: 5d / 2w / 1m / 1y\n|;
  1883.     print qq|   -r [#][all]\tRepeat selection process X amount of times. default: $default_repeat\n\t\t Will increment to n+X if starting point specified with -n\n|;
  1884.     print qq|   -i\t\tOpen any images related to selection, if found.\n|;
  1885.     print qq|   -fs\t\tFull Screen.\n|;
  1886.     print qq|   -m\t\tAttach MPlayer output, do not fork to background.\n|;
  1887.     print qq|   -k\t\tKill any existing mplayer instances before starting new ones.\n|;
  1888.     print qq|   -c\t\tToggle \$use_colors on/off.\n|;
  1889.     print qq|   -v\t\tVerbose information about the selected file. (file date)\n|;
  1890.     print qq|   -vv\t\tVery verbose: even more info.\n|;
  1891.     print qq|   --debug\tInclude script execution debug info.\n|;
  1892.     #print qq|   -z\t\tList Every file parsed from storage locations\n|;
  1893.    
  1894.     print qq|\n\n Example Usages:\n\n|;
  1895.    
  1896.     print qq|  Play a random file from the locations set in \@Collections array:\n|;
  1897.     print qq|  (\@Collections = "@Collections")\n|;
  1898.     print qq|\t$script_name\n\n|;
  1899.  
  1900.     print qq|  List files and play a random file from another directory:\n|;
  1901.     print qq|\t$script_name -l ~/Downloads\n\n|;
  1902.  
  1903.     print qq|  Order listing by mtime, select 3rd video from list:\n|;
  1904.     print qq|\t$script_name -l -o -n 3\n\n|;
  1905.  
  1906.     print qq|  Open multiple videos, no prompt. If not given, \$default_repeat = $default_repeat:\n|;
  1907.     print qq|\t$script_name -r 3 -a\n\n|;
  1908.  
  1909.     print qq|  List and play $default_repeat videos from the past month, muted, kill any already running:\n|;
  1910.     print qq|\t$script_name -q -l -t 1m -r -k\n\n|;
  1911.  
  1912.     print qq|  Starting at first vid, sequential play all videos that match search term:\n|;
  1913.     print qq|\t$script_name -l -o -s "star wars" -n 1 -r all\n\n|;
  1914.    
  1915.     print qq|\n|;
  1916.    
  1917.     exit;
  1918. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement