File: changelog.py

package info (click to toggle)
update-manager 0.200.5-2.1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 5,900 kB
  • sloc: python: 4,557; xml: 1,571; makefile: 103; sh: 71
file content (118 lines) | stat: -rw-r--r-- 4,005 bytes parent folder | download | duplicates (2)
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# UpdateManager/DistSpecific/changelog.py
#
#  Copyright (c) 2009 Canonical
#                2009 Stephan Peijnik
#
#  Author: Stephan Peijnik <debian@sp.or.at>
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License as
#  published by the Free Software Foundation; either version 2 of the
#  License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
#  USA.

""" Changelog fetcher functionality """

import logging
import urllib2

from threading import Thread

from UpdateManager.Util.enum import Enum

LOG = logging.getLogger('UpdateManager.DistSpecific.changelog')

CHANGELOG_FETCH_STATUS = Enum(
    FAILED = "Fetching failed",
    DONE = "Fetching finished")
""" Changelog fetcher status """

class ChangelogFetcherException(Exception):
    """ Changelog fetcher exception """
    pass

class ChangelogHandler(object):
    """ Changelog result handler """
    def changelog_finished(self, pkg_info, raw_changelog):
        """ Changelog fetching finished notification

        :param pkg_info: :class:`UpdateManager.Backend.PackageInfoBase` object
        :param raw_changelog: The last changelog entry as a string
        """
        raise NotImplementedError

    def changelog_failure(self, pkg_info, error_message):
        """ Changelog fetching failure notification

        :param pkg_info: :class:`UpdateManager.Backend.PackageInfoBase` object
        :param error_message: Error message
        """
        raise NotImplementedError

class ChangelogFetcher(object):
    """ Changelog Fetcher base class.

    This class must be subclassed by all ChangelogFetcher implementations.
    """
    def __init__(self, pkg_info, changelog_handler):
        self._pkg_info = pkg_info
        self._handler = changelog_handler

        LOG.debug("Fetching changelog entry for %s.",
                  pkg_info.get_package_name())
        name = "changelogfetcher-%s" % (pkg_info.get_package_name())
        Thread(target = self._do_fetch, name = name).start()

    def _do_fetch(self):
        """ The actual worker method.

        This method must be overridden.
        """
        raise NotImplementedError
    
class HTTPChangelogFetcher(ChangelogFetcher):
    """ Simple HTTP Changelog Fetcher """

    def _do_fetch(self):
        """ HTTP worker implementation """
        LOG.debug("Getting changelog URL for package %r", self._pkg_info)
        url = self._get_changelog_url(self._pkg_info)
        found_double_dash = False
        try:
            LOG.debug("Fetching %s...", url)
            connection = urllib2.urlopen(url)
            text = ""
            
            while not found_double_dash:
                line = connection.readline()
                if line.startswith(' -- '):
                    LOG.debug("Found double-dash sequence, closing stream.")
                    found_double_dash = True
                text += line
                
            connection.close()
            
            self._handler.changelog_finished(self._pkg_info, text)
        except urllib2.URLError, exc:
            LOG.error('Fetching the changelog entry via HTTP failed: %s',
                      exc)
            self._handler.changelog_failure(self._pkg_info, exc.message)

    def _get_changelog_url(self, pkg_info):
        """ Gets the (distribution-specific) changelog URL.

        :param pkg_info: :class:`UpdateManager.Backend.PackageInfoBase`
          object.

        This method must be overridden.
        """
        raise NotImplementedError