f1aa4e9b6c2a807d187811a226b52d9dcb734bbc
[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 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
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                         result = processRundow(octopusAPI, rundown);\r
57                         if (result == null)\r
58                                 return null;\r
59 \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
65                         logger.catching(e);\r
66                         logger.error(getJobRuntime().getMarker(), "A metaadat nem elérhető. A rendszer üzenete: {}", e.getMessage());\r
67                         return null;\r
68                 }\r
69 \r
70                 return result;\r
71         }\r
72 \r
73         private void createCatchedFile(Path catchedFilePath) throws IOException {\r
74                 try {\r
75                         EscortFiles.ensureUNCFolder(catchedFilePath.getParent());\r
76                         Files.createFile(catchedFilePath);\r
77                 } catch (IOException e) {\r
78                         logger.catching(e);\r
79                         logger.error(marker, "A '{}' jelzőfájl nem hozható létre. A rendszer üzenete: {}", catchedFilePath, e.getMessage());\r
80                         throw e;\r
81                 }\r
82         }\r
83 \r
84         @StepEntry\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
88                 try {\r
89                         Files.walkFileTree(Paths.get(sourcePath), new SimpleFileVisitor<Path>() {\r
90 \r
91                                 @Override\r
92                                 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {\r
93                                         FileVisitResult result = FileVisitResult.SKIP_SUBTREE;\r
94 \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
98                                         else {\r
99                                                 if ("HIRADO".equals(dir.getParent().toFile().getName().toUpperCase())\r
100                                                                 || "NAPIAKT".equals(dir.getParent().toFile().getName().toUpperCase())) {\r
101                                                         try {\r
102                                                                 startDateformat.parse(dir.toFile().getName());\r
103                                                                 result = FileVisitResult.CONTINUE;\r
104                                                         } catch (ParseException e) {\r
105                                                         }\r
106                                                 }\r
107                                         }\r
108 \r
109                                         if (result == FileVisitResult.CONTINUE)\r
110                                                 logger.info(dir);\r
111                                         return result;\r
112                                 }\r
113 \r
114                                 @Override\r
115                                 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {\r
116                                         FileVisitResult result = FileVisitResult.TERMINATE;\r
117                                         ArchiveItem item = null;\r
118                                         try {\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
123                                                 throw e;\r
124                                         }\r
125                                         if (item == null) {\r
126                                                 result = FileVisitResult.CONTINUE;\r
127                                         } else {\r
128                                                 logger.info(file);\r
129                                                 archiveItems[0] = item;\r
130                                         }\r
131                                         return result;\r
132                                 }\r
133 \r
134                         });\r
135 \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
139                         throw e;\r
140                 } finally {\r
141                 }\r
142                 ArchiveItem archiveItem = archiveItems[0];\r
143                 String targetFileName = null;\r
144 \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
148                 } else {\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
154                 }\r
155 \r
156                 return new Object[] { archiveItem, targetFileName };\r
157         }\r
158 \r
159         private Date getScheduledStart(String clipName, Date recordDate) {\r
160 \r
161                 if (StringUtils.isBlank(clipName)) {\r
162                         logger.warn(marker, "A fájlnak nincs neve, ezért nem archiválható.");\r
163                         return null;\r
164                 }\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
167                         return null;\r
168                 }\r
169 \r
170                 Date timePart = null;\r
171                 try {\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
176                         return null;\r
177                 }\r
178                 return CalendarUtils.createCalendar(CalendarUtils.createCalendar(recordDate), timePart).getTime();\r
179         }\r
180 \r
181         private ArchiveItem processPathItem(Path mediaFilePath) throws IOException {\r
182                 File mediaFile = mediaFilePath.toFile();\r
183 \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
189                         return null;\r
190                 }\r
191                 createCatchedFile(catchedFilePath);\r
192                 if (!catchedFile.exists()) {\r
193                         logger.warn("'{}' catchfile not exists.", catchedFilePath);\r
194                         return null;\r
195                 }\r
196 \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
200                         return null;\r
201                 }\r
202 \r
203                 ArchiveItem archiveItem = createArchiveItem(mediaFilePath, catchedFilePath);\r
204 \r
205                 if (archiveItem == null) {\r
206                         logger.warn("'{}' has no metadata specified.", mediaFilePath);\r
207                         return null;\r
208                 }\r
209 \r
210                 if (StringUtils.isBlank(archiveItem.getItemHouseId())) {\r
211                         logger.warn("'{}' has no Item HouseID specified in metadata.", mediaFilePath);\r
212                         return null;\r
213                 }\r
214 \r
215                 if (StringUtils.isBlank(archiveItem.getItemTitle())) {\r
216                         logger.warn("'{}' has no Item Title specified in metadata.", mediaFilePath);\r
217                         return null;\r
218                 }\r
219 \r
220                 if (StringUtils.isBlank(archiveItem.getMediaHouseId())) {\r
221                         logger.warn("'{}' has no Media HouseID specified in metadata.", mediaFilePath);\r
222                         return null;\r
223                 }\r
224 \r
225                 if (StringUtils.isBlank(archiveItem.getMediaTitle())) {\r
226                         logger.warn("'{}' has no Media Title specified in metadata.", mediaFilePath);\r
227                         return null;\r
228                 }\r
229                 return archiveItem;\r
230         }\r
231 \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
236 \r
237                 List<DBObject> stories = octopusAPI.getRundownFullStories(rundownID);\r
238                 if (stories == null)\r
239                         return null;\r
240 \r
241                 String name = NoSQLUtils.asString(NoSQLUtils.asDBObject(rundown, IOctopusAPI.RUNDOWN_TYPE), IOctopusAPI.NAME);\r
242                 if (StringUtils.isBlank(name))\r
243                         return null;\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
247                         return null;\r
248 \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
253 \r
254                 StringBuilder sb = new StringBuilder();\r
255                 for (DBObject s : stories) {\r
256                         BasicDBObject story = (BasicDBObject) s;\r
257 \r
258                         sb.append("*** ");\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
262                         sb.append(" ***");\r
263                         sb.append("\r\n");\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
270                                 sb.append("\r\n");\r
271                         }\r
272                 }\r
273                 result.setMediaHouseId(result.getItemHouseId());\r
274                 result.setMediaDescription(sb.toString());\r
275                 //TODO\r
276                 if (result.getMediaDescription() != null && result.getMediaDescription().length() > 5000)\r
277                         result.setMediaDescription(result.getMediaDescription().substring(0, 5000));\r
278                 return result;\r
279         }\r
280 }\r