599a73c9883becb4672097a9eca6fbea628996c9
[mediacube.git] /
1 package user.jobengine.server.steps;\r
2 \r
3 import java.io.File;\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
15 \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
20 \r
21 import com.ibm.nosql.json.api.BasicDBObject;\r
22 import com.ibm.nosql.json.api.DBObject;\r
23 \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
30 \r
31 public class RecordingsArchiveItemBuilderStep extends JobStep {\r
32         private static final String RECORDING = "Visszarögzítés";\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
40 \r
41         private Marker marker;\r
42 \r
43         private ArchiveItem createArchiveItem(Path mediaFilePath, Path catchedFilePath) {\r
44                 ArchiveItem result = null;\r
45                 try {\r
46 \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
54                                 return null;\r
55                         }\r
56                         //DB db = NoSQLUtils.getNoSQLDB();\r
57 \r
58                         //\r
59                         //                      BasicDBObject dbObject = (BasicDBObject) JSONUtil.jsonToDbObject(new String(readAllBytes));\r
60                         //                      if (dbObject == null)\r
61                         //                              throw new NullPointerException("Can not parse JSON file: " + jsonFilePath);\r
62                         result = processRundow(octopusAPI, rundown);\r
63                         if (result == null)\r
64                                 return null;\r
65 \r
66                         result.setMediaTitle(clipName);\r
67                         result.setMediaType(RECORDING);\r
68                         result.setMediaFile(mediaFilePath.toString());\r
69                         result.setCatchedFile(catchedFilePath.toString());\r
70                         //                      result.setDuration(NoSQLUtils.asLong(dbObject, DURATION));\r
71                 } catch (Exception e) {\r
72                         logger.catching(e);\r
73                         logger.error(getJobRuntime().getMarker(), "A metaadat nem elérhető. A rendszer üzenete: {}", e.getMessage());\r
74                         return null;\r
75                 }\r
76 \r
77                 return result;\r
78         }\r
79 \r
80         private void createCatchedFile(Path catchedFilePath) throws Exception {\r
81                 try {\r
82                         EscortFiles.ensureUNCFolder(catchedFilePath.getParent());\r
83                         Files.createFile(catchedFilePath);\r
84                 } catch (Exception e) {\r
85                         logger.catching(e);\r
86                         logger.error(marker, "A '{}' jelzőfájl nem hozható létre. A rendszer üzenete: {}", catchedFilePath, e.getMessage());\r
87                         throw e;\r
88                 }\r
89         }\r
90 \r
91         @StepEntry\r
92         public Object[] execute(String sourcePath, IJobEngine jobEngine, IJobRuntime jobRuntime) {\r
93                 final ArchiveItem[] archiveItems = { null };\r
94                 marker = getJobRuntime().getMarker();\r
95                 try {\r
96                         Files.walkFileTree(Paths.get(sourcePath), new SimpleFileVisitor<Path>() {\r
97 \r
98                                 @Override\r
99                                 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {\r
100                                         FileVisitResult result = FileVisitResult.SKIP_SUBTREE;\r
101 \r
102                                         if (dir.equals(Paths.get(sourcePath)) || "HIRADO".equals(dir.toFile().getName().toUpperCase())\r
103                                                         || "NAPIAKT".equals(dir.toFile().getName().toUpperCase()))\r
104                                                 result = FileVisitResult.CONTINUE;\r
105                                         else {\r
106                                                 if ("HIRADO".equals(dir.getParent().toFile().getName().toUpperCase())\r
107                                                                 || "NAPIAKT".equals(dir.getParent().toFile().getName().toUpperCase())) {\r
108                                                         try {\r
109                                                                 startDateformat.parse(dir.toFile().getName());\r
110                                                                 result = FileVisitResult.CONTINUE;\r
111                                                         } catch (ParseException e) {\r
112                                                         }\r
113                                                 }\r
114                                         }\r
115 \r
116                                         if (result == FileVisitResult.CONTINUE)\r
117                                                 logger.info(dir);\r
118                                         return result;\r
119                                 }\r
120 \r
121                                 @Override\r
122                                 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\r
123                                         FileVisitResult result = FileVisitResult.TERMINATE;\r
124                                         ArchiveItem item = null;\r
125                                         try {\r
126                                                 item = processPathItem(file);\r
127                                         } catch (Exception e) {\r
128                                                 logger.catching(e);\r
129                                                 logger.error(marker, "Az '{}' állomány feldolgozása sikertelen. A rendszer hibaüzenete: {}", file, e.getMessage());\r
130                                         }\r
131                                         if (item == null) {\r
132                                                 result = FileVisitResult.CONTINUE;\r
133                                         } else {\r
134                                                 logger.info(file);\r
135                                                 archiveItems[0] = item;\r
136                                         }\r
137                                         return result;\r
138                                 }\r
139 \r
140                         });\r
141 \r
142                 } catch (Exception e) {\r
143                         logger.catching(e);\r
144                         logger.error(marker, "Az '{}' mappa elérése sikertelen. A rendszer hibaüzenete: {}", sourcePath, e.getMessage());\r
145                 } finally {\r
146                 }\r
147                 ArchiveItem archiveItem = archiveItems[0];\r
148                 String targetFileName = null;\r
149 \r
150                 if (archiveItem == null || archiveItem.getMediaFile() == null)\r
151                         logger.warn(marker, "Az archiváló folyamat nem talált új anyagot.");\r
152                 else {\r
153                         String mediaFile = archiveItem.getMediaFile();\r
154                         String name = new File(mediaFile).getName();\r
155                         int extPos = name.toLowerCase().lastIndexOf(LXFEXT);\r
156                         targetFileName = String.format("20%s-%s", Paths.get(mediaFile).getParent().getFileName(), name.substring(0, extPos));\r
157                         logger.info(marker, "Az archiváló folyamat az '{}' anyagot archiválja.", mediaFile);\r
158                 }\r
159 \r
160                 return new Object[] { archiveItem, targetFileName };\r
161         }\r
162 \r
163         private Date getScheduledStart(String clipName, Date recordDate) {\r
164 \r
165                 if (StringUtils.isBlank(clipName)) {\r
166                         logger.warn(marker, "A fájlnak nincs neve, ezért nem archiválható.");\r
167                         return null;\r
168                 }\r
169                 if (recordDate == null) {\r
170                         logger.warn(marker, "Az '{}' fájl rögzítésének ideje nem meghatározható, ezért nem archiválható.", clipName);\r
171                         return null;\r
172                 }\r
173 \r
174                 Date timePart = null;\r
175                 try {\r
176                         String clipNameTime = clipName.split("_")[0];\r
177                         timePart = startTimeformat.parse(clipNameTime);\r
178                 } catch (ParseException e) {\r
179                         logger.warn(marker, "A '{}' fájl neve nem időbélyeggel kezdődik, ezért nem archiválható.", clipName);\r
180                         return null;\r
181                 }\r
182                 return CalendarUtils.createCalendar(CalendarUtils.createCalendar(recordDate), timePart).getTime();\r
183         }\r
184 \r
185         private ArchiveItem processPathItem(Path mediaFilePath) throws Exception {\r
186                 File mediaFile = mediaFilePath.toFile();\r
187 \r
188                 Path dotStorePath = Paths.get(mediaFilePath.getParent().toString(), STATUSFOLDER);\r
189                 Path catchedFilePath = Paths.get(dotStorePath.toString(), mediaFile.getName() + CATCHEDEXT);\r
190                 File catchedFile = catchedFilePath.toFile();\r
191                 if (catchedFile.exists()) {\r
192                         //logger.info("'{}' file is already catched", mediaFilePath);\r
193                         return null;\r
194                 }\r
195                 createCatchedFile(catchedFilePath);\r
196                 if (!catchedFile.exists()) {\r
197                         logger.warn("'{}' catchfile not exists.", catchedFilePath);\r
198                         return null;\r
199                 }\r
200 \r
201                 if (mediaFile.isDirectory() || !mediaFile.getName().toLowerCase().endsWith(LXFEXT.toLowerCase())\r
202                                 || mediaFilePath.getParent().toFile().getName().length() != 6) {\r
203                         logger.info("Skipping '{}'", mediaFilePath);\r
204                         return null;\r
205                 }\r
206 \r
207                 ArchiveItem archiveItem = createArchiveItem(mediaFilePath, catchedFilePath);\r
208 \r
209                 if (archiveItem == null) {\r
210                         logger.warn("'{}' has no metadata specified.", mediaFilePath);\r
211                         return null;\r
212                 }\r
213 \r
214                 if (StringUtils.isBlank(archiveItem.getItemHouseId())) {\r
215                         logger.warn("'{}' has no Item HouseID specified in metadata.", mediaFilePath);\r
216                         return null;\r
217                 }\r
218 \r
219                 if (StringUtils.isBlank(archiveItem.getItemTitle())) {\r
220                         logger.warn("'{}' has no Item Title specified in metadata.", mediaFilePath);\r
221                         return null;\r
222                 }\r
223 \r
224                 if (StringUtils.isBlank(archiveItem.getMediaHouseId())) {\r
225                         logger.warn("'{}' has no Media HouseID specified in metadata.", mediaFilePath);\r
226                         return null;\r
227                 }\r
228 \r
229                 if (StringUtils.isBlank(archiveItem.getMediaTitle())) {\r
230                         logger.warn("'{}' has no Media Title specified in metadata.", mediaFilePath);\r
231                         return null;\r
232                 }\r
233                 return archiveItem;\r
234         }\r
235 \r
236         private ArchiveItem processRundow(IOctopusAPI octopusAPI, DBObject r) throws Exception {\r
237                 BasicDBObject rundown = (BasicDBObject) r;\r
238                 long rundownID = rundown.getLong(IOctopusAPI.ID);\r
239                 logger.info("Processing rundown {} {}", rundownID, rundown.getString(IOctopusAPI.NAME));\r
240 \r
241                 List<DBObject> stories = octopusAPI.getRundownFullStories(rundownID);\r
242                 if (stories == null)\r
243                         return null;\r
244 \r
245                 String name = NoSQLUtils.asString(NoSQLUtils.asDBObject(rundown, IOctopusAPI.RUNDOWN_TYPE), IOctopusAPI.NAME);\r
246                 if (StringUtils.isBlank(name))\r
247                         return null;\r
248                 String channel = NoSQLUtils.asString(NoSQLUtils.asDBObject(rundown, IOctopusAPI.CHANNEL), IOctopusAPI.NAME);\r
249                 Date scheduledStart = rundown.getDate(IOctopusAPI.SCHEDULED_START);\r
250                 if (scheduledStart == null)\r
251                         return null;\r
252 \r
253                 ArchiveItem result = new ArchiveItem();\r
254                 result.setItemHouseId(String.valueOf(rundownID));\r
255                 String start = CalendarUtils.toString(CalendarUtils.createCalendar(scheduledStart), SCHEDULED_FORMAT);\r
256                 result.setItemTitle(String.format("%s %s %s", start, name, channel));\r
257 \r
258                 StringBuilder sb = new StringBuilder();\r
259                 for (DBObject s : stories) {\r
260                         BasicDBObject story = (BasicDBObject) s;\r
261 \r
262                         sb.append("*** ");\r
263                         sb.append(story.getString(IOctopusAPI.PARENT_STORY_ID));\r
264                         sb.append(" [" + story.getString(IOctopusAPI.FORMAT) + "] ");\r
265                         sb.append(story.getString(IOctopusAPI.NAME));\r
266                         sb.append(" ***");\r
267                         sb.append("\r\n");\r
268                         String content = story.getString(IOctopusAPI.SCRIPT_CONTENT);\r
269                         if (content != null) {\r
270                                 content = content.replace("\r\n\r\n\r\n\r\n", "\r\n");\r
271                                 content = content.replace("\r\n\r\n\r\n", "\r\n");\r
272                                 content = content.replace("\r\n\r\n", "\r\n");\r
273                                 sb.append(content);\r
274                                 sb.append("\r\n");\r
275                         }\r
276                 }\r
277                 result.setMediaHouseId(result.getItemHouseId());\r
278                 result.setMediaDescription(sb.toString());\r
279                 return result;\r
280         }\r
281 }\r