Commits

Shu Zong Chen  committed cf8ba86

snippet now uses cache

  • Participants
  • Parent commits 7c18003

Comments (0)

Files changed (2)

File snippet/models.py

 from django.db import models
+from django.conf import settings
+from django.core.cache import cache
+from django.db.models.signals import post_save, post_delete
+
+class SnippetCache(object):
+	def __init__(self):
+		print "SnippetCache started"
+		self.reset()
+
+	def cache_key(self, name):
+		try:
+			return settings.SNIPPET_CACHE_PREFIX + name
+		except:
+			return "SNIPPET_CACHE"+name
+
+	def get_cache(self, name):
+		return cache.get(self.cache_key(name))
+
+	def set_cache(self, name, value):
+		return cache.set(self.cache_key(name), value)
+
+	def del_cache(self, name):
+		return cache.delete(self.cache_key(name))
+
+	def get(self, name, default):
+		ret = self.get_cache(name)
+		if ret is not None:
+			return ret
+
+		try:
+			print "hitting db"
+			snippet = Snippet.objects.get(name=name)
+		except Snippet.DoesNotExist:
+			snippet = Snippet.objects.create(name=name, content=default)
+			snippet.save()
+		self.set_cache(name, snippet.content)
+		return snippet.content
+
+	def reset(self):
+		self.cache = {}
 
 # Create your models here.
 class Snippet(models.Model):
 	def __unicode__(self):
 		return self.name
 		
+Snippet.cache = SnippetCache()
+
+def invalidate_cache(sender, **kwargs):
+	Snippet.cache.del_cache(kwargs['instance'].name)
+
+post_save.connect(invalidate_cache, Snippet)
+post_delete.connect(invalidate_cache, Snippet)

File snippet/templatetags/snippet.py

 
 register = template.Library()
 
+default_snippet = {
+		"default": '"New Snippet"',
+		"safe": True,
+}
+
 class snippet_node(template.Node):
 	def __init__(self, name, default):
 		self.name = template.Variable(name)
-		if default:
-			self.default = template.Variable(default)
-		else:
-			self.default = None
+		self.default = default
 	
 	def render(self, context):
 		name = self.name.resolve(context)
-		try:
-			snippet = Snippet.objects.get(name=name)
-		except Snippet.DoesNotExist:
-			if self.default:
-				default = self.default.resolve(context)
-			else:
-				default = "New Snippet"
-			snippet = Snippet.objects.create(name=name, content=default)
-			snippet.save()
-		return snippet.content
-		
+		default = self.default.render(context)
+		return Snippet.cache.get(name, default)
+
 @register.tag
 def snippet(parser, token):
-	args = token.split_contents()
-	if len(args) > 3:
-		raise template.TemplateSyntaxError("Snippet takes at most two arguments")
-	if len(args) > 2:
-		default = args[2]
-	else:
-		default = None
-	name = args[1]
+	args, kwargs = interpret_args(
+		token.split_contents(),
+		default=default_snippet,
+	)
+	default = fake_nodelist(kwargs['default'])
+	name = args[0]
 	return snippet_node(name, default)
 
-class snippet_block_node(template.Node):
-	def __init__(self, nodelist, name):
-		self.name = template.Variable(name)
-		self.nodelist = nodelist
-	
-	def render(self, context):
-		name = self.name.resolve(context)
-		try:
-			snippet = Snippet.objects.get(name=name)
-		except Snippet.DoesNotExist:
-			default = self.nodelist.render(context)
-			snippet = Snippet.objects.create(name=name, content=default)
-			snippet.save()
-		return snippet.content
-
 @register.tag
 def snippetblock(parser, token):
-	args = token.split_contents()
-	if len(args) != 2:
-		raise template.TemplateSyntaxError("Snippetblock takes two arguments")
-	name = args[1]
-	nodelist = parser.parse(('endsnippetblock',))
+	args, kwargs = interpret_args(
+		token.split_contents(),
+		default=default_snippet,
+	)
+	name = args[0]
+	default = parser.parse(('endsnippetblock',))
 	parser.delete_first_token()
-	return snippet_block_node(nodelist, name)
+	return snippet_node(name, default)
 
+def interpret_args(token_args, default):
+	args = []
+	kwargs = dict(default)
+	for token in token_args[1:]:
+		if '=' in token:
+			if token[0] in ('\'', '"'):
+				args.append(token)
+			else:
+				key, value = token.split('=',1)
+				if key in kwargs:
+					kwargs[key] = value
+		else:
+			args.append(token)
+	if not len(args):
+		raise template.TemplateSyntaxError("Snippetblock needs an ID")
+	return args, kwargs
+
+class fake_nodelist(object):
+	def __init__(self, content):
+		self.content = template.Variable(content)
+	
+	def render(self, context):
+		return self.content.resolve(context)