def apply_filters(self, filters): # TODO: allow operators filters = deepcopy(filters) try: project = Project.filter_by(name=filters.pop('project')).first() query = Repo.filter_by(project=project) except KeyError: query = Repo.query if filters.get("distros", None): # TODO: we'll need some sort of schema validation here distro_list = util.parse_distro_query(filters.pop("distros")) distro_filter_list = [] has_arch_filter = False for distro in distro_list: # for deb-based distros we store codename in the db as version, # so try first with the codename, but fallback to # distro_version otherwise version_filter = distro["distro_codename"] or distro['distro_version'] if not version_filter: abort(400, "Invalid version or codename for distro: %s" % distro["distro"]) repo_filters = [Repo.distro == distro["distro"], Repo.distro_version == version_filter] if distro["arch"]: repo_filters.append(Arch.name == distro["arch"]) has_arch_filter = True distro_filter_list.append( and_(*repo_filters) ) if has_arch_filter: query = query.join(Repo.archs).filter(or_(*distro_filter_list)) else: query = query.filter(or_(*distro_filter_list)) for k, v in filters.items(): if k not in self.filters: # TODO: improve error reporting # 'invalid query params: %s' % k abort(400) if k in self.filters: query = self.filter_repo(k, v, query) return query