Commits

Janto Dreijer committed 90824d9

make templates django based and only show package info fields with actual values

Comments (0)

Files changed (3)

 		template_values["search_box_html"] = SearchPage.search_box()
 
 		# latest changes
+		#XXX codeblock waaaay too complex
 		t = time.time()
 		checked_urls = [] # the urls checked for updates
 		show_latest_changes = 0
 		template_values["newest_packages_html"] = newest_packages_html
 		self.write("<!-- checked changes in %0.2f sec -->" % (time.time() - t))
 
-		#~ # force a fetch of one of the http listings
-		#~ t = time.time()
-		#~ key = "next_listing_url_index"
-		#~ n = memcache.get(key)
-		#~ if n is None:
-			#~ n = 0
-		#~ memcache.set(key, (n+1) % len(checked_urls)) # set the next url to be fetched
-		#~ url = checked_urls[n]
-		#~ self.logger.info("forcing fetch of url: %s" % url)
-		#~ get_url(url, force_fetch=True, cache_duration=PACKAGE_NEWS_CACHE_DURATION)
-		#~ template_values["newest_packages_html"] += "<!-- forced fetch of url : %s in %0.2f seconds -->\n" % (url, time.time() - t)
-
 		# admin sidebar
 		template_values["admin_sidebar_html"] = ""
 		if users.is_current_user_admin():
 
 		# editor sidebar
 		template_values["editor_sidebar_html"] = ""
-		if current_user_is_editor():
+		if is_current_user_editor():
 
 			html = ['<h3><a href="/edit">Edit</a></h3>']
 			html.append('<ul>')
 
 			template_values["editor_sidebar_html"] = "\n".join(html)
 
-		self.write(get_template("header") % template_values)
+		self.write(render_template("header", template_values))
 
 	def print_footer(self, title=None):
 		template_values = {}
 		else:
 			template_values["login_logout_html"] = '<a href="%s">Sign in</a>' % users.create_login_url(url_requested)
 
-		template_values["load_time"] = time.time() - self.init_time
-		self.write(get_template("footer") % template_values)
+		template_values["load_time"] = "%0.3f" % (time.time() - self.init_time)
+		self.write(render_template("footer", template_values))
 
 	def print_menu(self):
 		pass
 			n = 0
 		memcache.set(key, (n+1) % len(checked_urls)) # set the next url to be fetched
 		url = checked_urls[n]
-		report = "forcing fetch of url: %s (n=%d)" % (url, n)
+		report = "forcing fetch of url: %s (n=%d/%d)" % (url, n, len(checked_urls))
 		self.logger.info(report)
 		self.write("<li>"+report)
 		get_url(url, force_fetch=True, cache_duration=PACKAGE_NEWS_CACHE_DURATION)
 	def get(self):
 		self.print_header()
 		self.print_menu()
-		self.write(get_template(self.name) % locals())
+		self.write(render_template(self.name, locals()))
 		self.print_footer()
 
 class ContributePage(Page):
 	def get(self):
 		self.print_header()
 		self.print_menu()
-		self.write(get_template(self.name) % locals())
+		self.write(render_template(self.name, locals()))
 		self.print_footer()
 
 class PackagesPage(Page):
 	return "\n".join(result)
 
 class Package(object):
-	def __init__(self, name, repo_url):
+	def __init__(self, name, repo_url, info_source=""):
 		"""
 		init should cache minimal information. actual information extraction should be done on page requests. with memcaching where needed.
 		"""
 		self.name = name
 		self.repo_url = repo_url
+		self.info_source = info_source
 
 	def release_files(self, return_checked_urls=False):
 		logger.debug(self.name)
 
 		package_news_items = []
 		checked_urls = []
-		for dist in ["2.5", "2.6", "3.0", "any", "source"]: # check various distributions
+		for dist in ["2.5", "2.6", "2.7", "3.0", "any", "source"]: # check various distributions
 			url = "http://pypi.python.org/packages/%(dist)s/%(first_char)s/%(package_name)s/" % locals()
 			checked_urls.append(url) # remember for forcing fetch
 			items = fetch_links_with_dates(url, cache_duration=PACKAGE_NEWS_CACHE_DURATION)
 		if expired or packages is None:
 			packages = {}
 
