Code source wiki de GalleryThumbsupEngine
Modifié par superadmin le 2022/11/21 08:20
Afficher les derniers auteurs
author | version | line-number | content |
---|---|---|---|
1 | package Macros | ||
2 | |||
3 | import com.xpn.xwiki.api.* | ||
4 | import com.xpn.xwiki.render.* | ||
5 | import com.xpn.xwiki.web.XWikiServletResponse | ||
6 | import org.apache.commons.io.FileUtils | ||
7 | |||
8 | public class GalleryThumbsupEngine { | ||
9 | |||
10 | XWiki xwiki; | ||
11 | Context context; | ||
12 | Document doc; | ||
13 | File targetDir; | ||
14 | String fullNameEscaped | ||
15 | // TODO adjust for the specific of the container's installation | ||
16 | File baseDir = new File("webapps/ROOT/resources/pictureExports"); | ||
17 | String basePictureExportsURL = "/resources/pictureExports" | ||
18 | String status = "IDLE" | ||
19 | String debugStr = "" | ||
20 | def webapp | ||
21 | String webappAttributename | ||
22 | |||
23 | ScriptXWikiServletRequest request; | ||
24 | XWikiServletResponse response; | ||
25 | |||
26 | void init(xwiki, context, doc) { | ||
27 | try { | ||
28 | this.xwiki = xwiki; | ||
29 | this.context = context; | ||
30 | this.request = context.request; | ||
31 | this.response = context.response; | ||
32 | this.doc = doc; | ||
33 | this.fullNameEscaped = doc.fullName.replaceAll("/","__").replaceAll(" ", "-").replaceAll(":", "_") | ||
34 | targetDir = new File(baseDir, fullNameEscaped) | ||
35 | this.webapp = this.context.request.httpServletRequest.getServletContext() | ||
36 | this.webappAttributename = "ThumbsUpProcess" + fullNameEscaped | ||
37 | } catch (Exception ex) { | ||
38 | debug(ex + " ") | ||
39 | ex.printStackTrace() | ||
40 | } | ||
41 | } | ||
42 | |||
43 | |||
44 | String debug(msg) { | ||
45 | debugStr += msg + "\n"; | ||
46 | System.err.println("GalleryThumbsUpEngine: " + msg) | ||
47 | } | ||
48 | |||
49 | String dumpDebug() { | ||
50 | if (request.debug || forceDebug) | ||
51 | return "== DEBUG ==\n\n {{{ ${debugStr} }}}" | ||
52 | else | ||
53 | return ""; | ||
54 | } | ||
55 | |||
56 | boolean needsActualization() { | ||
57 | if( !targetDir.isDirectory()) return true; | ||
58 | |||
59 | File outputMain = new File(new File(targetDir, "out"), "index.html") | ||
60 | if(!outputMain.isFile()) return true; | ||
61 | long lastModified = outputMain.lastModified()- 500 // -500 to cope for approximations of filesystems | ||
62 | for(def attachment in doc.getAttachmentList()) { | ||
63 | if(attachment.date.time > lastModified) return true | ||
64 | } | ||
65 | if(doc.date.time > lastModified) return true | ||
66 | return false | ||
67 | } | ||
68 | |||
69 | String getIFrameURL() { | ||
70 | return basePictureExportsURL + "/" + fullNameEscaped + "/out/index.html?version=" + doc.version | ||
71 | } | ||
72 | |||
73 | |||
74 | void startProduction() { | ||
75 | if ( !"IDLE".equals(getProcessStatus()) ) throw new IllegalAccessException("Another process is starting or failed.") | ||
76 | status = "EXPORTING" | ||
77 | Thread thread = new Thread("attachmentExport") { | ||
78 | public void run() { | ||
79 | syncExportAttachments() | ||
80 | startThumbsUp() // should finish right away but set the webappAttribute | ||
81 | } | ||
82 | } | ||
83 | thread.start() | ||
84 | webapp.setAttribute(webappAttributename,thread) | ||
85 | } | ||
86 | |||
87 | void syncExportAttachments() { | ||
88 | Set attachmentNames = new HashSet() | ||
89 | File srcDir = new File(new File(baseDir, fullNameEscaped), "src" ) | ||
90 | if(!srcDir.isDirectory()) | ||
91 | if(!srcDir.mkdirs()) throw new IllegalAccessException("Can't create directory " + srcDir) | ||
92 | // export new or changed attachments to files' | ||
93 | for(def attachment in doc.getAttachmentList()) { | ||
94 | attachmentNames.add(attachment.filename) | ||
95 | File targetFile= new File(srcDir, attachment.filename) | ||
96 | if(attachment.filename.toUpperCase().endsWith(".HEIC")) continue | ||
97 | if(!targetFile.isFile() || targetFile.lastModified() -500 < attachment.date.time) { | ||
98 | debug("Saving attachment " + attachment.filename + " to " + targetFile) | ||
99 | InputStream input = attachment.getContentInputStream() | ||
100 | if(input==null) continue | ||
101 | FileUtils.copyToFile(input, targetFile) | ||
102 | } | ||
103 | } | ||
104 | // remove files that are not attachments | ||
105 | for(File file in srcDir.listFiles()) { | ||
106 | if(!attachmentNames.contains(file.name)) { | ||
107 | debug("Deleting file " + file.name) | ||
108 | if(!file.delete()) | ||
109 | debug("File deletion failed.") | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | |||
114 | void startThumbsUp() { | ||
115 | status = "RUNNING" | ||
116 | String instructions = """./node_modules/.bin/thumbsup | ||
117 | --input "${fullNameEscaped}/src" | ||
118 | --output "${fullNameEscaped}/out" | ||
119 | --album-zip-files --title "" | ||
120 | --css gallerycustom.css """ | ||
121 | debug("Launching " + instructions) | ||
122 | Process process = instructions.execute([], baseDir) | ||
123 | process.consumeProcessOutput(System.out, System.err) | ||
124 | webapp.setAttribute(webappAttributename, process) | ||
125 | } | ||
126 | /** | ||
127 | * @return * One of IDLE, RUNNING, ERROR | ||
128 | */ | ||
129 | String getProcessStatus() { | ||
130 | def att = webapp.getAttribute(webappAttributename) | ||
131 | if(att == null) { | ||
132 | return status = "IDLE" | ||
133 | } else if(att instanceof Thread) { | ||
134 | Thread t = att | ||
135 | status = t.isAlive() ? "EXPORTING" : "ERROR" | ||
136 | } else if(att instanceof Process) { | ||
137 | Process process = att | ||
138 | System.err.println("Process: " + process) | ||
139 | if(process==null) return status = "IDLE" | ||
140 | boolean alive = false; int exitValue = -1; | ||
141 | try {exitValue = process.exitValue(); alive = false } | ||
142 | catch(IllegalThreadStateException ex) { alive = true } | ||
143 | if(!alive) | ||
144 | if(exitValue!=0) status == "ERROR" | ||
145 | else { // exitValue==0 | ||
146 | status = "IDLE" | ||
147 | webapp.setAttribute(webappAttributename, null) | ||
148 | } | ||
149 | else { | ||
150 | // otherwise alive = true | ||
151 | status = "RUNNING" | ||
152 | } } | ||
153 | return status; | ||
154 | } | ||
155 | |||
156 | void stopThumbsUp() { | ||
157 | def att = webapp.getAttribute(webappAttributename) | ||
158 | debug("Stopping " + att) | ||
159 | if(att instanceof Thread) { | ||
160 | Thread t = att | ||
161 | t.stop() | ||
162 | } else { | ||
163 | Process process = att | ||
164 | process.destroy() | ||
165 | } | ||
166 | webapp.setAttribute(webappAttributename,null) | ||
167 | } | ||
168 | |||
169 | } |