import os.path
import textwrap
import types
+from urllib import quote_plus
import yaml
if len(self.alternatives) > 0:
ret.append('(%s)' % ', '.join(
[unicode(a) for a in self.alternatives]))
- return ' '.join(ret)
+ return ' '.join([x for x in ret if x != None])
def to_yaml(self):
d = {}
def __unicode__(self):
if self.note == None:
- return '%s %s' % (unicode(self.amount), self.name)
- return '%s %s, %s' % (unicode(self.amount), self.name, self.note)
+ return '%s %s' % (unicode(self.amount or ''), self.name)
+ return '%s %s, %s' % (unicode(self.amount or ''), self.name, self.note)
def to_yaml(self):
d = {}
for paragraph in self]))
def from_yaml(self, string):
+ if string == None:
+ return
while len(self) > 0:
self.pop()
for paragraph in string.split('\n\n'):
Mix ingredients until salamander starts to smoke
<BLANKLINE>
Serve warm over rice
+ >>> r.matches_tags(None)
+ True
+ >>> r.matches_tags([])
+ True
+ >>> r.matches_tags(['dinner', 'apprentice'])
+ True
+ >>> r.matches_tags(['dinner', 'dragon'])
+ False
>>> pprint.pprint(r.to_yaml())
{'author': 'Merlin',
'directions': 'Mix ingredients until salamander starts to smoke\\n\\nServe warm over rice',
self.source = source
self.url = url
self.tags = tags
+ self.path = None
- def clean_name(self):
+ def clean_name(self, ascii=False):
name = self.name
- for from_,to in [(' ','_'), ('/', '_'),
- (',', ''), (u'\xe2\x80\x99', ''),
- ('&', 'and')]:
+ for from_,to in [(' ','_'), ('/', '_'), (',', ''), ('&', 'and')]:
name = name.replace(from_, to)
+ if ascii == True:
+ return quote_plus(name.encode('utf-8'))
return name
+ def matches_tags(self, tags):
+ """Return True if this recipe is tagges with each of the tags in tags.
+ """
+ if tags in [None, []]:
+ return True
+ if self.tags == None:
+ return False
+ for t in tags:
+ if t not in self.tags:
+ return False
+ return True
+
def __str__(self):
return str(self.__unicode__())
self.directions = Directions()
self.directions.from_yaml(dict.get('directions', None))
- def save(self, stream):
+ def save(self, stream, path=None):
yaml.dump(self.to_yaml(), stream,
default_flow_style=False, allow_unicode=True, width=78)
+ if path != None:
+ self.path = path
- def load(self, stream):
+ def load(self, stream, path=None):
dict = yaml.load(stream)
self.from_yaml(dict)
+ if path != None:
+ self.path = path
class Cookbook (list):
"""
def __init__(self, name="Mom's cookbook", *args, **kwargs):
self.name = name
+ self.save_dir = u'recipe'
super(Cookbook, self).__init__(*args, **kwargs)
- def save(self, dir='recipe'):
- if not os.path.isdir(dir):
- os.mkdir(dir)
+ def save(self):
+ if not os.path.isdir(self.save_dir):
+ os.mkdir(self.save_dir)
paths = []
for recipe in self:
- base_path = recipe.clean_name()
- path = base_path
- i = 2
- while path in paths:
- path = '%s_%d' % (base_path, i)
- i += 1
- for x in ['large']:
- if x in path:
- print paths[-4:]
- paths.append(path)
- with open(os.path.join(dir, path), 'w') as f:
- recipe.save(f)
-
- def load(self, dir='recipe'):
- for path in os.listdir(dir):
+ p = self._free_path(recipe, paths)
+ paths.append(p)
+ with open(p, 'w') as f:
+ recipe.save(f, p)
+
+ def load(self):
+ for path in sorted(os.listdir(self.save_dir)):
r = Recipe()
- p = os.path.join(dir, path)
+ p = os.path.join(self.save_dir, path)
with open(p, 'r') as f:
- r.load(f)
- r.path = p
+ r.load(f, p)
self.append(r)
def make_index(self):
self.index = {}
+ paths = [recipe.path for recipe in self]
for recipe in self:
self.index[recipe.name] = recipe
self.index[recipe.clean_name()] = recipe
+ self.index[recipe.clean_name(ascii=True)] = recipe
+ if recipe.path == None:
+ p = self._free_path(recipe, paths)
+ paths.append(p)
+ recipe.path = p
+
+ def _free_path(self, recipe, paths):
+ base_path = os.path.join(self.save_dir, recipe.clean_name())
+ path = base_path
+ i = 2
+ while path in paths:
+ path = '%s_%d' % (base_path, i)
+ i += 1
+ return path
+
+ def tags(self):
+ """List all tags used in this cookbook.
+ """
+ tags = set()
+ for recipe in self:
+ if recipe.tags != None:
+ tags = tags.union(set(recipe.tags))
+ return sorted(tags)
+
+ def tagged(self, tags=None):
+ """Iterate through all recipes matching the given list of tags.
+ """
+ for recipe in self:
+ if recipe.matches_tags(tags):
+ yield recipe
def test():