1 package user.jobengine.server.steps;
\r
4 import java.io.IOException;
\r
5 import java.nio.file.FileVisitResult;
\r
6 import java.nio.file.Files;
\r
7 import java.nio.file.Path;
\r
8 import java.nio.file.Paths;
\r
9 import java.nio.file.SimpleFileVisitor;
\r
10 import java.nio.file.attribute.BasicFileAttributes;
\r
11 import java.text.ParseException;
\r
12 import java.text.SimpleDateFormat;
\r
13 import java.util.Date;
\r
14 import java.util.List;
\r
16 import org.apache.commons.lang.StringUtils;
\r
17 import org.apache.logging.log4j.LogManager;
\r
18 import org.apache.logging.log4j.Logger;
\r
19 import org.apache.logging.log4j.Marker;
\r
21 import com.ibm.nosql.json.api.BasicDBObject;
\r
22 import com.ibm.nosql.json.api.DBObject;
\r
24 import user.commons.CalendarUtils;
\r
25 import user.commons.nosql.NoSQLUtils;
\r
26 import user.commons.octopus.IOctopusAPI;
\r
27 import user.commons.octopus.OctopusAPI;
\r
28 import user.jobengine.server.IJobEngine;
\r
29 import user.jobengine.server.IJobRuntime;
\r
31 public class RecordingsArchiveItemBuilderStep extends JobStep {
\r
32 private static final String MEDIATYPE = "Visszarögzített";
\r
33 private static final Logger logger = LogManager.getLogger();
\r
34 private static final String STATUSFOLDER = ".STATUS";
\r
35 private static final String LXFEXT = ".lxf";
\r
36 private static final String CATCHEDEXT = ".catched";
\r
37 private static final SimpleDateFormat startTimeformat = new SimpleDateFormat("HHmm");
\r
38 private static final SimpleDateFormat startDateformat = new SimpleDateFormat("yyMMdd");
\r
39 private static final String SCHEDULED_FORMAT = "yyyy.MM.dd HH:mm";
\r
41 private Marker marker;
\r
43 private ArchiveItem createArchiveItem(Path mediaFilePath, Path catchedFilePath) {
\r
44 ArchiveItem result = null;
\r
47 Date recordDate = startDateformat.parse(mediaFilePath.getParent().toFile().getName());
\r
48 String clipName = mediaFilePath.toFile().getName();
\r
49 Date scheduledStart = getScheduledStart(clipName, recordDate);
\r
50 IOctopusAPI octopusAPI = new OctopusAPI();
\r
51 DBObject rundown = octopusAPI.getRundown(scheduledStart);
\r
52 if (rundown == null) {
\r
53 logger.error(marker, "A '{}' anyaghoz nem található tükör '{}' kezdéssel, ezért nem archiválható.", clipName, scheduledStart);
\r
56 result = processRundow(octopusAPI, rundown);
\r
60 result.setMediaTitle(clipName);
\r
61 result.setMediaType(MEDIATYPE);
\r
62 result.setMediaFile(mediaFilePath.toString());
\r
63 result.setCatchedFile(catchedFilePath.toString());
\r
64 } catch (Exception e) {
\r
66 logger.error(getJobRuntime().getMarker(), "A metaadat nem elérhető. A rendszer üzenete: {}", e.getMessage());
\r
73 private void createCatchedFile(Path catchedFilePath) throws IOException {
\r
75 EscortFiles.ensureUNCFolder(catchedFilePath.getParent());
\r
76 Files.createFile(catchedFilePath);
\r
77 } catch (IOException e) {
\r
79 logger.error(marker, "A '{}' jelzőfájl nem hozható létre. A rendszer üzenete: {}", catchedFilePath, e.getMessage());
\r
85 public Object[] execute(String sourcePath, IJobEngine jobEngine, IJobRuntime jobRuntime) throws Exception {
\r
86 final ArchiveItem[] archiveItems = { null };
\r
87 marker = getJobRuntime().getMarker();
\r
89 Files.walkFileTree(Paths.get(sourcePath), new SimpleFileVisitor<Path>() {
\r
92 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
\r
93 FileVisitResult result = FileVisitResult.SKIP_SUBTREE;
\r
95 if (dir.equals(Paths.get(sourcePath)) || "HIRADO".equals(dir.toFile().getName().toUpperCase())
\r
96 || "NAPIAKT".equals(dir.toFile().getName().toUpperCase()))
\r
97 result = FileVisitResult.CONTINUE;
\r
99 if ("HIRADO".equals(dir.getParent().toFile().getName().toUpperCase())
\r
100 || "NAPIAKT".equals(dir.getParent().toFile().getName().toUpperCase())) {
\r
102 startDateformat.parse(dir.toFile().getName());
\r
103 result = FileVisitResult.CONTINUE;
\r
104 } catch (ParseException e) {
\r
109 if (result == FileVisitResult.CONTINUE)
\r
115 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
\r
116 FileVisitResult result = FileVisitResult.TERMINATE;
\r
117 ArchiveItem item = null;
\r
119 item = processPathItem(file);
\r
120 } catch (IOException e) {
\r
121 logger.catching(e);
\r
122 logger.error(marker, "Az '{}' állomány feldolgozása sikertelen. A rendszer hibaüzenete: {}", file, e.getMessage());
\r
125 if (item == null) {
\r
126 result = FileVisitResult.CONTINUE;
\r
129 archiveItems[0] = item;
\r
136 } catch (Exception e) {
\r
137 logger.catching(e);
\r
138 logger.error(marker, "Az '{}' mappa elérése sikertelen. A rendszer hibaüzenete: {}", sourcePath, e.getMessage());
\r
142 ArchiveItem archiveItem = archiveItems[0];
\r
143 String targetFileName = null;
\r
145 if (archiveItem == null || archiveItem.getMediaFile() == null) {
\r
146 logger.warn(marker, "Az archiváló folyamat nem talált új anyagot.");
\r
147 throw new Exception("No media to archive");
\r
149 String mediaFile = archiveItem.getMediaFile();
\r
150 String name = new File(mediaFile).getName();
\r
151 int extPos = name.toLowerCase().lastIndexOf(LXFEXT);
\r
152 targetFileName = String.format("20%s-%s", Paths.get(mediaFile).getParent().getFileName(), name.substring(0, extPos));
\r
153 logger.info(marker, "Az archiváló folyamat az '{}' anyagot archiválja.", mediaFile);
\r
156 return new Object[] { archiveItem, targetFileName };
\r
159 private Date getScheduledStart(String clipName, Date recordDate) {
\r
161 if (StringUtils.isBlank(clipName)) {
\r
162 logger.warn(marker, "A fájlnak nincs neve, ezért nem archiválható.");
\r
165 if (recordDate == null) {
\r
166 logger.warn(marker, "Az '{}' fájl rögzítésének ideje nem meghatározható, ezért nem archiválható.", clipName);
\r
170 Date timePart = null;
\r
172 String clipNameTime = clipName.split("_")[0];
\r
173 timePart = startTimeformat.parse(clipNameTime);
\r
174 } catch (ParseException e) {
\r
175 logger.warn(marker, "A '{}' fájl neve nem időbélyeggel kezdődik, ezért nem archiválható.", clipName);
\r
178 return CalendarUtils.createCalendar(CalendarUtils.createCalendar(recordDate), timePart).getTime();
\r
181 private ArchiveItem processPathItem(Path mediaFilePath) throws IOException {
\r
182 File mediaFile = mediaFilePath.toFile();
\r
184 Path dotStorePath = Paths.get(mediaFilePath.getParent().toString(), STATUSFOLDER);
\r
185 Path catchedFilePath = Paths.get(dotStorePath.toString(), mediaFile.getName() + CATCHEDEXT);
\r
186 File catchedFile = catchedFilePath.toFile();
\r
187 if (catchedFile.exists()) {
\r
188 //logger.info("'{}' file is already catched", mediaFilePath);
\r
191 createCatchedFile(catchedFilePath);
\r
192 if (!catchedFile.exists()) {
\r
193 logger.warn("'{}' catchfile not exists.", catchedFilePath);
\r
197 if (mediaFile.isDirectory() || !mediaFile.getName().toLowerCase().endsWith(LXFEXT.toLowerCase())
\r
198 || mediaFilePath.getParent().toFile().getName().length() != 6) {
\r
199 logger.info("Skipping '{}'", mediaFilePath);
\r
203 ArchiveItem archiveItem = createArchiveItem(mediaFilePath, catchedFilePath);
\r
205 if (archiveItem == null) {
\r
206 logger.warn("'{}' has no metadata specified.", mediaFilePath);
\r
210 if (StringUtils.isBlank(archiveItem.getItemHouseId())) {
\r
211 logger.warn("'{}' has no Item HouseID specified in metadata.", mediaFilePath);
\r
215 if (StringUtils.isBlank(archiveItem.getItemTitle())) {
\r
216 logger.warn("'{}' has no Item Title specified in metadata.", mediaFilePath);
\r
220 if (StringUtils.isBlank(archiveItem.getMediaHouseId())) {
\r
221 logger.warn("'{}' has no Media HouseID specified in metadata.", mediaFilePath);
\r
225 if (StringUtils.isBlank(archiveItem.getMediaTitle())) {
\r
226 logger.warn("'{}' has no Media Title specified in metadata.", mediaFilePath);
\r
229 return archiveItem;
\r
232 private ArchiveItem processRundow(IOctopusAPI octopusAPI, DBObject r) throws Exception {
\r
233 BasicDBObject rundown = (BasicDBObject) r;
\r
234 long rundownID = rundown.getLong(IOctopusAPI.ID);
\r
235 logger.info("Processing rundown {} {}", rundownID, rundown.getString(IOctopusAPI.NAME));
\r
237 List<DBObject> stories = octopusAPI.getRundownFullStories(rundownID);
\r
238 if (stories == null)
\r
241 String name = NoSQLUtils.asString(NoSQLUtils.asDBObject(rundown, IOctopusAPI.RUNDOWN_TYPE), IOctopusAPI.NAME);
\r
242 if (StringUtils.isBlank(name))
\r
244 String channel = NoSQLUtils.asString(NoSQLUtils.asDBObject(rundown, IOctopusAPI.CHANNEL), IOctopusAPI.NAME);
\r
245 Date scheduledStart = rundown.getDate(IOctopusAPI.SCHEDULED_START);
\r
246 if (scheduledStart == null)
\r
249 ArchiveItem result = new ArchiveItem();
\r
250 result.setItemHouseId(String.valueOf(rundownID));
\r
251 String start = CalendarUtils.toString(CalendarUtils.createCalendar(scheduledStart), SCHEDULED_FORMAT);
\r
252 result.setItemTitle(String.format("%s %s %s", start, name, channel));
\r
254 StringBuilder sb = new StringBuilder();
\r
255 for (DBObject s : stories) {
\r
256 BasicDBObject story = (BasicDBObject) s;
\r
259 sb.append(story.getString(IOctopusAPI.PARENT_STORY_ID));
\r
260 sb.append(" [" + story.getString(IOctopusAPI.FORMAT) + "] ");
\r
261 sb.append(story.getString(IOctopusAPI.NAME));
\r
264 String content = story.getString(IOctopusAPI.SCRIPT_CONTENT);
\r
265 if (content != null) {
\r
266 content = content.replace("\r\n\r\n\r\n\r\n", "\r\n");
\r
267 content = content.replace("\r\n\r\n\r\n", "\r\n");
\r
268 content = content.replace("\r\n\r\n", "\r\n");
\r
269 sb.append(content);
\r
273 result.setMediaHouseId(result.getItemHouseId());
\r
274 result.setMediaDescription(sb.toString());
\r
276 if (result.getMediaDescription() != null && result.getMediaDescription().length() > 5000)
\r
277 result.setMediaDescription(result.getMediaDescription().substring(0, 5000));
\r