PageRenderTime 58ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/fileops.py

https://gitlab.com/j000sh/hackerrank-to-git
Python | 136 lines | 126 code | 7 blank | 3 comment | 15 complexity | c0487c87def0b87559349975567a7d2a MD5 | raw file
  1. """
  2. This file does all the fancy git operations and file writing
  3. """
  4. import os
  5. import json
  6. from pprint import pprint
  7. from bs4 import BeautifulSoup
  8. from sh import git
  9. HR = 'https://www.hackerrank.com'
  10. HR_REST = HR + '/rest'
  11. CONTESTS = '/contests'
  12. CHALLENGES = '/challenges'
  13. SUBMISSIONS = '/submissions'
  14. SUBMISSIONS_GROUPED = SUBMISSIONS + '/grouped'
  15. def getFullPath(path):
  16. return os.path.abspath(path)
  17. def load(filename):
  18. try:
  19. return json.load(open(filename, 'r'))
  20. except FileNotFoundError as e:
  21. return None
  22. def dump(filename, data):
  23. json.dump(data, open(filename, 'w'))
  24. def initializeDir(path, user, repo = None):
  25. if not os.path.exists(path):
  26. print('making directories')
  27. os.makedirs(path)
  28. os.chdir(path)
  29. if os.path.exists('.git/'):
  30. print('git respository already initialized')
  31. return
  32. print('initializing git repository')
  33. git.init()
  34. os.chmod(path + '/.git/', 0b111000000)
  35. git.config('--local', 'user.name', '"' + user['name'] + '"')
  36. git.config('--local', 'user.email', '"' + user['email'] + '"')
  37. if repo:
  38. git.remote.add('origin', repo)
  39. def writeModels(models, html):
  40. if not models:
  41. return
  42. print('writing models')
  43. for t in sorted(models.keys()):
  44. (m, ty) = models[t]
  45. if ty == 'co':
  46. try:
  47. os.makedirs(m['model']['slug'])
  48. except:
  49. pass
  50. os.chdir(m['model']['slug'])
  51. if html:
  52. writeContest(m)
  53. elif ty == 'ch':
  54. try:
  55. os.chdir(m['contest_slug'])
  56. except:
  57. os.makedirs(m['contest_slug'])
  58. os.chdir(m['contest_slug'])
  59. if html:
  60. writeChallenge(m)
  61. elif ty == 'sub':
  62. os.chdir(m['contest_slug'])
  63. writeSubmission(m)
  64. os.chdir('..')
  65. def writeContest(contest):
  66. model = contest['model']
  67. hrurl = HR + CONTESTS + '/' + model['slug']
  68. resturl = HR_REST + CONTESTS + '/' + model['slug']
  69. challengehtml = '<ul>'
  70. for (challengeSlug, challenge) in contest['challenges'].items():
  71. challengehtml += '<li><a href="{}">{}</a></li>'.format(challengeSlug + '.html', challengeSlug)
  72. challengehtml += '</ul>'
  73. html = """<!DOCTYPE html>
  74. <html><head></head><body>
  75. <h1>{}</h1><a href="{}">Contest</a> <a href="{}">JSON</a><hr/>{}<hr/>
  76. <h2>Challenges</h2>{}</body></html>
  77. """.format(model['name'], hrurl, resturl, model['description_html'], challengehtml)
  78. filename = 'index.html'
  79. with open(filename, 'w') as f:
  80. f.write(BeautifulSoup(html, 'html5lib').prettify() + '\n')
  81. gitCommitModel(contest['model'], filename, 'contest created: ' + model['slug'])
  82. def writeChallenge(challenge):
  83. asseturl = 'https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_CHTML'
  84. js = "MathJax.Hub.Config({tex2jax:{inlineMath:[['$','$'],['\\(','\\)']]}});"
  85. hrurl = HR \
  86. + (CONTESTS + '/' + challenge['contest_slug'] if challenge['contest_slug'] != 'master' else '') \
  87. + CHALLENGES + '/' + challenge['slug']
  88. jsonurl = HR_REST + CONTESTS + '/' + challenge['contest_slug'] + CHALLENGES + '/' + challenge['slug']
  89. html = """<!DOCTYPE html>
  90. <html><head><meta charset="UTF-8"/>
  91. <script type="text/javascript" async src="{}">{}</script>
  92. </head><body><h1>{}</h1><p><a href="{}">Challenge</a> <a href="{}">JSON</a></p><hr/>{}</body></html>
  93. """.format(asseturl, js, challenge['name'], hrurl, jsonurl, challenge['body_html'])
  94. filename = challenge['slug'] + '.html'
  95. with open(filename, 'w') as f:
  96. f.write(BeautifulSoup(html, "html5lib").prettify() + "\n")
  97. gitCommitModel(challenge, filename, 'challenge created: ' + challenge['slug'])
  98. def writeSubmission(sub):
  99. filename = sub['challenge_slug'] + getFileExtension(sub)
  100. with open(filename, 'w') as f:
  101. f.write(sub['code'] + "\n")
  102. msg = "{} ({}) {} {}".format(sub['name'], sub['language'], getFrac(sub['testcase_status']), sub['status'])
  103. gitCommitModel(sub, filename, msg)
  104. def gitCommitModel(m, filename, msg):
  105. envDict = {'GIT_COMMITTER_DATE': m['created_at'], 'GIT_AUTHOR_DATE': m['created_at']}
  106. git.add(filename)
  107. git.commit(m=msg, _ok_code=[0,1], date=m['created_at'])
  108. git.commit('--no-edit', amend=True, _env=envDict) # force date
  109. def getFileExtension(submission):
  110. lang = submission['language']
  111. if lang == 'java' or lang == 'java8':
  112. return '.java'
  113. if lang == 'python' or lang == 'python3':
  114. return '.py'
  115. if lang == 'haskell':
  116. return '.hs'
  117. if lang == 'prolog' or lang == 'perl':
  118. return '.pl'
  119. return '.txt'
  120. def getFrac(testcases):
  121. return '[%d/%d]' % (sum(testcases), len(testcases))