Files
mapknitter/app/controllers/maps_controller.rb
Cess 253ab8b2f0 Refactoring controllers (#546)
* include byebug in test group

* refactor feeds controller

* refactor tags and maps controllers

* refactor images controller

* increase maps controller test coverage
2019-04-23 12:32:25 -04:00

203 lines
5.9 KiB
Ruby

# rubocop:disable LineLength
require 'open3'
class MapsController < ApplicationController
protect_from_forgery except: :export
before_filter :require_login, only: %i[edit update destroy]
before_filter :find_map, only: %i[show annotate embed edit update images export exports destroy]
layout 'knitter2'
def index
# show only maps with at least 1 image to reduce spammer interest
@maps = Map.page(params[:page])
.per_page(20)
.where(archived: false, password: '')
.order('updated_at DESC')
.joins(:warpables)
.group('maps.id')
# ensure even maps with no images are shown on front page and don't get lost; some spam risk
@new_maps = Map.where(archived: false, password: '')
.order('updated_at DESC')
render layout: 'application'
end
def map
@maps = Map.map
render layout: false
end
def new
@map = Map.new
end
def create
if logged_in?
@map = current_user.maps.new(params[:map])
@map.author = current_user.login # eventually deprecate
if @map.save
redirect_to "/maps/#{@map.slug}"
else
render 'new'
end
else
@map = Map.new(params[:map])
if Rails.env != 'production' || verify_recaptcha(model: @map, message: "ReCAPTCHA thinks you're not human! Try again!")
if @map.save
redirect_to "/maps/#{@map.slug}"
else
render 'new'
end
else
@map.errors.add(:base, I18n.t(:wrong_captcha))
render 'new'
end
end
end
def show
@map.zoom ||= 12
# this is used for the resolution slider
@resolution = @map.average_cm_per_pixel.round(4)
@resolution = 5 if @resolution < 5 # soft-set min res
# remove following lines once legacy interface is deprecated
render template: 'map/show', layout: 'knitter' if params[:legacy]
end
def archive
@map = Map.find_by_slug(params[:id])
if logged_in? && current_user.can_delete?(@map)
@map.archived = true
if @map.save
flash[:notice] = 'Archived map.'
else
flash[:error] = 'Failed to archive map.'
end
else
flash[:error] = 'Only admins may archive maps.'
end
redirect_to '/?_=' + Time.now.to_i.to_s
end
def embed
@map.zoom ||= 12
@embed = true
render template: 'maps/show'
end
def annotate
@map.zoom = 12 # get rid of this; use setBounds or something
@annotations = true # loads annotations-specific assets
end
def edit; end
def update
@map.name = params[:map][:name]
@map.location = params[:map][:location]
@map.lat = params[:map][:lat]
@map.lon = params[:map][:lon]
@map.description = params[:map][:description]
@map.license = params[:map][:license] if @map.user_id == current_user.id
save_tags(@map)
@map.save
redirect_to action: 'show'
end
def destroy
if current_user.can_delete?(@map)
@map.destroy
flash[:notice] = 'Map deleted.'
redirect_to '/'
else
flash[:error] = 'Only admins or map owners may delete maps.'
redirect_to "/maps/#{@map.slug}"
end
end
# used by leaflet to fetch corner coords of each warpable
def images
warpables = []
@map.warpables.each do |warpable|
warpables << warpable
warpables.last[:nodes] = warpable.nodes_array
warpables.last.src = warpable.image.url
warpables.last.srcmedium = warpable.image.url(:medium)
end
render json: warpables
end
# run the export
def export
if logged_in? || Rails.env.development? || verify_recaptcha(model: @map, message: "ReCAPTCHA thinks you're not a human!")
render text: @map.run_export(current_user, params[:resolution].to_f)
else
render text: 'You must be logged in to export, unless the map is anonymous.'
end
end
# render list of exports
def exports
render partial: 'maps/exports', layout: false
end
# list by region
def region
area = params[:id] || 'this area'
@title = "Maps in #{area}"
ids = Map.bbox(params[:minlat], params[:minlon], params[:maxlat], params[:maxlon]).collect(&:id)
@maps = Map.where(password: '')
.where('id IN (?)', ids)
.paginate(page: params[:page], per_page: 24)
.except(:styles)
@maps.each do |map|
map.image_urls = map.warpables.map { |warpable| warpable.image.url }
end
respond_to do |format|
format.html { render 'maps/index', layout: 'application' }
format.json { render json: @maps.to_json(methods: :image_urls) }
end
end
# list by license
def license
@title = "Maps licensed '#{params[:id]}'"
@maps = Map.where(password: '', license: params[:id])
.order('updated_at DESC')
.paginate(page: params[:page], per_page: 24)
render 'maps/index', layout: 'application'
end
def featured
@title = 'Featured maps'
@maps = Map.joins(:warpables)
.select('maps.*, count(maps.id) as image_count')
.group('warpables.map_id')
.order('image_count DESC')
.paginate(page: params[:page], per_page: 24)
render 'maps/index', layout: 'application'
end
def search
params[:id] ||= params[:q]
@maps = Map.select('archived, author created_at, description, id, lat, license, location, name, slug, tile_layer, tile_url, tiles, updated_at, user_id, version, zoom')
.where('archived = ? AND (name LIKE ? OR location LIKE ? OR description LIKE ?)', false, '%' + params[:id] + '%', '%' + params[:id] + '%', '%' + params[:id] + '%')
.paginate(page: params[:page], per_page: 24)
@title = "Search results for '#{params[:id]}'"
respond_to do |format|
format.html { render 'maps/index', layout: 'application' }
format.json { render json: @maps }
end
end
private
def find_map
@map = Map.find(params[:id])
end
end
# rubocop:enable LineLength