/kai/model/blog.py

https://bitbucket.org/bbangert/kai/ · Python · 126 lines · 110 code · 15 blank · 1 comment · 4 complexity · a0e875397af048e0865449f9453ebfe1 MD5 · raw file

  1. import os
  2. import sha
  3. from datetime import datetime
  4. import pylons
  5. from couchdb.schema import DateTimeField, Document, TextField, ListField, View
  6. from kai.lib.helpers import textilize
  7. class Article(Document):
  8. """Represents an article"""
  9. type = TextField(default='Article')
  10. slug = TextField()
  11. title = TextField()
  12. human_id = TextField()
  13. author = TextField(default='anonymous')
  14. summary = TextField(default='')
  15. body = TextField(default='')
  16. extended = TextField(default='')
  17. published = DateTimeField()
  18. updated = DateTimeField()
  19. tags = ListField(TextField())
  20. @property
  21. def feed_title(self):
  22. return self.title
  23. @property
  24. def feed_link(self):
  25. return pylons.url('article_archives', article=self, qualified=True)
  26. @property
  27. def feed_description(self):
  28. return textilize(self.body)
  29. @property
  30. def atom_id(self):
  31. host = pylons.request.host
  32. if ':' in host:
  33. host = host.split(':', 1)[0]
  34. return 'tag:%s,%04d-%02d-%02d:%s' % (
  35. host, self.published.year, self.published.month,
  36. self.published.day, self.id
  37. )
  38. def store(self, db, update_timestamp=True):
  39. if not self.published:
  40. self.published = datetime.utcnow()
  41. if update_timestamp or not self.updated:
  42. self.updated = datetime.utcnow()
  43. Document.store(self, db)
  44. all_months = View('articles', '''
  45. function(doc) {
  46. if (doc.type == 'Article') {
  47. var year = parseInt(doc.published.substr(0, 4), 10);
  48. var month = parseInt(doc.published.substr(5, 2), 10);
  49. emit([year, month], 1);
  50. }
  51. }''', '''
  52. function(keys, values) {
  53. return sum(values);
  54. }''',
  55. wrapper=lambda row: datetime(row.key[0], row.key[1], 1),
  56. name='months', group=True)
  57. all_tags = View('articles', '''
  58. function(doc) {
  59. if (doc.type == 'Article' && doc.tags) {
  60. for (var idx in doc.tags) {
  61. emit(doc.tags[idx], 1);
  62. }
  63. }
  64. }''', '''
  65. function(keys, values) {
  66. return sum(values);
  67. }''',
  68. wrapper=lambda row: row.key,
  69. name='tags', group=True)
  70. by_month = View('articles', '''
  71. function(doc) {
  72. if (doc.type == 'Article') {
  73. var year = parseInt(doc.published.substr(0, 4), 10);
  74. var month = parseInt(doc.published.substr(5, 2), 10);
  75. emit([year, month, doc.published], {
  76. slug: doc.slug, title: doc.title, author: doc.author,
  77. summary: doc.summary, published: doc.published,
  78. updated: doc.updated, tags: doc.tags
  79. });
  80. }
  81. }''')
  82. by_tag = View('articles', u'''
  83. function(doc) {
  84. if (doc.type == 'Article' && doc.tags) {
  85. for (var idx in doc.tags) {
  86. emit([doc.tags[idx], doc.published], {
  87. slug: doc.slug, title: doc.title, author: doc.author,
  88. published: doc.published, updated: doc.updated,
  89. summary: doc.summary, body: doc.body, tags: doc.tags,
  90. extended: doc.extended != '' ? '...' : null
  91. });
  92. }
  93. }
  94. }''')
  95. by_time = View('articles', '''
  96. function(doc) {
  97. if (doc.type == 'Article') {
  98. emit(doc.published,
  99. {slug:doc.slug, title:doc.title,
  100. author:doc.author, body:doc.body,
  101. published:doc.published, summary:doc.summary});
  102. }
  103. }''')
  104. by_slug = View('articles', '''
  105. function(doc) {
  106. if (doc.type == 'Article') {
  107. var year = parseInt(doc.published.substr(0, 4), 10);
  108. var month = parseInt(doc.published.substr(5, 2), 10);
  109. emit([year, month, doc.slug], null)
  110. }
  111. }''')