| 1 | # -*- Mode: Python -*- |
|---|
| 2 | # vi:si:et:sw=4:sts=4:ts=4 |
|---|
| 3 | |
|---|
| 4 | # code to handle import errors and tell us more information about the |
|---|
| 5 | # missing dependency |
|---|
| 6 | |
|---|
| 7 | import os |
|---|
| 8 | import sys |
|---|
| 9 | import urllib |
|---|
| 10 | |
|---|
| 11 | from moap.util import distro |
|---|
| 12 | |
|---|
| 13 | class Dependency: |
|---|
| 14 | module = None |
|---|
| 15 | name = None |
|---|
| 16 | homepage = None |
|---|
| 17 | |
|---|
| 18 | def install(self, distro): |
|---|
| 19 | """ |
|---|
| 20 | Return an explanation on how to install the given dependency |
|---|
| 21 | for the given distro/version/arch. |
|---|
| 22 | |
|---|
| 23 | @type distro: L{distro.Distro} |
|---|
| 24 | |
|---|
| 25 | @rtype: str or None |
|---|
| 26 | @returns: an explanation on how to install the dependency, or None. |
|---|
| 27 | """ |
|---|
| 28 | name = distro.distributor + '_install' |
|---|
| 29 | m = getattr(self, name, None) |
|---|
| 30 | if m: |
|---|
| 31 | return m(distro) |
|---|
| 32 | |
|---|
| 33 | def FedoraCore_yum(self, packageName): |
|---|
| 34 | """ |
|---|
| 35 | Returns a string explaining how to install the given package. |
|---|
| 36 | """ |
|---|
| 37 | return "On Fedora, you can install %s with:\n" \ |
|---|
| 38 | "su -c \"yum install %s\"" % (self.module, packageName) |
|---|
| 39 | |
|---|
| 40 | def Ubuntu_apt(self, packageName): |
|---|
| 41 | """ |
|---|
| 42 | Returns a string explaining how to install the given package. |
|---|
| 43 | """ |
|---|
| 44 | return "On Ubuntu, you can install %s with:\n" \ |
|---|
| 45 | "sudo apt-get install %s" % (self.module, packageName) |
|---|
| 46 | |
|---|
| 47 | class RDF(Dependency): |
|---|
| 48 | module = 'RDF' |
|---|
| 49 | name = "Redland RDF Python Bindings" |
|---|
| 50 | homepage = "http://librdf.org/docs/python.html" |
|---|
| 51 | |
|---|
| 52 | def FedoraCore_install(self, distro): |
|---|
| 53 | return "python-redland is not yet available in Fedora Extras.\n" |
|---|
| 54 | |
|---|
| 55 | def Ubuntu_install(self, distro): |
|---|
| 56 | return self.Ubuntu_apt('python-librdf') |
|---|
| 57 | |
|---|
| 58 | class Cheetah(Dependency): |
|---|
| 59 | module = 'Cheetah' |
|---|
| 60 | name = "Cheetah templating language" |
|---|
| 61 | homepage = "http://cheetahtemplate.org/" |
|---|
| 62 | |
|---|
| 63 | def FedoraCore_install(self, distro): |
|---|
| 64 | if distro.atLeast('4'): |
|---|
| 65 | return self.FedoraCore_yum('python-cheetah') |
|---|
| 66 | |
|---|
| 67 | return "python-cheetah is only available in Fedora 4 or newer.\n" |
|---|
| 68 | |
|---|
| 69 | class genshi(Dependency): |
|---|
| 70 | module = 'genshi' |
|---|
| 71 | name = "Genshi templating language" |
|---|
| 72 | homepage = "http://genshi.edgewall.com/" |
|---|
| 73 | |
|---|
| 74 | def FedoraCore_install(self, distro): |
|---|
| 75 | return "genshi is not yet available in Fedora Extras.\n" |
|---|
| 76 | |
|---|
| 77 | def Ubuntu_install(self, distro): |
|---|
| 78 | return self.Ubuntu_apt('python-genshi') |
|---|
| 79 | |
|---|
| 80 | class pygoogle(Dependency): |
|---|
| 81 | module = 'pygoogle' |
|---|
| 82 | name = "A Python Interface to the Google API" |
|---|
| 83 | homepage = "http://pygoogle.sourceforge.net/" |
|---|
| 84 | |
|---|
| 85 | def FedoraCore_install(self, distro): |
|---|
| 86 | return "pygoogle is not yet available in Fedora Extras.\n" |
|---|
| 87 | |
|---|
| 88 | class yahoo(Dependency): |
|---|
| 89 | module = 'yahoo' |
|---|
| 90 | name = "A Python Interface to the Yahoo Web API" |
|---|
| 91 | homepage = "http://developer.yahoo.com/python/" |
|---|
| 92 | |
|---|
| 93 | def FedoraCore_install(self, distro): |
|---|
| 94 | return "python-yahoo is not yet available in Fedora Extras.\n" |
|---|
| 95 | |
|---|
| 96 | # non-python dependencies |
|---|
| 97 | class ctags(Dependency): |
|---|
| 98 | module = 'ctags' |
|---|
| 99 | name = "Exuberant ctags" |
|---|
| 100 | homepage = "http://ctags.sourceforge.net/" |
|---|
| 101 | |
|---|
| 102 | def FedoraCore_install(self, distro): |
|---|
| 103 | return self.FedoraCore_yum('ctags') |
|---|
| 104 | |
|---|
| 105 | def handleImportError(exception): |
|---|
| 106 | """ |
|---|
| 107 | Handle dependency import errors by displaying more information about |
|---|
| 108 | the dependency. |
|---|
| 109 | """ |
|---|
| 110 | first = exception.args[0] |
|---|
| 111 | if first.find('No module named ') < 0: |
|---|
| 112 | raise |
|---|
| 113 | module = first[len('No module named '):] |
|---|
| 114 | module = module.split('.')[0] |
|---|
| 115 | deps = {} |
|---|
| 116 | for dep in [RDF(), Cheetah(), genshi(), pygoogle(), yahoo()]: |
|---|
| 117 | deps[dep.module] = dep |
|---|
| 118 | |
|---|
| 119 | if module in deps.keys(): |
|---|
| 120 | dep = deps[module] |
|---|
| 121 | sys.stderr.write("Could not import python module '%s'\n" % module) |
|---|
| 122 | sys.stderr.write('This module is part of %s.\n' % dep.name) |
|---|
| 123 | |
|---|
| 124 | handleMissingDependency(dep) |
|---|
| 125 | |
|---|
| 126 | # how to confirm the python module got installed |
|---|
| 127 | sys.stderr.write( |
|---|
| 128 | 'You can confirm it is installed by starting Python and running:\n') |
|---|
| 129 | sys.stderr.write('import %s\n' % module) |
|---|
| 130 | |
|---|
| 131 | return |
|---|
| 132 | |
|---|
| 133 | # re-raise if we didn't have it |
|---|
| 134 | raise |
|---|
| 135 | |
|---|
| 136 | def getTicketURL(summary): |
|---|
| 137 | reporter = os.environ.get('EMAIL_ADDRESS', None) |
|---|
| 138 | get = "summary=%s" % urllib.quote(summary) |
|---|
| 139 | if reporter: |
|---|
| 140 | get += "&reporter=%s" % urllib.quote(reporter) |
|---|
| 141 | return 'https://thomas.apestaart.org/moap/trac/newticket?' + get |
|---|
| 142 | |
|---|
| 143 | def handleMissingDependency(dep): |
|---|
| 144 | if dep.homepage: |
|---|
| 145 | sys.stderr.write('See %s for more information.\n\n' % dep.homepage) |
|---|
| 146 | |
|---|
| 147 | d = distro.getDistroFromRelease() |
|---|
| 148 | if d: |
|---|
| 149 | howto = dep.install(d) |
|---|
| 150 | if howto: |
|---|
| 151 | sys.stderr.write(howto) |
|---|
| 152 | else: |
|---|
| 153 | url = getTicketURL('DEP: %s, %s' % (dep.module, d.description)) |
|---|
| 154 | sys.stderr.write("""On %s, MOAP does not know how to install %s. |
|---|
| 155 | Please file a bug at: |
|---|
| 156 | %s |
|---|
| 157 | with instructions on how to install the dependency so we can add it. |
|---|
| 158 | """ % (d.description, dep.module, url)) |
|---|
| 159 | else: |
|---|
| 160 | url = getTicketURL('DISTRO: Unknown') |
|---|
| 161 | sys.stderr.write("""MOAP does not know your distribution. |
|---|
| 162 | Please file a bug at: |
|---|
| 163 | %s |
|---|
| 164 | with instructions on how to recognize your distribution so we can add it. |
|---|
| 165 | """ % url) |
|---|
| 166 | |
|---|
| 167 | sys.stderr.write('\n') |
|---|
| 168 | |
|---|
| 169 | sys.stderr.write('Please install %s and try again.\n' % dep.module) |
|---|