1
- #!/usr/bin/env python
1
+ #!/usr/bin/env python3
2
2
3
- import re
4
3
import os
5
4
import os .path
6
5
import sys
7
6
import time
8
7
import shutil
9
- import socket
10
8
import subprocess
11
9
import logging
12
10
import optparse
@@ -18,91 +16,11 @@ def log ( message ):
18
16
return
19
17
20
18
21
- class ErrorMessage ( Exception ):
22
-
23
- def __init__ ( self , code , * arguments ):
24
- self ._code = code
25
- self ._errors = [ 'Malformed call to ErrorMessage()'
26
- , '{}' .format (arguments ) ]
27
- text = None
28
- if len (arguments ) == 1 :
29
- if isinstance (arguments [0 ],Exception ): text = str (arguments [0 ]).split ('\n ' )
30
- else :
31
- self ._errors = arguments [0 ]
32
- elif len (arguments ) > 1 :
33
- text = list (arguments )
34
- if text :
35
- self ._errors = []
36
- while len (text [0 ]) == 0 : del text [0 ]
37
- lstrip = 0
38
- if text [0 ].startswith ('[ERROR]' ): lstrip = 8
39
- for line in text :
40
- if line [0 :lstrip ] == ' ' * lstrip or \
41
- line [0 :lstrip - 1 ] == '[ERROR]' :
42
- self ._errors += [ line [lstrip :] ]
43
- else :
44
- self ._errors += [ line .lstrip () ]
45
-
46
- def __str__ ( self ):
47
- if not isinstance (self ._errors ,list ):
48
- return "[ERROR] %s" % self ._errors
49
- formatted = "\n "
50
- for i in range (len (self ._errors )):
51
- if i == 0 : formatted += "[ERROR] {}" .format ( self ._errors [i ] )
52
- else : formatted += " {}" .format ( self ._errors [i ] )
53
- if i + 1 < len (self ._errors ): formatted += "\n "
54
- return formatted
55
-
56
- def addMessage ( self , message ):
57
- if not isinstance (self ._errors ,list ):
58
- self ._errors = [ self ._errors ]
59
- if isinstance (message ,list ):
60
- for line in message :
61
- self ._errors += [ line ]
62
- else :
63
- self ._errors += [ message ]
64
-
65
- def terminate ( self ):
66
- print ( self )
67
- sys .exit (self ._code )
68
-
69
- def _getCode ( self ): return self ._code
70
-
71
- code = property (_getCode )
72
-
73
-
74
19
class Configuration ( object ):
75
20
76
21
def __init__ ( self ):
77
- self .onSource = False
78
- self .onLepka = False
79
- self .onDocker = False
80
- hostname = socket .gethostname ()
81
- if hostname .startswith ('lepka' ): self .onLepka = False
82
- else : self .onDocker = True
83
- scriptDir = os .path .abspath (os .getcwd ())
84
- if scriptDir .endswith ( 'coriolis/documentation' ) and not self .onLepka :
85
- self .onLepka = False
86
- self .onSource = True
87
- if self .onDocker :
88
- log ( 'Using *Docker* configuration.' )
89
- self .pelicanDir = '/data/git/coriolis.lip6.fr/pelican'
90
- self .apacheDir = '/var/www/html'
91
- if self .onLepka :
92
- log ( 'Using *Lepka* configuration.' )
93
- #self.pelicanDir = os.path.join( os.environ['HOME'], 'cms/coriolis.lip6.fr/pelican' )
94
- self .pelicanDir = scriptDir
95
- self .apacheDir = '/dsk/l1/httpd/coriolis'
96
- if self .onSource :
97
- log ( 'Using *Source* configuration.' )
98
- self .pelicanDir = scriptDir
99
- self .apacheDir = None
100
- self .localDocDir = '/dsk/l1/jpc/coriolis-2.x/Linux.el9/Release.Shared/install/share/doc/coriolis2/en/html/doc'
101
- self .remoteDocDir = '/data'
102
- self .remoteGitDir = '/data/git'
103
- self .remotePelicanDir = os .path .join ( self .remoteGitDir , 'coriolis.lip6.fr/pelican' )
104
- self .pluginsDir = os .path .join ( self .remoteGitDir , 'pelican-plugins' )
105
- self .logDir = os .path .join ( self .pelicanDir , 'logs' )
22
+ self .pluginsDir = 'pelican-plugins'
23
+ self .logDir = 'logs'
106
24
self .target = 'coriolis-d'
107
25
108
26
@@ -133,45 +51,8 @@ def execute ( self ):
133
51
if len (self .errlog ): logging .error ( self .errlog .decode ('utf-8' ))
134
52
status = child .returncode
135
53
status >>= 8
136
- if status != 0 :
137
- ErrorMessage ( status , "{} (status:{})." .format (error ,status ) ).terminate ()
138
54
return status
139
55
140
- @staticmethod
141
- def rmtree ( path ):
142
- command = 'rm -rf {}' .format ( path )
143
- try :
144
- log ( command )
145
- shutil .rmtree ( path )
146
- except shutil .Error as e :
147
- logging .error ( str (e ) )
148
- return 1
149
- return 0
150
-
151
- @staticmethod
152
- def copytree ( src , dst ):
153
- command = 'cp -r {} {}' .format ( src , dst )
154
- try :
155
- log ( command )
156
- shutil .copytree ( src , dst )
157
- except OSError as e :
158
- logging .error ( e )
159
- return 1
160
- except shutil .Error as errors :
161
- for error in errors :
162
- logging .error ( 'cp {} {}: {}' .format (src ,dst ,error ) )
163
- return 1
164
- return 0
165
-
166
-
167
- class SshCommand ( object ):
168
-
169
- def __init__ ( self , scriptlet ):
170
- self .scriptlet = scriptlet
171
-
172
- def execute ( self , target ):
173
- command = [ 'ssh' , '-x' , target , self .scriptlet ]
174
- Command ( command ).execute ()
175
56
176
57
177
58
class Document ( object ):
@@ -182,38 +63,29 @@ def __init__ ( self, conf, document ):
182
63
self .rdir = os .path .dirname ( document )
183
64
184
65
def toPdf ( self ):
185
- pdfDir = '{}/ content/pdfs' . format ( self . conf . pelicanDir )
186
- stylesheet = '{}/ etc/SoC-ReST.tex' . format ( self . conf . pelicanDir )
66
+ pdfDir = 'content/pdfs'
67
+ stylesheet = 'etc/SoC-ReST.tex'
187
68
documentPdf = '{}.pdf' .format ( self .document )
188
69
documentRst = '{}.rst' .format ( self .document )
189
70
documentTex = '{}.tex' .format ( self .document )
190
- documentRawTex = '{}-raw.tex' .format ( self .document )
191
71
documentTmps = [ documentTex
192
- , documentRawTex
193
72
, '{}.log' .format ( self .document )
194
73
, '{}.out' .format ( self .document )
195
74
, '{}.aux' .format ( self .document )
196
75
, '{}.toc' .format ( self .document )
197
76
]
198
77
targetPdf = os .path .join ( pdfDir , documentPdf )
199
-
78
+
200
79
cwd = os .getcwd ()
201
- os .chdir ( os . path . join ( self .conf . pelicanDir , self . rdir ) )
202
- os .environ [ 'TEXINPUTS' ] = '{} /etc/images//:./images//:' . format ( self . conf . pelicanDir )
80
+ os .chdir (self .rdir )
81
+ os .environ [ 'TEXINPUTS' ] = '. /etc/images//:./images//:'
203
82
Command ( [ 'rst2latex' , '--use-latex-toc'
204
83
, '--stylesheet={}' .format ( stylesheet )
205
84
, documentRst
206
- , documentRawTex
207
85
] ).execute ()
208
- pMulticol = re .compile ( r' \\& \\\\multicolumn\{2\}\{l\|\}\{' )
209
- fdi = open ( documentRawTex , 'r' )
210
- fdo = open ( documentTex , 'w' )
211
- for line in fdi .readlines ():
212
- fdo .write ( pMulticol .sub (' \\ & \\ \\ multicolumn{2}{p{0.6\\ \\ DUtablewidth}|}{' ,line ) )
213
- fdi .close ()
214
- fdo .close ()
215
86
Command ( [ 'pdflatex' , '-halt-on-error' , documentTex ] ).execute ()
216
87
Command ( [ 'pdflatex' , '-halt-on-error' , documentTex ] ).execute ()
88
+ os .chdir (cwd )
217
89
for file in documentTmps :
218
90
if os .path .isfile ( file ):
219
91
os .unlink ( file )
@@ -226,77 +98,6 @@ def toPdf ( self ):
226
98
os .chdir ( cwd )
227
99
228
100
229
- class Site ( object ):
230
-
231
- def __init__ ( self , conf ):
232
- self .conf = conf
233
-
234
- def build ( self ):
235
- print ( 'cd {}' .format ( self .conf .pelicanDir ))
236
- os .chdir ( self .conf .pelicanDir )
237
- status = Command ( [ 'pelican' , '-vD' , '--ignore-cache' , 'content' ] ).execute ()
238
- if status : return status
239
- if self .conf .onLepka :
240
- Command .rmtree ( self .conf .apacheDir )
241
- Command .copytree ( './output' , self .conf .apacheDir )
242
- Command .copytree ( self .conf .localDocDir , os .path .join (self .conf .apacheDir ,'doc' ) )
243
-
244
- def gitPush ( self ):
245
- print ( 'cd {}' .format ( self .conf .pelicanDir ))
246
- os .chdir ( self .conf .pelicanDir )
247
- lines = ''
248
- cmd = Command ( ['git' , 'status' , 'content' , 'common' , 'theme' ] )
249
- cmd .execute ()
250
- if cmd .outlog : lines = cmd .outlog .split ('\n ' )
251
- if lines [- 2 ] != 'nothing to commit, working directory clean' :
252
- message = [ 'There are some uncommited changes in the site contents.' ] + lines
253
- print ( ErrorMessage ( 1 , message ))
254
- Command ( ['git' , 'push' ] ).execute ()
255
- return True
256
-
257
- def gitCommitPdfs ( self ):
258
- print ( 'cd {}' .format ( self .conf .pelicanDir ))
259
- os .chdir ( self .conf .pelicanDir )
260
- lines = ''
261
- cmd = Command ( ['git' , 'status' , 'content/pdfs' ] )
262
- cmd .execute ()
263
- if cmd .outlog : lines = cmd .outlog .decode ('utf-8' ).split ('\n ' )
264
- if lines [- 2 ] != 'nothing to commit, working directory clean' :
265
- message = 'Updated PDFs, %s.' % time .strftime ( '%B %d, %Y (%H:%M)' )
266
- Command ( ['git' , 'add' , 'content/pdfs' ] ).execute ()
267
- Command ( ['git' , 'commit' , '-m' , message ] ).execute ()
268
- return True
269
-
270
- def remoteBuild ( self ):
271
- Command ( [ 'ssh' , '-x' , '-o' , 'StrictHostKeyChecking no'
272
- , self .conf .target , "echo 'Force SSH key loading.'" ] ).execute ()
273
- Command ( [ 'rsync' , '--rsh=/usr/bin/ssh' , '-avH'
274
- , self .conf .localDocDir
275
- , '{}:{}' .format (self .conf .target ,self .conf .remoteDocDir ) ] ).execute ()
276
- remoteScript = \
277
- ' if [ ! -d {remotePelicanDir} ]; then' \
278
- ' cd {remoteGitDir};' \
279
- ' git clone gitsoc@bop-t:coriolis.lip6.fr;' \
280
- ' sudo pelican-themes -s {remotePelicanDir}/themes/nest-coriolis;' \
281
- ' sudo chown -R pelican:pelican /var/www/html;' \
282
- ' fi;' \
283
- ' cd {remotePelicanDir};' \
284
- ' git pull;' \
285
- ' if [ ! -d {pluginsDir} ]; then' \
286
- ' cd {remoteGitDir};' \
287
- ' git clone https://github.com/getpelican/pelican-plugins;' \
288
- ' cd pelican-plugins;' \
289
- ' patch -p1 -i {remotePelicanDir}/patchs/0001-bootstrap-rst.no-math.patch;' \
290
- ' fi;' \
291
- ' cd {remotePelicanDir};' \
292
- ' ./build.py -p;' \
293
- .format ( pluginsDir = self .conf .pluginsDir
294
- , remoteGitDir = self .conf .remoteGitDir
295
- , remotePelicanDir = self .conf .remotePelicanDir
296
- )
297
- SshCommand ( remoteScript ).execute ( self .conf .target )
298
-
299
-
300
101
if __name__ == '__main__' :
301
102
usage = \
302
103
'\n ' \
@@ -334,7 +135,6 @@ def remoteBuild ( self ):
334
135
parser .add_option ( '-p' , '--pelican' , action = 'store_true' , dest = 'doPelican' , help = 'Run pelican.' )
335
136
parser .add_option ( '-P' , '--pdfs' , action = 'store_true' , dest = 'doPdfs' , help = 'Generate the PDFs.' )
336
137
parser .add_option ( '-C' , '--coriolis' , action = 'store_true' , dest = 'doCoriolis' , help = 'Build/update the web site on the server (docker).' )
337
- parser .add_option ( '-g' , '--git' , action = 'store_true' , dest = 'doCommit' , help = 'Commit the PDFs.' )
338
138
(options , args ) = parser .parse_args ()
339
139
conf = Configuration ()
340
140
if not os .path .isdir ( conf .logDir ):
@@ -353,14 +153,8 @@ def remoteBuild ( self ):
353
153
, Document ( conf , 'content/pages/check-toolkit/CheckToolkit' )
354
154
, Document ( conf , 'content/pages/rds/RDS' )
355
155
]
356
- coriolis = Site ( conf )
357
156
if options .doPdfs :
358
157
for document in documents : document .toPdf ()
359
- if options .doCommit :
360
- coriolis .gitCommitPdfs ()
361
158
if options .doPelican :
362
- coriolis .build ()
363
- if options .doCoriolis :
364
- coriolis .gitPush ()
365
- coriolis .remoteBuild ()
159
+ Command ( [ 'pelican' , '-vD' , '--ignore-cache' , 'content' ] ).execute ()
366
160
sys .exit ( 0 )
0 commit comments