Coverage for webapp/integrations/views.py: 71%

69 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-27 22:07 +0000

1from datetime import datetime 

2from flask import ( 

3 Blueprint, 

4 render_template, 

5 make_response, 

6 redirect, 

7 abort, 

8 url_for, 

9) 

10from flask.json import jsonify 

11from github import Github 

12from os import getenv 

13 

14from webapp.integrations.logic import Interfaces 

15from webapp.observability.utils import trace_function 

16from webapp.store_api import publisher_gateway 

17 

18interface_logic = Interfaces() 

19 

20integrations = Blueprint( 

21 "integrations", 

22 __name__, 

23 template_folder="/templates", 

24 static_folder="/static", 

25) 

26 

27GITHUB_TOKEN = getenv("GITHUB_TOKEN") 

28 

29github_client = Github(GITHUB_TOKEN) 

30 

31 

32@trace_function 

33def get_interfaces(): 

34 interfaces = interface_logic.get_interfaces() 

35 

36 response = { 

37 "interfaces": interfaces, 

38 "size": len(interfaces), 

39 } 

40 return response 

41 

42 

43@trace_function 

44@integrations.route("/integrations.json") 

45def interfaces_json(): 

46 return get_interfaces() 

47 

48 

49@trace_function 

50@integrations.route("/integrations", defaults={"path": ""}) 

51def all_interfaces(path): 

52 if not getenv("ENVIRONMENT") in ["devel", "staging"]: 

53 return render_template("404.html") 

54 

55 response = get_interfaces() 

56 context = {"interfaces": response["interfaces"]} 

57 return render_template("interfaces/index.html", **context) 

58 

59 

60@trace_function 

61@integrations.route("/integrations/<path:path>") 

62def single_interface(path): 

63 is_draft = path.endswith("draft") 

64 interface = None 

65 

66 if is_draft: 

67 response = get_single_interface(path.replace("/draft", ""), "draft") 

68 else: 

69 response = get_single_interface(path, "") 

70 

71 interface = eval(response.data.decode("utf-8")) 

72 

73 if ( 

74 "status" not in interface 

75 and "other_charms" in interface 

76 and len(interface["other_charms"]["providers"]) == 0 

77 and len(interface["other_charms"]["requirers"]) == 0 

78 ): 

79 return abort(404) 

80 

81 if ( 

82 not is_draft 

83 and "status" in interface 

84 and interface["status"] == "draft" 

85 ): 

86 return redirect(url_for(".single_interface", path=f"{path}/draft")) 

87 

88 context = {"interface": interface} 

89 return render_template("interfaces/index.html", **context) 

90 

91 

92@trace_function 

93@integrations.route( 

94 "/integrations/<interface_name>.json", defaults={"status": ""} 

95) 

96@integrations.route("/integrations/<interface_name>/<status>.json") 

97def get_single_interface(interface_name, status): 

98 repo_has_interface = interface_logic.repo_has_interface(interface_name) 

99 

100 other_requirers = publisher_gateway.find(requires=[interface_name]).get( 

101 "results", [] 

102 ) 

103 other_providers = publisher_gateway.find(provides=[interface_name]).get( 

104 "results", [] 

105 ) 

106 

107 res = {} 

108 # check if interface exists in github repo 

109 if not repo_has_interface: 

110 res["other_charms"] = { 

111 "providers": other_providers, 

112 "requirers": other_requirers, 

113 } 

114 return jsonify(res) 

115 

116 interface = interface_logic.get_interface_from_path(interface_name) 

117 

118 readme_contentfile = interface_logic.repo.get_contents( 

119 f"interfaces/{interface_name}/v{interface['version']}/README.md" 

120 ) 

121 readme = readme_contentfile.decoded_content.decode("utf-8") 

122 

123 last_modified = datetime.strptime( 

124 readme_contentfile.last_modified, "%a, %d %b %Y %H:%M:%S %Z" 

125 ).isoformat() 

126 

127 res["body"] = interface_logic.convert_readme( 

128 interface_name, f"v{interface['version']}", readme, 2 

129 ) 

130 

131 res["name"] = interface_logic.get_interface_name_from_readme(readme) 

132 res["charms"] = { 

133 "providers": interface["providers"], 

134 "requirers": interface["requirers"], 

135 } 

136 res["last_modified"] = last_modified 

137 res["status"] = interface["status"] 

138 

139 res["version"] = interface["version"] 

140 

141 res["other_charms"] = { 

142 "providers": other_providers, 

143 "requirers": other_requirers, 

144 } 

145 

146 response = make_response(res) 

147 response.cache_control.max_age = "76800" 

148 return response