|
- class WikiPagesController < ApplicationController
- def show
- render_wiki_page_or_404 WikiPage.find(params[:id])
- end
-
- def show_by_title
- render_wiki_page_or_404 WikiPage.find_by(title: params[:title])
- end
-
- def diff
- id = params[:id]
- from = params[:from]
- to = params[:to].presence
- return head :bad_request if id.blank? || from.blank?
-
- wiki_page_from = WikiPage.find(id)
- wiki_page_to = wiki_page_from.clone
- wiki_page_from.sha = from
- wiki_page_to.sha = to
-
- diffs = Diff::LCS.sdiff(wiki_page_from.body, wiki_page_to.body)
- diff_json = diffs.map { |change|
- case change.action
- when ?=
- { type: 'context', content: change.old_element }
- when ?|
- [{ type: 'removed', content: change.old_element },
- { type: 'added', content: change.new_element }]
- when ?+
- { type: 'added', content: change.new_element }
- when ?-
- { type: 'removed', content: change.old_element }
- end
- }.flatten.compact
-
- render json: { wiki_page_id: wiki_page_from.id,
- title: wiki_page_from.title,
- older_sha: wiki_page_from.sha,
- newer_sha: wiki_page_to.sha,
- diff: diff_json }
- end
-
- def create
- return head :unauthorized unless current_user
- return head :forbidden unless ['admin', 'member'].include?(current_user.role)
-
- wiki_page = WikiPage.new(title: params[:title], created_user: current_user, updated_user: current_user)
- if wiki_page.save
- wiki_page.set_body params[:body], user: current_user
- render json: wiki_page, status: :created
- else
- render json: { errors: wiki_page.errors.full_messages }, status: :unprocessable_entity
- end
- end
-
- def update
- return head :unauthorized unless current_user
- return head :forbidden unless current_user.member?
-
- title = params[:title]
- body = params[:body]
-
- return head :unprocessable_entity if title.blank? || body.blank?
-
- wiki_page = WikiPage.find(params[:id])
- wiki_page.title = title
- wiki_page.updated_user = current_user
- wiki_page.set_body(body, user: current_user)
- wiki_page.save!
-
- head :ok
- end
-
- def search
- title = params[:title]&.strip
-
- q = WikiPage.all
- q = q.where('title LIKE ?', "%#{ WikiPage.sanitize_sql_like(title) }%") if title.present?
-
- render json: q.limit(20)
- end
-
- def changes
- id = params[:id]
- log = if id.present?
- wiki.page("#{ id }.md")&.versions
- else
- wiki.repo.log('main', nil)
- end
- return render json: [] unless log
-
- render json: log.map { |commit|
- wiki_page = WikiPage.find(commit.message.split(' ')[1].to_i)
- wiki_page.sha = commit.id
-
- next nil if wiki_page.sha.blank?
-
- user = User.find(commit.author.name.to_i)
-
- { sha: wiki_page.sha,
- pred: wiki_page.pred,
- succ: wiki_page.succ,
- wiki_page: wiki_page && { id: wiki_page.id, title: wiki_page.title },
- user: user && { id: user.id, name: user.name },
- change_type: commit.message.split(' ')[0].downcase[0...(-1)],
- timestamp: commit.authored_date }
- }.compact
- end
-
- private
-
- WIKI_PATH = Rails.root.join('wiki').to_s
-
- def wiki
- @wiki ||= Gollum::Wiki.new(WIKI_PATH)
- end
-
- def render_wiki_page_or_404 wiki_page
- return head :not_found unless wiki_page
-
- wiki_page.sha = params[:version].presence
-
- body = wiki_page.body
- sha = wiki_page.sha
- pred = wiki_page.pred
- succ = wiki_page.succ
- render json: wiki_page.as_json.merge(body:, sha:, pred:, succ:)
- end
- end
|