// XXX dir.canWrite() has issues on Windows, so verify it directly: // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6203387 public static boolean isDirectoryWritable(File dir) { boolean isWritable = false; if (dir != null) { // new File("").isDirectory() is false, even though getAbsolutePath() returns the right path. // this resolves it dir = dir.getAbsoluteFile(); if (dir.isDirectory()) { File file = new File( dir, String.format( "pms_directory_write_test_%d_%d.tmp", System.currentTimeMillis(), Thread.currentThread().getId())); try { if (file.createNewFile()) { if (isFileWritable(file)) { isWritable = true; } if (!file.delete()) { LOGGER.warn("Can't delete temporary test file: {}", file.getAbsolutePath()); } } } catch (IOException | SecurityException ioe) { } } } return isWritable; }
/** * Shift timing of subtitles in SSA/ASS or SRT format and converts charset to UTF8 if necessary * * @param inputSubtitles Subtitles file in SSA/ASS or SRT format * @param timeShift Time stamp value * @return Converted subtitles file * @throws IOException */ public static DLNAMediaSubtitle shiftSubtitlesTimingWithUtfConversion( final DLNAMediaSubtitle inputSubtitles, double timeShift) throws IOException { if (inputSubtitles == null) { throw new NullPointerException("inputSubtitles should not be null."); } if (!inputSubtitles.isExternal()) { throw new IllegalArgumentException("inputSubtitles should be external."); } if (isBlank(inputSubtitles.getExternalFile().getName())) { throw new IllegalArgumentException( "inputSubtitles' external file should not have blank name."); } if (inputSubtitles.getType() == null) { throw new NullPointerException("inputSubtitles.getType() should not be null."); } if (!isSupportsTimeShifting(inputSubtitles.getType())) { throw new IllegalArgumentException( "inputSubtitles.getType() " + inputSubtitles.getType() + " is not supported."); } final File convertedSubtitlesFile = new File( configuration.getTempFolder(), getBaseName(inputSubtitles.getExternalFile().getName()) + System.currentTimeMillis() + ".tmp"); FileUtils.forceDeleteOnExit(convertedSubtitlesFile); BufferedReader input; final boolean isSubtitlesCodepageForcedInConfigurationAndSupportedByJVM = isNotBlank(configuration.getSubtitlesCodepage()) && Charset.isSupported(configuration.getSubtitlesCodepage()); final boolean isSubtitlesCodepageAutoDetectedAndSupportedByJVM = isNotBlank(inputSubtitles.getExternalFileCharacterSet()) && Charset.isSupported(inputSubtitles.getExternalFileCharacterSet()); if (isSubtitlesCodepageForcedInConfigurationAndSupportedByJVM) { input = new BufferedReader( new InputStreamReader( new FileInputStream(inputSubtitles.getExternalFile()), Charset.forName(configuration.getSubtitlesCodepage()))); } else if (isSubtitlesCodepageAutoDetectedAndSupportedByJVM) { input = new BufferedReader( new InputStreamReader( new FileInputStream(inputSubtitles.getExternalFile()), Charset.forName(inputSubtitles.getExternalFileCharacterSet()))); } else { input = new BufferedReader( new InputStreamReader(new FileInputStream(inputSubtitles.getExternalFile()))); } final BufferedWriter output = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(convertedSubtitlesFile), Charset.forName("UTF-8"))); String line; double startTime; double endTime; try { if (SubtitleType.ASS.equals(inputSubtitles.getType())) { while ((line = input.readLine()) != null) { if (startsWith(line, "Dialogue:")) { String[] timings = splitPreserveAllTokens(line, ","); if (timings.length >= 3 && isNotBlank(timings[1]) && isNotBlank(timings[1])) { startTime = convertSubtitleTimingStringToTime(timings[1]); endTime = convertSubtitleTimingStringToTime(timings[2]); if (startTime >= timeShift) { timings[1] = convertTimeToSubtitleTimingString( startTime - timeShift, TimingFormat.ASS_TIMING); timings[2] = convertTimeToSubtitleTimingString(endTime - timeShift, TimingFormat.ASS_TIMING); output.write(join(timings, ",") + "\n"); } else { continue; } } else { output.write(line + "\n"); } } else { output.write(line + "\n"); } } } else if (SubtitleType.SUBRIP.equals(inputSubtitles.getType())) { int n = 1; while ((line = input.readLine()) != null) { if (contains(line, ("-->"))) { startTime = convertSubtitleTimingStringToTime(line.substring(0, line.indexOf("-->") - 1)); endTime = convertSubtitleTimingStringToTime(line.substring(line.indexOf("-->") + 4)); if (startTime >= timeShift) { output.write("" + (n++) + "\n"); output.write( convertTimeToSubtitleTimingString( startTime - timeShift, TimingFormat.SRT_TIMING)); output.write(" --> "); output.write( convertTimeToSubtitleTimingString(endTime - timeShift, TimingFormat.SRT_TIMING) + "\n"); while (isNotBlank(line = input.readLine())) { // Read all following subs lines output.write(line + "\n"); } output.write("" + "\n"); } } } } } finally { if (output != null) { output.flush(); output.close(); } if (input != null) { input.close(); } } final DLNAMediaSubtitle convertedSubtitles = new DLNAMediaSubtitle(); convertedSubtitles.setExternalFile(convertedSubtitlesFile); convertedSubtitles.setType(inputSubtitles.getType()); convertedSubtitles.setLang(inputSubtitles.getLang()); convertedSubtitles.setFlavor(inputSubtitles.getFlavor()); convertedSubtitles.setId(inputSubtitles.getId()); return convertedSubtitles; }