Skip to content

Commit

Permalink
AddonManager: Provisions to support different git hosting platforms t…
Browse files Browse the repository at this point in the history
…han github
  • Loading branch information
yorikvanhavre committed Jul 10, 2019
1 parent b51bf9a commit 3342225
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 34 deletions.
16 changes: 6 additions & 10 deletions src/Mod/AddonManager/AddonManager.py
Expand Up @@ -44,12 +44,8 @@
import sys
import tempfile

from addonmanager_utilities import translate
from addonmanager_utilities import update_macro_details
from addonmanager_utilities import install_macro
from addonmanager_utilities import remove_macro
from addonmanager_utilities import remove_directory_if_empty
from addonmanager_utilities import restartFreeCAD
import addonmanager_utilities as utils
from addonmanager_utilities import translate # this needs to be as is for pylupdate
from addonmanager_workers import *

def QT_TRANSLATE_NOOP(ctx,txt):
Expand Down Expand Up @@ -194,7 +190,7 @@ def reject(self):
if ret == m.Ok:
shutil.rmtree(self.macro_repo_dir,onerror=self.remove_readonly)
# restart FreeCAD after a delay to give time to this dialog to close
QtCore.QTimer.singleShot(1000,restartFreeCAD)
QtCore.QTimer.singleShot(1000,utils.restartFreeCAD)
try:
shutil.rmtree(self.macro_repo_dir,onerror=self.remove_readonly)
except:
Expand Down Expand Up @@ -359,7 +355,7 @@ def add_macro(self, macro):
if macro in self.macros:
# The macro is already in the list of macros.
old_macro = self.macros[self.macros.index(macro)]
update_macro_details(old_macro, macro)
utils.update_macro_details(old_macro, macro)
else:
from PySide import QtGui
self.macros.append(macro)
Expand Down Expand Up @@ -402,7 +398,7 @@ def install(self,repos=None):
elif self.dialog.tabWidget.currentIndex() == 1:
# Tab "Macros".
macro = self.macros[self.dialog.listMacros.currentRow()]
if install_macro(macro, self.macro_repo_dir):
if utils.install_macro(macro, self.macro_repo_dir):
self.dialog.description.setText(translate("AddonsInstaller", "Macro successfully installed. The macro is now available from the Macros dialog."))
else:
self.dialog.description.setText(translate("AddonsInstaller", "Unable to install"))
Expand Down Expand Up @@ -474,7 +470,7 @@ def remove(self):
elif self.dialog.tabWidget.currentIndex() == 1:
# Tab "Macros".
macro = self.macros[self.dialog.listMacros.currentRow()]
if remove_macro(macro):
if utils.remove_macro(macro):
self.dialog.description.setText(translate('AddonsInstaller', 'Macro successfully removed.'))
else:
self.dialog.description.setText(translate('AddonsInstaller', 'Macro could not be removed.'))
Expand Down
55 changes: 55 additions & 0 deletions src/Mod/AddonManager/addonmanager_utilities.py
Expand Up @@ -233,3 +233,58 @@ def restartFreeCAD():
if FreeCADGui.getMainWindow().close():
QtCore.QProcess.startDetached(QtGui.QApplication.applicationFilePath(),args)


def getzipurl(baseurl):

"Returns the location of a zip file from a repo, if available"

url = getserver(baseurl).strip("/")
if url.endswith("github.com"):
return baseurl+"/archive/master.zip"
elif url.endswith("framagit.org"):
# https://framagit.org/freecad-france/mooc-workbench/-/archive/master/mooc-workbench-master.zip
reponame = baseurl.strip("/").split("/")[-1]
return baseurl+"/-/archive/master/"+reponame+"-master.zip"
else:
print("Debug: addonmanager_utilities.getzipurl: Unknown git host:",url)
return None


def getreadmeurl(baseurl):

"Returns the location of a readme file"

url = getserver(baseurl).strip("/")
if url.endswith("github.com") or url.endswith("framagit.org"):
return baseurl+"/blob/master/README.md"
else:
print("Debug: addonmanager_utilities.getreadmeurl: Unknown git host:",url)
return None


def getreadmeregex(baseurl):

"""Return a regex string that extracts the contents to be displayed in the description
panel of the Addon manager, from raw HTML data (the readme's html rendering usually)"""

url = getserver(baseurl).strip("/")
if url.endswith("github.com"):
return "<article.*?>(.*?)</article>"
elif url.endswith("framagit.org"):
return None # the readme content on framagit is generated by javascript so unretrievable by urlopen
else:
print("Debug: addonmanager_utilities.getreadmeregex: Unknown git host:",url)
return None


def getdescregex(baseurl):

"""Returns a regex string that extracts a WB description to be displayed in the description
panel of the Addon manager, if the README could not be found"""

url = getserver(baseurl).strip("/")
if url.endswith("github.com") or url.endswith("framagit.org"):
return "<meta property=\"og:description\" content=\"(.*?)\""
else:
print("Debug: addonmanager_utilities.getdescregex: Unknown git host:",url)
return None
55 changes: 31 additions & 24 deletions src/Mod/AddonManager/addonmanager_workers.py
Expand Up @@ -31,11 +31,9 @@

from PySide import QtCore

import addonmanager_utilities as utils
from addonmanager_utilities import translate # this needs to be as is for pylupdate
from addonmanager_macro import Macro
from addonmanager_utilities import urlopen
from addonmanager_utilities import translate
from addonmanager_utilities import symlink
from addonmanager_utilities import getserver

