Coverage for sources/mimeogram/fsprotect/core.py: 96%

23 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-03 00:13 +0000

1# vim: set filetype=python fileencoding=utf-8: 

2# -*- coding: utf-8 -*- 

3 

4#============================================================================# 

5# # 

6# Licensed under the Apache License, Version 2.0 (the "License"); # 

7# you may not use this file except in compliance with the License. # 

8# You may obtain a copy of the License at # 

9# # 

10# http://www.apache.org/licenses/LICENSE-2.0 # 

11# # 

12# Unless required by applicable law or agreed to in writing, software # 

13# distributed under the License is distributed on an "AS IS" BASIS, # 

14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

15# See the License for the specific language governing permissions and # 

16# limitations under the License. # 

17# # 

18#============================================================================# 

19 

20 

21''' Core entities for filesystem protection. ''' 

22 

23 

24from __future__ import annotations 

25 

26from .. import __ 

27 

28 

29class Protector( # pylint: disable=invalid-metaclass 

30 __.typx.Protocol, 

31 metaclass = __.ImmutableStandardProtocolDataclass, 

32 decorators = ( __.standard_dataclass, __.typx.runtime_checkable ), 

33): 

34 ''' Filesystem protection checker. ''' 

35 

36 @__.abc.abstractmethod 

37 def verify( self, path: __.Path ) -> Status: 

38 ''' Verifies if a path should be protected. ''' 

39 raise NotImplementedError 

40 

41 

42class Status( 

43 metaclass = __.ImmutableStandardDataclass, 

44 decorators = ( __.standard_dataclass, ), 

45): 

46 ''' Protection status for location. ''' 

47 

48 path: __.Path 

49 reason: __.typx.Optional[ Reasons ] = None 

50 active: bool = False 

51 

52 def __bool__( self ): return self.active 

53 

54 @property 

55 def description( self ) -> str: 

56 ''' Human-readable description of protection. ''' 

57 if not self.active: return 'Not protected' 

58 return ( 

59 f"Protected: {self.reason.value}" 

60 if self.reason else 'Protected' ) 

61 

62 

63class Reasons( __.enum.Enum ): 

64 ''' Reasons why location may be protected. ''' 

65 

66 Concealment = 'Hidden file or directory' 

67 Credentials = 'Credentials or secrets location' 

68 CustomAddition = 'User-specified custom location' 

69 OsDirectory = 'Operating system directory' 

70 PlatformSensitive = 'Platform-sensitive location' 

71 UserConfiguration = 'User configuration directory' 

72 VersionControl = 'Version control internals'