+			from_pypi_search = 1
+			if from_pypi_search:
+				logger.info("loading packages from PyPI")
+				server = xmlrpclib.ServerProxy('http://pypi.python.org/pypi', transport=GoogleXMLRPCTransport())
+				results = server.search(dict(name="scikits"))
+				for package_name in set(result["name"] for result in results): # unique names, pypi contains duplicate names
+
+					#~ package_name_short = package_name.split(".", 1)[0] if package_name.startswith("scikits.") else package_name
+					repo_url = "" #XXX where can we get this?
+					package = Package(name=package_name, repo_url=repo_url, info_source="PyPI")
+					packages[package.name] = package
+
 			from_repo = 1
 			if from_repo:
 				for repo_base_url in [
 					logger.info("loading packages from repo %s" % repo_base_url)
 					for repo_url in fetch_dir_links(repo_base_url):
 						package_name = "scikits.%s" % os.path.split(repo_url)[1]
-						if package_name in packages:
-							continue
 
 						# check if really a package
 						#~ url = os.path.join(repo_url, "setup.py")
 						#~ if result.status_code != 200: # setup.py was not found
 							#~ continue
 
-						package = Package(name=package_name, repo_url=repo_url)
+						package = Package(name=package_name, repo_url=repo_url, info_source="svn.scipy.org")
 						packages[package.name] = package
 
-			from_pypi_search = 1
-			if from_pypi_search:
-				logger.info("loading packages from PyPI")
-				server = xmlrpclib.ServerProxy('http://pypi.python.org/pypi', transport=GoogleXMLRPCTransport())
-				results = server.search(dict(name="scikits"))
-				for package_name in set(result["name"] for result in results): # unique names, pypi contains duplicate names
-
-					#XXX remove this once no longer scanning repo for package name
-					if package_name in packages:
-						continue
-
-					#~ package_name_short = package_name.split(".", 1)[0] if package_name.startswith("scikits.") else package_name
-					repo_url = "" #XXX where can we get this?
-					package = Package(name=package_name, repo_url=repo_url)
-					packages[package.name] = package
-
 			assert Cache.set(key="packages", value=packages, duration=PACKAGE_LISTING_CACHE_DURATION), package
 
 		return packages
 	def info(self, force_fetch=False):
 		d = dict(
 			name=self.name,
+			pypi_name="",
 			shortdesc="",
 			description="",
 			homepage="",
 			revision="",
 			people="",
+			info_source=self.info_source,
+			download_link="",
 			)
 		doap_result = get_url(
 			"http://pypi.python.org/pypi?:action=doap&name=%s" % self.name,
 				d[name] = value
 
 			d["people"] = ", ".join(d["people"])
+			d["pypi_name"] = d["name"]
 
 			download_page = d.get("download-page", "") or ("http://pypi.python.org/pypi/%(name)s" % d)
 			d["download_link"] = make_link(download_page)
 
-		else:
-
-			d["download_link"] = "<code>svn checkout %s</code>" % make_link(self.repo_url)
-
 		d["short_name"] = d["name"].split(".")[-1]
 
 		return d
 		revision = d.get("revision")
 		revision = ("version " + revision) if revision else ""
 
-		return get_template("package_info") % dictadd(self.__dict__, d, locals())
+		return render_template("package_info", dictadd(self.__dict__, d, locals()))
 
 class SearchPage(Page):
 	name="search"
 	except AttributeError:
 		raise NoSuchTemplateException(name)
 
+def render_template(template_name, d):
+	return templating.Template(get_template(template_name)).render(templating.Context(d))
+
 class DBPageTemplate(db.Model):
 	name = db.StringProperty(required=True)
 	text = db.TextProperty()
 	email = db.StringProperty(required=True)
 	comment = db.StringProperty()
 
-def current_user_is_editor():
+def is_current_user_editor():
+	if users.is_current_user_admin():
+		return True
 	user = users.get_current_user()
 	if user is None:
 		return False
 			self.write('<a href="%s">sign in</a>' % users.create_login_url(url_requested))
 			self.print_footer()
 			return
-		if not current_user_is_editor():
+		if not is_current_user_editor():
 			self.write('only site editors allowed here.\n')
 			self.write('<a href="%s">sign out</a>.' % users.create_logout_url(url_requested))
 			self.print_footer()
 		# backup and stats
 
 		self.write("<h1>Page Templates</h1>")
+		self.write("<p>Django style templates</p>")
 		self.write("<p>")
 		if self.request.get("email_backup") == "yes":
 			t = datetime.datetime.now()
 	def get(self):
 		self.print_header()
 		self.print_menu()
-		self.write(get_template("about") % locals())
+		self.write(render_template("about", locals()))
 		self.print_footer()
 
 class DebugPage(Page):

code/templates.py

+"""
+This might not be such a good way to store page temlplates, but what are the alternatives?
+	I don't want to store it as part of the DB alone as I want this info available both when running a local GAE and on the online GAE.
+	I don't want to store it as separate files, because then you won't be able to modify them from the web. GAE doesn't support writing to "files" (probably) for security reasons.
+
+So the way of currenty doing things:
+	Manually check the online version every few months if there were any modifications made to the templated pages. If there was, paste the new version into this page.
+	Yes, it's disgusting. If you can think of a better way please let me know.
+
+- Janto
+
+"""
+
 names = [
 	"header",
 	"footer",
 
 <html>
 <head>
-	<title>SciKits - %(name)s</title>
+	<title>SciKits - {{ name }}</title>
 	<script type="text/javascript" src="/static/jquery.js"></script>
 	<script type="text/javascript" src="/static/jquery.corners.min.js"></script>
 
 <div class="sphinxsidebar">
 <div class="sphinxsidebarwrapper">
 
-	%(admin_sidebar_html)s
+	{{ admin_sidebar_html }}
 
-	%(editor_sidebar_html)s
+	{{ editor_sidebar_html }}
 
-	%(newest_packages_html)s
+	{{ newest_packages_html }}
 
 	<h3>Quick search</h3>
-	%(search_box_html)s
+	{{ search_box_html }}
 
 </div>
 </div>
 <div class="bodywrapper">
 <div class="body">
 
-<div class="section" id="%(name)s">
+<div class="section" id="{{ name }}">
 
 """
 
 
 <div class="footer">
 See the <a href="http://code.google.com/p/scikits-index/source/checkout">source</a>.
-Created page in %(load_time)0.3f seconds. %(login_logout_html)s
+Created page in {{ load_time }} seconds. {{login_logout_html}}
 <br />
 Designed by <a href="http://janto.blogspot.com/">Janto Dreijer</a>.
 Appearance based on <a href="http://sphinx.pocoo.org/">Sphinx</a> and <a href="http://www.vistaicons.com/icon/i160s0/phuzion_icon_pack.htm">Phuzion icons</a>.
 });
 </script>
 
-%(google_analytics)s
+{{ google_analytics }}
 
+<!--
+The following page request is vital to the working of the site.
+If it's not called then (see Issue#2)
+-->
 <script type="text/javascript">
-jQuery.get("/worker?name=%(name)s");
+jQuery.get("/worker?name={{ name }}");
 </script>
 
 </body>
 <h3>Add your own package</h3>
 
 <p>
-<a href="http://www.scipy.org/scipy/scikits/">SciKits developer resources</a>
+<a href="http://projects.scipy.org/scikits">SciKits developer resources</a>
 </p>
 
 <p>
 """
 
 package_info_template = """
-<a href="" style="text-decoration:none"><h1>%(name)s</h1></a>
-<i>%(revision)s</i>
+<a href="" style="text-decoration:none"><h1>{{ name }}</h1></a>
+<i>{{ revision }}</i>
 <p>
-%(shortdesc)s
+{{ shortdesc }}
 </p>
 
 <p>
-<img src="/static/images/download_32.png" width="16" border="0" /> Download:  %(download_link)s <br />
-Homepage: <a href="%(homepage)s">%(homepage)s</a> <br />
-PyPI: <a href="http://pypi.python.org/pypi/%(name)s">http://pypi.python.org/pypi/%(name)s</a> <br />
-Source Repository: <a href="%(repo_url)s">%(repo_url)s</a> <br />
-People: %(people)s <br />
+{% if download_link %}
+<img src="/static/images/download_32.png" width="16" border="0" /> Download:  {{ download_link }} <br />
+{% endif %}
+{% if homepage %}
+Homepage: <a href="{{ homepage }}">{{ homepage }}</a> <br />
+{% endif %}
+{% if pypi_name %}
+PyPI: <a href="http://pypi.python.org/pypi/{{ pypi_name }}">http://pypi.python.org/pypi/{{ pypi_name }}</a> <br />
+{% endif %}
+{% if repo_url %}
+Source Repository: <a href="{{ repo_url }}">{{ repo_url }}</a> <br />
+{% endif %}
+{% if people %}
+People: {{ people }} <br />
+{% endif %}
 </p>
 
+{% if escaped_description %}
 <h3>Description</h3>
-<i>fetched from source</i>
 <div style="background-color:#f0f0f0; padding:5px" class="rounded">
-%(escaped_description)s
+{{ escaped_description }}
 </div>
+{% endif %}
 
 <h3>Installation</h3>
 
+{% if pypi_name %}
 <h4>PyPI</h4>
 <p>
-You can download the latest distribution from PyPI here: <a href="http://pypi.python.org/pypi/%(name)s">http://pypi.python.org/pypi/%(name)s</a>
+You can download the latest distribution from PyPI here: <a href="http://pypi.python.org/pypi/{{ name }}">http://pypi.python.org/pypi/{{ name }}</a>
 </p>
 
 <h4>Easy Install</h4>
 <p>
-Install the <a href="http://peak.telecommunity.com/DevCenter/EasyInstall">Easy Install</a> tools. Afterwards you can install %(name)s from the terminal by executing:
-<pre>sudo easy_install %(name)s</pre>
+Install the <a href="http://peak.telecommunity.com/DevCenter/EasyInstall">Easy Install</a> tools. Afterwards you can install {{ name }} from the terminal by executing:
+<pre>sudo easy_install {{ pypi_name }}</pre>
 </p>
 
 <p>
 If you prefer to do a local installation, specify an installation prefix:
-<pre>easy_install --prefix=${HOME} %(name)s</pre>
+<pre>easy_install --prefix=${HOME} {{ pypi_name }}</pre>
 and ensure that your <code>PYTHONPATH</code> is up to date, e.g.:
 <pre>export PYTHONPATH=$PYTHONPATH:${HOME}/lib/python2.5/site-packages</pre>
 </p>
+{% endif %}
 
+{% if repo_url %}
 <h4>Source code</h4>
 <p>
 You can get the latest sources from the repository using
-<pre>svn checkout <a href="%(repo_url)s">%(repo_url)s</a></pre>
+<pre>svn checkout <a href="{{ repo_url }}">{{ repo_url }}</a></pre>
 </p>
+{% endif %}
+
+{% if info_source %}
+<p><i>This package was discovered in {{ info_source }}.</i></p>
+{% endif %}
 
 """
 from google.appengine.ext import webapp, db
 from google.appengine.api import users
 
+from google.appengine.ext.webapp import template as templating
+
 import xmlrpclib
 
 import PyRSS2Gen
 		else:
 			assert Cache.set(key=url, value=response, duration=cache_duration), url
 	else:
-		logger.debug("cache hit for %s" % url)
+		#~ logger.debug("cache hit for %s" % url)
+		pass
 
 	return response