base.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. # SPDX-License-Identifier: AGPL-3.0-or-later
  2. #
  3. # Copyright (C) 2023 Ferass El Hafidi <vitali64pmemail@protonmail.com>
  4. from markupsafe import escape
  5. from pycmarkgfm import gfm_to_html as markdown
  6. from base64 import b64decode # For some reason GitLab encodes file contents
  7. import requests
  8. """
  9. This API "library" basically turns JSON returned by the GitLab API into valid
  10. HTML5 that is then embedded in Laboratory templates.
  11. """
  12. def api_call(url):
  13. return requests.get(url).json()
  14. def errcheck(instance, repo = None, group = None, username = None):
  15. # TODO: Better error handling
  16. try: requests.get('https://%s/api/v4/' % instance)
  17. except requests.exceptions.ConnectionError: return 404 # ...what?
  18. if repo != None:
  19. try:
  20. api_call('https://%s/api/v4/projects/%s' \
  21. % (instance, repo))['name']
  22. except KeyError:
  23. return 404
  24. if group != None:
  25. try:
  26. api_call('https://%s/api/v4/groups/%s' \
  27. % (instance, group))['name']
  28. except KeyError:
  29. return 404
  30. if username != None:
  31. try:
  32. api_call('https://%s/api/v4/users?username=%s' \
  33. % (instance, username))[0]
  34. except IndexError: return 404
  35. except KeyError: return 404
  36. return 200
  37. def get_projects_list(instance, search_query = None, group = None, page = 1):
  38. if search_query is None and group is None:
  39. projects_list = api_call('https://%s/api/v4/projects?page=%s' \
  40. % (instance, page))
  41. elif group is not None and search_query is None: # Groups
  42. projects_list = api_call('https://%s/api/v4/groups/%s?page=%s' \
  43. % (instance, group, page))['projects']
  44. elif group is not None and search_query is not None: # Groups
  45. projects_list = api_call('https://%s/api/v4/groups/%s?search=%s&page=%s' \
  46. % (instance, group, search_query, page))['projects']
  47. else: # Search
  48. projects_list = api_call(\
  49. 'https://%s/api/v4/projects?search_namespaces=true&search=%s&page=%s' \
  50. % (instance, search_query, page))
  51. if projects_list == []:
  52. return "<p style=\"background-color: orangered; padding: 10px\">" \
  53. "an error occured: no projects found</p>"
  54. # Convert to HTML
  55. projects_list_html = "<table class=\"laboratory_list\"><tbody>"
  56. projects_list_html += "<tr>" "<th>Name</th>" \
  57. "<th>Description</th>" "<th>Owner or group</th>" "<th>Idle</th>" "</tr>"
  58. for project in projects_list:
  59. projects_list_html += "<tr><td><a href=\"/%s/%s/\">%s</a></th>" % \
  60. (instance, project['path_with_namespace'], \
  61. project['path_with_namespace']) + \
  62. "<td><a href=\"/%s/%s\">%s</a></td>" % (instance, \
  63. project['path_with_namespace'], project['description']) + \
  64. "<td><a href=\"/%s/%s\">%s</a></td>" % (instance, \
  65. project['path_with_namespace'], \
  66. project['namespace']['name']) + \
  67. "<td><a href=\"/%s/%s\">%s</a></td></tr>" % (instance, \
  68. project['path_with_namespace'], project['last_activity_at'])
  69. projects_list_html += "</tbody></table>"
  70. projects_list_html += "<a href=\"?page=%s\">Next →</a>" % (page + 1)
  71. return projects_list_html