package ctbrec; import java.io.File; import java.io.Serializable; import java.time.Duration; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Optional; import ctbrec.event.EventBusHolder; import ctbrec.event.RecordingStateChangedEvent; import ctbrec.recorder.download.Download; public class Recording implements Serializable { private Model model; private transient Download download; private Instant startDate; private String path; private State status = State.UNKNOWN; private int progress = -1; private long sizeInByte = -1; private String metaDataFile; public enum State { RECORDING("recording"), GENERATING_PLAYLIST("generating playlist"), POST_PROCESSING("post-processing"), FINISHED("finished"), DOWNLOADING("downloading"), DELETING("deleting"), DELETED("deleted"), UNKNOWN("unknown"), WAITING("waiting"), FAILED("failed"); private String desc; State(String desc) { this.desc = desc; } @Override public String toString() { return desc; } } public Instant getStartDate() { return startDate; } public void setStartDate(Instant startDate) { this.startDate = startDate; } public State getStatus() { return status; } public void setStatus(State status) { this.status = status; } public void setStatusWithEvent(State status) { setStatus(status); fireStatusEvent(status); } public int getProgress() { return this.progress; } public void setProgress(int progress) { this.progress = progress; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public File getAbsoluteFile() { String recordingsDir = Config.getInstance().getSettings().recordingsDir; File recordingsFile = new File(recordingsDir, getPath()); return recordingsFile; } public long getSizeInByte() { return sizeInByte; } public void setSizeInByte(long sizeInByte) { this.sizeInByte = sizeInByte; } public void postprocess() { getDownload().postprocess(this); } private void fireStatusEvent(State status) { RecordingStateChangedEvent evt = new RecordingStateChangedEvent(getDownload().getTarget(), status, getModel(), getStartDate()); EventBusHolder.BUS.post(evt); } public Model getModel() { return model; } public void setModel(Model model) { this.model = model; } public Download getDownload() { return download; } public void setDownload(Download download) { this.download = download; } public String getMetaDataFile() { return metaDataFile; } public void setMetaDataFile(String metaDataFile) { this.metaDataFile = metaDataFile; } public Duration getLength() { if (getDownload() != null) { return getDownload().getLength(); } else { return Duration.ofSeconds(0); } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((getStartDate() == null) ? 0 : (int) (getStartDate().toEpochMilli() ^ (getStartDate().toEpochMilli() >>> 32))); result = prime * result + ((model == null) ? 0 : model.hashCode()); result = prime * result + ((path == null) ? 0 : path.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if(!(obj instanceof Recording)) { return false; } Recording other = (Recording) obj; if (getModel() == null) { if (other.getModel() != null) { return false; } } else if (!getModel().equals(other.getModel())) { return false; } if (getPath() == null) { if (other.getPath() != null) { return false; } } else if (!getPath().equals(other.getPath())) { return false; } if (getStartDate() == null) { if (other.getStartDate() != null) { return false; } } else if (getStartDate().toEpochMilli() != other.getStartDate().toEpochMilli()) { return false; } return true; } @Override public String toString() { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(Config.RECORDING_DATE_FORMAT); LocalDateTime localStartDate = LocalDateTime.ofInstant(getStartDate(), ZoneId.systemDefault()); return getModel().getSanitizedNamed() + '_' + formatter.format(localStartDate); } private long getSize() { File rec = new File(Config.getInstance().getSettings().recordingsDir, getPath()); if (rec.isDirectory()) { return getDirectorySize(rec); } else { if (!rec.exists()) { if (rec.getName().endsWith(".m3u8")) { return getDirectorySize(rec.getParentFile()); } else { return -1; } } else { return rec.length(); } } } private long getDirectorySize(File dir) { long size = 0; if (dir.exists()) { File[] files = dir.listFiles(); if (files == null) { return 0; } for (File file : files) { size += file.length(); } } return size; } public void refresh() { sizeInByte = getSize(); } public boolean isSegmented() { return !Optional.ofNullable(getPath()).orElse("").endsWith(".mp4"); } }