Coverage for /home/runner/work/viur-core/viur-core/viur/src/viur/core/utils/__init__.py: 15%

86 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-09-03 13:41 +0000

1import logging 

2import typing as t 

3import warnings 

4import datetime 

5from . import string, parse, json # noqa: used by external imports 

6from viur.core import current, db 

7from viur.core.config import conf 

8 

9 

10def utcNow() -> datetime.datetime: 

11 """ 

12 Returns an actual timestamp with UTC timezone setting. 

13 """ 

14 return datetime.datetime.now(datetime.timezone.utc) 

15 

16 

17def seoUrlToEntry(module: str, 

18 entry: t.Optional["SkeletonInstance"] = None, 

19 skelType: t.Optional[str] = None, 

20 language: t.Optional[str] = None) -> str: 

21 """ 

22 Return the seo-url to a skeleton instance or the module. 

23 

24 :param module: The module name. 

25 :param entry: A skeleton instance or None, to get the path to the module. 

26 :param skelType: # FIXME: Not used 

27 :param language: For which language. 

28 If None, the language of the current request is used. 

29 :return: The path (with a leading /). 

30 """ 

31 from viur.core import conf 

32 pathComponents = [""] 

33 if language is None: 

34 language = current.language.get() 

35 if conf.i18n.language_method == "url": 

36 pathComponents.append(language) 

37 if module in conf.i18n.language_module_map and language in conf.i18n.language_module_map[module]: 

38 module = conf.i18n.language_module_map[module][language] 

39 pathComponents.append(module) 

40 if not entry: 

41 return "/".join(pathComponents) 

42 else: 

43 try: 

44 currentSeoKeys = entry["viurCurrentSeoKeys"] 

45 except: 

46 return "/".join(pathComponents) 

47 if language in (currentSeoKeys or {}): 

48 pathComponents.append(str(currentSeoKeys[language])) 

49 elif "key" in entry: 

50 key = entry["key"] 

51 if isinstance(key, str): 

52 try: 

53 key = db.Key.from_legacy_urlsafe(key) 

54 except: 

55 pass 

56 pathComponents.append(str(key.id_or_name) if isinstance(key, db.Key) else str(key)) 

57 elif "name" in dir(entry): 

58 pathComponents.append(str(entry.name)) 

59 return "/".join(pathComponents) 

60 

61 

62def seoUrlToFunction(module: str, function: str, render: t.Optional[str] = None) -> str: 

63 from viur.core import conf 

64 lang = current.language.get() 

65 if module in conf.i18n.language_module_map and lang in conf.i18n.language_module_map[module]: 

66 module = conf.i18n.language_module_map[module][lang] 

67 if conf.i18n.language_method == "url": 

68 pathComponents = ["", lang] 

69 else: 

70 pathComponents = [""] 

71 targetObject = conf.main_resolver 

72 if module in targetObject: 

73 pathComponents.append(module) 

74 targetObject = targetObject[module] 

75 if render and render in targetObject: 

76 pathComponents.append(render) 

77 targetObject = targetObject[render] 

78 if function in targetObject: 

79 func = targetObject[function] 

80 if func.seo_language_map and lang in func.seo_language_map: 

81 pathComponents.append(func.seo_language_map[lang]) 

82 else: 

83 pathComponents.append(function) 

84 return "/".join(pathComponents) 

85 

86 

87def normalizeKey(key: t.Union[None, 'db.KeyClass']) -> t.Union[None, 'db.KeyClass']: 

88 """ 

89 Normalizes a datastore key (replacing _application with the current one) 

90 

91 :param key: Key to be normalized. 

92 

93 :return: Normalized key in string representation. 

94 """ 

95 if key is None: 

96 return None 

97 if key.parent: 

98 parent = normalizeKey(key.parent) 

99 else: 

100 parent = None 

101 return db.Key(key.kind, key.id_or_name, parent=parent) 

102 

103 

104# DEPRECATED ATTRIBUTES HANDLING 

105__UTILS_CONF_REPLACEMENT = { 

106 "projectID": "viur.instance.project_id", 

107 "isLocalDevelopmentServer": "viur.instance.is_dev_server", 

108 "projectBasePath": "viur.instance.project_base_path", 

109 "coreBasePath": "viur.instance.core_base_path" 

110} 

111 

112__UTILS_NAME_REPLACEMENT = { 

113 "currentLanguage": ("current.language", current.language), 

114 "currentRequest": ("current.request", current.request), 

115 "currentRequestData": ("current.request_data", current.request_data), 

116 "currentSession": ("current.session", current.session), 

117 "downloadUrlFor": ("modules.file.File.create_download_url", "viur.core.modules.file.File.create_download_url"), 

118 "escapeString": ("utils.string.escape", string.escape), 

119 "generateRandomString": ("utils.string.random", string.random), 

120 "getCurrentUser": ("current.user.get", current.user.get), 

121 "is_prefix": ("utils.string.is_prefix", string.is_prefix), 

122 "parse_bool": ("utils.parse.bool", parse.bool), 

123 "srcSetFor": ("modules.file.File.create_src_set", "viur.core.modules.file.File.create_src_set"), 

124} 

125 

126 

127def __getattr__(attr): 

128 if replace := __UTILS_CONF_REPLACEMENT.get(attr): 128 ↛ 129line 128 didn't jump to line 129 because the condition on line 128 was never true

129 msg = f"Use of `utils.{attr}` is deprecated; Use `conf.{replace}` instead!" 

130 warnings.warn(msg, DeprecationWarning, stacklevel=3) 

131 logging.warning(msg, stacklevel=3) 

132 return conf[replace] 

133 

134 if replace := __UTILS_NAME_REPLACEMENT.get(attr): 134 ↛ 135line 134 didn't jump to line 135 because the condition on line 134 was never true

135 msg = f"Use of `utils.{attr}` is deprecated; Use `{replace[0]}` instead!" 

136 warnings.warn(msg, DeprecationWarning, stacklevel=3) 

137 logging.warning(msg, stacklevel=3) 

138 

139 ret = replace[1] 

140 

141 # When this is a string, try to resolve by dynamic import 

142 if isinstance(ret, str): 

143 mod, item, attr = ret.rsplit(".", 2) 

144 mod = __import__(mod, fromlist=(item,)) 

145 item = getattr(mod, item) 

146 ret = getattr(item, attr) 

147 

148 return ret 

149 

150 return super(__import__(__name__).__class__).__getattribute__(attr)