#!/usr/bin/env python3 # -*- coding: utf-8 -*- # vim: set noexpandtab tabstop=4 shiftwidth=4 autoindent smartindent: # Searches over the network to find out which RPM package distributes # a given file. # # Written by Lucas C. Villa Real # Released under the GNU GPL version 2 or above. import os import sys import argparse import subprocess from html.parser import HTMLParser class RPMFind_Parser(HTMLParser): ''' Parses the HTML data output by rpmfind.net ''' def __init__(self): self.tags = [] self.candidates = [] HTMLParser.__init__(self) def handle_starttag(self, tag, attrs): self.tags.append(tag) def handle_endtag(self, tag): self.tags.pop() def handle_data(self, data): if len(self.tags) and self.tags[-1] == "a" and data.find(".rpm") >= 0: self.candidates.append(data) def get_pkgname(self): if len(self.candidates) == 0: return "" name = os.path.commonprefix(self.candidates) if name.endswith("-"): name = name[:-1] return name class RPMFinder: def find(self, path, arch, distro): ''' Searches rpmfind.net for a given file. Arch and distro can be provided to reduce the search scope. Returns the package name on success or an empty string if no matches were found. ''' self.path = path self.arch = arch self.distro = distro return self.__search_rpmfind_net() def __search_rpmfind_net(self): path = self.path.replace("/", "%2F") arch = self.arch baseuri = "http://rpmfind.net/linux/rpm2html/search.php" query = "?query={0}&submit=Search+...&system=&arch={1}".format(path, arch) html = subprocess.check_output(["wget", "--quiet", "{0}{1}".format(baseuri, query), "-O", "-"]) htmlparser = RPMFind_Parser() htmlparser.feed(html) return htmlparser.get_pkgname() def main(): argparser = argparse.ArgumentParser(argument_default="") argparser.add_argument("--path", type=str, help="File name to search for in the remote RPM databases") argparser.add_argument("--arch", type=str, help="Architecture (optional)") argparser.add_argument("--distro", type=str, help="Distribution (optional)") args = argparser.parse_args() if len(args.path) == 0: argparser.print_help() sys.exit(1) pkgname = RPMFinder().find(args.path, args.arch, args.distro) if len(pkgname): print(pkgname) if __name__ == "__main__": main()