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>
4This file is part of toktokkie.
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.
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.
16You should have received a copy of the GNU General Public License
17along with toktokkie. If not, see <http://www.gnu.org/licenses/>.
18LICENSE"""
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
31class Updater:
32 """
33 Class that defines the common behaviour of Updaters
34 """
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__)
44 self.metadata = metadata
45 self.args = args
47 update_file = self.update_file(metadata.directory_path)
48 self.config = {} # type: Dict[str, Any]
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)
57 self.validate()
59 @classmethod
60 def name(cls) -> str:
61 """
62 :return: The name of the Updater
63 """
64 raise NotImplementedError()
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 )
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()
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
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)
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
120 def update(self):
121 """
122 Executes the update
123 :return: None
124 """
125 raise NotImplementedError()
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))