~ubuntu-branches/ubuntu/lucid/software-properties/lucid

33 by Michael Vogt
* Support adding PPA keys automatically (thanks to
1
#  software-properties PPA support
2
#
3
#  Copyright (c) 2004-2009 Canonical Ltd.
4
#
5
#  Author: Michael Vogt <mvo@debian.org>
6
#
7
#  This program is free software; you can redistribute it and/or
8
#  modify it under the terms of the GNU General Public License as
9
#  published by the Free Software Foundation; either version 2 of the
10
#  License, or (at your option) any later version.
11
#
12
#  This program is distributed in the hope that it will be useful,
13
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
#  GNU General Public License for more details.
16
#
17
#  You should have received a copy of the GNU General Public License
18
#  along with this program; if not, write to the Free Software
19
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20
#  USA
21
22
from threading import Thread
23
from urllib2 import urlopen, Request, URLError
24
import re
25
import subprocess
35 by Michael Vogt
* new helper script "add-apt-repository" that can be used to
26
import apt_pkg
33 by Michael Vogt
* Support adding PPA keys automatically (thanks to
27
from urlparse import urlparse
28
29
def expand_ppa_line(abrev, distro_codename):
40 by Amichai Rothman, Harald Sitter, Amichai Rothman
[ Harald Sitter ]
30
    """ Convert an abbreviated ppa name of the form 'ppa:$name' to a
31
        proper sources.list line of the form 'deb ...' """
33 by Michael Vogt
* Support adding PPA keys automatically (thanks to
32
    # leave non-ppa: lines unchanged
33
    if not abrev.startswith("ppa:"):
35 by Michael Vogt
* new helper script "add-apt-repository" that can be used to
34
        return (abrev, None)
33 by Michael Vogt
* Support adding PPA keys automatically (thanks to
35
    # FIXME: add support for dependency PPAs too (once we can get them
36
    #        via some sort of API, see LP #385129)
37
    abrev = abrev.split(":")[1]
38
    ppa_owner = abrev.split("/")[0]
39
    try:
40
        ppa_name = abrev.split("/")[1]
41
    except IndexError, e:
42
        ppa_name = "ppa"
35 by Michael Vogt
* new helper script "add-apt-repository" that can be used to
43
    sourceslistd = apt_pkg.Config.FindDir("Dir::Etc::sourceparts")
44
    line = "deb http://ppa.launchpad.net/%s/%s/ubuntu %s main" % (
33 by Michael Vogt
* Support adding PPA keys automatically (thanks to
45
        ppa_owner, ppa_name, distro_codename)
35 by Michael Vogt
* new helper script "add-apt-repository" that can be used to
46
    file = "%s/%s-%s-%s.list" % (
47
        sourceslistd, ppa_owner, ppa_name, distro_codename)
48
    return (line, file)
33 by Michael Vogt
* Support adding PPA keys automatically (thanks to
49
50
51
class AddPPASigningKeyThread(Thread):
52
    " thread class for adding the signing key in the background "
53
54
    def __init__(self, ppa_path):
55
        Thread.__init__(self)
56
        self.ppa_path = ppa_path
57
        
58
    def run(self):
59
        self.add_ppa_signing_key(self.ppa_path)
60
        
61
    def add_ppa_signing_key(self, ppa_path):
62
        """Query and add the corresponding PPA signing key.
63
        
64
        The signing key fingerprint is obtained from the Launchpad PPA page,
65
        via a secure channel, so it can be trusted.
66
        """
67
        owner_name, ppa_name, distro = ppa_path[1:].split('/')
45 by Michael Vogt
* softwareproperties/ppa.py:
68
        lp_url = ('https://launchpad.net/api/1.0/~%s/+archive/%s' % (
33 by Michael Vogt
* Support adding PPA keys automatically (thanks to
69
            owner_name, ppa_name))
70
        try:
71
            # we ask for a JSON structure from lp_page, we could use
72
            # simplejson, but the format is simple enough for the regexp
73
            req =  Request(lp_url)
74
            req.add_header("Accept","application/json")
75
            lp_page = urlopen(req).read()
76
            #print lp_page
77
            signing_key_fingerprint = re.findall(
40 by Amichai Rothman, Harald Sitter, Amichai Rothman
[ Harald Sitter ]
78
                '\"signing_key_fingerprint\": \"(\w*)\"', lp_page)
79
            if not signing_key_fingerprint:
80
              raise IOError()
33 by Michael Vogt
* Support adding PPA keys automatically (thanks to
81
            # FIXME: this needs to go - elmo says the keyserver will not handle
82
            #        the load
45 by Michael Vogt
* softwareproperties/ppa.py:
83
            res = subprocess.call(
33 by Michael Vogt
* Support adding PPA keys automatically (thanks to
84
                ["apt-key", "adv", "--keyserver", "keyserver.ubuntu.com",
40 by Amichai Rothman, Harald Sitter, Amichai Rothman
[ Harald Sitter ]
85
                 "--recv", signing_key_fingerprint[0]])
45 by Michael Vogt
* softwareproperties/ppa.py:
86
            return (res == 0)
33 by Michael Vogt
* Support adding PPA keys automatically (thanks to
87
        except URLError, e:
40 by Amichai Rothman, Harald Sitter, Amichai Rothman
[ Harald Sitter ]
88
            print "Error reading %s: %s" % (lp_url, e)
45 by Michael Vogt
* softwareproperties/ppa.py:
89
            return False
40 by Amichai Rothman, Harald Sitter, Amichai Rothman
[ Harald Sitter ]
90
        except IOError, e:
91
            print "Error: can't find signing_key_fingerprint at %s" % lp_url
45 by Michael Vogt
* softwareproperties/ppa.py:
92
            return False