annotate rhodecode/lib/middleware/pygrack.py @ 2382:034e4fe1ebb2 beta

changed dulwich git interface to gitweb + subprocessio
author Marcin Kuzminski <marcin@python-works.com>
date Mon, 04 Jun 2012 02:56:09 +0200
parents
children 378b0247e938
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2382
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
1 import os
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
2 import socket
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
3 import logging
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
4 import subprocess
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
5
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
6 from webob import Request, Response, exc
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
7
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
8 from rhodecode.lib import subprocessio
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
9
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
10 log = logging.getLogger(__name__)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
11
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
12
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
13 class FileWrapper(object):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
14
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
15 def __init__(self, fd, content_length):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
16 self.fd = fd
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
17 self.content_length = content_length
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
18 self.remain = content_length
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
19
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
20 def read(self, size):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
21 if size <= self.remain:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
22 try:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
23 data = self.fd.read(size)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
24 except socket.error:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
25 raise IOError(self)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
26 self.remain -= size
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
27 elif self.remain:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
28 data = self.fd.read(self.remain)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
29 self.remain = 0
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
30 else:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
31 data = None
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
32 return data
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
33
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
34 def __repr__(self):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
35 return '<FileWrapper %s len: %s, read: %s>' % (
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
36 self.fd, self.content_length, self.content_length - self.remain
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
37 )
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
38
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
39
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
40 class GitRepository(object):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
41 git_folder_signature = set(['config', 'head', 'info', 'objects', 'refs'])
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
42 commands = ['git-upload-pack', 'git-receive-pack']
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
43
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
44 def __init__(self, repo_name, content_path):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
45 files = set([f.lower() for f in os.listdir(content_path)])
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
46 if not (self.git_folder_signature.intersection(files)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
47 == self.git_folder_signature):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
48 raise OSError('%s missing git signature' % content_path)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
49 self.content_path = content_path
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
50 self.valid_accepts = ['application/x-%s-result' %
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
51 c for c in self.commands]
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
52 self.repo_name = repo_name
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
53
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
54 def _get_fixedpath(self, path):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
55 """
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
56 Small fix for repo_path
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
57
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
58 :param path:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
59 :type path:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
60 """
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
61 return path.split(self.repo_name, 1)[-1].strip('/')
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
62
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
63 def inforefs(self, request, environ):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
64 """
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
65 WSGI Response producer for HTTP GET Git Smart
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
66 HTTP /info/refs request.
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
67 """
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
68
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
69 git_command = request.GET['service']
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
70 if git_command not in self.commands:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
71 log.debug('command %s not allowed' % git_command)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
72 return exc.HTTPMethodNotAllowed()
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
73
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
74 # note to self:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
75 # please, resist the urge to add '\n' to git capture and increment
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
76 # line count by 1.
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
77 # The code in Git client not only does NOT need '\n', but actually
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
78 # blows up if you sprinkle "flush" (0000) as "0001\n".
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
79 # It reads binary, per number of bytes specified.
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
80 # if you do add '\n' as part of data, count it.
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
81 smart_server_advert = '# service=%s' % git_command
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
82 try:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
83 out = subprocessio.SubprocessIOChunker(
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
84 r'git %s --stateless-rpc --advertise-refs "%s"' % (
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
85 git_command[4:], self.content_path),
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
86 starting_values=[
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
87 str(hex(len(smart_server_advert) + 4)[2:]
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
88 .rjust(4, '0') + smart_server_advert + '0000')
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
89 ]
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
90 )
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
91 except EnvironmentError, e:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
92 log.exception(e)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
93 raise exc.HTTPExpectationFailed()
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
94 resp = Response()
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
95 resp.content_type = 'application/x-%s-advertisement' % str(git_command)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
96 resp.app_iter = out
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
97 return resp
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
98
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
99 def backend(self, request, environ):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
100 """
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
101 WSGI Response producer for HTTP POST Git Smart HTTP requests.
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
102 Reads commands and data from HTTP POST's body.
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
103 returns an iterator obj with contents of git command's
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
104 response to stdout
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
105 """
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
106 git_command = self._get_fixedpath(request.path_info)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
107 if git_command not in self.commands:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
108 log.debug('command %s not allowed' % git_command)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
109 return exc.HTTPMethodNotAllowed()
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
110
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
111 if 'CONTENT_LENGTH' in environ:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
112 inputstream = FileWrapper(environ['wsgi.input'],
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
113 request.content_length)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
114 else:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
115 inputstream = environ['wsgi.input']
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
116
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
117 try:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
118 out = subprocessio.SubprocessIOChunker(
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
119 r'git %s --stateless-rpc "%s"' % (git_command[4:],
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
120 self.content_path),
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
121 inputstream=inputstream
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
122 )
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
123 except EnvironmentError, e:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
124 log.exception(e)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
125 raise exc.HTTPExpectationFailed()
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
126
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
127 if git_command in [u'git-receive-pack']:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
128 # updating refs manually after each push.
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
129 # Needed for pre-1.7.0.4 git clients using regular HTTP mode.
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
130 subprocess.call(u'git --git-dir "%s" '
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
131 'update-server-info' % self.content_path,
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
132 shell=True)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
133
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
134 resp = Response()
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
135 resp.content_type = 'application/x-%s-result' % git_command.encode('utf8')
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
136 resp.app_iter = out
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
137 return resp
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
138
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
139 def __call__(self, environ, start_response):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
140 request = Request(environ)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
141 _path = self._get_fixedpath(request.path_info)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
142 if _path.startswith('info/refs'):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
143 app = self.inforefs
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
144 elif [a for a in self.valid_accepts if a in request.accept]:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
145 app = self.backend
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
146 try:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
147 resp = app(request, environ)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
148 except exc.HTTPException, e:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
149 resp = e
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
150 log.exception(e)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
151 except Exception, e:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
152 log.exception(e)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
153 resp = exc.HTTPInternalServerError()
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
154 return resp(environ, start_response)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
155
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
156
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
157 class GitDirectory(object):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
158
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
159 def __init__(self, repo_root, repo_name):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
160 repo_location = os.path.join(repo_root, repo_name)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
161 if not os.path.isdir(repo_location):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
162 raise OSError(repo_location)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
163
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
164 self.content_path = repo_location
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
165 self.repo_name = repo_name
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
166 self.repo_location = repo_location
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
167
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
168 def __call__(self, environ, start_response):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
169 content_path = self.content_path
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
170 try:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
171 app = GitRepository(self.repo_name, content_path)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
172 except (AssertionError, OSError):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
173 if os.path.isdir(os.path.join(content_path, '.git')):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
174 app = GitRepository(os.path.join(content_path, '.git'))
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
175 else:
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
176 return exc.HTTPNotFound()(environ, start_response)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
177 return app(environ, start_response)
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
178
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
179
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
180 def make_wsgi_app(repo_name, repo_root):
034e4fe1ebb2 changed dulwich git interface to gitweb + subprocessio
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
181 return GitDirectory(repo_root, repo_name)