| 234 | | __all__ = ['T', 'TracResource', 'StanResource', 'ProxyResource'] |
|---|
| | 237 | class APIDocResource(Resource): |
|---|
| | 238 | """ |
|---|
| | 239 | """ |
|---|
| | 240 | def __init__(self, vhostPath, projectURLProto, projectRepoProto): |
|---|
| | 241 | self.vhostPath = vhostPath |
|---|
| | 242 | for name in ('projectURLProto', 'projectRepoProto'): |
|---|
| | 243 | string = locals()[name] |
|---|
| | 244 | if "%s" not in string: |
|---|
| | 245 | raise ValueError("Invalid string prototype '%s'" % string) |
|---|
| | 246 | setattr(self, name, string) |
|---|
| | 247 | |
|---|
| | 248 | def _executable(self, name): |
|---|
| | 249 | result = procutils.which(name)[0] |
|---|
| | 250 | if not result: |
|---|
| | 251 | raise ImportError("Can't locate %s executable" % name) |
|---|
| | 252 | |
|---|
| | 253 | def locateChild(self, request, segments): |
|---|
| | 254 | """ |
|---|
| | 255 | """ |
|---|
| | 256 | def ready(null): |
|---|
| | 257 | urlPath = "/api/%s/%s" % (projectName, apiFile) |
|---|
| | 258 | newURL = (request.scheme, request.host, urlPath, '', '', '') |
|---|
| | 259 | return resource.RedirectResource(*newURL), () |
|---|
| | 260 | |
|---|
| | 261 | projectName = segments[0] |
|---|
| | 262 | packageName = projectName.lower().replace("-", "_") |
|---|
| | 263 | if len(segments) > 1: |
|---|
| | 264 | apiFile = segments[1] |
|---|
| | 265 | else: |
|---|
| | 266 | apiFile = "%s.html" % packageName |
|---|
| | 267 | d = defer.maybeDeferred( |
|---|
| | 268 | self.ensureDocsPresent, projectName, packageName, apiFile) |
|---|
| | 269 | d.addCallback(ready) |
|---|
| | 270 | return d |
|---|
| | 271 | |
|---|
| | 272 | def ensureDocsPresent(self, projectName, packageName, apiFile): |
|---|
| | 273 | """ |
|---|
| | 274 | """ |
|---|
| | 275 | filePath = os.path.join(self.vhostPath, 'api', projectName, apiFile) |
|---|
| | 276 | if False and not os.path.exists(filePath): |
|---|
| | 277 | tmpDir = tempfile.mkdtemp() |
|---|
| | 278 | d = self.svn(tmpDir, projectName) |
|---|
| | 279 | d.addCallback(lambda _: self.pydoctor(tmpDir, projectName)) |
|---|
| | 280 | d.addCallback(lambda _: shutil.rmtree(tmpDir)) |
|---|
| | 281 | return d |
|---|
| | 282 | |
|---|
| | 283 | def svn(self, tmpDir, projectName): |
|---|
| | 284 | """ |
|---|
| | 285 | """ |
|---|
| | 286 | repo = self.projectRepoProto % projectName |
|---|
| | 287 | args = [ |
|---|
| | 288 | "export", "-q", "--force", |
|---|
| | 289 | "%s/%s/trunk" % (repo, projectName)] |
|---|
| | 290 | return utils.getProcessValue( |
|---|
| | 291 | self._executable('svn'), args=args, path=tmpDir) |
|---|
| | 292 | |
|---|
| | 293 | def pydoctor(self, tmpDir, vhostPath, projectName): |
|---|
| | 294 | """ |
|---|
| | 295 | """ |
|---|
| | 296 | url = self.projectURLProto % projectName |
|---|
| | 297 | args = [ |
|---|
| | 298 | "--add-package=%s" % packageName, |
|---|
| | 299 | "--project-name=%s" % projectName, |
|---|
| | 300 | "--make-html", |
|---|
| | 301 | "--html-output=%s/api/%s" % (self.vhostPath, projectName), |
|---|
| | 302 | "--project-url=%s%s" % (url, projectName)] |
|---|
| | 303 | return utils.getProcessValue( |
|---|
| | 304 | self._executable('pydoctor'), args=args, path=tmpDir) |
|---|
| | 305 | |
|---|
| | 306 | |
|---|
| | 307 | __all__ = [ |
|---|
| | 308 | 'T', 'TracResource', 'StanResource', 'ProxyResource', 'APIDocResource'] |
|---|