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

40 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-05 08:06 +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 

16 

17from collections.abc import Awaitable 

18from typing import ClassVar, Final 

19 

20import regex 

21from redis.asyncio import Redis 

22from tornado.web import HTTPError 

23 

24from .. import EVENT_REDIS 

25from ..utils.base_request_handler import BaseRequestHandler 

26from ..utils.request_handler import APIRequestHandler, HTMLRequestHandler 

27from ..utils.utils import ModuleInfo 

28 

29 

30def get_module_info() -> ModuleInfo: 

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

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

33 return ModuleInfo( 

34 handlers=( 

35 (r"/LOLWUT", LOLWUT), 

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

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

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

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

40 ), 

41 name="LOLWUT", 

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

43 path="/LOLWUT", 

44 keywords=( 

45 "LOLWUT", 

46 "Redis", 

47 ), 

48 ) 

49 

50 

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

52 """Generate art.""" 

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

54 

55 

56class LOLWUT(HTMLRequestHandler): 

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

58 

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

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

61 if not EVENT_REDIS.is_set(): 

62 raise HTTPError(503) 

63 

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

65 

66 if head: 

67 return 

68 

69 await self.render( 

70 "ansi2html.html", 

71 ansi=art, 

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

73 powered_by_name="Redis", 

74 ) 

75 

76 

77class LOLWUTAPI(APIRequestHandler): 

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

79 

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

81 "text/plain", 

82 *APIRequestHandler.POSSIBLE_CONTENT_TYPES, 

83 ) 

84 

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

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

87 if not EVENT_REDIS.is_set(): 

88 raise HTTPError(503) 

89 

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

91 

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

93 return await self.finish(art) 

94 

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

96 

97 

98class LOLWUTRedirectHandler(BaseRequestHandler): 

99 """Redirect to the LOLWUT page.""" 

100 

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

102 

103 def get(self) -> None: 

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

105 self.redirect( 

106 LOLWUTRedirectHandler.REPL_PATTERN.sub( 

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

108 ) 

109 ) 

110 

111 head = get 

112 post = get 

113 

114 @staticmethod 

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

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

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