/* This file is part of JFLICKS. JFLICKS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. JFLICKS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with JFLICKS. If not, see <http://www.gnu.org/licenses/>. */ package org.jflicks.cleaner.ray; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.Date; import org.jflicks.job.AbstractJob; import org.jflicks.job.JobManager; import org.jflicks.nms.NMS; import org.jflicks.tv.Recording; import org.jflicks.tv.recorder.Recorder; import org.jflicks.util.LogUtil; import org.apache.commons.io.FileUtils; /** * This job supports the Ray Cleaner service. * * @author Doug Barnum * @version 1.0 */ public class RayCleanerJob extends AbstractJob { private RayCleaner rayCleaner; /** * This job supports the RayCleaner plugin. * * @param rc A RayCleaner instance. */ public RayCleanerJob(RayCleaner rc) { setRayCleaner(rc); // First run we will go after 2 minutes setSleepTime(120000); } private RayCleaner getRayCleaner() { return (rayCleaner); } private void setRayCleaner(RayCleaner r) { rayCleaner = r; } /** * {@inheritDoc} */ public void start() { setTerminate(false); } /** * {@inheritDoc} */ public void run() { while (!isTerminate()) { JobManager.sleep(getSleepTime()); RayCleaner rc = getRayCleaner(); if (rc != null) { NMS nms = rc.getNMS(); if (nms != null) { if (isSystemReady(nms)) { Recording[] recs = nms.getRecordings(); if ((recs != null) && (recs.length > 0)) { for (int i = 0; i < recs.length; i++) { if (isReadyToClean(recs[i], rc.getRecordingMinimumAge())) { clean(recs[i]); } } } else { LogUtil.log(LogUtil.DEBUG, "Cleaner NO - no recordings"); } } else { LogUtil.log(LogUtil.DEBUG, "Cleaner NO - something recording"); } } } setSleepTime(rc.getTimeBetweenCleanings() * 1000); } } /** * {@inheritDoc} */ public void stop() { setTerminate(true); } private boolean isSystemReady(NMS n) { boolean result = true; if (n != null) { Recorder[] array = n.getRecorders(); if (array != null) { for (int i = 0; i < array.length; i++) { if (array[i].isRecording()) { result = false; break; } } } } return (result); } private boolean isReadyToClean(Recording r, int seconds) { boolean result = false; if (r != null) { // Double check is isnt recording. if (!r.isCurrentlyRecording()) { // Now see if the indexer has finished. String path = r.getPath(); String ext = r.getIndexedExtension(); if ((path != null) && (ext != null)) { File f = new File(path + "." + ext); if ((f.exists()) && (f.isFile())) { Date d = r.getDate(); if (d != null) { long lsecs = (long) seconds; lsecs *= 1000; long when = d.getTime() + r.getDuration() + lsecs; long now = System.currentTimeMillis(); if (now > when) { LogUtil.log(LogUtil.DEBUG, "Cleaner YES to clean: " + r); result = true; } else { LogUtil.log(LogUtil.DEBUG, "Cleaner NO too young: " + r); } } else { LogUtil.log(LogUtil.DEBUG, "Cleaner no date cannot determine age: " + r); } } else { LogUtil.log(LogUtil.DEBUG, "Cleaner no not indexed: " + r); } } else { LogUtil.log(LogUtil.DEBUG, "Cleaner no not indexed: " + r); } } else { LogUtil.log(LogUtil.DEBUG, "Cleaner no it's still recording: " + r); } } return (result); } private void clean(Recording r) { if (r != null) { String path = r.getPath(); File fpath = new File(path); String prefix = fpath.getName(); prefix = prefix.substring(0, prefix.length() - 2); File parent = fpath.getParentFile(); File[] files = parent.listFiles(new HlsFileFilter(prefix)); if ((files != null) && (files.length > 0)) { for (int i = 0; i < files.length; i++) { try { FileUtils.forceDelete(files[i]); LogUtil.log(LogUtil.DEBUG, "Cleaner got: " + files[i].getPath()); } catch (IOException ex) { LogUtil.log(LogUtil.WARNING, "Cleaner could not delete: " + ex.getMessage()); } } // Last thing to get is the m3u8 file. It's different that it doesn't have the // .ts before the .m3u8 File m3u8 = new File(parent, prefix + "m3u8"); if ((m3u8.exists()) && (m3u8.isFile())) { try { FileUtils.forceDelete(m3u8); LogUtil.log(LogUtil.DEBUG, "Cleaner got m3u8: " + m3u8.getPath()); } catch (IOException ex) { LogUtil.log(LogUtil.WARNING, "Cleaner could not delete m3u8: " + ex.getMessage()); } } } } } private class HlsFileFilter implements FileFilter { private String prefix; public HlsFileFilter(String s) { prefix = s; } public boolean accept(File f) { boolean result = false; if ((prefix != null) && (f != null)) { String name = f.getName(); if ((name.startsWith(prefix)) && (name.endsWith(".ts"))) { result = true; } } return (result); } } }