mirror of
https://github.com/minetest/contentdb.git
synced 2024-12-23 14:32:25 +01:00
Fix issues with Package sets by adding a PackageSet class
This commit is contained in:
parent
7fdd2cc7c9
commit
2d54fe4ed7
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from typing import List, Dict
|
from typing import List, Dict, Optional, Iterator, Iterable
|
||||||
|
|
||||||
from app.logic.LogicError import LogicError
|
from app.logic.LogicError import LogicError
|
||||||
from app.models import Package, MetaPackage, PackageType, PackageState, PackageGameSupport, db
|
from app.models import Package, MetaPackage, PackageType, PackageState, PackageGameSupport, db
|
||||||
@ -54,13 +54,40 @@ mtg_mod_blacklist = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class PackageSet:
|
||||||
|
packages: Dict[str, Package]
|
||||||
|
|
||||||
|
def __init__(self, packages: Optional[Iterable[Package]] = None):
|
||||||
|
self.packages = {}
|
||||||
|
if packages:
|
||||||
|
self.update(packages)
|
||||||
|
|
||||||
|
def update(self, packages: Iterable[Package]):
|
||||||
|
for package in packages:
|
||||||
|
key = package.getId()
|
||||||
|
if key not in self.packages:
|
||||||
|
self.packages[key] = package
|
||||||
|
|
||||||
|
def intersection_update(self, other):
|
||||||
|
keys = set(self.packages.keys())
|
||||||
|
keys.difference_update(set(other.packages.keys()))
|
||||||
|
for key in keys:
|
||||||
|
del self.packages[key]
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.packages)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return self.packages.values().__iter__()
|
||||||
|
|
||||||
|
|
||||||
class GameSupportResolver:
|
class GameSupportResolver:
|
||||||
checked_packages = set()
|
checked_packages = set()
|
||||||
checked_metapackages = set()
|
checked_metapackages = set()
|
||||||
resolved_packages = {}
|
resolved_packages: Dict[str, PackageSet] = {}
|
||||||
resolved_metapackages = {}
|
resolved_metapackages: Dict[str, PackageSet] = {}
|
||||||
|
|
||||||
def resolve_for_meta_package(self, meta: MetaPackage, history: List[str]) -> set[Package]:
|
def resolve_for_meta_package(self, meta: MetaPackage, history: List[str]) -> PackageSet:
|
||||||
print(f"Resolving for {meta.name}", file=sys.stderr)
|
print(f"Resolving for {meta.name}", file=sys.stderr)
|
||||||
|
|
||||||
key = meta.name
|
key = meta.name
|
||||||
@ -69,11 +96,11 @@ class GameSupportResolver:
|
|||||||
|
|
||||||
if key in self.checked_metapackages:
|
if key in self.checked_metapackages:
|
||||||
print(f"Error, cycle found: {','.join(history)}", file=sys.stderr)
|
print(f"Error, cycle found: {','.join(history)}", file=sys.stderr)
|
||||||
return set()
|
return PackageSet()
|
||||||
|
|
||||||
self.checked_metapackages.add(key)
|
self.checked_metapackages.add(key)
|
||||||
|
|
||||||
retval = set()
|
retval = PackageSet()
|
||||||
|
|
||||||
for package in meta.packages:
|
for package in meta.packages:
|
||||||
if package.state != PackageState.APPROVED:
|
if package.state != PackageState.APPROVED:
|
||||||
@ -84,7 +111,7 @@ class GameSupportResolver:
|
|||||||
|
|
||||||
ret = self.resolve(package, history)
|
ret = self.resolve(package, history)
|
||||||
if len(ret) == 0:
|
if len(ret) == 0:
|
||||||
retval = set()
|
retval = PackageSet()
|
||||||
break
|
break
|
||||||
|
|
||||||
retval.update(ret)
|
retval.update(ret)
|
||||||
@ -92,29 +119,29 @@ class GameSupportResolver:
|
|||||||
self.resolved_metapackages[key] = retval
|
self.resolved_metapackages[key] = retval
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
def resolve(self, package: Package, history: List[str]) -> set[Package]:
|
def resolve(self, package: Package, history: List[str]) -> PackageSet:
|
||||||
key = "{}/{}".format(package.author.username.lower(), package.name)
|
key = package.getId()
|
||||||
print(f"Resolving for {key}", file=sys.stderr)
|
print(f"Resolving for {key}", file=sys.stderr)
|
||||||
|
|
||||||
history = history.copy()
|
history = history.copy()
|
||||||
history.append(key)
|
history.append(key)
|
||||||
|
|
||||||
if package.type == PackageType.GAME:
|
if package.type == PackageType.GAME:
|
||||||
return {package}
|
return PackageSet([package])
|
||||||
|
|
||||||
if key in self.resolved_packages:
|
if key in self.resolved_packages:
|
||||||
return self.resolved_packages.get(key)
|
return self.resolved_packages.get(key)
|
||||||
|
|
||||||
if key in self.checked_packages:
|
if key in self.checked_packages:
|
||||||
print(f"Error, cycle found: {','.join(history)}", file=sys.stderr)
|
print(f"Error, cycle found: {','.join(history)}", file=sys.stderr)
|
||||||
return set()
|
return PackageSet()
|
||||||
|
|
||||||
self.checked_packages.add(key)
|
self.checked_packages.add(key)
|
||||||
|
|
||||||
if package.type != PackageType.MOD:
|
if package.type != PackageType.MOD:
|
||||||
raise LogicError(500, "Got non-mod")
|
raise LogicError(500, "Got non-mod")
|
||||||
|
|
||||||
retval = set()
|
retval = PackageSet()
|
||||||
|
|
||||||
for dep in package.dependencies.filter_by(optional=False).all():
|
for dep in package.dependencies.filter_by(optional=False).all():
|
||||||
ret = self.resolve_for_meta_package(dep.meta_package, history)
|
ret = self.resolve_for_meta_package(dep.meta_package, history)
|
||||||
@ -138,15 +165,15 @@ class GameSupportResolver:
|
|||||||
db.session.add(support)
|
db.session.add(support)
|
||||||
|
|
||||||
def update(self, package: Package) -> None:
|
def update(self, package: Package) -> None:
|
||||||
previous_supported: Dict[Package, PackageGameSupport] = {}
|
previous_supported: Dict[str, PackageGameSupport] = {}
|
||||||
for support in package.supported_games.all():
|
for support in package.supported_games.all():
|
||||||
previous_supported[support.game] = support
|
previous_supported[support.game.getId()] = support
|
||||||
|
|
||||||
retval = self.resolve(package, [])
|
retval = self.resolve(package, [])
|
||||||
for game in retval:
|
for game in retval:
|
||||||
assert game
|
assert game
|
||||||
|
|
||||||
lookup = previous_supported.pop(game, None)
|
lookup = previous_supported.pop(game.getId(), None)
|
||||||
if lookup is None:
|
if lookup is None:
|
||||||
support = PackageGameSupport(package, game)
|
support = PackageGameSupport(package, game)
|
||||||
db.session.add(support)
|
db.session.add(support)
|
||||||
|
@ -483,12 +483,6 @@ class Package(db.Model):
|
|||||||
|
|
||||||
return Package.query.filter(Package.name == parts[1], Package.author.has(username=parts[0])).first()
|
return Package.query.filter(Package.name == parts[1], Package.author.has(username=parts[0])).first()
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
return self.name == other.name and self.author_id == other.author_id
|
|
||||||
|
|
||||||
def __hash__(self):
|
|
||||||
return hash((self.author_id, self.name))
|
|
||||||
|
|
||||||
def getId(self):
|
def getId(self):
|
||||||
return "{}/{}".format(self.author.username, self.name)
|
return "{}/{}".format(self.author.username, self.name)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user