better-wrong-script.diff
[platform/upstream/rpmlint.git] / AbstractCheck.py
1 # -*- coding: utf-8 -*-
2 #############################################################################
3 # File          : AbstractCheck.py
4 # Package       : rpmlint
5 # Author        : Frederic Lepied
6 # Created on    : Tue Sep 28 00:22:38 1999
7 # Version       : $Id: AbstractCheck.py 1891 2011-11-23 20:03:00Z scop $
8 # Purpose       : Abstract class to hold all the derived classes.
9 #############################################################################
10
11 import re
12 import socket
13 import urllib2
14
15 from Filter import addDetails, printInfo, printWarning
16 import Config
17
18 # Note: do not add any capturing parentheses here
19 macro_regex = re.compile('%+[{(]?\w+[)}]?')
20
21 class _HeadRequest(urllib2.Request):
22     def get_method(self):
23         return "HEAD"
24 class _HeadRedirectHandler(urllib2.HTTPRedirectHandler):
25     def redirect_request(*args):
26         res = urllib2.HTTPRedirectHandler.redirect_request(*args)
27         if res:
28             res = _HeadRequest(res.get_full_url())
29         return res
30
31 class AbstractCheck:
32     known_checks = {}
33
34     def __init__(self, name):
35         if not AbstractCheck.known_checks.get(name):
36             AbstractCheck.known_checks[name] = self
37         self.name = name
38         self.verbose = False
39         self.network_enabled = Config.getOption("NetworkEnabled", False)
40         self.network_timeout = Config.getOption("NetworkTimeout", 10)
41
42     def check(self, pkg):
43         raise NotImplementedError('check must be implemented in subclass')
44
45     def check_url(self, pkg, tag, url):
46         """Check that URL points to something that seems to exist.
47            Return info() of the response if available."""
48         if not self.network_enabled:
49             if self.verbose:
50                 printInfo(pkg, 'network-checks-disabled', url)
51             return
52
53         if self.verbose:
54             printInfo(pkg, 'checking-url', url,
55                       '(timeout %s seconds)' % self.network_timeout)
56
57         # Could use timeout kwarg to urlopen, but that's python >= 2.6 only
58         socket.setdefaulttimeout(self.network_timeout)
59         res = None
60         try:
61             opener = urllib2.build_opener(_HeadRedirectHandler())
62             opener.addheaders = [('User-Agent',
63                                   'rpmlint/%s' % Config.__version__)]
64             res = opener.open(_HeadRequest(url))
65         except Exception, e:
66             errstr = str(e) or repr(e) or type(e)
67             printWarning(pkg, 'invalid-url', '%s:' % tag, url, errstr)
68         info = None
69         if res:
70             info = res.info()
71             res.close()
72         return info
73
74 class AbstractFilesCheck(AbstractCheck):
75     def __init__(self, name, file_regexp):
76         self.__files_re = re.compile(file_regexp)
77         AbstractCheck.__init__(self, name)
78     def check(self, pkg):
79         if pkg.isSource():
80             return
81         ghosts = pkg.ghostFiles()
82         for filename in (x for x in pkg.files() if x not in ghosts):
83             if self.__files_re.match(filename):
84                 self.check_file(pkg, filename)
85
86
87     def check_file(self, pkg, filename):
88         """Virtual method called for each file that match the regexp passed
89         to the constructor.
90         """
91         raise NotImplementedError('check must be implemented in subclass')
92
93 addDetails(
94 'invalid-url',
95 '''The value should be a valid, public HTTP, HTTPS, or FTP URL.''',
96
97 'network-checks-disabled',
98 '''Checks requiring network access have not been enabled in configuration,
99 see the NetworkEnabled option.''',
100 )
101
102 # AbstractCheck.py ends here
103
104 # Local variables:
105 # indent-tabs-mode: nil
106 # py-indent-offset: 4
107 # End:
108 # ex: ts=4 sw=4 et