kapsikkum-unmanic – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3  
4 """
5 unmanic.plugins_api.py
6  
7 Written by: Josh.5 <jsunnex@gmail.com>
8 Date: 03 Mar 2021, (12:10 PM)
9  
10 Copyright:
11 Copyright (C) Josh Sunnex - All Rights Reserved
12  
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19  
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22  
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
27 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
28 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
29 OR OTHER DEALINGS IN THE SOFTWARE.
30  
31 """
32 import hashlib
33 import json
34 import tornado.log
35  
36 from unmanic.libs.plugins import PluginsHandler
37 from unmanic.libs.uiserver import UnmanicDataQueues
38 from unmanic.libs.unplugins import PluginExecutor
39 from unmanic.webserver.api_v1.base_api_handler import BaseApiHandler
40  
41  
42 class ApiPluginsHandler(BaseApiHandler):
43 name = None
44 params = None
45 unmanic_data_queues = None
46  
47 routes = [
48 {
49 "supported_methods": ["GET"],
50 "call_method": "get_plugin_list",
51 "path_pattern": r"/api/v1/plugins/list",
52 },
53 {
54 "supported_methods": ["POST"],
55 "call_method": "install_plugin_by_id",
56 "path_pattern": r"/api/v1/plugins/install",
57 },
58 {
59 "supported_methods": ["GET"],
60 "call_method": "get_repo_list",
61 "path_pattern": r"/api/v1/plugins/repos/list",
62 },
63 {
64 "supported_methods": ["POST"],
65 "call_method": "update_repo_list",
66 "path_pattern": r"/api/v1/plugins/repos/update",
67 },
68 {
69 "supported_methods": ["GET"],
70 "call_method": "update_repos",
71 "path_pattern": r"/api/v1/plugins/repos/fetch",
72 },
73 ]
74  
75 def initialize(self, **kwargs):
76 self.name = 'plugins_api'
77 self.params = kwargs.get("params")
78 udq = UnmanicDataQueues()
79 self.unmanic_data_queues = udq.get_unmanic_data_queues()
80  
81 def set_default_headers(self):
82 """Set the default response header to be JSON."""
83 self.set_header("Content-Type", 'application/json; charset="utf-8"')
84  
85 def get(self, path):
86 self.action_route()
87  
88 def post(self, path):
89 self.action_route()
90  
91 def prepare_filtered_plugins(self, request_dict):
92 """
93 Returns a object of records filtered and sorted
94 according to the provided request.
95  
96 :param request_dict:
97 :return:
98 """
99  
100 # Generate filters for query
101 start = request_dict.get('start')
102 length = request_dict.get('length')
103  
104 search = request_dict.get('search')
105 search_value = search.get("value")
106  
107 # Force sort order always by ID desc
108 order = [
109 {
110 "column": 'name',
111 "dir": 'asc',
112 }
113 ]
114  
115 # Fetch Plugins
116 plugins = PluginsHandler()
117 # Get total count
118 records_total_count = plugins.get_total_plugin_list_count()
119 # Get quantity after filters (without pagination)
120 records_filtered_count = plugins.get_plugin_list_filtered_and_sorted(order=order, start=0, length=0,
121 search_value=search_value).count()
122 # Get filtered/sorted results
123 plugin_results = plugins.get_plugin_list_filtered_and_sorted(order=order, start=start, length=length,
124 search_value=search_value)
125  
126 # Build return data
127 return_data = {
128 "draw": request_dict.get('draw'),
129 "recordsTotal": records_total_count,
130 "recordsFiltered": records_filtered_count,
131 "successCount": 0,
132 "failedCount": 0,
133 "data": []
134 }
135  
136 # Iterate over plugins and append them to the plugin data
137 for plugin_result in plugin_results:
138 # Set plugin status
139 plugin_status = {
140 "enabled": plugin_result.get('enabled'),
141 "update_available": plugin_result.get('update_available'),
142 }
143 # Set params as required in template
144 item = {
145 'id': plugin_result.get('id'),
146 'plugin_id': plugin_result.get('plugin_id'),
147 'icon': plugin_result.get('icon'),
148 'name': plugin_result.get('name'),
149 'description': plugin_result.get('description'),
150 'tags': plugin_result.get('tags'),
151 'author': plugin_result.get('author'),
152 'version': plugin_result.get('version'),
153 'status': plugin_status,
154 'selected': False,
155 }
156 return_data["data"].append(item)
157  
158 # Return results
159 return return_data
160  
161 def update_repo_list(self, *args, **kwargs):
162 repos_list = self.get_argument('repos_list')
163  
164 if repos_list:
165 repos_list = repos_list.splitlines()
166  
167 try:
168 plugins = PluginsHandler()
169 plugins.set_plugin_repos(repos_list)
170 except Exception as e:
171 tornado.log.app_log.exception("Exception in updating repo list - {}".format(str(e)), exc_info=True)
172  
173 self.get_repo_list()
174  
175 def get_repo_list(self):
176 try:
177 plugins = PluginsHandler()
178 # Fetch the data again from the database
179 current_repos = plugins.get_plugin_repos()
180  
181 # Remove the default plugin repo from the list
182 return_repos = []
183 default_repo = plugins.get_default_repo()
184 for repo in current_repos:
185 if not repo.get("path").startswith(default_repo):
186 return_repos.append(repo)
187  
188 # Return success
189 self.write(json.dumps({"success": True, "repos": return_repos}))
190 except Exception as e:
191 tornado.log.app_log.exception("Exception in fetching the current repo list - {}".format(str(e)), exc_info=True)
192  
193 # Return failure
194 self.write(json.dumps({"success": False}))
195  
196 def update_repos(self, *args, **kwargs):
197 plugins = PluginsHandler()
198 if plugins.update_plugin_repos():
199 # Return success
200 self.write(json.dumps({"success": True}))
201 else:
202 # Return failure
203 self.write(json.dumps({"success": False}))
204  
205 def get_plugin_list(self, *args, **kwargs):
206 plugins = PluginsHandler()
207 # Fetch a list of plugin data cached locally
208 plugin_list = plugins.get_installable_plugins_list()
209 self.write(json.dumps({"success": True, "plugins": plugin_list}))
210  
211 def install_plugin_by_id(self, *args, **kwargs):
212 plugin_id = self.get_argument('plugin_id')
213  
214 # Fetch a list of plugin data cached locally
215 plugins = PluginsHandler()
216 success = plugins.install_plugin_by_id(plugin_id)
217  
218 if success:
219 # Return success
220 self.write(json.dumps({"success": True}))
221 else:
222 # Return failure
223 self.write(json.dumps({"success": False}))
224  
225 def __get_plugin_changelog(self, plugin_id):
226 """
227 Given a plugin ID , return a list of lines read from the plugin's changelog
228  
229 :param plugin_id:
230 :return:
231 """
232 # Fetch plugin changelog
233 plugin_executor = PluginExecutor()
234 return plugin_executor.get_plugin_changelog(plugin_id)
235  
236 def __get_plugin_long_description(self, plugin_id):
237 """
238 Given a plugin ID , return a list of lines read from the plugin's changelog
239  
240 :param plugin_id:
241 :return:
242 """
243 # Fetch plugin changelog
244 plugin_executor = PluginExecutor()
245 return plugin_executor.get_plugin_long_description(plugin_id)