Coverage for an_website / quotes / generator.py: 70.000%

30 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-24 17:35 +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"""Generate quotes and authors for users to make their own wrong quotes.""" 

15 

16import random 

17 

18from ..utils.request_handler import APIRequestHandler 

19from .utils import ( 

20 Author, 

21 Quote, 

22 QuoteReadyCheckHandler, 

23 get_authors, 

24 get_quotes, 

25 get_wrong_quotes, 

26) 

27 

28 

29def get_authors_and_quotes(count: int) -> tuple[list[Author], list[Quote]]: 

30 """Get random batch of authors and quotes.""" 

31 if count < 1: 

32 return [], [] 

33 

34 authors: list[Author] = list(get_authors(shuffle=True)[:count]) 

35 quotes: list[Quote] = list(get_quotes(shuffle=True)[:count]) 

36 

37 if len(authors) <= 1 or len(quotes) <= 1: 

38 return authors, quotes 

39 

40 wrong_quote = get_wrong_quotes(lambda wq: wq.rating > 0, shuffle=True)[0] 

41 

42 if (wq_author := wrong_quote.author) not in authors: 

43 authors[random.randrange(0, len(authors))] = wq_author # nosec: B311 

44 

45 if (wq_quote := wrong_quote.quote) not in quotes: 

46 quotes[random.randrange(0, len(quotes))] = wq_quote # nosec: B311 

47 

48 return authors, quotes 

49 

50 

51class QuoteGenerator(QuoteReadyCheckHandler): 

52 """The request handler for the quote generator HTML page.""" 

53 

54 async def get(self, *, head: bool = False) -> None: 

55 """Handle GET requests.""" 

56 count = self.get_int_argument("count", 5, min_=0, max_=10) 

57 authors, quotes = get_authors_and_quotes(count) 

58 if head: 

59 return 

60 await self.render( 

61 "pages/quotes/generator.html", authors=authors, quotes=quotes 

62 ) 

63 

64 

65class QuoteGeneratorAPI(APIRequestHandler, QuoteReadyCheckHandler): 

66 """The request handler for the quote generator API.""" 

67 

68 async def get(self, *, head: bool = False) -> None: 

69 """Handle GET requests.""" 

70 count = self.get_int_argument("count", 5, min_=0, max_=10) 

71 authors, quotes = get_authors_and_quotes(count) 

72 if head: 

73 return 

74 await self.finish_dict( 

75 count=count, 

76 authors=[author.to_json() for author in authors], 

77 quotes=[quote.to_json() for quote in quotes], 

78 )