X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;f=mythtv%2Fwar%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fmythtv%2FLinkStructure.java;fp=mythtv%2Fwar%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fmythtv%2FLinkStructure.java;h=486723373f60e3e39de5e651f5adaf6a48313653;hb=84623d9c9d1297b2440b0fd8075ec7c89f2dd502;hp=0000000000000000000000000000000000000000;hpb=aa4e06ab19e030bf82638600d051b71fe847d0f7;p=utils diff --git a/mythtv/war/src/main/java/org/wamblee/mythtv/LinkStructure.java b/mythtv/war/src/main/java/org/wamblee/mythtv/LinkStructure.java new file mode 100644 index 00000000..48672337 --- /dev/null +++ b/mythtv/war/src/main/java/org/wamblee/mythtv/LinkStructure.java @@ -0,0 +1,213 @@ +/* + * Copyright 2006 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.wamblee.mythtv; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wamblee.io.SimpleProcess; +import org.wamblee.io.DirectoryMonitor.Listener; + +/** + * Link structure. + */ +public class LinkStructure implements Listener { + + private static final Log LOG = LogFactory.getLog(LinkStructure.class); + + private String _monitorDir; + + private File _linkDir; + + private RecordingDatabase _database; + + private SimpleDateFormat _format; + + private Map _recordings; + + public LinkStructure(String aMonitorDir, File aLinkDir, + RecordingDatabase aDatabase) { + _monitorDir = aMonitorDir + "/"; + deleteDir(aLinkDir); + _linkDir = aLinkDir; + _database = aDatabase; + _format = new SimpleDateFormat("yyyy-MM-dd-HH:mm"); + _recordings = new HashMap(); + } + + private void deleteDir(File aFile) { + for (File file: aFile.listFiles()) { + if ( file.isDirectory()) { + deleteDir(file); + } + LOG.info("File deleted " + file + ": " + file.delete()); + } + } + + /* + * (non-Javadoc) + * + * @see org.wamblee.io.DirectoryMonitor.Listener#fileChanged(java.io.File) + */ + public void fileChanged(File aFile) { + LOG.debug("file changed " + aFile); + + // Re-assess file type + Recording recording = _recordings.get(aFile); + LOG.debug("Recording changed " + recording); + recording.setFilesize(aFile.length()); + _database.update(recording); + String dir = getDirectory(recording); + FileType type = getFileType(aFile); + String path = dir + "/" + getFilename(recording, type); + + if (exists(dir + "/" + getFilename(recording, type))) { + // Nothing to do. + } else { + mkdir(dir); + for (FileType t : FileType.values()) { + rmlink(dir + "/" + getFilename(recording, t)); + } + createSymLink(_monitorDir + aFile.getName(), dir + "/" + + getFilename(recording, type)); + } + } + + /* + * (non-Javadoc) + * + * @see org.wamblee.io.DirectoryMonitor.Listener#fileCreated(java.io.File) + */ + public void fileCreated(File aFile) { + LOG.debug("file created " + aFile); + Recording recording = _database.findRecording(aFile.getName()); + _recordings.put(aFile, recording); + LOG.info("New recording detected " + aFile + " " + + recording); + + recording.setFilesize(aFile.length()); + _database.update(recording); + String dir = getDirectory(recording); + mkdir(dir); + createSymLink(_monitorDir + aFile.getName(), dir + "/" + + getFilename(recording, getFileType(aFile))); + } + + /* + * (non-Javadoc) + * + * @see org.wamblee.io.DirectoryMonitor.Listener#fileDeleted(java.io.File) + */ + public void fileDeleted(File aFile) { + LOG.debug("file deleted " + aFile); + Recording recording = _recordings.get(aFile); + _recordings.remove(recording); + // mythtv will remove the recording from its database itself. + LOG.info("recording deleted " + recording); + String dir = getDirectory(recording); + for (FileType t: FileType.values()) { + rmlink(dir + "/" + getFilename(recording, t)); + } + rmdir(dir); + } + + private String getDirectory(Recording aRecording) { + return aRecording.getTitle().replaceAll("/", "-"); + } + + private FileType getFileType(File aFile) { + SimpleProcess process = new SimpleProcess(new File(_monitorDir), new String[] { + "file", aFile.getName() }); + try { + process.run(); + if (process.getStdout().contains("RIFF")) { + return FileType.AVI; + } else { + return FileType.MPG; + } + } catch (IOException e) { + LOG.error("Determining filetype for " + aFile + " failed", e); + return FileType.MPG; + } + } + + private String getFilename(Recording aRecording, FileType aType) { + return (_format.format(aRecording.getProgstart()) + "-" + + aRecording.getSubtitle() + "-" + + aRecording.getChannel().getName() + "." + + aType.toString().toLowerCase()).replaceAll("/", "-"); + } + + private boolean exists(String aPath) { + LOG.debug("exists " + aPath); + return new File(_linkDir, aPath).exists(); + } + + private void rmlink(String aPath) { + LOG.debug("rmlink " + aPath); + File link = new File(_linkDir, aPath); + //if ( !link.exists()) { + // return; + // } + if (!link.delete()) { + LOG.warn("Delete failed: " + aPath); + } else { + LOG.info("Removed link " + link); + } + } + + private void mkdir(String aDir) { + LOG.debug("mkdir " + aDir); + File dir = new File(_linkDir, aDir); + if ( dir.isDirectory()) { + return; + } + if (!dir.mkdirs()) { + LOG.warn("Could not create directory path: " + aDir); + } else { + LOG.info("Created directory " + dir); + } + } + + private void rmdir(String aDir) { + LOG.debug("rmdir " + aDir); + File dir = new File(_linkDir, aDir); + if (!dir.delete()) { + LOG.warn("Directory not deleted (still recordings left): " + aDir); + } else { + LOG.info("Directory " + dir + " deleted."); + } + } + + private void createSymLink(String aTarget, String aSource) { + try { + SimpleProcess process = new SimpleProcess(_linkDir, new String[] { + "ln", "-s", aTarget, aSource }); + process.run(); + LOG.info("Created symlink " + aSource + " -> " + aTarget); + } catch (IOException e) { + LOG.error( + "Could not create symlink: " + aTarget + " <- " + aSource, + e); + } + } +}