aboutsummaryrefslogtreecommitdiff
path: root/bin/RPMFinder
blob: 49900b6dca54255966ffa43c4505d2f1050b4c42 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/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 <lucasvr@gobolinux.org>
# 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()