ぼざクリタグ広場 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.
 
 
 
 
 
 

196 lines
5.4 KiB

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