File indexing completed on 2026-04-09 07:48:49
0001
0002 """
0003 pub.py
0004 =========
0005
0006 Used for example from qudarap/tests/pub.sh::
0007
0008 #!/bin/bash -l
0009 export SRC_BASE=$TMP/QCerenkovTest
0010 pub.py $*
0011
0012 Leading to destination base folder ~/simoncblyth.bitbucket.io/env/presentation/QCerenkovTest/
0013
0014 And CSGOptiX/pub.sh::
0015
0016 #!/bin/bash -l
0017 export SRC_BASE=$TMP/CSGOptiX/CSGOptiXSimtraceTest
0018 pub.py $*
0019
0020 Leading to destination base folder ~/simoncblyth.bitbucket.io/env/presentation/CSGOptiXSimtraceTest/
0021
0022 And extg4/pub.sh::
0023
0024 #!/bin/bash -l
0025 export SRC_BASE=$TMP/extg4/X4IntersectTest
0026 pub.py $*
0027
0028 Leading to destination base folder ~/simoncblyth.bitbucket.io/env/presentation/X4IntersectTest/
0029
0030 Usage::
0031
0032 ./pub.sh sp # list source paths : use this to find obsolete ones for deletion
0033 ./pub.sh dp # list destination paths
0034 ./pub.sh xdp # list existing destination paths
0035
0036 ./pub.sh cp # emit to stdout the commands to copy png to publication area preserving relative path info
0037 ./pub.sh cp | sh # pipe to shell to make copies
0038 ./pub.sh cp | grep 1,3 | sh # select what to copy
0039
0040
0041 ./pub.sh s5 # emit to stdout the s5 rst lines to in presentation rst
0042 ./pub.sh # emit to stdout both the above
0043
0044 """
0045 import os, sys, logging, argparse
0046 log = logging.getLogger(__name__)
0047
0048 class Pub(object):
0049 DEST_ROOT = os.path.expanduser("~/simoncblyth.bitbucket.io")
0050 DEST_BASE = os.path.join(DEST_ROOT, "env/presentation")
0051 INDENT = " "
0052
0053 @classmethod
0054 def FindDigest(cls, path):
0055 hexchar = "0123456789abcdef"
0056 digest = None
0057 for elem in path.split("/"):
0058 if len(elem) == 32 and set(elem).issubset(hexchar):
0059 digest = elem
0060 pass
0061 pass
0062 return digest
0063
0064
0065 def __init__(self, base=None, exts=[".png", ".jpg"], digestprefix=False):
0066 if base is None:
0067 base = os.environ.get("SRC_BASE", "$TMP/NonExisting")
0068 pass
0069 expect = os.path.isdir(base)
0070 if not expect:
0071 log.fatal("base directory %s does not exist, set envvar SRC_BASE to an existing directory" % base )
0072 pass
0073 assert expect
0074 name = os.path.basename(base)
0075 digest = self.FindDigest(base)
0076 log.debug("digest %s " % digest )
0077
0078 if digestprefix == False:
0079 elem = [self.DEST_BASE, name]
0080 else:
0081 elem = [self.DEST_BASE, digest, name]
0082 pass
0083 dest = os.path.join(*list(filter(None,elem)))
0084
0085 log.debug("elem %s " % str(elem))
0086 log.debug("base %s " % base)
0087 log.debug("dest %s " % dest)
0088
0089 geom = os.environ.get("GEOM", "")
0090 self.find(base, exts, with_elem=geom)
0091
0092 cmds, s5ps, s5ti = self.copy_cmds(dest)
0093
0094 self.dest = dest
0095 self.cmds = cmds
0096 self.s5ps = s5ps
0097 self.s5ti = s5ti
0098
0099 def find(self, base, exts, with_elem=""):
0100 """
0101 Collect base relative paths to files with extension *ext*
0102 """
0103 base = os.path.expandvars(base)
0104 res = []
0105 for root, dirs, files in os.walk(base):
0106 for name in files:
0107 for ext in exts:
0108 if name.endswith(ext):
0109 path = os.path.join(root, name)
0110 relpath = path[len(base)+1:]
0111
0112 if len(with_elem) > 0:
0113 elem = relpath.split("/")
0114 contains_elem = with_elem in elem
0115 else:
0116 contains_elem = True
0117 pass
0118 log.debug("relpath %s contains_elem %s with_elem %s " % (relpath, contains_elem, with_elem) )
0119
0120 if contains_elem:
0121 res.append(relpath)
0122 pass
0123 pass
0124 pass
0125 pass
0126 pass
0127 self.base = base
0128 self.res = sorted(res)
0129 log.debug("found %d res " % len(self.res))
0130
0131
0132 def copy_cmds(self, dest):
0133 """
0134 """
0135 cmds = []
0136 s5ps = []
0137 s5ti = []
0138 for rel in self.res:
0139 spath = os.path.join(self.base, rel)
0140 dpath = os.path.join(dest, rel)
0141 ddir = os.path.dirname( dpath)
0142 cmds.append("mkdir -p %s " % ddir)
0143 cmds.append("cp %s %s " % (spath, dpath))
0144 s5p = "/"+dpath[len(self.DEST_ROOT)+1:]
0145 s5ps.append(s5p)
0146 elem = rel.split("/")
0147
0148 if len(elem) > 2:
0149
0150 title = "_".join([elem[-3], elem[-2], elem[-1]])
0151 elif len(elem) > 1:
0152 title = "_".join([elem[-2], elem[-1]])
0153 else:
0154 title = elem[0]
0155 pass
0156
0157 log.debug("rel %s elem %d title %s " % (rel, len(elem), title))
0158
0159 s5ti.append(title)
0160 pass
0161 return cmds, s5ps, s5ti
0162
0163 def spaths(self):
0164 spl = []
0165 for rel in self.res:
0166 spath = os.path.join(self.base, rel)
0167 spl.append(spath)
0168 pass
0169 return spl
0170
0171 def dpaths(self):
0172 dest = self.dest
0173 dpl = []
0174 for rel in self.res:
0175 dpath = os.path.join(dest, rel)
0176 dpl.append(dpath)
0177 pass
0178 return dpl
0179
0180 def existing_dpaths(self):
0181 dpl = self.dpaths()
0182 xdp = []
0183 for dp in dpl:
0184 if os.path.exists(dp):
0185 xdp.append(dp)
0186 pass
0187 pass
0188 return xdp
0189
0190 def s5_titles(self):
0191 lines = []
0192 for i in range(len(self.s5ti)):
0193 s5t = self.s5ti[i]
0194 title = ":i:`%s`" % s5t
0195 undertitle = "-" * (3+len(title))
0196 lines.append(title)
0197 lines.append(undertitle)
0198 lines.append("")
0199 pass
0200 return "\n".join(lines)
0201
0202 def __repr__(self):
0203 lines = []
0204 indent = self.INDENT
0205 assert len(self.s5ps) == len(self.s5ti)
0206 for i in range(len(self.s5ps)):
0207 s5p = self.s5ps[i]
0208 s5t = self.s5ti[i]
0209 lines.append(indent)
0210 lines.append(indent+s5t)
0211 lines.append(indent+s5p+" 1280px_720px")
0212 pass
0213 return "\n".join(lines)
0214
0215 def __str__(self):
0216 return "\n".join(self.cmds)
0217
0218
0219
0220 def parse_args(doc, **kwa):
0221 parser = argparse.ArgumentParser(doc)
0222 parser.add_argument( "--level", default="info", help="logging level" )
0223 parser.add_argument( "--digestprefix", action="store_true", default=False, help="prefix with geocache digest" )
0224 parser.add_argument( "args", nargs="*", help="arg" )
0225 args = parser.parse_args()
0226 fmt = '[%(asctime)s] p%(process)s {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s'
0227
0228 loglevel = args.level.upper()
0229
0230
0231 logging.basicConfig(level=getattr(logging,loglevel), format=fmt)
0232 return args
0233
0234
0235
0236 if __name__ == '__main__':
0237
0238 pargs = parse_args(__doc__)
0239 args = pargs.args
0240
0241 p = Pub(digestprefix=pargs.digestprefix)
0242 for arg in args:
0243 if arg == "cp":
0244 print(p)
0245 elif arg == "help":
0246 print(__doc__)
0247 elif arg == "s5":
0248 print(repr(p))
0249 elif arg == "t5":
0250 print(p.s5_titles())
0251 elif arg == "sp":
0252 print("\n".join(p.spaths()))
0253 elif arg == "dp":
0254 print("\n".join(p.dpaths()))
0255 elif arg == "xdp":
0256 print("\n".join(p.existing_dpaths()))
0257 else:
0258 print(p)
0259 print(repr(p))
0260 pass
0261 pass
0262