/loggerhead/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/loggerhead/trunk

« back to all changes in this revision

Viewing changes to loggerhead/controllers/download_ui.py

  • Committer: Ubuntu One Auto Copilot
  • Author(s): Jelmer Vernooij
  • Date: 2023-02-03 20:03:20 UTC
  • mfrom: (547.1.1 lp:loggerhead)
  • Revision ID: otto-copilot@canonical.com-20230203200320-czhzowsk0q4v4g94
Upgrade Python code to a modern version

Merged from https://code.launchpad.net/~jelmer/loggerhead/pyupgrade/+merge/436797

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
#
15
15
# You should have received a copy of the GNU General Public License
16
16
# along with this program; if not, write to the Free Software
17
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335  USA
18
18
#
19
19
 
20
20
import logging
21
21
import mimetypes
22
22
import urllib
23
23
 
 
24
from breezy.errors import NoSuchId, NoSuchRevision
 
25
 
 
26
try:
 
27
    from breezy.transport import NoSuchFile
 
28
except ImportError:
 
29
    from breezy.errors import NoSuchFile
 
30
 
 
31
from breezy import osutils, urlutils
24
32
from paste import httpexceptions
25
33
from paste.request import path_info_pop
26
34
 
27
 
from loggerhead.controllers import TemplatedBranchView
 
35
from ..controllers import TemplatedBranchView
28
36
 
29
37
log = logging.getLogger("loggerhead.controllers")
30
38
 
31
39
 
32
40
class DownloadUI (TemplatedBranchView):
33
41
 
34
 
    def __call__(self, environ, start_response):
35
 
        # /download/<rev_id>/<file_id>/[filename]
36
 
 
37
 
        h = self._history
38
 
 
 
42
    def encode_filename(self, filename):
 
43
 
 
44
        return urlutils.escape(filename)
 
45
 
 
46
    def get_args(self, environ):
39
47
        args = []
40
48
        while True:
41
49
            arg = path_info_pop(environ)
42
50
            if arg is None:
43
51
                break
44
52
            args.append(arg)
 
53
        return args
45
54
 
 
55
    def __call__(self, environ, start_response):
 
56
        # /download/<rev_id>/<filename>
 
57
        h = self._history
 
58
        args = self.get_args(environ)
46
59
        if len(args) < 2:
47
60
            raise httpexceptions.HTTPMovedPermanently(
48
61
                self._branch.absolute_url('/changes'))
49
 
 
50
62
        revid = h.fix_revid(args[0])
51
 
        file_id = args[1]
52
 
        path, filename, content = h.get_file(file_id, revid)
 
63
        try:
 
64
            path, filename, content = h.get_file("/".join(args[1:]), revid)
 
65
        except (NoSuchFile, NoSuchRevision):
 
66
            raise httpexceptions.HTTPNotFound()
53
67
        mime_type, encoding = mimetypes.guess_type(filename)
54
68
        if mime_type is None:
55
69
            mime_type = 'application/octet-stream'
56
 
 
57
70
        self.log.info('/download %s @ %s (%d bytes)',
58
71
                      path,
59
72
                      h.get_revno(revid),
60
73
                      len(content))
61
 
        encoded_filename = urllib.quote(filename.encode('utf-8'))
 
74
        encoded_filename = self.encode_filename(filename)
62
75
        headers = [
63
76
            ('Content-Type', mime_type),
64
77
            ('Content-Length', str(len(content))),
67
80
            ]
68
81
        start_response('200 OK', headers)
69
82
        return [content]
 
83
 
 
84
 
 
85
class DownloadTarballUI(DownloadUI):
 
86
 
 
87
    def __call__(self, environ, start_response):
 
88
        """Stream a tarball from a bazaar branch."""
 
89
        # Tried to re-use code from downloadui, not very successful
 
90
        if not self._branch.export_tarballs:
 
91
            raise httpexceptions.HTTPForbidden(
 
92
                "Tarball downloads are not allowed")
 
93
        archive_format = "tgz"
 
94
        history = self._history
 
95
        self.args = self.get_args(environ)
 
96
        if len(self.args):
 
97
            revid = history.fix_revid(self.args[0])
 
98
            version_part = '-r' + self.args[0]
 
99
        else:
 
100
            revid = self.get_revid()
 
101
            version_part = ''
 
102
        # XXX: Perhaps some better suggestion based on the URL or path?
 
103
        #
 
104
        # TODO: Perhaps set the tarball suggested mtime to the revision
 
105
        # mtime.
 
106
        root = self._branch.friendly_name or 'branch'
 
107
        filename = root + version_part + '.' + archive_format
 
108
        encoded_filename = self.encode_filename(filename)
 
109
        headers = [
 
110
            ('Content-Type', 'application/octet-stream'),
 
111
            ('Content-Disposition',
 
112
                "attachment; filename*=utf-8''%s" % (encoded_filename,)),
 
113
            ]
 
114
        start_response('200 OK', headers)
 
115
        tree = history._branch.repository.revision_tree(revid)
 
116
        return tree.archive(root=root, format=archive_format, name=filename)