Advertisement
Guest User

XBMC.MyLibrary Runtime Filter Patch - AngryCamel - 20120806

a guest
Aug 6th, 2012
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 18.25 KB | None | 0 0
  1. Index: utilities/Config.java
  2. ===================================================================
  3. --- utilities/Config.java   (revision 8)
  4. +++ utilities/Config.java   (working copy)
  5. @@ -146,10 +146,10 @@
  6.                  
  7.  
  8.           //populate charactes that we do not allow in file names
  9. -        char[] specialChars = {'<', '>', ':', '"', '/', '\\', '|', '?', '*', '*', '~', '’'};
  10. +        char[] specialChars = {'<', '>', ':', '"', '/', '\\', '|', '?', '*', '*', '~', '٧};
  11.          for(char c : specialChars) ILLEGAL_FILENAME_CHARS.put(new Integer((int) c), "illegal");
  12.  
  13. -        char[] uncommonChars = {'<', '>', ':', '"', '/', '\\', '|', '?', '*', '#', '$', '%', '^', '*', '!', '~','\'', '’', '=', '[' ,']', '(', ')', ';', '\\' ,',', '_'};
  14. +        char[] uncommonChars = {'<', '>', ':', '"', '/', '\\', '|', '?', '*', '#', '$', '%', '^', '*', '!', '~','\'', '٧, '=', '[' ,']', '(', ')', ';', '\\' ,',', '_'};
  15.          for(char c : uncommonChars) UNCOMMON_CHARS.put(new Integer((int) c), "illegal");
  16.  
  17.          //set up logs
  18. Index: utilities/Constants.java
  19. ===================================================================
  20. --- utilities/Constants.java    (revision 8)
  21. +++ utilities/Constants.java    (working copy)
  22. @@ -33,6 +33,9 @@
  23.      public final static String  MOVIE_SET = "MOVIE_SET";
  24.      public final static String  PREFIX = "PREFIX";
  25.      public final static String  SUFFIX = "SUFFIX";
  26. +  
  27. +   //AngryCamel - 20120805 2351
  28. +    public final static String  RUNTIME = "runtime";
  29.  
  30.      public final static String  FOLDERS_ONLY = "FOLDERS_ONLY";
  31.      public final static String  FILES_ONLY = "FILES_ONLY";
  32. Index: utilities/Filter.java
  33. ===================================================================
  34. --- utilities/Filter.java   (revision 8)
  35. +++ utilities/Filter.java   (working copy)
  36. @@ -7,7 +7,7 @@
  37.  
  38.  public class Filter
  39.  {
  40. -    public static boolean FilterMatch(String path, Map<String, List<String>> filters)
  41. +    public static boolean FilterMatch(String path, int runtime, Map<String, List<String>> filters)
  42.      {
  43.          if(filters == null || filters.isEmpty()) return true;//no filters to exclude on
  44.  
  45. @@ -32,6 +32,127 @@
  46.                      if(!path.toLowerCase().contains(filterString.toLowerCase()))
  47.                          return false;//this path does not contains this string, return false because all filters must match
  48.                  }
  49. +               //AngryCamel - 20120805 2351
  50. +               //  <runtime> - Matches if the runtime of the file fits the criteria specified in seconds along with the
  51. +               //   relational operator value. The format is "<relational_operator>|<runtime_seconds>". Posible relational
  52. +               //   operators are: EQ:Equal to, GT:Greater than, LT:Less than, NE:Not equal to, GE:Greater than or equal to,
  53. +               //   LE:Less than or equal to. Matches only on files and not directories.
  54. +               // Example:
  55. +               // <!-- (Recursive) Modern Marvels Episodes over 20 minutes long -->
  56. +               // <subfolder name="History Channel/Modern Marvels" type="episodes" >
  57. +               //      <filter>
  58. +               //          <runtime>GT|1200</runtime>             
  59. +               //      </filter>
  60. +               // </subfolder>
  61. +                else if(type.equalsIgnoreCase(Constants.RUNTIME))
  62. +                {
  63. +                   String[] splitFilterStr;
  64. +                   int runtimeFilter = 0;
  65. +                   String operator = "";
  66. +
  67. +                   Config.log(Config.DEBUG, "Checking runtime filter: "+ filterString);
  68. +                  
  69. +                   splitFilterStr = filterString.split(Pattern.quote("|"));
  70. +                   if(splitFilterStr.length < 2)
  71. +                       return false;//filter string format invalid
  72. +                  
  73. +                   operator = splitFilterStr[0];
  74. +                  
  75. +                   try{
  76. +                       runtimeFilter = Integer.parseInt(splitFilterStr[1]);
  77. +                   }catch (NumberFormatException e){
  78. +                       Config.log(Config.DEBUG, "Failed parsing the runtime filter time to an integer: "+ splitFilterStr[1]);
  79. +                       return false;//filter string format invalid
  80. +                   }
  81. +
  82. +                   Config.log(Config.DEBUG, "   Runtime Filter - operator: "+ operator);
  83. +                   Config.log(Config.DEBUG, "   Runtime Filter - runtime: "+ runtimeFilter);
  84. +                   Config.log(Config.DEBUG, "   Actual Runtime: "+ runtime);
  85. +                  
  86. +                   if(operator.equals("EQ"))
  87. +                   {
  88. +                       //Handle Equal To check here
  89. +                       if(runtime == runtimeFilter)
  90. +                       {
  91. +                           return true;
  92. +                       }
  93. +                       else
  94. +                       {
  95. +                           Config.log(Config.DEBUG, "   Failed: actual runtime is not equal to the filter runtime");
  96. +                           return false;
  97. +                       }
  98. +                   }
  99. +                   else if(operator.equals("GT"))
  100. +                   {
  101. +                       //Handle Greater Than check here
  102. +                       if(runtime > runtimeFilter)
  103. +                       {
  104. +                           return true;
  105. +                       }
  106. +                       else
  107. +                       {
  108. +                           Config.log(Config.DEBUG, "   Failed: actual runtime is not greater than the filter runtime");
  109. +                           return false;
  110. +                       }
  111. +                   }
  112. +                   else if(operator.equals("LT"))
  113. +                   {
  114. +                       //Handle Less Than check here
  115. +                       if(runtime < runtimeFilter)
  116. +                       {
  117. +                           return true;
  118. +                       }
  119. +                       else
  120. +                       {
  121. +                           Config.log(Config.DEBUG, "   Failed: actual runtime is not less than the filter runtime");
  122. +                           return false;
  123. +                       }
  124. +                   }
  125. +                   else if(operator.equals("NE"))
  126. +                   {
  127. +                       //Handle Not Equal To check here
  128. +                       if(runtime != runtimeFilter)
  129. +                       {
  130. +                           return true;
  131. +                       }
  132. +                       else
  133. +                       {
  134. +                           Config.log(Config.DEBUG, "   Failed: actual runtime is equal to the filter runtime");
  135. +                           return false;
  136. +                       }
  137. +                   }
  138. +                   else if(operator.equals("GE"))
  139. +                   {
  140. +                       //Handle Greater than or equal to check here
  141. +                       if(runtime >= runtimeFilter)
  142. +                       {
  143. +                           return true;
  144. +                       }
  145. +                       else
  146. +                       {
  147. +                           Config.log(Config.DEBUG, "   Failed: actual runtime is not greater than or equal to the filter runtime");
  148. +                           return false;
  149. +                       }
  150. +                   }
  151. +                   else if(operator.equals("LE"))
  152. +                   {
  153. +                       //Handle Less than or equal to check here
  154. +                       if(runtime <= runtimeFilter)
  155. +                       {
  156. +                           return true;
  157. +                       }
  158. +                       else
  159. +                       {
  160. +                           Config.log(Config.DEBUG, "   Failed: actual runtime is not less than or equal to the filter runtime");
  161. +                           return false;
  162. +                       }
  163. +                   }
  164. +                   else
  165. +                   {
  166. +                       Config.log(Config.DEBUG, "   Failed: unkown relational operator");
  167. +                       return false;//unknown relational operator
  168. +                   }
  169. +                }
  170.                  else
  171.                  {
  172.                       Config.log(Config.WARNING, "Unknown filter type: \""+type+"\"");
  173. Index: utilities/Subfolder.java
  174. ===================================================================
  175. --- utilities/Subfolder.java    (revision 8)
  176. +++ utilities/Subfolder.java    (working copy)
  177. @@ -341,14 +341,16 @@
  178.       * Returns true if it is allowed by ALL filters or filter matching is not used
  179.       * Returns false if this path should be skipped
  180.       */
  181. -    public boolean isAllowedByFilters(String path)
  182. +   //AngryCamel - 20120805 2351
  183. +    // public boolean isAllowedByFilters(String path)
  184. +   public boolean isAllowedByFilters(String path, int runtime)
  185.      {
  186.          path = Config.escapePath(path);
  187.         //check against filters
  188.         boolean shouldFilter = shouldFilter();
  189.         boolean filterMatch = true;//default
  190.         if(shouldFilter)
  191. -           filterMatch = Filter.FilterMatch(path, filters);
  192. +           filterMatch = Filter.FilterMatch(path, runtime, filters); //AngryCamel - 20120805 2351
  193.          if(!filterMatch)
  194.          {
  195.              Config.log(DEBUG, "Skipping this path because it doesn't match any filters: "+ path);
  196. Index: utilities/XBMCFile.java
  197. ===================================================================
  198. --- utilities/XBMCFile.java (revision 8)
  199. +++ utilities/XBMCFile.java (working copy)
  200. @@ -30,6 +30,9 @@
  201.      boolean hasBeenLookedUpOnTVDB = false;
  202.      String fileOrDir;
  203.      private boolean skippedBecauseAlreadyArchived = false;
  204. +  
  205. +   //AngryCamel - 20120805 2351
  206. +   int runtime=0;
  207.      
  208.      
  209.      ///for multi-file vidoes
  210. @@ -58,24 +61,36 @@
  211.          dest.setTVDBId(source.getTVDBId());
  212.          dest.setYear(source.getYear());
  213.      }
  214. -    public XBMCFile(String fileOrDir, String fanart, String file, String fileLabel, String thumbnail, String parentPath, Subfolder matchingSubfolder)
  215. +  
  216. +   //AngryCamel - 20120805 2351
  217. +    //public XBMCFile(String fileOrDir, String fanart, String file, String fileLabel, String thumbnail, String parentPath, Subfolder matchingSubfolder)
  218. +   public XBMCFile(String fileOrDir, String fanart, String file, String fileLabel, String thumbnail, int runtime, String parentPath, Subfolder matchingSubfolder)
  219.      {
  220.          this.fileOrDir = fileOrDir;
  221.          this.fanart = fanart;
  222.          this.file = file;
  223.          this.fileLabel = fileLabel;// == null ? null : fileLabel.replace("/", "-");
  224.          this.thumbnail = thumbnail;
  225. +      
  226. +       //AngryCamel - 20120805 2351
  227. +        this.runtime = runtime;
  228. +      
  229.          this.parentPath = parentPath;
  230.          this.subfolder = matchingSubfolder;
  231.      }
  232.      
  233. -    public XBMCFile(String fileOrDir, String fanart, String file, String fileLabel, String thumbnail)
  234. +    //AngryCamel - 20120805 2351
  235. +    //public XBMCFile(String fileOrDir, String fanart, String file, String fileLabel, String thumbnail)
  236. +   public XBMCFile(String fileOrDir, String fanart, String file, String fileLabel, String thumbnail, int runtime)
  237.      {
  238.          this.fileOrDir = fileOrDir;
  239.          this.fanart = fanart;
  240.          this.file = file;
  241.          this.fileLabel = fileLabel;// == null ? null : fileLabel.replace("/", "-");
  242.          this.thumbnail = thumbnail;
  243. +      
  244. +       //AngryCamel - 20120805 2351
  245. +        this.runtime = runtime;
  246.      }
  247.      
  248.      //limited constructor used in manual archiving
  249. @@ -266,6 +281,13 @@
  250.      {
  251.          this.episodeNumber = episodeNumber;
  252.      }
  253. +  
  254. +   //AngryCamel - 20120805 2351
  255. +    public void setRuntime(int runtime)
  256. +    {
  257. +        this.runtime = runtime;
  258. +    }
  259. +  
  260.      public int getSeasonNumber()
  261.      {
  262.          return seasonNumber;
  263. @@ -378,6 +400,12 @@
  264.      {
  265.          return parentPath;
  266.      }
  267. +  
  268. +   //AngryCamel - 20120805 2351
  269. +    public int getRuntime()
  270. +    {
  271. +        return runtime;
  272. +    }
  273.  
  274.      public String stripExtras(String source)
  275.      {
  276. Index: utilities/XbmcJsonRpc.java
  277. ===================================================================
  278. --- utilities/XbmcJsonRpc.java  (revision 8)
  279. +++ utilities/XbmcJsonRpc.java  (working copy)
  280. @@ -5,6 +5,9 @@
  281.  import java.net.SocketException;
  282.  import java.util.*;
  283.  import java.util.concurrent.*;
  284. +import java.util.regex.Matcher;
  285. +import java.util.regex.Pattern;
  286. +
  287.  import org.json.*;
  288.  
  289.  public class XbmcJsonRpc implements Runnable, Constants
  290. @@ -340,12 +343,17 @@
  291.      public static XBMCFile getXBMCFile(String fileOrDir, JSONObject json)
  292.      {
  293.          try {
  294. +           //AngryCamel - 20120806 2206
  295. +           String runtimeStr = json.has("runtime") ? json.getString("runtime") : "";
  296. +           int runtime = parseRuntime(runtimeStr);
  297. +          
  298.              XBMCFile xbmcFile = new XBMCFile(
  299.                          fileOrDir,
  300.                          json.has("fanart") ? json.getString("fanart") : null,
  301. -                        json.has("file") ? json.getString("file") : null,
  302. +                        json.has("file") ? json.getString("file") : null,
  303.                          json.has("label") ? json.getString("label") : null,
  304. -                        json.has("thumbnail") ? json.getString("thumbnail") : null
  305. +                        json.has("thumbnail") ? json.getString("thumbnail") : null,
  306. +                       runtime //AngryCamel - 20120806 2206
  307.                      );
  308.              return xbmcFile;
  309.          }
  310. @@ -416,8 +424,15 @@
  311.          params.put("directory",dir);
  312.          
  313.          final String mediaType = "files";//files should return everything after fix here: http://forum.xbmc.org/showthread.php?t=114921
  314. -        params.put("media", mediaType);        
  315. +        params.put("media", mediaType);  
  316.          
  317. +       //AngryCamel - 20120805 2351
  318. +       // -Added runtime for the runtime filter.
  319. +       // -You were referencing label (returned when title is specified in properties), thumbnail, and fanart when creating XBMCFile but
  320. +       //  they were not coming back in the JSON reponse, so I added those while I was at it.
  321. +        final String[] properties = {"runtime", "title", "thumbnail", "fanart"};//files should return everything after fix here: http://forum.xbmc.org/showthread.php?t=114921
  322. +        params.put("properties", properties);  
  323. +        
  324.          /*Sort testing
  325.           *
  326.          boolean sort = true;
  327. @@ -470,17 +485,22 @@
  328.                      if(!files.isEmpty())
  329.                      {
  330.                          for(JSONObject file : files)
  331. -                        {                          
  332. -                           XBMCFile xbmcFile = new XBMCFile(
  333. +                        {
  334. +                           //AngryCamel - 20120806 2206
  335. +                           String runtimeStr = file.has("runtime") ? file.getString("runtime") : "";
  336. +                           int runtime = parseRuntime(runtimeStr);
  337. +                          
  338. +                           XBMCFile xbmcFile = new XBMCFile(
  339.                                      FILE,
  340.                                      file.has("fanart") ? file.getString("fanart") : null,
  341.                                      file.getString("file"), //required
  342.                                      file.getString("label"), //required
  343.                                      file.has("thumbnail") ? file.getString("thumbnail") : null,
  344. +                                    runtime, //AngryCamel - 20120806 2206
  345.                                      fullPathLabel,
  346.                                      subf);
  347.  
  348. -                           boolean allowed = subf.isAllowedByFilters(xbmcFile.getFullPathEscaped());
  349. +                           boolean allowed = subf.isAllowedByFilters(xbmcFile.getFullPathEscaped(), xbmcFile.getRuntime()); //AngryCamel - 20120805 2351
  350.                             if(!allowed) continue;
  351.  
  352.                             boolean excluded = subf.isExcluded(xbmcFile.getFullPathEscaped());
  353. @@ -521,6 +541,7 @@
  354.                                                  file, //required
  355.                                                  label, //required
  356.                                                  directory.has("thumbnail") ? directory.getString("thumbnail") : null,
  357. +                                               0, //AngryCamel - 20120805 2351
  358.                                                  fullPathLabel,
  359.                                                  subf);
  360.                                  filesAndDirsFound.put(xbmcFile);
  361. @@ -587,7 +608,111 @@
  362.              }
  363.          }//end if valid json returned
  364.      }
  365. +    
  366. +    //AngryCamel - 20120806 214700
  367. +    //  -Added runtime parsing to detect the format and if necessary translate to a number of minutes as an integer
  368. +    public static int parseRuntime(String runtimeStr)
  369. +    {
  370. +       if(runtimeStr.equals(""))
  371. +           return 0;
  372. +      
  373. +       int runTime = 0;
  374. +      
  375. +       //HH:MM:SS Pattern matches any of the following:
  376. +       //39:10, 31:46, 1:39:58, 9:13, 69:58:06
  377. +       String hhmmssPattern = "(\\d*):?(\\d*)?:([0-5][0-9])";  
  378. +      
  379. +       // Compile and use regular expression
  380. +       Pattern pattern = Pattern.compile(hhmmssPattern);
  381. +       Matcher matcher = pattern.matcher(runtimeStr);
  382. +       boolean matchFound = matcher.find();
  383. +       if (matchFound) {
  384. +           int hours = 0, mins = 0, secs = 0;
  385.  
  386. +           /*
  387. +           String groupStr = "";
  388. +           for (int i=0; i<=matcher.groupCount(); i++) {
  389. +                groupStr += " Group("+i+"): "+matcher.group(i);
  390. +            }
  391. +           Config.log(Config.DEBUG, "Match:"+ groupStr);
  392. +           */
  393. +          
  394. +           if(matcher.groupCount()==3)
  395. +           {
  396. +               //For patterns without an hour segment, the minute will go into group 1 and the seconds into group 3. Group 2 will be empty
  397. +               //For patterns with an hour segment (total of 4), the hour will go into group 1, minute into group 2, and the seconds into group 3
  398. +               if(matcher.group(2).length() < 1)
  399. +               {
  400. +                   //This is a MM:SS match
  401. +                   //Config.log(Config.DEBUG, "Matched on MM:SS pattern: "+ runtimeStr);
  402. +                  
  403. +                   //Parse the minutes
  404. +                   if(matcher.group(1).length()>0)
  405. +                   {
  406. +                       try{
  407. +                           mins = Integer.parseInt(matcher.group(1));
  408. +                       }catch (NumberFormatException e){}
  409. +                   }
  410. +                   //Config.log(Config.DEBUG, "   Mins: "+ mins);
  411. +                  
  412. +                   //Parse the seconds
  413. +                   if(matcher.group(3).length()>0)
  414. +                   {
  415. +                       try{
  416. +                           secs = Integer.parseInt(matcher.group(3));
  417. +                       }catch (NumberFormatException e){}
  418. +                   }
  419. +                   //Config.log(Config.DEBUG, "   Secs: "+ secs);
  420. +               }
  421. +               else
  422. +               {
  423. +                   //This is a HH:MM:SS match
  424. +                   //Config.log(Config.DEBUG, "Matched on HH:MM:SS pattern: "+ runtimeStr);
  425. +                  
  426. +                   //Parse the hours
  427. +                   if(matcher.group(1).length()>0)
  428. +                   {
  429. +                       try{
  430. +                           hours = Integer.parseInt(matcher.group(1));
  431. +                       }catch (NumberFormatException e){}
  432. +                   }
  433. +                   //Config.log(Config.DEBUG, "   Hours: "+ hours);
  434. +                  
  435. +                   //Parse the minutes
  436. +                   if(matcher.group(2).length()>0)
  437. +                   {
  438. +                       try{
  439. +                           mins = Integer.parseInt(matcher.group(2));
  440. +                       }catch (NumberFormatException e){}
  441. +                   }
  442. +                   //Config.log(Config.DEBUG, "   Mins: "+ mins);
  443. +                  
  444. +                   //Parse the seconds
  445. +                   if(matcher.group(3).length()>0)
  446. +                   {
  447. +                       try{
  448. +                           secs = Integer.parseInt(matcher.group(3));
  449. +                       }catch (NumberFormatException e){}
  450. +                   }
  451. +                   //Config.log(Config.DEBUG, "   Secs: "+ secs);
  452. +               }
  453. +           }
  454. +           //Now add it all up
  455. +           runTime = (60*60*hours) + (60*mins) + secs;
  456. +       }
  457. +       else
  458. +       {
  459. +           //Format did not match HH:MM:SS format; try to parse as int
  460. +           //Config.log(Config.DEBUG, "Runtime format has no pattern (parsing as int): "+ runtimeStr);
  461. +           try{
  462. +               runTime = Integer.parseInt(runtimeStr);
  463. +           }catch (NumberFormatException e){}
  464. +       }
  465. +
  466. +       Config.log(Config.DEBUG, "Parsed " + runtimeStr + " to " + runTime + " mins");
  467. +        return runTime;
  468. +    }
  469. +
  470.  
  471.      
  472.      Socket jsonRPCSocket = null;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement