ぼざクリタグ広場 https://hub.nizika.monster
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

200 lines
5.6 KiB

  1. class WikiPagesController < ApplicationController
  2. rescue_from Wiki::Commit::Conflict, with: :render_wiki_conflict
  3. def index
  4. pages = WikiPage.all
  5. render json: pages.as_json(methods: [:title])
  6. end
  7. def show
  8. page = WikiPage.find_by(id: params[:id])
  9. render_wiki_page_or_404 page
  10. end
  11. def show_by_title
  12. title = params[:title].to_s.strip
  13. page = WikiPage.joins(:tag_name)
  14. .includes(:tag_name)
  15. .find_by(tag_names: { name: title })
  16. render_wiki_page_or_404 page
  17. end
  18. def exists
  19. if WikiPage.exists?(id: params[:id])
  20. head :no_content
  21. else
  22. head :not_found
  23. end
  24. end
  25. def exists_by_title
  26. title = params[:title].to_s.strip
  27. if WikiPage.joins(:tag_name).exists?(tag_names: { name: title })
  28. head :no_content
  29. else
  30. head :not_found
  31. end
  32. end
  33. def diff
  34. id = params[:id]
  35. return head :bad_request if id.blank?
  36. from = params[:from].presence
  37. to = params[:to].presence
  38. page = WikiPage.find(id)
  39. from_rev = from && page.wiki_revisions.find(from)
  40. to_rev = to ? page.wiki_revisions.find(to) : page.current_revision
  41. if ((from_rev && !(from_rev.content?)) || !(to_rev&.content?))
  42. return head :unprocessable_entity
  43. end
  44. diffs = Diff::LCS.sdiff(from_rev&.body&.lines || [], to_rev.body.lines)
  45. diff_json = diffs.map { |change|
  46. case change.action
  47. when ?=
  48. { type: 'context', content: change.old_element }
  49. when ?!
  50. [{ type: 'removed', content: change.old_element },
  51. { type: 'added', content: change.new_element }]
  52. when ?+
  53. { type: 'added', content: change.new_element }
  54. when ?-
  55. { type: 'removed', content: change.old_element }
  56. end
  57. }.flatten.compact
  58. render json: { wiki_page_id: page.id,
  59. title: page.title,
  60. older_revision_id: from_rev&.id,
  61. newer_revision_id: to_rev.id,
  62. diff: diff_json }
  63. end
  64. def create
  65. return head :unauthorized unless current_user
  66. return head :forbidden unless current_user.member?
  67. title = params[:title]&.strip
  68. body = params[:body].to_s
  69. return head :unprocessable_entity if title.blank? || body.blank?
  70. page = WikiPage.new(title:, created_user: current_user, updated_user: current_user)
  71. if page.save
  72. message = params[:message].presence
  73. Wiki::Commit.content!(page:, body:, created_user: current_user, message:)
  74. render json: page.as_json(methods: [:title]), status: :created
  75. else
  76. render json: { errors: page.errors.full_messages },
  77. status: :unprocessable_entity
  78. end
  79. end
  80. def update
  81. return head :unauthorized unless current_user
  82. return head :forbidden unless current_user.member?
  83. title = params[:title]&.strip
  84. body = params[:body].to_s
  85. return head :unprocessable_entity if title.blank? || body.blank?
  86. page = WikiPage.find(params[:id])
  87. base_revision_id = page.current_revision.id
  88. if params[:title].present? && params[:title].strip != page.title
  89. return head :unprocessable_entity
  90. end
  91. message = params[:message].presence
  92. Wiki::Commit.content!(page:,
  93. body:,
  94. created_user: current_user,
  95. message:,
  96. base_revision_id:)
  97. head :ok
  98. end
  99. def search
  100. title = params[:title].to_s.strip
  101. q = WikiPage.joins(:tag_name).includes(:tag_name)
  102. if title.present?
  103. q = q.where('tag_names.name LIKE ?', "%#{ WikiPage.sanitize_sql_like(title) }%")
  104. end
  105. render json: q.limit(20).as_json(methods: [:title])
  106. end
  107. def changes
  108. id = params[:id].presence
  109. q = WikiRevision.includes(:wiki_page, :created_user).order(id: :desc)
  110. q = q.where(wiki_page_id: id) if id
  111. render json: q.limit(200).map { |rev|
  112. { revision_id: rev.id,
  113. pred: rev.base_revision_id,
  114. succ: nil,
  115. wiki_page: { id: rev.wiki_page_id, title: rev.wiki_page.title },
  116. user: { id: rev.created_user.id, name: rev.created_user.name },
  117. kind: rev.kind,
  118. message: rev.message,
  119. timestamp: rev.created_at }
  120. }.compact
  121. end
  122. private
  123. def render_wiki_page_or_404 page
  124. return head :not_found unless page
  125. if params[:version].present?
  126. rev = page.wiki_revisions.find_by(id: params[:version])
  127. return head :not_found unless rev
  128. if rev.redirect?
  129. return (
  130. redirect_to wiki_page_by_title_path(title: rev.redirect_page.title),
  131. status: :moved_permanently)
  132. end
  133. body = rev.body
  134. revision_id = rev.id
  135. pred = page.pred_revision_id(revision_id)
  136. succ = page.succ_revision_id(revision_id)
  137. return render json: page.as_json(methods: [:title])
  138. .merge(body:, revision_id:, pred:, succ:)
  139. end
  140. rev = page.current_revision
  141. unless rev
  142. return render json: page.as_json(methods: [:title])
  143. .merge(body: nil, revision_id: nil, pred: nil, succ: nil)
  144. end
  145. if rev.redirect?
  146. return (
  147. redirect_to wiki_page_by_title_path(title: rev.redirect_page.title),
  148. status: :moved_permanently)
  149. end
  150. body = rev.body
  151. revision_id = rev.id
  152. pred = page.pred_revision_id(revision_id)
  153. succ = page.succ_revision_id(revision_id)
  154. render json: page.as_json(methods: [:title]).merge(body:, revision_id:, pred:, succ:)
  155. end
  156. def render_wiki_conflict err
  157. render json: { error: 'conflict', message: err.message }, status: :conflict
  158. end
  159. end