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 abc import ABC 

24from typing import Optional, Any, Dict, List 

25from toktokkie.enums import MediaType, IdType 

26from toktokkie.metadata.base.IdHelper import IdHelper 

27 

28 

29class MetadataBase(IdHelper, ABC): 

30 """ 

31 Base class for all metadata classes. Specifies most of the 

32 methods required by Metadata classes. 

33 """ 

34 

35 logger = logging.getLogger(__name__) 

36 """ 

37 Logger for the metadata class 

38 """ 

39 

40 directory_path: str 

41 """ 

42 The path to the directory this metadata describes 

43 """ 

44 

45 json: Dict[str, Any] 

46 

47 @property 

48 def metadata_file(self) -> str: 

49 """ 

50 :return: The path to the metadata file 

51 """ 

52 return os.path.join(self.directory_path, ".meta/info.json") 

53 

54 @property 

55 def icon_directory(self) -> str: 

56 """ 

57 :return: The path to the the icon directory 

58 """ 

59 return os.path.join(self.directory_path, ".meta/icons") 

60 

61 @property 

62 def name(self) -> str: 

63 """ 

64 :return: The name of the media 

65 """ 

66 return os.path.basename(os.path.abspath(self.directory_path)) 

67 

68 @name.setter 

69 def name(self, name: str): 

70 """ 

71 Renames the media directory 

72 :param name: The new name of the media directory 

73 :return: None 

74 """ 

75 new_path = os.path.join(os.path.dirname(self.directory_path), name) 

76 os.rename(self.directory_path, new_path) 

77 self.directory_path = new_path 

78 

79 @property 

80 def tags(self) -> List[str]: 

81 """ 

82 :return: A list of tags 

83 """ 

84 return self.json.get("tags", []) 

85 

86 @tags.setter 

87 def tags(self, tags: List[str]): 

88 """ 

89 Setter method for the tags property 

90 :param tags: The tags to set 

91 :return: None 

92 """ 

93 self.json["tags"] = tags 

94 

95 @property 

96 def ids(self) -> Dict[IdType, List[str]]: 

97 """ 

98 :return: A dictionary containing lists of IDs mapped to ID types 

99 """ 

100 return self.fill_ids( 

101 self.objectify_ids(self.json["ids"]), 

102 self.valid_id_types() 

103 ) 

104 

105 @ids.setter 

106 def ids(self, ids: Dict[IdType, List[str]]): 

107 """ 

108 Setter method for the IDs of the metadata object. 

109 Previous IDs will be overwritten! 

110 :param ids: The IDs to set 

111 :return: None 

112 """ 

113 self.json["ids"] = self.stringify_ids(self.minimize_ids(ids)) 

114 

115 @property 

116 def urls(self) -> Dict[IdType, List[str]]: 

117 """ 

118 Generates URLs for the stored ID types of this metadata object 

119 :return: The URLs mapped to their respective id types 

120 """ 

121 ids = self.ids 

122 urls: Dict[IdType, List[str]] = {x: [] for x in ids.keys()} 

123 

124 for id_type, values in ids.items(): 

125 for value in values: 

126 url = self.generate_url_for_id( 

127 id_type, 

128 self.media_type(), 

129 value 

130 ) 

131 urls[id_type].append(url) 

132 

133 return urls 

134 

135 @classmethod 

136 def media_type(cls) -> MediaType: 

137 """ 

138 :return: The media type of the Metadata class 

139 """ 

140 raise NotImplementedError() # pragma: no cover 

141 

142 @classmethod 

143 def valid_id_types(cls) -> List[IdType]: 

144 """ 

145 :return: Valid ID types for the metadata 

146 """ 

147 raise NotImplementedError() # pragma: no cover 

148 

149 @classmethod 

150 def required_id_types(cls) -> List[IdType]: 

151 """ 

152 :return: Required ID types for the metadata 

153 """ 

154 return [] # pragma: no cover 

155 

156 def __str__(self) -> str: 

157 """ 

158 :return: A string representation of the metadata 

159 """ 

160 json_data = json.dumps( 

161 self.json, 

162 sort_keys=True, 

163 indent=4, 

164 separators=(",", ": ") 

165 ) 

166 return "Name: {}\nMedia Type: {}\nInfo:\n{}".format( 

167 self.name, 

168 self.media_type().name, 

169 json_data 

170 ) 

171 

172 def __eq__(self, other: object) -> bool: 

173 """ 

174 Checks equality with another object 

175 :param other: The other object 

176 :return: True if equal, False otherwise 

177 """ 

178 if not isinstance(other, type(self)): 

179 return False 

180 else: 

181 return self.json == other.json 

182 

183 def write(self): 

184 """ 

185 Writes the metadata to the metadata file 

186 :return: None 

187 """ 

188 self.logger.debug("Writing Metadata: {}".format(self.json)) 

189 

190 if not os.path.isdir(os.path.dirname(self.metadata_file)): 

191 os.makedirs(os.path.dirname(self.metadata_file)) 

192 

193 self.json["type"] = self.media_type().value 

194 

195 with open(self.metadata_file, "w") as f: 

196 f.write(json.dumps( 

197 self.json, 

198 sort_keys=True, 

199 indent=4, 

200 separators=(",", ": ") 

201 )) 

202 

203 def print_folder_icon_source(self): 

204 """ 

205 Prints a message with a URL for possible folder icons on deviantart 

206 :return: None 

207 """ 

208 deviantart = "https://www.deviantart.com" 

209 url = "{}/popular-all-time/?section=&global=1&q={}".format( 

210 deviantart, 

211 "+".join(self.name.split(" ") + ["folder", "icon"]) 

212 ) 

213 print("Search folder icons here:") 

214 print(url) 

215 

216 def set_ids(self, id_type: IdType, ids: List[str]): 

217 """ 

218 Sets IDs for one ID type to the metadata 

219 :param id_type: The id type 

220 :param ids: The IDs to set 

221 :return: None 

222 """ 

223 metadata_ids = self.ids 

224 metadata_ids[id_type] = ids 

225 self.ids = metadata_ids 

226 

227 def get_icon_file(self, name: str) -> Optional[str]: 

228 """ 

229 Retrieves the path to an icon file, if it exists 

230 :param name: The name of the icon. 

231 :return: The path to the icon file or None, if the file does not exist 

232 """ 

233 path = os.path.join(self.icon_directory, "{}.png".format(name)) 

234 if os.path.isfile(path): 

235 return path 

236 else: 

237 return None