Coverage for portality/lib/coerce.py: 74%

66 statements  

« prev     ^ index     » next       coverage.py v6.4.2, created at 2022-07-20 16:12 +0100

1# ~~Coerce:Library~~ 

2from portality.lib import dates 

3from datetime import date, datetime 

4from portality.lib import seamless 

5from portality.datasets import get_country_code, get_currency_code 

6 

7 

8def to_datestamp(in_format=None): 

9 def stampify(val): 

10 return dates.parse(val, format=in_format) 

11 return stampify 

12 

13 

14def date_str(in_format=None, out_format=None): 

15 def datify(val): 

16 if val is None or val == "": 

17 return None 

18 if isinstance(val, date) or isinstance(val, datetime): 

19 return dates.format(val, format=out_format) 

20 else: 

21 return dates.reformat(val, in_format=in_format, out_format=out_format) 

22 

23 return datify 

24 

25 

26def to_isolang(output_format=None): 

27 """ 

28 :param output_format: format from input source to putput. Must be one of: 

29 * alpha3 

30 * alt3 

31 * alpha2 

32 * name 

33 * fr 

34 Can be a list in order of preference, too 

35 ~~-> Languages:Data~~ 

36 :return: 

37 """ 

38 # delayed import, since we may not always want to load the whole dataset for a dataobj 

39 from portality.lib import isolang as dataset 

40 

41 # sort out the output format list 

42 if output_format is None: 

43 output_format = ["alpha3"] 

44 if not isinstance(output_format, list): 

45 output_format = [output_format] 

46 

47 def isolang(val): 

48 if val is None: 

49 return None 

50 l = dataset.find(val) 

51 if l is None: 

52 raise ValueError("Unable to find iso code for language {x}".format(x=val)) 

53 for f in output_format: 

54 v = l.get(f) 

55 if v is None or v == "": 

56 continue 

57 return v.upper() 

58 

59 return isolang 

60 

61 

62def to_currency_code(val): 

63 """ 

64 ~~-> Currencies:Data~~ 

65 :param val: 

66 :return: 

67 """ 

68 if val is None: 

69 return None 

70 nv = get_currency_code(val) 

71 if nv is None: 

72 raise ValueError("Unable to convert {x} to a valid currency code".format(x=val)) 

73 uc = seamless.to_utf8_unicode 

74 return uc(nv) 

75 

76 

77def to_country_code(val): 

78 """ 

79 ~~-> Countries:Data~~ 

80 :param val: 

81 :return: 

82 """ 

83 if val is None: 

84 return None 

85 nv = get_country_code(val, fail_if_not_found=True) 

86 if nv is None: 

87 raise ValueError("Unable to convert {x} to a valid country code".format(x=val)) 

88 uc = seamless.to_utf8_unicode 

89 return uc(nv) 

90 

91 

92def to_issn(issn): 

93 if len(issn) > 9 or issn == '': 

94 raise ValueError("Unable to normalise {x} to valid ISSN".format(x=issn)) 

95 

96 issn = issn.upper() 

97 if len(issn) == 9: 

98 return issn 

99 

100 if len(issn) == 8: 

101 if "-" in issn: 

102 return "0" + issn 

103 else: 

104 return issn[:4] + "-" + issn[4:] 

105 

106 if len(issn) < 8: 

107 if "-" in issn: 

108 return ("0" * (9 - len(issn))) + issn 

109 else: 

110 issn = ("0" * (8 - len(issn))) + issn 

111 return issn[:4] + "-" + issn[4:] 

112 

113 

114# ~~-> Seamless:Library~~ 

115COERCE_MAP = { 

116 "unicode": seamless.to_utf8_unicode, 

117 "unicode_upper" : seamless.to_unicode_upper, 

118 "unicode_lower" : seamless.to_unicode_lower, 

119 "integer": seamless.intify, 

120 "float": seamless.floatify, 

121 "url": seamless.to_url, 

122 "bool": seamless.to_bool, 

123 "datetime" : seamless.to_datetime, 

124 "utcdatetime" : date_str(), 

125 "utcdatetimemicros" : date_str(out_format="%Y-%m-%dT%H:%M:%S.%fZ"), 

126 "bigenddate" : date_str(out_format="%Y-%m-%d"), 

127 "isolang": to_isolang(), 

128 "isolang_2letter": to_isolang(output_format="alpha2"), 

129 "country_code": to_country_code, 

130 "currency_code": to_currency_code, 

131 "issn" : to_issn 

132}