1# vim:set et ts=4 sw=4: 

2 

3"""Text utility functions 

4 

5@contact: Debian FTP Master <ftpmaster@debian.org> 

6@copyright: 2000, 2001, 2002, 2003, 2004, 2005, 2006 James Troup <james@nocrew.org> 

7@license: GNU General Public License version 2 or later 

8""" 

9 

10# This program is free software; you can redistribute it and/or modify 

11# it under the terms of the GNU General Public License as published by 

12# the Free Software Foundation; either version 2 of the License, or 

13# (at your option) any later version. 

14 

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

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

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

18# GNU General Public License for more details. 

19 

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

21# along with this program; if not, write to the Free Software 

22# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

23 

24import email.header 

25 

26from .dak_exceptions import ParseMaintError 

27from .regexes import re_parse_maintainer 

28 

29################################################################################ 

30 

31 

32def rfc2047_encode(s): 

33 """ 

34 Encodes a (header) string per RFC2047 if necessary. If the 

35 string is neither ASCII nor UTF-8, it's assumed to be ISO-8859-1. 

36 """ 

37 for enc in ("ascii", "utf-8", "iso-8859-1"): 37 ↛ 44line 37 didn't jump to line 44, because the loop on line 37 didn't complete

38 try: 

39 return email.header.Header(s, enc, 998).encode() 

40 except UnicodeEncodeError: 

41 pass 

42 

43 # If we get here, we're boned beyond belief 

44 raise RuntimeError("Failed to encode string") 

45 

46 

47################################################################################ 

48 

49# <Culus> 'The standard sucks, but my tool is supposed to interoperate 

50# with it. I know - I'll fix the suckage and make things 

51# incompatible!' 

52 

53 

54def fix_maintainer(maintainer: str) -> tuple[str, str, str, str]: 

55 """ 

56 Parses a Maintainer or Changed-By field and returns: 

57 1. an RFC822 compatible version, 

58 2. an RFC2047 compatible version, 

59 3. the name 

60 4. the email 

61 

62 The name is forced to UTF-8 for both 1. and 3.. If the name field 

63 contains '.' or ',' (as allowed by Debian policy), 1. and 2. are 

64 switched to 'email (name)' format. 

65 

66 """ 

67 maintainer = maintainer.strip() 

68 if not maintainer: 

69 return ("", "", "", "") 

70 

71 if maintainer.find("<") == -1: 

72 email = maintainer 

73 name = "" 

74 elif maintainer[0] == "<" and maintainer[-1:] == ">": 

75 email = maintainer[1:-1] 

76 name = "" 

77 else: 

78 m = re_parse_maintainer.match(maintainer) 

79 if not m: 

80 raise ParseMaintError("Doesn't parse as a valid Maintainer field.") 

81 name = m.group(1) 

82 email = m.group(2) 

83 

84 # Get an RFC2047 compliant version of the name 

85 rfc2047_name = rfc2047_encode(name) 

86 

87 if name.find(",") != -1 or name.find(".") != -1: 

88 rfc822_maint = "%s (%s)" % (email, name) 

89 rfc2047_maint = "%s (%s)" % (email, rfc2047_name) 

90 else: 

91 rfc822_maint = "%s <%s>" % (name, email) 

92 rfc2047_maint = "%s <%s>" % (rfc2047_name, email) 

93 

94 if email.find("@") == -1 and email.find("buildd_") != 0: 

95 raise ParseMaintError("No @ found in email address part.") 

96 

97 return (rfc822_maint, rfc2047_maint, name, email) 

98 

99 

100################################################################################ 

101 

102 

103def split_uploaders(field): 

104 import re 

105 

106 for u in re.sub(">[ ]*,", ">\t", field).split("\t"): 

107 u = u.strip() 

108 # Trailing commas will give an empty final uploader 

109 if u: 109 ↛ 106line 109 didn't jump to line 106, because the condition on line 109 was never false

110 yield u