Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1"""LICENSE 

2Copyright 2015 Hermann Krumrey <hermann@krumreyh.com> 

3 

4This file is part of toktokkie. 

5 

6toktokkie is free software: you can redistribute it and/or modify 

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

8the Free Software Foundation, either version 3 of the License, or 

9(at your option) any later version. 

10 

11toktokkie is distributed in the hope that it will be useful, 

12but WITHOUT ANY WARRANTY; without even the implied warranty of 

13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

14GNU General Public License for more details. 

15 

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

17along with toktokkie. If not, see <http://www.gnu.org/licenses/>. 

18LICENSE""" 

19 

20import os 

21import json 

22import logging 

23from typing import Dict, Any, List, Optional 

24from jsonschema import validate, ValidationError 

25from toktokkie.metadata.base.Metadata import Metadata 

26from toktokkie.enums import MediaType 

27from toktokkie.exceptions import InvalidUpdateInstructions, \ 

28 MissingUpdateInstructions 

29 

30 

31class Updater: 

32 """ 

33 Class that defines the common behaviour of Updaters 

34 """ 

35 

36 def __init__(self, metadata: Metadata, args: Dict[str, Any]): 

37 """ 

38 Initializes the Updater object 

39 :param metadata: The metadata belonging to the media to update 

40 :param args: The command line arguments used to configure the Updater 

41 """ 

42 self.logger = logging.getLogger(self.__class__.__name__) 

43 

44 self.metadata = metadata 

45 self.args = args 

46 

47 update_file = self.update_file(metadata.directory_path) 

48 self.config = {} # type: Dict[str, Any] 

49 

50 if self.json_schema() is not None: 

51 if os.path.isfile(update_file): 

52 with open(update_file, "r") as f: 

53 self.config = json.load(f) 

54 else: 

55 raise MissingUpdateInstructions(self.update_file) 

56 

57 self.validate() 

58 

59 @classmethod 

60 def name(cls) -> str: 

61 """ 

62 :return: The name of the Updater 

63 """ 

64 raise NotImplementedError() 

65 

66 @classmethod 

67 def update_file(cls, meta_dir: str) -> str: 

68 """ 

69 Generates the path to the update file 

70 :param meta_dir: The meta directory 

71 :return: 

72 """ 

73 return os.path.join( 

74 meta_dir, 

75 ".meta/{}_update.json".format(cls.name()) 

76 ) 

77 

78 @classmethod 

79 def applicable_media_types(cls) -> List[MediaType]: 

80 """ 

81 :return: A list of media type with which the updater can be used with 

82 """ 

83 raise NotImplementedError() 

84 

85 @classmethod 

86 def json_schema(cls) -> Optional[Dict[str, Any]]: 

87 """ 

88 :return: Optional JSON schema for a configuration file 

89 """ 

90 return None 

91 

92 @classmethod 

93 def prompt(cls, metadata: Metadata): 

94 """ 

95 Prompts the user for information to create a config file 

96 :param metadata: The metadata of the media for which to create an 

97 updater config file 

98 :return: None 

99 """ 

100 config = cls._prompt(metadata) 

101 if config is not None: 

102 with open(cls.update_file(metadata.directory_path), "w") as f: 

103 json.dump(config, f, indent=4) 

104 

105 # noinspection PyUnusedLocal 

106 @classmethod 

107 def _prompt(cls, metadata: Metadata) -> Optional[Dict[str, Any]]: 

108 """ 

109 Prompts the user for information to create a config file 

110 This method is meant to be overridden by subclasses 

111 :param metadata: The metadata of the media for which to create an 

112 updater config file 

113 :return: The configuration JSON data 

114 """ 

115 logging.getLogger(__name__).warning( 

116 "This Updater does not support update config files" 

117 ) 

118 return None 

119 

120 def update(self): 

121 """ 

122 Executes the update 

123 :return: None 

124 """ 

125 raise NotImplementedError() 

126 

127 def validate(self): 

128 """ 

129 Checks if the configuration is valid 

130 :return: None 

131 """ 

132 if self.json_schema() is not None: 

133 try: 

134 validate(instance=self.config, schema=self.json_schema()) 

135 except ValidationError as e: 

136 raise InvalidUpdateInstructions(str(e))