Coverage for an_website/lolwut/lolwut.py: 77.500%

40 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-10 18:56 +0000

1# This program is free software: you can redistribute it and/or modify 

2# it under the terms of the GNU Affero General Public License as 

3# published by the Free Software Foundation, either version 3 of the 

4# License, or (at your option) any later version. 

5# 

6# This program is distributed in the hope that it will be useful, 

7# but WITHOUT ANY WARRANTY; without even the implied warranty of 

8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

9# GNU Affero General Public License for more details. 

10# 

11# You should have received a copy of the GNU Affero General Public License 

12# along with this program. If not, see <https://www.gnu.org/licenses/>. 

13 

14"""The page that generates art.""" 

15 

16from collections.abc import Awaitable 

17from typing import ClassVar, Final 

18 

19import regex 

20from redis.asyncio import Redis 

21from tornado.web import HTTPError 

22 

23from .. import EVENT_REDIS 

24from ..utils.base_request_handler import BaseRequestHandler 

25from ..utils.request_handler import APIRequestHandler, HTMLRequestHandler 

26from ..utils.utils import ModuleInfo 

27 

28 

29def get_module_info() -> ModuleInfo: 

30 """Create and return the ModuleInfo for this module.""" 

31 args = r"(?:\d+/)*\d+" 

32 return ModuleInfo( 

33 handlers=( 

34 (r"/LOLWUT", LOLWUT), 

35 (rf"/LOLWUT/({args})", LOLWUT), 

36 (r"/api/LOLWUT", LOLWUTAPI), 

37 (rf"/api/LOLWUT/({args})", LOLWUTAPI), 

38 (rf"(?i)(?:/api)?/lolwut(?:/{args})?", LOLWUTRedirectHandler), 

39 ), 

40 name="LOLWUT", 

41 description="LOLWUT; präsentiert von Redis", 

42 path="/LOLWUT", 

43 keywords=( 

44 "LOLWUT", 

45 "Redis", 

46 ), 

47 ) 

48 

49 

50def generate_art(redis: Redis[str], args: str | None) -> Awaitable[bytes]: 

51 """Generate art.""" 

52 return redis.lolwut(*(args.split("/") if args else ())) 

53 

54 

55class LOLWUT(HTMLRequestHandler): 

56 """The request handler for the LOLWUT page.""" 

57 

58 async def get(self, args: None | str = None, *, head: bool = False) -> None: 

59 """Handle GET requests to the LOLWUT page.""" 

60 if not EVENT_REDIS.is_set(): 

61 raise HTTPError(503) 

62 

63 art = await generate_art(self.redis, args) 

64 

65 if head: 

66 return 

67 

68 await self.render( 

69 "ansi2html.html", 

70 ansi=art, 

71 powered_by="https://redis.io", 

72 powered_by_name="Redis", 

73 ) 

74 

75 

76class LOLWUTAPI(APIRequestHandler): 

77 """The request handler for the LOLWUT API.""" 

78 

79 POSSIBLE_CONTENT_TYPES: ClassVar[tuple[str, ...]] = ( 

80 "text/plain", 

81 *APIRequestHandler.POSSIBLE_CONTENT_TYPES, 

82 ) 

83 

84 async def get(self, args: None | str = None) -> None: 

85 """Handle GET requests to the LOLWUT API.""" 

86 if not EVENT_REDIS.is_set(): 

87 raise HTTPError(503) 

88 

89 art = await generate_art(self.redis, args) 

90 

91 if self.content_type == "text/plain": 

92 return await self.finish(art) 

93 

94 await self.finish({"LOLWUT": art}) 

95 

96 

97class LOLWUTRedirectHandler(BaseRequestHandler): 

98 """Redirect to the LOLWUT page.""" 

99 

100 REPL_PATTERN: Final = regex.compile(r"/lolwut(/|\?|$)", regex.IGNORECASE) 

101 

102 def get(self) -> None: 

103 """Handle requests to the LOLWUT page.""" 

104 self.redirect( 

105 LOLWUTRedirectHandler.REPL_PATTERN.sub( 

106 LOLWUTRedirectHandler.repl_match, self.request.full_url(), 1 

107 ) 

108 ) 

109 

110 head = get 

111 post = get 

112 

113 @staticmethod 

114 def repl_match(match: regex.Match[str]) -> str: 

115 """Return the correct replacement for the given match.""" 

116 return f"/LOLWUT{match.group(1)}"