compile_pysrc.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import argparse
  2. import os
  3. import shutil
  4. import subprocess
  5. import tarfile
  6. LIMIT = 6000
  7. def parse_args():
  8. parser = argparse.ArgumentParser()
  9. parser.add_argument('--input', required=True)
  10. parser.add_argument('--output', required=True)
  11. parser.add_argument('--rescompiler', required=True)
  12. subparsers = parser.add_subparsers(dest='mode')
  13. parser_py2 = subparsers.add_parser('py2')
  14. parser_py2.add_argument('--py_compile', required=True)
  15. parser_py2.add_argument('--python', required=True)
  16. parser_py3 = subparsers.add_parser('py3')
  17. parser_py3.add_argument('--pycc', required=True)
  18. return parser.parse_args()
  19. def call(cmd, cwd=None, env=None):
  20. return subprocess.check_output(cmd, stdin=None, stderr=subprocess.STDOUT, cwd=cwd, env=env)
  21. def iterate_py2_resource_params(py_files):
  22. for py in py_files:
  23. mod = py[:-3].replace('/', '.')
  24. key = '/py_modules/{}'.format(mod)
  25. yield py, key
  26. yield '-', 'resfs/src/{}={}'.format(key, py)
  27. yield '{}.yapyc'.format(py), '/py_code/{}'.format(mod)
  28. def iterate_py3_resource_params(py_files):
  29. for py in py_files:
  30. for ext in ('', '.yapyc3'):
  31. path = '{}{}'.format(py, ext)
  32. dest = 'py/{}'.format(path)
  33. key = 'resfs/file/{}'.format(dest)
  34. src = 'resfs/src/{}={}'.format(key, os.path.basename(path))
  35. yield '-', src
  36. yield path, key
  37. def main():
  38. args = parse_args()
  39. names = []
  40. with tarfile.open(args.input, 'r') as tar:
  41. names = tar.getnames()
  42. tar.extractall()
  43. if args.mode == 'py3':
  44. pycc_cmd = [args.pycc]
  45. pycc_ext = '.yapyc3'
  46. iterate_resource_params = iterate_py3_resource_params
  47. else:
  48. pycc_cmd = [args.python, args.py_compile]
  49. pycc_ext = '.yapyc'
  50. iterate_resource_params = iterate_py2_resource_params
  51. py_files = sorted(names)
  52. for py in py_files:
  53. cmd = pycc_cmd + ['{}-'.format(os.path.basename(py)), py, '{}{}'.format(py, pycc_ext)]
  54. call(cmd)
  55. outputs = []
  56. cmd = [args.rescompiler, '{}.0'.format(args.output)]
  57. size = 0
  58. for path, key in iterate_resource_params(py_files):
  59. addendum = len(path) + len(key)
  60. if size + addendum > LIMIT and len(cmd) > 2:
  61. call(cmd)
  62. outputs.append(cmd[1])
  63. cmd[1] = '{}.{}'.format(args.output, len(outputs))
  64. cmd = cmd[0:2]
  65. size = 0
  66. cmd.extend([path, key])
  67. size += addendum
  68. if len(outputs) == 0:
  69. cmd[1] = args.output
  70. call(cmd)
  71. else:
  72. call(cmd)
  73. outputs.append(cmd[1])
  74. with open(args.output, 'w') as fout:
  75. for fname in outputs:
  76. with open(fname, 'r') as fin:
  77. shutil.copyfileobj(fin, fout)
  78. if __name__ == '__main__':
  79. main()