doc.rb 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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 name
  33. @name || super.try(:demodulize)
  34. end
  35. def slug
  36. slug = @slug || name.try(:downcase)
  37. version? ? "#{slug}~v#{version}" : slug
  38. end
  39. def path
  40. slug
  41. end
  42. def index_path
  43. File.join path, INDEX_FILENAME
  44. end
  45. def db_path
  46. File.join path, DB_FILENAME
  47. end
  48. def as_json
  49. json = { name: name, slug: slug, type: type }
  50. json[:links] = links if links.present?
  51. json[:release] = release if release.present?
  52. json
  53. end
  54. def store_page(store, id)
  55. store.open(path) do
  56. if page = new.build_page(id) and store_page?(page)
  57. store.write page[:store_path], page[:output]
  58. true
  59. else
  60. false
  61. end
  62. end
  63. end
  64. def store_pages(store)
  65. index = EntryIndex.new
  66. pages = PageDb.new
  67. store.replace(path) do
  68. new.build_pages do |page|
  69. next unless store_page?(page)
  70. store.write page[:store_path], page[:output]
  71. index.add page[:entries]
  72. pages.add page[:path], page[:output]
  73. end
  74. if index.present?
  75. store_index(store, INDEX_FILENAME, index)
  76. store_index(store, DB_FILENAME, pages)
  77. true
  78. else
  79. false
  80. end
  81. end
  82. end
  83. private
  84. def store_page?(page)
  85. page[:entries].present?
  86. end
  87. def store_index(store, filename, index)
  88. old_json = store.read(filename) || '{}'
  89. new_json = index.to_json
  90. instrument "#{filename.remove('.json')}.doc", before: old_json, after: new_json
  91. store.write(filename, new_json)
  92. end
  93. end
  94. def initialize
  95. raise NotImplementedError, "#{self.class} is an abstract class and cannot be instantiated." if self.class.abstract
  96. end
  97. def build_page(id, &block)
  98. raise NotImplementedError
  99. end
  100. def build_pages(&block)
  101. raise NotImplementedError
  102. end
  103. end
  104. end