MACROS_BLACKLIST = ["BOLTS","WorkFeatures","how to install","PartsLibrary","FCGear"]
OBSOLETE = ["assembly2","drawing_dimensioning","cura_engine"] # These addons will print an additional message informing the user
Expand Down Expand Up @@ -65,7 +63,7 @@ def run(self):
"populates the list of addons"

self.progressbar_show.emit(True)
u = urlopen("https://github.com/FreeCAD/FreeCAD-addons")
u = utils.urlopen("https://github.com/FreeCAD/FreeCAD-addons")
if not u:
self.progressbar_show.emit(False)
self.done.emit()
Expand Down Expand Up @@ -134,7 +132,7 @@ def run(self):
i = 0
for repo in self.repos:
url = repo[1]
u = urlopen(url)
u = utils.urlopen(url)
if not u:
self.stop = True
return
Expand Down Expand Up @@ -275,7 +273,7 @@ def retrieve_macros_from_wiki(self):

self.info_label_signal.emit("Downloading list of macros from the FreeCAD wiki...")
self.progressbar_show.emit(True)
u = urlopen("https://www.freecadweb.org/wiki/Macros_recipes")
u = utils.urlopen("https://www.freecadweb.org/wiki/Macros_recipes")
if not u:
return
p = u.read()
Expand Down Expand Up @@ -319,20 +317,25 @@ def run(self):
self.info_label.emit(translate("AddonsInstaller", "Retrieving info from") + ' ' + str(url))
desc = ""
# get the README if possible
u = urlopen(url+"/blob/master/README.md")
readmeurl = utils.getreadmeurl(url)
if not readmeurl:
print("Debug: README not found for",url)
u = utils.urlopen(readmeurl)
if not u:
u = urlopen(url+"/blob/master/Readme.md")
print("Debug: README not found at",readmeurl)
if u:
p = u.read()
if sys.version_info.major >= 3 and isinstance(p, bytes):
p = p.decode("utf-8")
u.close()
readme = re.findall("<article.*?>(.*?)</article>",p,flags=re.MULTILINE|re.DOTALL)
if readme:
desc += readme[0]
readmeregex = utils.getreadmeregex(url)
if readmeregex:
readme = re.findall(readmeregex,p,flags=re.MULTILINE|re.DOTALL)
if readme:
desc += readme[0]
else:
# fall back to the description text
u = urlopen(url)
u = utils.urlopen(url)
if not u:
self.progressbar_show.emit(False)
self.stop = True
Expand All @@ -341,9 +344,11 @@ def run(self):
if sys.version_info.major >= 3 and isinstance(p, bytes):
p = p.decode("utf-8")
u.close()
desc = re.findall("<meta property=\"og:description\" content=\"(.*?)\"",p)
if desc:
desc = desc[0]
descregex = utils.getdescregex(url)
if descregex:
desc = re.findall(descregex,p)
if desc:
desc = desc[0]
if not desc:
desc = "Unable to retrieve addon description"
self.repos[self.idx].append(desc)
Expand Down Expand Up @@ -414,7 +419,7 @@ def loadImages(self,message,url,wbName):
# remove everything after the ?
path = path.split("?")[0]
if not path.startswith("http"):
path = getserver(url) + path
path = utils.getserver(url) + path
name = path.split("/")[-1]
if name and path.startswith("http"):
storename = os.path.join(store,name)
Expand All @@ -423,7 +428,7 @@ def loadImages(self,message,url,wbName):
storename = os.path.join(store,wbName+name[-remainChars:])
if not os.path.exists(storename):
try:
u = urlopen(path)
u = utils.urlopen(path)
imagedata = u.read()
u.close()
except:
Expand Down Expand Up @@ -595,7 +600,7 @@ def run(self):
for f in os.listdir(clonedir):
if f.lower().endswith(".fcmacro"):
print("copying macro:",f)
symlink(os.path.join(clonedir, f), os.path.join(macro_dir, f))
utils.symlink(os.path.join(clonedir, f), os.path.join(macro_dir, f))
FreeCAD.ParamGet('User parameter:Plugins/'+self.repos[idx][0]).SetString("destination",clonedir)
answer += "\n\n"+translate("AddonsInstaller", "A macro has been installed and is available under Macro -> Macros menu")+":"
answer += "\n<b>" + f + "</b>"
Expand All @@ -615,7 +620,7 @@ def checkDependencies(self,baseurl):
if not depsurl.endswith("/"):
depsurl += "/"
depsurl += "master/metadata.txt"
mu = urlopen(depsurl)
mu = utils.urlopen(depsurl)
if mu:
# metadata.txt found
depsfile = mu.read()
Expand Down Expand Up @@ -659,9 +664,9 @@ def checkDependencies(self,baseurl):
message += translate("AddonsInstaller","Please install the missing components first.")
return ok, message

def download(self,giturl,clonedir):
def download(self,baseurl,clonedir):

"downloads and unzip from github"
"downloads and unzip a zip version from a git repo"

import zipfile
bakdir = None
Expand All @@ -671,10 +676,12 @@ def download(self,giturl,clonedir):
shutil.rmtree(bakdir)
os.rename(clonedir,bakdir)
os.makedirs(clonedir)
zipurl = giturl+"/archive/master.zip"
zipurl = utils.getzipurl(baseurl)
if not zipurl:
return translate("AddonsInstaller", "Error: Unable to locate zip from") + " " + baseurl
try:
print("Downloading "+zipurl)
u = urlopen(zipurl)
u = utils.urlopen(zipurl)
except:
return translate("AddonsInstaller", "Error: Unable to download") + " " + zipurl
if not u:
Expand Down

0 comments on commit 3342225

Please sign in to comment.