2 # Copyright (C) 2018 rubenwardy
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <https://www.gnu.org/licenses/>.
18 import flask, json, os
19 from flask.ext.sqlalchemy import SQLAlchemy
20 from urllib.error import HTTPError
22 from urllib.parse import urlparse, quote_plus
24 from app.models import *
25 from app.tasks import celery, TaskError
26 from app.utils import randomString
29 def __init__(self, url):
32 m = re.search("^\/([^\/]+)\/([^\/]+)\/?$", url.path)
37 repo = m.group(2).replace(".git", "")
38 self.baseUrl = "https://raw.githubusercontent.com/{}/{}/master" \
44 return self.baseUrl is not None
47 return "https://github.com/{}/{}".format(self.user, self.repo)
49 def getIssueTrackerURL(self):
50 return "https://github.com/{}/{}/issues/".format(self.user, self.repo)
52 def getModConfURL(self):
53 return self.baseUrl + "/mod.conf"
56 return self.baseUrl + "/description.txt"
58 def getScreenshotURL(self):
59 return self.baseUrl + "/screenshot.png"
61 def getCommitsURL(self, branch):
62 return "https://api.github.com/repos/{}/{}/commits?sha={}" \
63 .format(self.user, self.repo, urllib.parse.quote_plus(branch))
65 def getCommitDownload(self, commit):
66 return "https://github.com/{}/{}/archive/{}.zip" \
67 .format(self.user, self.repo, commit)
70 krock_list_cache = None
71 krock_list_cache_by_name = None
73 global krock_list_cache
74 global krock_list_cache_by_name
76 if krock_list_cache is None:
77 contents = urllib.request.urlopen("http://krock-works.16mb.com/MTstuff/modList.php").read().decode("utf-8")
78 list = json.loads(contents)
81 if not ("title" in x and "author" in x and \
82 "topicId" in x and "link" in x and x["link"] != ""):
86 m = re.search("\[([A-Za-z0-9_]+)\]", x["title"])
90 x["name"] = m.group(1)
96 "author": x["author"],
98 "topicId": x["topicId"],
102 krock_list_cache = [g(x) for x in list if h(x)]
103 krock_list_cache_by_name = {}
104 for x in krock_list_cache:
105 if not x["name"] in krock_list_cache_by_name:
106 krock_list_cache_by_name[x["name"]] = []
108 krock_list_cache_by_name[x["name"]].append(x)
110 return krock_list_cache, krock_list_cache_by_name
112 def findModInfo(author, name, link):
113 list, lookup = getKrockList()
115 if name is not None and name in lookup:
116 if len(lookup[name]) == 1:
117 return lookup[name][0]
119 for x in lookup[name]:
120 if x["author"] == author:
123 if link is not None and len(link) > 15:
125 if link in x["link"]:
131 def parseConf(string):
133 for line in string.split("\n"):
136 key = line[:idx].strip()
137 value = line[idx+1:].strip()
144 def getMeta(urlstr, author):
145 url = urlparse(urlstr)
148 if url.netloc == "github.com":
149 urlmaker = GithubURLMaker(url)
151 raise TaskError("Unsupported repo")
153 if not urlmaker.isValid():
154 raise TaskError("Error! Url maker not valid")
158 result["repo"] = urlmaker.getRepoURL()
159 result["issueTracker"] = urlmaker.getIssueTrackerURL()
162 contents = urllib.request.urlopen(urlmaker.getModConfURL()).read().decode("utf-8")
163 conf = parseConf(contents)
164 for key in ["name", "description", "title"]:
166 result[key] = conf[key]
170 print("mod.conf does not exist")
173 result["title"] = result["name"].replace("_", " ").title()
175 if not "description" in result:
177 contents = urllib.request.urlopen(urlmaker.getDescURL()).read().decode("utf-8")
178 result["description"] = contents.strip()
180 print("description.txt does not exist!")
182 if "description" in result:
183 desc = result["description"]
184 idx = desc.find(".") + 1
185 cutIdx = min(len(desc), 200 if idx < 5 else idx)
186 result["short_description"] = desc[:cutIdx]
188 info = findModInfo(author, result.get("name"), result["repo"])
190 result["forumId"] = info.get("topicId")
196 def makeVCSRelease(id, branch):
197 release = PackageRelease.query.get(id)
200 raise TaskError("No such release!")
202 if release.package is None:
203 raise TaskError("No package attached to release")
205 url = urlparse(release.package.repo)
208 if url.netloc == "github.com":
209 urlmaker = GithubURLMaker(url)
211 raise TaskError("Unsupported repo")
213 if not urlmaker.isValid():
214 raise TaskError("Invalid github repo URL")
216 commitsURL = urlmaker.getCommitsURL(branch)
217 contents = urllib.request.urlopen(commitsURL).read().decode("utf-8")
218 commits = json.loads(contents)
220 if len(commits) == 0 or not "sha" in commits[0]:
221 raise TaskError("No commits found")
223 release.url = urlmaker.getCommitDownload(commits[0]["sha"])
225 release.task_id = None
232 def importRepoScreenshot(id):
233 package = Package.query.get(id)
235 raise Exception("Unexpected none package")
238 url = urlparse(package.repo)
240 if url.netloc == "github.com":
241 urlmaker = GithubURLMaker(url)
243 raise TaskError("Unsupported repo")
245 if not urlmaker.isValid():
246 raise TaskError("Error! Url maker not valid")
249 filename = randomString(10) + ".png"
250 imagePath = os.path.join(app.config["UPLOAD_FOLDER"], filename)
252 urllib.request.urlretrieve(urlmaker.getScreenshotURL(), imagePath)
254 ss = PackageScreenshot()
256 ss.title = "screenshot.png"
257 ss.url = "/uploads/" + filename
261 return "/uploads/" + filename
263 print("screenshot.png does not exist")