-/*
- * 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.
- *
- * @author Erik Brakkee
- */
-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<File,Recording> _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<File,Recording>();
- }
-
- 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.info("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());
- if ( recording == null ) {
- LOG.warn("Spurious recording which should not exist according to mythtv: " + aFile);
- return;
- }
- _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", aTarget, aSource });
- process.run();
- LOG.info("Created symlink " + aSource + " -> " + aTarget);
- } catch (IOException e) {
- LOG.error(
- "Could not create symlink: " + aTarget + " <- " + aSource,
- e);
- }
- }
-}