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

193 lines
5.5 KiB

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