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 

20from typing import List, Dict, Any, Optional, Set 

21from puffotter.prompt import prompt 

22from xdcc_dl.xdcc import download_packs 

23from xdcc_dl.pack_search.SearchEngine import SearchEngineType, SearchEngine 

24from xdcc_dl.entities.XDCCPack import XDCCPack 

25from toktokkie.metadata.base.Metadata import Metadata 

26from toktokkie.utils.update.TvUpdater import TvUpdater, DownloadInstructions 

27 

28 

29class XDCCUpdater(TvUpdater): 

30 """ 

31 Class that handles the configuration and execution of an xdcc update 

32 """ 

33 

34 @classmethod 

35 def name(cls) -> str: 

36 """ 

37 :return: The name of the Updater 

38 """ 

39 return "xdcc" 

40 

41 @classmethod 

42 def search_engine_names(cls) -> Set[str]: 

43 """ 

44 :return: The names of applicable search engines 

45 """ 

46 return SearchEngineType.choices() 

47 

48 @classmethod 

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

50 """ 

51 :return: Optional JSON schema for a configuration file 

52 """ 

53 schema = super().json_schema() 

54 assert schema is not None 

55 schema["properties"]["bot"] = {"type": "string"} 

56 schema["required"].append("bot") 

57 return schema 

58 

59 @property 

60 def search_engine(self) -> SearchEngine: 

61 """ 

62 :return: The search engine to use 

63 """ 

64 return SearchEngineType.resolve(self.config["search_engine"]) 

65 

66 @classmethod 

67 def predefined_patterns(cls) -> Dict[str, str]: 

68 """ 

69 :return: Predefined search patterns for this updater 

70 """ 

71 return { 

72 "horriblesubs": "[HorribleSubs] @{NAME} - @{EPI-2} [@{RES-P}].mkv", 

73 "subsplease": "[SubsPlease] @{NAME} - @{EPI-2} " 

74 "(@{RES-P}) [@{HASH}].mkv" 

75 } 

76 

77 def perform_search(self, search_term: str, search_regex: str) -> List[Any]: 

78 """ 

79 Performs a search using the selected search engine 

80 :param search_term: The term to search for 

81 :param search_regex: The expected regex 

82 :return: The search results 

83 """ 

84 search_results = super().perform_search(search_term, search_regex) 

85 search_results = [ 

86 x for x in search_results if x.bot == self.bot 

87 ] 

88 return search_results 

89 

90 @property 

91 def bot(self) -> str: 

92 """ 

93 :return: The bot to use for updating 

94 """ 

95 return self.config["bot"] 

96 

97 @classmethod 

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

99 """ 

100 Prompts the user for information to create a config file 

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

102 updater config file 

103 :return: The configuration JSON data 

104 """ 

105 json_data = super()._prompt(metadata) 

106 assert json_data is not None 

107 json_data["bot"] = prompt("Bot", default="CR-HOLLAND|NEW") 

108 return json_data 

109 

110 def download(self, download_instructions: List[DownloadInstructions]): 

111 """ 

112 Performs a download 

113 :param download_instructions: The download instrcutions 

114 :return: None 

115 """ 

116 packs = [] 

117 for instructions in download_instructions: 

118 pack: XDCCPack = instructions.search_result 

119 pack.set_directory(instructions.directory) 

120 pack.set_filename(instructions.filename, True) 

121 pack.set_original_filename( 

122 pack.original_filename.replace("'", "_") 

123 ) # Fixes filenames 

124 packs.append(pack) 

125 

126 download_packs( 

127 packs, 

128 timeout=self.args["timeout"], 

129 throttle=self.args["throttle"] 

130 )