Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(73)

Side by Side Diff: misc/dashboard/godashboard/package.py

Issue 224043: code review 224043: goinstall: an experiment in (external) package installation (Closed)
Patch Set: code review 224043: goinstall: an experiment in (external) package installation Created 15 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « misc/dashboard/godashboard/app.yaml ('k') | src/cmd/clean.bash » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2010 The Go Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style
3 # license that can be found in the LICENSE file.
4
5 # This is the server part of the package dashboard.
6 # It must be run by App Engine.
7
8 from google.appengine.api import memcache
9 from google.appengine.runtime import DeadlineExceededError
10 from google.appengine.ext import db
11 from google.appengine.ext import webapp
12 from google.appengine.ext.webapp import template
13 from google.appengine.ext.webapp.util import run_wsgi_app
14 import binascii
15 import datetime
16 import hashlib
17 import hmac
18 import logging
19 import os
20 import re
21 import struct
22 import time
23 import urllib2
24
25 # Storage model for package info recorded on server.
26 # Just path, count, and time of last install.
27 class Package(db.Model):
28 path = db.StringProperty()
29 web_url = db.StringProperty() # derived from path
30 count = db.IntegerProperty()
31 last_install = db.DateTimeProperty()
32
33 re_bitbucket = re.compile(r'^bitbucket\.org/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+$')
34 re_googlecode = re.compile(r'^[a-z0-9\-]+\.googlecode\.com/(svn|hg)$')
35 re_github = re.compile(r'^github\.com/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+$')
36
37 MaxPathLength = 100
38
39 class PackagePage(webapp.RequestHandler):
40 def get(self):
41 if self.request.get('fmt') == 'json':
42 return self.json()
43
44 q = Package.all()
45 q.order('-last_install')
46 by_time = q.fetch(100)
47
48 q = Package.all()
49 q.order('-count')
50 by_count = q.fetch(100)
51
52 self.response.headers['Content-Type'] = 'text/html; charset=utf-8'
53 path = os.path.join(os.path.dirname(__file__), 'package.html')
54 self.response.out.write(template.render(path, {"by_time": by_time, "by_c ount": by_count}))
55
56 def json(self):
57 self.response.set_status(200)
58 self.response.headers['Content-Type'] = 'text/plain; charset=utf-8'
59 q = Package.all()
60 s = '{"packages": ['
61 sep = ''
62 for r in q.fetch(1000):
63 s += '%s\n\t{"path": "%s", "last_install": "%s", "count": "%s"}' % ( sep, r.path, r.last_install, r.count)
64 sep = ','
65 s += '\n]}\n'
66 self.response.out.write(s)
67
68 def can_get_url(self, url):
69 try:
70 req = urllib2.Request(url)
71 response = urllib2.urlopen(req)
72 return True
73 except:
74 return False
75
76 def is_valid_package_path(self, path):
77 return (re_bitbucket.match(path) or
78 re_googlecode.match(path) or
79 re_github.match(path))
80
81 def record_pkg(self, path):
82 # sanity check string
83 if not path or len(path) > MaxPathLength or not self.is_valid_package_pa th(path):
84 return False
85
86 # look in datastore
87 key = 'pkg-' + path
88 p = Package.get_by_key_name(key)
89 if p is None:
90 # not in datastore - verify URL before creating
91 if re_bitbucket.match(path):
92 check_url = 'http://' + path + '/?cmd=heads'
93 web = 'http://' + path + '/'
94 elif re_github.match(path):
95 # github doesn't let you fetch the .git directory anymore.
96 # fetch .git/info/refs instead, like git clone would.
97 check_url = 'http://'+path+'.git/info/refs'
98 web = 'http://' + path
99 elif re_googlecode.match(path):
100 check_url = 'http://'+path
101 web = 'http://code.google.com/p/' + path[:path.index('.')]
102 else:
103 logging.error('unrecognized path: %s', path)
104 return False
105 if not self.can_get_url(check_url):
106 logging.error('cannot get %s', check_url)
107 return False
108 p = Package(key_name = key, path = path, count = 0, web_url = web)
109
110 # update package object
111 p.count += 1
112 p.last_install = datetime.datetime.utcnow()
113 p.put()
114 return True
115
116 def post(self):
117 path = self.request.get('path')
118 ok = self.record_pkg(path)
119 if ok:
120 self.response.set_status(200)
121 self.response.out.write('ok')
122 else:
123 logging.error('invalid path in post: %s', path)
124 self.response.set_status(500)
125 self.response.out.write('not ok')
126
127 def main():
128 app = webapp.WSGIApplication([('/package', PackagePage)], debug=True)
129 run_wsgi_app(app)
130
131 if __name__ == '__main__':
132 main()
OLDNEW
« no previous file with comments | « misc/dashboard/godashboard/app.yaml ('k') | src/cmd/clean.bash » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b