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

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