def run(self): current_thread = QtCore.QThread.currentThread() for repo in self.repos: if repo.url and utils.recognized_git_location(repo): # package.xml index = NetworkManager.AM_NETWORK_MANAGER.submit_unmonitored_get( utils.construct_git_url(repo, "package.xml") ) self.requests[index] = ( repo, UpdateMetadataCacheWorker.RequestType.PACKAGE_XML, ) self.total_requests += 1 # metadata.txt index = NetworkManager.AM_NETWORK_MANAGER.submit_unmonitored_get( utils.construct_git_url(repo, "metadata.txt") ) self.requests[index] = ( repo, UpdateMetadataCacheWorker.RequestType.METADATA_TXT, ) self.total_requests += 1 # requirements.txt index = NetworkManager.AM_NETWORK_MANAGER.submit_unmonitored_get( utils.construct_git_url(repo, "requirements.txt") ) self.requests[index] = ( repo, UpdateMetadataCacheWorker.RequestType.REQUIREMENTS_TXT, ) self.total_requests += 1 while self.requests: if current_thread.isInterruptionRequested(): NetworkManager.AM_NETWORK_MANAGER.completed.disconnect( self.download_completed ) for request in self.requests.keys(): NetworkManager.AM_NETWORK_MANAGER.abort(request) return # 50 ms maximum between checks for interruption QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents, 50) # This set contains one copy of each of the repos that got some kind of data in # this process. For those repos, tell the main Addon Manager code that it needs # to update its copy of the repo, and redraw its information. for repo in self.updated_repos: self.package_updated.emit(repo)
def __init__(self, name: str, url: str, status: Status, branch: str): self.name = name.strip() self.display_name = self.name self.url = url.strip() self.branch = branch.strip() self.python2 = False self.obsolete = False self.rejected = False self.repo_type = Addon.Kind.WORKBENCH self.description = None self.tags = set() # Just a cache, loaded from Metadata # To prevent multiple threads from running git actions on this repo at the same time self.git_lock = Lock() # To prevent multiple threads from accessing the status at the same time self.status_lock = Lock() self.set_status(status) from addonmanager_utilities import construct_git_url # The url should never end in ".git", so strip it if it's there parsed_url = urlparse(self.url) if parsed_url.path.endswith(".git"): self.url = (parsed_url.scheme + "://" + parsed_url.netloc + parsed_url.path[:-4]) if parsed_url.query: self.url += "?" + parsed_url.query if parsed_url.fragment: self.url += "#" + parsed_url.fragment if utils.recognized_git_location(self): self.metadata_url = construct_git_url(self, "package.xml") else: self.metadata_url = None self.metadata = None self.icon = None self.cached_icon_filename = "" self.macro = None # Bridge to Gaël Écorchard's macro management class self.updated_timestamp = None self.installed_version = None # Each repo is also a node in a directed dependency graph (referenced by name so # they cen be serialized): self.requires: Set[str] = set() self.blocks: Set[str] = set() # And maintains a list of required and optional Python dependencies from metadata.txt self.python_requires: Set[str] = set() self.python_optional: Set[str] = set()
def test_recognized_git_location(self): recognized_urls = [ "https://github.com/FreeCAD/FreeCAD", "https://gitlab.com/freecad/FreeCAD", "https://framagit.org/freecad/FreeCAD", "https://salsa.debian.org/science-team/freecad", ] for url in recognized_urls: repo = Addon("Test Repo", url, Addon.Status.NOT_INSTALLED, "branch") self.assertTrue(recognized_git_location(repo), f"{url} was unexpectedly not recognized") unrecognized_urls = [ "https://google.com", "https://freecad.org", "https://not.quite.github.com/FreeCAD/FreeCAD", "https://github.com.malware.com/", ] for url in unrecognized_urls: repo = Addon("Test Repo", url, Addon.Status.NOT_INSTALLED, "branch") self.assertFalse(recognized_git_location(repo), f"{url} was unexpectedly recognized")