1
0

doc.rb 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. module Docs
  2. class Doc
  3. INDEX_FILENAME = 'index.json'
  4. DB_FILENAME = 'db.json'
  5. class << self
  6. include Instrumentable
  7. attr_accessor :name, :slug, :type, :release, :abstract, :links
  8. def inherited(subclass)
  9. subclass.type = type
  10. end
  11. def version(version = nil, &block)
  12. return @version if version.nil?
  13. klass = Class.new(self)
  14. klass.class_exec(&block)
  15. klass.name = name
  16. klass.slug = slug
  17. klass.version = version
  18. klass.links = links
  19. @versions ||= []
  20. @versions << klass
  21. klass
  22. end
  23. def version=(value)
  24. @version = value.to_s
  25. end
  26. def versions
  27. @versions.presence || [self]
  28. end
  29. def version?
  30. version.present?
  31. end
  32. def versioned?
  33. @versions.presence
  34. end
  35. def name
  36. @name || super.try(:demodulize)
  37. end
  38. def slug
  39. slug = @slug || name.try(:downcase)
  40. version? ? "#{slug}~v#{version}" : slug
  41. end
  42. def path
  43. slug
  44. end
  45. def index_path
  46. File.join path, INDEX_FILENAME
  47. end
  48. def db_path
  49. File.join path, DB_FILENAME
  50. end
  51. def as_json
  52. json = { name: name, slug: slug, type: type }
  53. json[:links] = links if links.present?
  54. json[:release] = release if release.present?
  55. json
  56. end
  57. def store_page(store, id)
  58. store.open(path) do
  59. if page = new.build_page(id) and store_page?(page)
  60. store.write page[:store_path], page[:output]
  61. true
  62. else
  63. false
  64. end
  65. end
  66. end
  67. def store_pages(store)
  68. index = EntryIndex.new
  69. pages = PageDb.new
  70. store.replace(path) do
  71. new.build_pages do |page|
  72. next unless store_page?(page)
  73. store.write page[:store_path], page[:output]
  74. index.add page[:entries]
  75. pages.add page[:path], page[:output]
  76. end
  77. if index.present?
  78. store_index(store, INDEX_FILENAME, index)
  79. store_index(store, DB_FILENAME, pages)
  80. true
  81. else
  82. false
  83. end
  84. end
  85. end
  86. private
  87. def store_page?(page)
  88. page[:entries].present?
  89. end
  90. def store_index(store, filename, index)
  91. old_json = store.read(filename) || '{}'
  92. new_json = index.to_json
  93. instrument "#{filename.remove('.json')}.doc", before: old_json, after: new_json
  94. store.write(filename, new_json)
  95. end
  96. end
  97. def initialize
  98. raise NotImplementedError, "#{self.class} is an abstract class and cannot be instantiated." if self.class.abstract
  99. end
  100. def build_page(id, &block)
  101. raise NotImplementedError
  102. end
  103. def build_pages(&block)
  104. raise NotImplementedError
  105. end
  106. end
  107. end