A copyright violation detector running on Wikimedia Cloud Services https://tools.wmflabs.org/copyvios/
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 

180 行
5.8 KiB

  1. #! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import logging
  4. import os
  5. import shutil
  6. import subprocess
  7. page_src = """#! /usr/bin/env python
  8. # -*- coding: utf-8 -*-
  9. import os
  10. import sys
  11. os.chdir("..")
  12. plat = sys.platform
  13. if plat.startswith("sunos"):
  14. plat = "solaris"
  15. elif plat.startswith("linux"):
  16. plat = "linux"
  17. sys.path.insert(0, os.path.expanduser("~/.local/" + plat + "/lib/python2.7/site-packages"))
  18. sys.path.insert(0, ".")
  19. from mako.template import Template
  20. from mako.lookup import TemplateLookup
  21. from toolserver.cookies import parse_cookies
  22. def main(environ, start_response):
  23. lookup = TemplateLookup(directories=["{{pages_dir}}"],
  24. input_encoding="utf8")
  25. template = Template(filename="{{src}}", module_directory="{{temp_dir}}",
  26. lookup=lookup, format_exceptions=True)
  27. headers = [("Content-Type", "text/html")]
  28. cookies = parse_cookies(environ)
  29. page = template.render(environ=environ, headers=headers,
  30. cookies=cookies).encode("utf8")
  31. start_response("200 OK", headers)
  32. return [page]
  33. if __name__ == "__main__":
  34. from flup.server.fcgi import WSGIServer
  35. WSGIServer(main).run()
  36. """
  37. rewrite_script_src = """match URL into $ with ^/~earwig/{0}(\?.*?)?$
  38. if matched then
  39. set URL = /~earwig/rewrite/{0}.fcgi$1
  40. goto END
  41. endif
  42. """
  43. class Builder(object):
  44. def __init__(self):
  45. self.build_dir = "www"
  46. self.static_dir = "static"
  47. self.pages_dir = "pages"
  48. self.support_dir = "pages/support"
  49. self.temp_dir = "temp"
  50. self.rs_file = "rewrite.script"
  51. self.root = logging.getLogger("builder")
  52. self.root.addHandler(logging.NullHandler())
  53. self._pages = []
  54. def _enable_logging(self):
  55. handler = logging.StreamHandler()
  56. handler.setFormatter(_LogFormatter())
  57. self.root.addHandler(handler)
  58. self.root.setLevel(logging.DEBUG)
  59. def _replace_file(self, name, program, logger):
  60. logger.debug("{0} {1}".format(program, name))
  61. replacement = subprocess.check_output([program, name])
  62. os.remove(name)
  63. with open(name, "w") as fp:
  64. fp.write(replacement)
  65. def _gen_page(self, page, base):
  66. if not page.endswith(".mako"):
  67. base.warn("Skipping {0} (not endswith('.mako'))".format(page))
  68. return
  69. logger = base.getChild(page.rsplit(".", 1)[0])
  70. self._pages.append(page.rsplit(".", 1)[0])
  71. src = os.path.join(self.pages_dir, page)
  72. dest = os.path.join(self.build_dir, page.replace(".mako", ".fcgi"))
  73. logger.debug("build {0} -> {1}".format(src, dest))
  74. content = page_src.replace("{{src}}", src)
  75. content = content.replace("{{pages_dir}}", self.pages_dir)
  76. content = content.replace("{{temp_dir}}", self.temp_dir)
  77. with open(dest, "w") as fp:
  78. fp.write(content)
  79. logger.debug("chmod 0755 {0}".format(dest))
  80. os.chmod(dest, 0755)
  81. def clean(self):
  82. logger = self.root.getChild("clean")
  83. targets = (self.build_dir, self.temp_dir)
  84. for target in targets:
  85. if os.path.exists(target):
  86. logger.debug("rm -r {0}".format(target))
  87. shutil.rmtree(target)
  88. logger.debug("mkdir {0}".format(target))
  89. os.mkdir(target)
  90. def gen_static(self):
  91. logger = self.root.getChild("static")
  92. dest = os.path.join(self.build_dir, "static")
  93. logger.debug("copytree {0} -> {1}".format(self.static_dir, dest))
  94. shutil.copytree(self.static_dir, dest)
  95. for dirpath, dirnames, filenames in os.walk(dest):
  96. for filename in filenames:
  97. name = os.path.join(dirpath, filename)
  98. if name.endswith(".js"):
  99. self._replace_file(name, "uglifyjs", logger)
  100. elif name.endswith(".css"):
  101. self._replace_file(name, "uglifycss", logger)
  102. def gen_pages(self):
  103. logger = self.root.getChild("pages")
  104. pages = os.listdir(self.pages_dir)
  105. for page in pages:
  106. if not os.path.isfile(os.path.join(self.pages_dir, page)):
  107. continue
  108. self._gen_page(page, logger)
  109. def gen_zws(self):
  110. logger = self.root.getChild("zws")
  111. target = self.rs_file
  112. if os.path.exists(target):
  113. logger.debug("rm {0}".format(target))
  114. os.remove(target)
  115. logger.debug("build rewrite.script")
  116. with open(target, "w") as fp:
  117. for page in self._pages:
  118. fp.write(rewrite_script_src.format(page))
  119. def build(self):
  120. self._enable_logging()
  121. self.root.info("Building project...")
  122. self.clean()
  123. self.gen_static()
  124. self.gen_pages()
  125. self.gen_zws()
  126. self.root.info("Done!")
  127. class _LogFormatter(logging.Formatter):
  128. def __init__(self):
  129. fmt = "[%(asctime)s %(lvl)s] %(name)s: %(message)s"
  130. datefmt = "%Y-%m-%d %H:%M:%S"
  131. _format = super(_LogFormatter, self).format
  132. self.format = lambda record: _format(self.colorize(record))
  133. super(_LogFormatter, self).__init__(fmt=fmt, datefmt=datefmt)
  134. def colorize(self, record):
  135. l = record.levelname.ljust(8)
  136. if record.levelno == logging.DEBUG:
  137. record.lvl = l.join(("\x1b[34m", "\x1b[0m")) # Blue
  138. if record.levelno == logging.INFO:
  139. record.lvl = l.join(("\x1b[32m", "\x1b[0m")) # Green
  140. if record.levelno == logging.WARNING:
  141. record.lvl = l.join(("\x1b[33m", "\x1b[0m")) # Yellow
  142. if record.levelno == logging.ERROR:
  143. record.lvl = l.join(("\x1b[31m", "\x1b[0m")) # Red
  144. if record.levelno == logging.CRITICAL:
  145. record.lvl = l.join(("\x1b[1m\x1b[31m", "\x1b[0m")) # Bold red
  146. return record
  147. if __name__ == "__main__":
  148. Builder().build()