Coverage for adhoc-cicd-odoo-odoo / odoo / tools / osutil.py: 16%

44 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-09 18:22 +0000

1# -*- coding: utf-8 -*- 

2# Part of Odoo. See LICENSE file for full copyright and licensing details. 

3 

4""" 

5Some functions related to the os and os.path module 

6""" 

7import os 

8import re 

9import zipfile 

10 

11 

12WINDOWS_RESERVED = re.compile(r''' 

13 ^ 

14 # forbidden stems: reserved keywords 

15 (:?CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9]) 

16 # even with an extension this is recommended against 

17 (:?\..*)? 

18 $ 

19''', flags=re.IGNORECASE | re.VERBOSE) 

20def clean_filename(name, replacement=''): 

21 """ Strips or replaces possibly problematic or annoying characters our of 

22 the input string, in order to make it a valid filename in most operating 

23 systems (including dropping reserved Windows filenames). 

24 

25 If this results in an empty string, results in "Untitled" (localized). 

26 

27 Allows: 

28 

29 * any alphanumeric character (unicode) 

30 * underscore (_) as that's innocuous 

31 * dot (.) except in leading position to avoid creating dotfiles 

32 * dash (-) except in leading position to avoid annoyance / confusion with 

33 command options 

34 * brackets ([ and ]), while they correspond to shell *character class* 

35 they're a common way to mark / tag files especially on windows 

36 * parenthesis ("(" and ")"), a more natural though less common version of 

37 the former 

38 * space (" ") 

39 

40 :param str name: file name to clean up 

41 :param str replacement: 

42 replacement string to use for sequences of problematic input, by default 

43 an empty string to remove them entirely, each contiguous sequence of 

44 problems is replaced by a single replacement 

45 :rtype: str 

46 """ 

47 if WINDOWS_RESERVED.match(name): 

48 return "Untitled" 

49 return re.sub(r'[^\w_.()\[\] -]+', replacement, name).lstrip('.-') or "Untitled" 

50 

51def zip_dir(path, stream, include_dir=True, fnct_sort=None): # TODO add ignore list 

52 """ 

53 : param fnct_sort : Function to be passed to "key" parameter of built-in 

54 python sorted() to provide flexibility of sorting files 

55 inside ZIP archive according to specific requirements. 

56 """ 

57 path = os.path.normpath(path) 

58 len_prefix = len(os.path.dirname(path)) if include_dir else len(path) 

59 if len_prefix: 

60 len_prefix += 1 

61 

62 dir_root_path = os.path.realpath(path) 

63 with zipfile.ZipFile(stream, 'w', compression=zipfile.ZIP_DEFLATED, allowZip64=True) as zipf: 

64 for dirpath, _dirnames, filenames in os.walk(path): 

65 filenames = sorted(filenames, key=fnct_sort) 

66 for fname in filenames: 

67 bname, ext = os.path.splitext(fname) 

68 ext = ext or bname 

69 if ext not in ['.pyc', '.pyo', '.swp', '.DS_Store']: 

70 fpath = os.path.normpath(os.path.join(dirpath, fname)) 

71 real_fpath = os.path.realpath(fpath) 

72 if os.path.isfile(real_fpath) and os.path.commonpath([dir_root_path, real_fpath]) == dir_root_path: 

73 zipf.write(real_fpath, fpath[len_prefix:]) 

74 

75 

76if os.name != 'nt': 76 ↛ 79line 76 didn't jump to line 79 because the condition on line 76 was always true

77 is_running_as_nt_service = lambda: False 

78else: 

79 import win32service as ws 

80 import win32serviceutil as wsu 

81 

82 from contextlib import contextmanager 

83 from odoo.release import nt_service_name 

84 

85 def is_running_as_nt_service(): 

86 @contextmanager 

87 def close_srv(srv): 

88 try: 

89 yield srv 

90 finally: 

91 ws.CloseServiceHandle(srv) 

92 

93 try: 

94 with close_srv(ws.OpenSCManager(None, None, ws.SC_MANAGER_ALL_ACCESS)) as hscm: 

95 with close_srv(wsu.SmartOpenService(hscm, nt_service_name, ws.SERVICE_ALL_ACCESS)) as hs: 

96 info = ws.QueryServiceStatusEx(hs) 

97 return info['ProcessId'] == os.getppid() 

98 except Exception: 

99 return False