- name: Setup ruby
uses: ruby/setup-ruby@v1
with:
- ruby-version: 3.1
+ ruby-version: 3.2
rubygems: 3.4.10
bundler-cache: true
- name: Create base branch
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
env:
- ruby: '3.1'
+ ruby: '3.2'
jobs:
rubocop:
name: RuboCop
name: Ruby ${{ matrix.ruby }}
strategy:
matrix:
- ruby: ['3.1', '3.2', '3.3', '3.4']
+ ruby: ['3.2', '3.3', '3.4']
runs-on: ubuntu-latest
env:
RAILS_ENV: test
- ./.rubocop/specific_action_names.rb
AllCops:
- TargetRubyVersion: 3.1
+ TargetRubyVersion: 3.2
NewCops: enable
Exclude:
- 'vendor/**/*'
- 'bin/setup'
- 'bin/update'
+Style/RaiseArgs:
+ Exclude:
+ - 'lib/osm.rb'
+
Style/StringLiterals:
EnforcedStyle: double_quotes
- app/controllers/**/*.rb
Exclude:
# This is a todo list, but is currently too long for `rubocop --auto-gen-config`
- - 'app/controllers/api/changeset_comments_controller.rb'
- 'app/controllers/api/changesets_controller.rb'
- 'app/controllers/api/notes_controller.rb'
- 'app/controllers/api/user_preferences_controller.rb'
-FROM debian:bookworm
+FROM ruby:3.2-bookworm
ENV DEBIAN_FRONTEND=noninteractive
gem "cancancan"
gem "config"
gem "delayed_job_active_record"
-gem "dry-schema", "< 1.14.0" # see https://github.com/openstreetmap/openstreetmap-website/issues/5482
gem "dry-validation"
gem "frozen_record"
gem "http_accept_language", "~> 2.1.1"
# Used to validate widths
gem "unicode-display_width"
-# Lock some modules to old versions for ruby 3.1 support
-gem "zeitwerk", "< 2.7"
-
# Gems useful for development
group :development do
gem "better_errors"
autoprefixer-rails (10.4.19.0)
execjs (~> 2)
aws-eventstream (1.3.1)
- aws-partitions (1.1051.0)
- aws-sdk-core (3.218.1)
+ aws-partitions (1.1054.0)
+ aws-sdk-core (3.219.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
base64
jmespath (~> 1, >= 1.6.1)
- aws-sdk-kms (1.98.0)
+ aws-sdk-kms (1.99.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5)
- aws-sdk-s3 (1.181.0)
+ aws-sdk-s3 (1.182.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
concurrent-ruby (~> 1.0)
dry-core (~> 1.1)
zeitwerk (~> 2.6)
- dry-schema (1.13.4)
+ dry-schema (1.14.0)
concurrent-ruby (~> 1.0)
dry-configurable (~> 1.0, >= 1.0.1)
- dry-core (~> 1.0, < 2)
- dry-initializer (~> 3.0)
- dry-logic (>= 1.4, < 2)
- dry-types (>= 1.7, < 2)
+ dry-core (~> 1.1)
+ dry-initializer (~> 3.2)
+ dry-logic (~> 1.5)
+ dry-types (~> 1.8)
zeitwerk (~> 2.6)
dry-types (1.8.2)
bigdecimal (~> 3.0)
dry-inflector (~> 1.0)
dry-logic (~> 1.4)
zeitwerk (~> 2.6)
- dry-validation (1.10.0)
+ dry-validation (1.11.1)
concurrent-ruby (~> 1.0)
- dry-core (~> 1.0, < 2)
- dry-initializer (~> 3.0)
- dry-schema (>= 1.12, < 2)
+ dry-core (~> 1.1)
+ dry-initializer (~> 3.2)
+ dry-schema (~> 1.14)
zeitwerk (~> 2.6)
erb_lint (0.9.0)
activesupport
marcel (1.0.4)
matrix (0.4.2)
maxminddb (0.1.22)
- mini_magick (5.1.2)
+ mini_magick (5.2.0)
benchmark
logger
mini_mime (1.1.5)
lint_roller (~> 1.1)
rubocop (>= 1.72.1, < 2.0)
rubocop-ast (>= 1.38.0, < 2.0)
- rubocop-rails (2.30.1)
+ rubocop-rails (2.30.2)
activesupport (>= 4.2.0)
lint_roller (~> 1.1)
rack (>= 1.1)
actionpack (>= 6.1)
activesupport (>= 6.1)
sprockets (>= 3.0.0)
- stringio (3.1.3)
+ stringio (3.1.5)
strong_migrations (1.8.0)
activerecord (>= 5.2)
teaspoon (1.4.0)
i18n (>= 0.8.0)
simpleidn
vendorer (0.2.0)
- version_gem (1.1.4)
+ version_gem (1.1.6)
webmock (3.25.0)
addressable (>= 2.8.0)
crack (>= 0.3.2)
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
- zeitwerk (2.6.18)
+ zeitwerk (2.7.2)
PLATFORMS
ruby
doorkeeper
doorkeeper-i18n
doorkeeper-openid_connect
- dry-schema (< 1.14.0)
dry-validation
erb_lint
factory_bot_rails
validates_email_format_of (>= 1.5.1)
vendorer
webmock
- zeitwerk (< 2.7)
BUNDLED WITH
2.5.22
## Minimum requirements
-* Ruby 3.1+
+* Ruby 3.2+
* PostgreSQL 13+
* Bundler (see note below about [developer Ruby setup](#rbenv))
* Javascript Runtime
can [:read, :feed, :search], Note
can :create, Note unless user
- can [:read, :download], Changeset
+ can :read, Changeset
can :read, ChangesetComment
can :read, Tracepoint
can :read, User
end
if user.moderator?
- can [:destroy, :restore], ChangesetComment if scopes.include?("write_changeset_comments")
+ can [:create, :destroy], :changeset_comment_visibility if scopes.include?("write_changeset_comments")
can :destroy, Note if scopes.include?("write_notes")
--- /dev/null
+module Api
+ module ChangesetComments
+ class VisibilitiesController < ApiController
+ before_action :check_api_writable
+ before_action :authorize
+
+ authorize_resource :class => :changeset_comment_visibility
+
+ before_action :set_request_formats
+
+ ##
+ # Sets visible flag on comment to true
+ def create
+ # Check the arguments are sane
+ raise OSM::APIBadUserInput, "No id was given" unless params[:changeset_comment_id]
+
+ # Extract the arguments
+ changeset_comment_id = params[:changeset_comment_id].to_i
+
+ # Find the changeset
+ comment = ChangesetComment.find(changeset_comment_id)
+
+ # Unhide the comment
+ comment.update(:visible => true)
+
+ # Return a copy of the updated changeset
+ @changeset = comment.changeset
+
+ respond_to do |format|
+ format.xml
+ format.json
+ end
+ end
+
+ ##
+ # Sets visible flag on comment to false
+ def destroy
+ # Check the arguments are sane
+ raise OSM::APIBadUserInput, "No id was given" unless params[:changeset_comment_id]
+
+ # Extract the arguments
+ changeset_comment_id = params[:changeset_comment_id].to_i
+
+ # Find the changeset
+ comment = ChangesetComment.find(changeset_comment_id)
+
+ # Hide the comment
+ comment.update(:visible => false)
+
+ # Return a copy of the updated changeset
+ @changeset = comment.changeset
+
+ respond_to do |format|
+ format.xml
+ format.json
+ end
+ end
+ end
+ end
+end
# Add a comment to a changeset
def create
# Check the arguments are sane
- raise OSM::APIBadUserInput, "No id was given" unless params[:id]
+ raise OSM::APIBadUserInput, "No id was given" unless params[:changeset_id]
raise OSM::APIBadUserInput, "No text was given" if params[:text].blank?
raise OSM::APIRateLimitExceeded if rate_limit_exceeded?
# Extract the arguments
- id = params[:id].to_i
+ changeset_id = params[:changeset_id].to_i
body = params[:text]
# Find the changeset and check it is valid
- changeset = Changeset.find(id)
+ changeset = Changeset.find(changeset_id)
raise OSM::APIChangesetNotYetClosedError, changeset if changeset.open?
# Add a comment to the changeset
end
end
- ##
- # Sets visible flag on comment to false
- def destroy
- # Check the arguments are sane
- raise OSM::APIBadUserInput, "No id was given" unless params[:id]
-
- # Extract the arguments
- id = params[:id].to_i
-
- # Find the changeset
- comment = ChangesetComment.find(id)
-
- # Hide the comment
- comment.update(:visible => false)
-
- # Return a copy of the updated changeset
- @changeset = comment.changeset
- render "api/changesets/show"
-
- respond_to do |format|
- format.xml
- format.json
- end
- end
-
- ##
- # Sets visible flag on comment to true
- def restore
- # Check the arguments are sane
- raise OSM::APIBadUserInput, "No id was given" unless params[:id]
-
- # Extract the arguments
- id = params[:id].to_i
-
- # Find the changeset
- comment = ChangesetComment.find(id)
-
- # Unhide the comment
- comment.update(:visible => true)
-
- # Return a copy of the updated changeset
- @changeset = comment.changeset
- render "api/changesets/show"
-
- respond_to do |format|
- format.xml
- format.json
- end
- end
-
private
##
--- /dev/null
+module Api
+ module Changesets
+ class DownloadsController < ApiController
+ before_action :setup_user_auth
+
+ authorize_resource :changeset
+
+ before_action :set_request_formats
+
+ ##
+ # download the changeset as an osmChange document.
+ #
+ # to make it easier to revert diffs it would be better if the osmChange
+ # format were reversible, i.e: contained both old and new versions of
+ # modified elements. but it doesn't at the moment...
+ #
+ # this method cannot order the database changes fully (i.e: timestamp and
+ # version number may be too coarse) so the resulting diff may not apply
+ # to a different database. however since changesets are not atomic this
+ # behaviour cannot be guaranteed anyway and is the result of a design
+ # choice.
+ def show
+ changeset = Changeset.find(params[:changeset_id])
+
+ # get all the elements in the changeset which haven't been redacted
+ # and stick them in a big array.
+ elements = if show_redactions?
+ [changeset.old_nodes,
+ changeset.old_ways,
+ changeset.old_relations].flatten
+ else
+ [changeset.old_nodes.unredacted,
+ changeset.old_ways.unredacted,
+ changeset.old_relations.unredacted].flatten
+ end
+
+ # sort the elements by timestamp and version number, as this is the
+ # almost sensible ordering available. this would be much nicer if
+ # global (SVN-style) versioning were used - then that would be
+ # unambiguous.
+ elements.sort_by! { |e| [e.timestamp, e.version] }
+
+ # generate an output element for each operation. note: we avoid looking
+ # at the history because it is simpler - but it would be more correct to
+ # check these assertions.
+ @created = []
+ @modified = []
+ @deleted = []
+
+ elements.each do |elt|
+ if elt.version == 1
+ # first version, so it must be newly-created.
+ @created << elt
+ elsif elt.visible
+ # must be a modify
+ @modified << elt
+ else
+ # if the element isn't visible then it must have been deleted
+ @deleted << elt
+ end
+ end
+
+ respond_to do |format|
+ format.xml
+ end
+ end
+
+ private
+
+ def show_redactions?
+ current_user&.moderator? && params[:show_redactions] == "true"
+ end
+ end
+ end
+end
@changeset = Changeset.find(params[:id])
if params[:include_discussion].presence
@comments = @changeset.comments
- @comments = @comments.unscope(:where => :visible) if params[:show_hidden_comments].presence && can?(:restore, ChangesetComment)
+ @comments = @comments.unscope(:where => :visible) if params[:show_hidden_comments].presence && can?(:create, :changeset_comment_visibility)
@comments = @comments.includes(:author)
end
end
end
- ##
- # download the changeset as an osmChange document.
- #
- # to make it easier to revert diffs it would be better if the osmChange
- # format were reversible, i.e: contained both old and new versions of
- # modified elements. but it doesn't at the moment...
- #
- # this method cannot order the database changes fully (i.e: timestamp and
- # version number may be too coarse) so the resulting diff may not apply
- # to a different database. however since changesets are not atomic this
- # behaviour cannot be guaranteed anyway and is the result of a design
- # choice.
- def download
- changeset = Changeset.find(params[:id])
-
- # get all the elements in the changeset which haven't been redacted
- # and stick them in a big array.
- elements = [changeset.old_nodes.unredacted,
- changeset.old_ways.unredacted,
- changeset.old_relations.unredacted].flatten
-
- # sort the elements by timestamp and version number, as this is the
- # almost sensible ordering available. this would be much nicer if
- # global (SVN-style) versioning were used - then that would be
- # unambiguous.
- elements.sort_by! { |e| [e.timestamp, e.version] }
-
- # generate an output element for each operation. note: we avoid looking
- # at the history because it is simpler - but it would be more correct to
- # check these assertions.
- @created = []
- @modified = []
- @deleted = []
-
- elements.each do |elt|
- if elt.version == 1
- # first version, so it must be newly-created.
- @created << elt
- elsif elt.visible
- # must be a modify
- @modified << elt
- else
- # if the element isn't visible then it must have been deleted
- @deleted << elt
- end
- end
-
- respond_to do |format|
- format.xml
- end
- end
-
##
# updates a changeset's tags. none of the changeset's attributes are
# user-modifiable, so they will be ignored.
@note_includes_anonymous = @note.author.nil? || @note_comments.find { |comment| comment.author.nil? }
- @note_comments = @note_comments.drop(1) if @note.author.nil? || @note.author.active?
+ @note_comments = @note_comments.drop(1) if @note_comments.first&.event == "opened"
rescue ActiveRecord::RecordNotFound
render :template => "browse/not_found", :status => :not_found
end
##
# display a list of users matching specified criteria
def show
- @params = params.permit(:status, :ip, :before, :after)
+ @params = params.permit(:status, :username, :ip, :before, :after)
users = User.all
users = users.where(:status => @params[:status]) if @params[:status].present?
+ users = users.where("LOWER(email) = LOWER(?) OR LOWER(NORMALIZE(display_name, NFKC)) = LOWER(NORMALIZE(?, NFKC))", @params[:username], @params[:username]) if @params[:username].present?
users = users.where("creation_address <<= ?", @params[:ip]) if @params[:ip].present?
@users_count = users.limit(501).count
module NoteHelper
include ActionView::Helpers::TranslationHelper
- def note_description(author, description)
+ def note_description(author, description, first_comment)
if !author.nil? && author.status == "deleted"
RichText.new("text", t("notes.show.description_when_author_is_deleted"))
+ elsif first_comment&.event != "opened"
+ RichText.new("text", t("notes.show.description_when_there_is_no_opening_comment"))
else
description
end
tag.svg path_tag, :width => 16, :height => 16
end
- def previous_page_svg_tag(**options)
- adjacent_page_svg_tag(dir == "rtl" ? 1 : -1, **options)
+ def previous_page_svg_tag(**)
+ adjacent_page_svg_tag(dir == "rtl" ? 1 : -1, **)
end
- def next_page_svg_tag(**options)
- adjacent_page_svg_tag(dir == "rtl" ? -1 : 1, **options)
+ def next_page_svg_tag(**)
+ adjacent_page_svg_tag(dir == "rtl" ? -1 : 1, **)
end
def key_svg_tag(**options)
# Return the note's description, derived from the first comment
def description
if user_ip.nil? && user_id.nil?
- all_comments.first.body
+ all_comments.first.body if all_comments.first&.event == "opened"
else
RichText.new("text", super)
end
# Return the note's author object, derived from the first comment
def author
if user_ip.nil? && user_id.nil?
- all_comments.first.author
+ all_comments.first.author if all_comments.first&.event == "opened"
else
super
end
--- /dev/null
+json.partial! "api/root_attributes"
+
+json.changeset do
+ json.partial! "api/changesets/changeset", :changeset => @changeset
+end
--- /dev/null
+xml.instruct! :xml, :version => "1.0"
+
+xml.osm(OSM::API.new.xml_root_attributes) do |osm|
+ osm << render(:partial => "api/changesets/changeset", :object => @changeset)
+end
--- /dev/null
+json.partial! "api/root_attributes"
+
+json.changeset do
+ json.partial! "api/changesets/changeset", :changeset => @changeset
+end
--- /dev/null
+xml.instruct! :xml, :version => "1.0"
+
+xml.osm(OSM::API.new.xml_root_attributes) do |osm|
+ osm << render(:partial => "api/changesets/changeset", :object => @changeset)
+end
xml.osmChange(OSM::API.new.xml_root_attributes) do |osm|
@created.each do |elt|
osm.create do |create|
- create << render(elt)
+ create << render(:partial => "api/#{elt.to_partial_path}", :object => elt)
end
end
@modified.each do |elt|
osm.modify do |modify|
- modify << render(elt)
+ modify << render(:partial => "api/#{elt.to_partial_path}", :object => elt)
end
end
@deleted.each do |elt|
osm.delete do |delete|
- delete << render(elt)
+ delete << render(:partial => "api/#{elt.to_partial_path}", :object => elt)
end
end
end
@changesets.each do |changeset|
feed.entry(changeset, :updated => changeset.closed_at, :id => changeset_url(changeset.id, :only_path => false)) do |entry|
entry.link :rel => "alternate",
- :href => changeset_show_url(changeset, :only_path => false),
+ :href => api_changeset_url(changeset, :only_path => false),
:type => "application/osm+xml"
entry.link :rel => "alternate",
- :href => changeset_download_url(changeset, :only_path => false),
+ :href => api_changeset_download_url(changeset, :only_path => false),
:type => "application/osmChange+xml"
if !changeset.tags.empty? && changeset.tags.key?("comment")
—
<%= tag.button t(".#{comment.visible ? 'hide' : 'unhide'}_comment"),
:class => "btn btn-sm small btn-link link-secondary p-0 align-baseline",
- :data => { :method => "POST",
- :url => comment.visible ? changeset_comment_hide_url(comment) : changeset_comment_unhide_url(comment) } %>
+ :data => { :method => comment.visible ? "DELETE" : "POST",
+ :url => api_changeset_comment_visibility_path(comment) } %>
<% end %>
</small>
<div class="mx-2">
:name => "comment",
:disabled => true,
:data => { :method => "POST",
- :url => changeset_comment_url(@changeset) } %>
+ :url => api_changeset_changeset_comments_path(@changeset) } %>
</div>
</form>
<% else %>
</div>
<div class='secondary-actions'>
- <%= link_to(t(".changesetxml"), :controller => "api/changesets", :action => "show") %>
+ <%= link_to t(".changesetxml"), api_changeset_path(@changeset) %>
·
- <%= link_to(t(".osmchangexml"), :controller => "api/changesets", :action => "download") %>
+ <%= link_to t(".osmchangexml"), api_changeset_download_path(@changeset) %>
</div>
<% if @next_by_user || @prev_by_user %>
</td>
<td><%= link_to note.id, note %></td>
<td><%= note_author(note.author) %></td>
- <td><%= note_description(note.author, note.description).to_html %></td>
+ <td><%= note_description(note.author, note.description, current_user&.moderator? ? note.comments.unscope(:where => :visible).first : note.comments.first).to_html %></td>
<td><%= friendly_date_ago(note.created_at) %></td>
<td><%= friendly_date_ago(note.updated_at) %></td>
</tr>
<div>
<h4><%= t(".description") %></h4>
<div class="overflow-hidden ms-2">
- <%= note_description(@note.author, @note.description).to_html %>
+ <%= note_description(@note.author, @note.description, current_user&.moderator? ? @note.comments.unscope(:where => :visible).first : @note.comments.first).to_html %>
</div>
<div class="details" data-coordinates="<%= @note.lat %>,<%= @note.lon %>" data-status="<%= @note.status %>">
:data => { :behavior => "category_dropdown" },
:class => "form-select" %>
</div>
+ <div class="mb-3 col-md">
+ <%= text_field_tag :username,
+ params[:username],
+ :placeholder => t(".name_or_email"),
+ :autocomplete => "on",
+ :class => "form-control" %>
+ </div>
<div class="mb-3 col-md">
<%= text_field_tag :ip,
params[:ip],
APP_ROOT = File.expand_path("..", __dir__)
APP_NAME = "openstreetmap".freeze
-def system!(*args)
- system(*args, :exception => true)
+def system!(*)
+ system(*, :exception => true)
end
FileUtils.chdir APP_ROOT do
resource "/diary/*/rss", :headers => :any, :methods => [:get]
resource "/trace/*/data", :headers => :any, :methods => [:get]
resource "/user/*/diary/rss", :headers => :any, :methods => [:get]
+ resource "/rails/active_storage/*", :headers => :any, :methods => [:get]
end
end
accounts:
show:
title: Рэдагаваць уліковы запіс
+ my_account: Мой уліковы запіс
current email address: Бягучы адрас электроннай пошты
external auth: Знешняя Аўтэнтыфікацыя
openid:
Калі ласка, прайдзіце па спасылцы і азнаёмцеся з тэкстам.'
read_tou: Я згаджаюся з Умовамі выкарыстання
continue: Працягнуць
+ cancel: Скасаваць
you need to accept or decline: Калі ласка, прачытайце, а потым згадзіцеся
ці адхіліце новыя ўмовы супрацоўніцтва для працягу.
legale_select: 'Краіна пражывання:'
allow_write_prefs: měnit jejich uživatelské nastavení
allow_write_diary: vytvářet deníkové záznamy a komentáře
allow_write_api: upravovat mapu
+ allow_write_changeset_comments: komentovat sady změn
allow_read_gpx: číst jejich soukromé GPS stopy
allow_write_gpx: nahrávat GPS stopy
allow_write_notes: měnit poznámky
accounts:
show:
title: Upravit účet
+ my_account: Můj účet
current email address: Stávající e-mailová adresa
external auth: Externí autentizace
openid:
agreed_with_pd: Také jste prohlásili, že své editace považujete za volné dílo.
link: https://wiki.openstreetmap.org/wiki/Cs:Open_Database_License/Contributor_Terms?uselang=cs
link text: co to znamená?
+ not_agreed_with_pd: Neprohlásili jste, že své editace považujete za volné
+ dílo.
+ pd_link_text: prohlásit
save changes button: Uložit změny
delete_account: Smazat účet…
go_public:
pro přispěvatele. Podrobnější informace najdete na %{terms_declined_link}.
terms_declined_link: této wikistránce
terms_declined_url: http://wiki.openstreetmap.org/wiki/CS:Contributor_Terms_Declined?uselang=cs
+ pd_declarations:
+ show:
+ title: Považujte mé příspěvky za volné dílo
+ consider_pd: Považuji své příspěvky za volné dílo
+ consider_pd_why: Proč bych mohl chtít, aby moje příspěvky byly volným dílem?
+ confirm: Potvrdit
+ create:
+ successfully_declared: Úspěšně jste prohlásili, že své příspěvky považujete
+ za volné dílo.
+ already_declared: Již dříve jste prohlásili, že své příspěvky považujete za
+ volné dílo.
+ did_not_confirm: Nepotvrdili jste, že považujete své příspěvky za volné dílo.
browse:
deleted_ago_by_html: Smazáno %{time_ago} uživatelem %{user}
edited_ago_by_html: Upraveno %{time_ago} uživatelem %{user}
start_rjs:
feature_warning: Načítá se %{num_features} prvků, což může váš prohlížeč zpomalit
či zablokovat. Určitě chcete tato data zobrazit?
+ feature_error: 'Nepodařilo se načíst prvky: %{message}'
load_data: Nahrát data
loading: Načítá se…
tag_details:
bridleway: Koňská stezka
bus_guideway: Autobusová dráha
bus_stop: Autobusová zastávka
+ busway: Trasa metrobusu
construction: Silnice ve výstavbě
corridor: Koridor
crossing: Přechod
offline_flash:
osm_offline: Databáze OpenStreetMap je momentálně kvůli probíhající neodkladné
údržbě mimo provoz.
+ osm_read_only: Databáze OpenStreetMap je momentálně kvůli probíhající neodkladné
+ údržbě pouze pro čtení.
+ expected_restore_html: Očekáváme se, že služby budou obnoveny v %{time}.
announcement: Oznámení si můžete přečíst zde.
user_mailer:
diary_comment_notification:
write_prefs: Měnit preference uživatele
write_diary: Vytvářet deníkové záznamy a komentáře
write_api: Upravovat mapu
+ write_changeset_comments: Komentovat sady změn
read_gpx: Číst soukromé GPS stopy
write_gpx: Nahrávat GPS stopy
write_notes: Měnit poznámky
write_redactions: Skrývat mapová data
+ write_blocks: Vytvářet a rušit blokování uživatelů
read_email: Přečíst e-mailovou adresu uživatele
consume_messages: Číst, aktualizovat stav a mazat zprávy uživatelů
send_messages: Posílat soukromé zprávy jiným uživatelům
my notes: Moje poznámky k mapě
my messages: Moje zprávy
my profile: Můj profil
+ my_account: Můj účet
my comments: Moje komentáře
my_preferences: Moje preference
my_dashboard: Moje nástěnka
show:
title: Uživatelé
heading: Uživatelé
+ select_status: Vyberte stav
+ states:
+ pending: Čekající
+ active: Aktivní
+ confirmed: Potvrzený
+ suspended: Pozastavený
+ deleted: Smazaný
+ name_or_email: Jméno nebo e-mail
+ ip_address: IP adresa
+ search: Hledat
page:
found_users:
one: Nalezen %{count} uživatel
closed_title: 'Vyřešená poznámka #%{note_name}'
hidden_title: 'Skrytá poznámka #%{note_name}'
description_when_author_is_deleted: smazáno
+ description_when_there_is_no_opening_comment: neznámé
event_opened_by_html: Vytvořeno uživatelem %{user} %{time_ago}
event_opened_by_anonymous_html: Vytvořeno anonymním uživatelem %{time_ago}
event_commented_by_html: Komentář od uživatele %{user} %{time_ago}
ninth: "9."
tenth: "10."
time: Čas
+ download: Stáhnout trasu jako GeoJSON
+ filename: trasa
query:
node: Uzel
way: Cesta
show_address: Zobrazit adresu
query_features: Průzkum prvků
centre_map: Zde vystředit mapu
+ home:
+ marker_title: Poloha mého domova
+ not_set: Ve vašem účtu není nastavena poloha domova
redactions:
edit:
heading: Upravit redakci
allow_write_prefs: addasu eu dewisiadau defnyddiwr
allow_write_diary: creu cofnodion dyddiadur a sylwadau
allow_write_api: golygu'r map
+ allow_write_changeset_comments: rhoi sylwadau ar grwpiau newid
allow_read_gpx: darllen eu harllwybrau GPS
allow_write_gpx: uwchlwytho olion GPS
allow_write_notes: addasu nodiadau
accounts:
show:
title: Golygu cyfrif
+ my_account: Fy Nghyfrif
current email address: Cyfeiriad E-bost Cyfredol
external auth: Dilysu Allanol
openid:
+ link: https://wiki.openstreetmap.org/wiki/OpenID
link text: beth yw hwn?
contributor terms:
heading: Telerau Cyfranwyr
newydd.
agreed_with_pd: Rydych hefyd wedi datgan eich bod yn ystyried bod eich golygiadau
yn y Parth Cyhoeddus.
+ link: https://osmfoundation.org/wiki/Licence/Contributor_Terms
link text: beth yw hwn?
+ not_agreed_with_pd: Nid ydych wedi datgan eich bod yn ystyried bod eich golygiadau
+ yn y Parth Cyhoeddus.
+ pd_link_text: datgan
save changes button: Cadw Newidiadau
delete_account: Dileu Cyfrif...
go_public:
a lleoliad cartref yn cael eu dileu.
delete_display_name: Bydd eich enw defnyddiwr yn cael ei ddileu, a gellir
ei ailddefnyddio gan gyfrifon eraill.
+ retain_caveats: 'Fodd bynnag, bydd rhywfaint o wybodaeth amdanoch yn cael
+ ei chadw ar OpenStreetMap, hyd yn oed ar ôl i''ch cyfrif gael ei ddileu:'
retain_edits: Bydd eich golygiadau i'r gronfa ddata mapiau, os ydynt yn bodoli,
yn cael eu cadw.
retain_traces: Cedwir unrhyw olion rydych chi wedi uwchlwytho os ydynt yn
terms_declined_url: https://wiki.openstreetmap.org/wiki/Contributor_Terms_Declined
pd_declarations:
show:
+ title: Ystyried bod fy nghyfraniadau yn y Parth Cyhoeddus
+ consider_pd: Ystyriaf fod fy nghyfraniadau yn y Parth Cyhoeddus
+ consider_pd_why: Pam fyddwn am gael fy nghyfraniadau yn y Parth Cyhoeddus?
consider_pd_why_url: https://osmfoundation.org/wiki/Licence_and_Legal_FAQ/Why_would_I_want_my_contributions_to_be_public_domain
+ confirm: Cadarnhau
+ create:
+ successfully_declared: Rydych wedi datgan yn llwyddiannus eich bod yn ystyried
+ bod eich golygiadau yn y Parth Cyhoeddus.
browse:
deleted_ago_by_html: Dilëwyd %{time_ago} gan %{user}
edited_ago_by_html: Golygwyd %{time_ago} gan %{user}
title: Heb ei Ganfod
timeout:
title: Gwall Goramser
- sorry: Sori, cymerodd yn rhy hir i adalw data math %{type} gyda'r id %{id}.
+ sorry: 'Mae''n ddrwg gennym, cymerodd rhy hir i nôl data %{type} #%{id}.'
type:
node: nod
way: llwybr
start_rjs:
feature_warning: Wrthi'n llwytho %{num_features} nodwedd, a all arafu neu chwalu
eich porwr. Ydych chi wir eisiau gweld y data?
+ feature_error: 'Ni ellid llwytho nodweddion: %{message}'
load_data: Llwytho Data
loading: Wrthi'n llwytho...
tag_details:
view_redacted_data: Gweld Data Wedi'i Gorchuddio
view_redaction_message: Gweld Neges Orchuddio
nodes:
+ not_found_message:
+ sorry: 'Mae''n ddrwg gennym, ni ellid dod o hyd i nod #%{id}.'
timeout:
- sorry: Sori, cymerodd yn rhy hir i adalw data'r nod gyda'r id %{id}.
+ sorry: 'Mae''n ddrwg gennym, cymerodd rhy hir i nôl data nod #%{id}.'
old_nodes:
not_found_message:
- sorry: 'Sori, ni ellir canfod fersiwn %{version} o''r nod #%{id}.'
+ sorry: 'Mae''n ddrwg gennym, ni ellid dod o hyd i fersiwn %{version} o nod #%{id}.'
timeout:
- sorry: Sori, cymerodd yn rhy hir i adalw hanes y nod gyda'r id %{id}.
+ sorry: 'Mae''n ddrwg gennym, cymerodd rhy hir i nôl hanes nod #%{id}.'
ways:
+ not_found_message:
+ sorry: 'Mae''n ddrwg gennym, ni ellid dod o hyd i lwybr #%{id}.'
timeout:
- sorry: Sori, cymerodd yn rhy hir i adalw data'r llwybr gyda'r id %{id}.
+ sorry: 'Mae''n ddrwg gennym, cymerodd rhy hir i nôl data llwybr #%{id}.'
old_ways:
not_found_message:
- sorry: 'Sori, ni ellir canfod fersiwn %{version} o lwybr #%{id}.'
+ sorry: 'Mae''n ddrwg gennym, ni ellid dod o hyd i fersiwn %{version} o lwybr
+ #%{id}.'
timeout:
- sorry: Sori, cymerodd yn rhy hir i adalw hanes y llwybr gyda'r id %{id}.
+ sorry: 'Mae''n ddrwg gennym, cymerodd rhy hir i nôl hanes llwybr #%{id}.'
relations:
+ not_found_message:
+ sorry: 'Mae''n ddrwg gennym, ni ellid dod o hyd i berthynas #%{id}.'
timeout:
- sorry: Sori, cymerodd yn rhy hir i adalw data'r perthynas gyda'r id %{id}.
+ sorry: 'Mae''n ddrwg gennym, cymerodd rhy hir i nôl data perthynas #%{id}.'
old_relations:
not_found_message:
- sorry: 'Sori, ni ellir canfod fersiwn %{version} o''r perthynas #%{id}.'
+ sorry: 'Mae''n ddrwg gennym, ni ellid dod o hyd i fersiwn %{version} o berthynas
+ #%{id}.'
timeout:
- sorry: Sori, cymerodd yn rhy hir i adalw hanes y perthynas gyda'r id %{id}.
+ sorry: 'Mae''n ddrwg gennym, cymerodd rhy hir i nôl hanes perthynas #%{id}.'
changeset_comments:
feeds:
comment:
title_all: Trafodaeth grŵp newid OpenStreetMap
title_particular: Trafodaeth grŵp newid OpenStreetMap %{changeset_id}
timeout:
- sorry: Sori, cymerodd yn rhy hir i adalw rhestr o sylwadau grŵp newid y gofynnoch
- amdanynt.
+ sorry: Mae'n ddrwg gennym, cymerodd rhy hir i nôl rhestr o sylwadau grŵp newid
+ y gofynnoch amdanynt.
changesets:
changeset:
no_edits: (dim golygiadau)
title: Grwpiau newid
title_user: Grwpiau newid gan %{user}
title_user_link_html: Grwpiau newid gan %{user_link}
+ title_followed: Grwpiau newid gan bobl rydych yn eu dilyn
title_nearby: Grwpiau newid gan ddefnyddwyr gerllaw
empty: Heb ganfod grwpiau newid.
empty_area: Heb ganfod grwpiau newid yn yr ardal hon.
ways_paginated: Llwybrau (%{x}-%{y} o %{count})
relations: Perthnasau (%{count})
relations_paginated: Perthnasau (%{x}-%{y} o %{count})
+ not_found_message:
+ sorry: 'Mae''n ddrwg gennym, ni ellid dod o hyd i grŵp newid #%{id}.'
timeout:
- sorry: Sori, cymerodd y rhestr o grwpiau newid y gofynnoch amdanynt rhy hir
- i'w hadalw.
+ sorry: Mae'n ddrwg gennym, cymerodd rhy hir i nôl rhestr o grŵp newid y gofynnoch
+ amdanynt.
changeset_subscriptions:
show:
subscribe:
created_by_html: Crëwyd gan %{link_user} ar %{created}.
no_such_entry:
heading: 'Dim cofnod gyda''r id: %{id}'
- body: Mae'n ddrwg gennym, nid oes grŵp newid gyda'r id %{id}. Gwiriwch eich
- sillafu, neu efallai bod y ddolen rydych chi wedi ei chlicio arni'n anghywir.
+ body: Mae'n ddrwg gennym, nid oes grŵp newid gyda'r cyfeirnod %{id}. Gwiriwch
+ eich sillafu, neu efallai bod y ddolen rydych chi wedi ei chlicio arni'n anghywir.
dashboards:
contact:
km away: '%{count}km i ffwrdd'
no_such_entry:
title: Dim cofnod dyddiadur
heading: 'Dim cofnod gyda''r id: %{id}'
- body: Mae'n ddrwg gennym, nid oes cofnod dyddiadur neu sylw gyda'r id %{id}.
- Gwiriwch eich sillafu, neu efallai bod y ddolen rydych chi wedi ei chlicio
- arni'n anghywir.
+ body: Mae'n ddrwg gennym, nid oes cofnod dyddiadur neu sylw gyda'r cyfeirnod
+ %{id}. Gwiriwch eich sillafu, neu efallai bod y ddolen rydych chi wedi ei
+ chlicio arni'n anghywir.
diary_entry:
posted_by_html: Postiwyd gan %{link_user} ar %{created} yn %{language_link}
updated_at_html: Diweddarwyd ddiwethaf ar %{updated}.
heading: Ydych chi am ddilyn %{user}?
button: Dilyn Defnyddiwr
unfollow:
+ heading: Ydych chi am ddad-ddilyn %{user}?
button: Dad-ddilyn Defnyddiwr
create:
success: Rydych nawr yn dilyn %{name}!
+ failed: Mae'n ddrwg gennym, mae eich cais i ddilyn %{name} wedi methu.
already_followed: Rydych chi eisoes yn dilyn %{name}.
+ destroy:
+ success: Rydych chi wedi dad-ddilyn %{name}.
+ not_followed: Nid ydych yn dilyn %{name}.
geocoder:
search:
title:
bridleway: Llwybr Ceffyl
bus_guideway: Lon Bysiau
bus_stop: Safle Bws
+ busway: Ffordd Fws
construction: Priffordd yn cael ei Adeiladu
corridor: Coridor
crossing: Croesfan
track: Trac Rhedeg
water_park: Parc Dŵr
"yes": Hamdden
+ lock:
+ "yes": Loc
man_made:
adit: Adit
advertising: Hysbysebu
reservoir: Cronfa Ddŵr
basin: Basn Dwr
fishpond: Pwll Pysgod
+ lagoon: Lagŵn
+ wastewater: Dŵr Gwastraff
+ lock: Loc
waterway:
artificial: Dyfrffyrdd Artiffisial
boatyard: Iard Gychod
reports: Adroddiadau
last_updated: Diweddarwyd ddiwethaf
last_updated_time_ago_user_html: '%{time_ago} gan %{user}'
+ reporting_users: Defnyddiwyr sydd wedi rhoi gwybod
reports_count:
zero: '%{count} Adroddiad'
one: '%{count} Adroddiad'
few: '%{count} Adroddiad'
many: '%{count} Adroddiad'
other: '%{count} Adroddiad'
+ more_reporters: a %{count} arall
reported_item: Eitem a roddwyd gwybod
states:
ignored: Anwybyddwyd
reopened: Mae statws y mater wedi'i osod i 'Agored'
comments:
comment_from_html: Sylw gan %{user_link} ar %{comment_created_at}
+ reassign_to_moderators: Ailbennu Mater i Gymedrolwyr
+ reassign_to_administrators: Ailbennu Mater i Weinyddwyr
reports:
reported_by_html: Adroddwyd fel %{category} gan %{user} ar %{updated_at}
helper:
communities: Cymunedau
learn_more: Dysgu Rhagor
more: Rhagor
+ offline_flash:
+ osm_offline: Mae cronfa ddata OpenStreetMap all-lein ar hyn o bryd er mwyn gwneud
+ gwaith cynnal a chadw hanfodol.
+ osm_read_only: Nid yw'n bosib golygu cronfa ddata OpenStreetMap ar hyn o bryd
+ tra bod gwaith cynnal a chadw hanfodol yn digwydd.
+ expected_restore_html: Disgwylir i wasanaethau gael eu hadfer ymhen %{time}.
+ announcement: Gallwch ddarllen y cyhoeddiad yma.
user_mailer:
diary_comment_notification:
description: 'Cofnod Dyddiadur OpenStreetMap #%{id}'
follow_notification:
hi: Helo %{to_user},
subject: '[OpenStreetMap] Mae %{user} wedi eich dilyn'
+ followed_you: Mae %{user} bellach yn eich dilyn ar OpenStreetMap.
see_their_profile: 'Gallwch weld eu proffil yma: %{userurl}.'
see_their_profile_html: 'Gallwch weld eu proffil yma: %{userurl}.'
+ follow_them: Gallwch hefyd ddilyn y defnyddiwr hwn yn %{followurl}.
+ follow_them_html: Gallwch hefyd ddilyn y defnyddiwr hwn yn %{followurl}.
gpx_details:
details: 'Manylion eich ffeil:'
filename: Enw ffeil
no_such_message:
title: Dim neges o'r fath
heading: Dim neges o'r fath
- body: Sori, nid oes neges gyda'r id yno.
+ body: Mae'n ddrwg gennym, nid oes neges gyda'r cyfeirnod yno.
show:
title: Darllen neges
reply_button: Ateb
login_button: Mewngofnodi
with external: neu fewngofnodi gyda thrydydd parti
or: neu
- auth failure: Mae'n ddrwg gennym, ni ellir mewngofnodi gyda'r manylion hynny.
+ auth failure: Mae'n ddrwg gennym, ni ellid mewngofnodi gyda'r manylion hynny.
destroy:
title: Allgofnodi
heading: Allgofnodi o OpenStreetMap
not_public_flash:
not_public: Nid ydych wedi gosod eich golygiadau i fod yn gyhoeddus.
user_page_link: tudalen defnyddiwr
+ anon_edits_html: (%{link})
+ anon_edits_link: https://wiki.openstreetmap.org/wiki/Disabling_anonymous_edits
anon_edits_link_text: Gweld pam.
edit:
id_not_configured: iD heb ei ffurfweddu
trace_uploaded: Mae eich ffeil GPX wedi'i huwchlwytho ac yn aros i gael ei chynnwys
yn y gronfa ddata. Bydd hyn fel arfer yn digwydd o fewn hanner awr, a bydd
e-bost yn cael ei anfon atoch ar ôl cwblhau.
- upload_failed: Mae'n ddrwg gennym, methodd eich uwchlwythiad GPX. Mae gweinyddwr
- wedi cael gwybod am y gwall. Ceisiwch eto.
+ upload_failed: Mae'n ddrwg gennym, mae eich uwchlwythiad GPX wedi methu. Mae
+ gweinyddwr wedi cael gwybod am y gwall. Ceisiwch eto.
traces_waiting:
zero: Mae gennych %{count} ôl yn aros i'w uwchlwytho. Arhoswch i'r rhain orffen
cyn uwchlwytho rhagor, er mwyn osgoi rhwystro'r ciw i ddefnyddwyr eraill.
write_prefs: Addasu dewisiadau defnyddwyr
write_diary: Creu cofnodion dyddiadur a sylwadau
write_api: Golygu'r map
+ write_changeset_comments: Rhoi sylwadau ar grwpiau newid
read_gpx: Darllen olion GPS preifat
write_gpx: Uwchlwytho olion GPS
write_notes: Addasu nodiadau
write_redactions: Gorchuddio data map
+ write_blocks: Creu a dirymu blociau defnyddwyr
read_email: Darllen cyfeiriad e-bost defnyddwyr
consume_messages: Darllen, diweddaru statws a dileu negeseuon defnyddiwr
send_messages: Anfon negeseuon preifat at ddefnyddwyr eraill
confirm_delete: Dileu'r ap hwn?
client_id: ID Cleient
client_secret: Cyfrinach Cleient
+ client_secret_warning: Gwnewch yn siŵr eich bod yn cadw'r gyfrinach hon - ni
+ fydd ar gael i chi eto
permissions: Caniatadau
redirect_uris: Ailgyfeirio URIs
oauth2_authorizations:
my notes: Nodiadau
my messages: Negeseuon
my profile: Proffil
+ my_account: Fy Nghyfrif
my comments: Sylwadau
my_preferences: Dewisiadau
my_dashboard: Dangosfwrdd
show:
title: Defnyddwyr
heading: Defnyddwyr
+ select_status: Dewiswch Statws
+ states:
+ pending: Arfaethedig
+ active: Gweithredol
+ confirmed: Cadarnhawyd
+ suspended: Wedi'u hatal
+ deleted: Wedi'u dileu
+ name_or_email: Enw neu Gyfeiriad E-bost
+ ip_address: Cyfeiriad IP
+ search: Chwilio
page:
found_users:
zero: Canfuwyd %{count} defnyddiwr
summary_no_ip_html: '%{name} wedi''i greu ar %{date}'
comments:
index:
+ heading_html: Sylwadau %{user}
changesets: Grwpiau newid
- diary_entries: Cofnodion dyddiadur
+ diary_entries: Cofnodion Dyddiadur
no_comments: Dim sylwadau
changeset_comments:
index:
suspended:
title: Cyfrif wedi'i atal
heading: Cyfrif wedi'i atal
- support: cymorth
+ support: chymorth
automatically_suspended: Mae'n ddrwg gennym, mae eich cyfrif wedi'i atal yn
awtomatig oherwydd gweithgarwch amheus.
+ contact_support_html: Bydd y penderfyniad hwn yn cael ei adolygu gan weinyddwr
+ yn fuan, neu gallwch gysylltu â %{support_link} os hoffech drafod hyn.
auth_failure:
no_authorization_code: Dim cod awdurdodi
invalid_scope: Sgop annilys
open_title: 'Nodyn heb ei ddatrys #%{note_name}'
closed_title: 'Nodyn wedi''i ddatrys #%{note_name}'
hidden_title: 'Nodyn cudd #%{note_name}'
+ description_when_author_is_deleted: wedi'i ddileu
+ description_when_there_is_no_opening_comment: anhysbys
event_opened_by_html: Crëwyd gan %{user} %{time_ago}
event_opened_by_anonymous_html: Crëwyd gan berson ddienw %{time_ago}
event_commented_by_html: Sylw gan %{user} %{time_ago}
wybod i fapwyr eraill fel y gallwn ei ddatrys. Symudwch y marciwr i'r safle
cywir ac ysgrifennwch nodyn i esbonio'r broblem.
anonymous_warning_html: Nid ydych chi wedi mewngofnodi. %{log_in} neu %{sign_up}
- os ydych chi eisiau derbyn diweddariadau am eich nodyn.
+ os ydych am gael diweddariadau ar gyfer eich nodyn a helpu mapwyr eraill i'w
+ ddatrys.
anonymous_warning_log_in: Mewngofnodwch
anonymous_warning_sign_up: gofrestrwch
+ counter_warning_html: Rydych chi eisoes wedi creu o leiaf %{x_anonymous_notes},
+ sy'n wych i'r gymuned, diolch! Nawr rydym yn eich annog i %{contribute_by_yourself},
+ nid yw mor gymhleth â hynny, a %{community_can_help}.
+ x_anonymous_notes:
+ zero: '%{count} nodyn dienw'
+ one: '%{count} nodyn dienw'
+ two: '%{count} nodyn dienw'
+ few: '%{count} nodyn dienw'
+ many: '%{count} nodyn dienw'
+ other: '%{count} nodyn dienw'
counter_warning_guide_link:
+ text: gyfrannu eich hun
url: https://wiki.openstreetmap.org/wiki/Beginners%27_guide
+ counter_warning_forum_link:
+ text: gall y gymuned eich helpu
advice: Mae eich nodyn yn gyhoeddus a gellid ei ddefnyddio i ddiweddaru'r map,
felly peidiwch ag ysgrifennu gwybodaeth bersonol, na gwybodaeth o fapiau hawlfreintiedig
neu gyfeiriaduron.
showing_page: Tudalen %{page}
next: Nesaf
previous: Cynt
+ not_found_message:
+ sorry: 'Mae''n ddrwg gennym, ni ellid dod o hyd i nodyn #%{id}.'
javascripts:
close: Cau
share:
distance_km: '%{distance}km'
errors:
no_route: Ni ellir dod o hyd i'r llwybr rhwng y ddau le.
- no_place: Ymddiheuriadau - ni ellir canfod '%{place}'.
+ no_place: Mae'n ddrwg gennym - ni ellid dod o hyd i '%{place}'.
instructions:
continue_without_exit: Parhau ar %{name}
slight_right_without_exit: Ychydig i'r dde i %{name}
ninth: 9fed
tenth: 10fed
time: Amser
+ download: Lawrlwytho'r llwybr fel GeoJSON
+ filename: ffordd
query:
node: Nod
way: Llwybr
show_address: Dangos cyfeiriad
query_features: Ymholiad nodweddion
centre_map: Canoli'r map yma
+ home:
+ marker_title: Fy lleoliad cartref
+ not_set: Nid yw lleoliad cartref wedi'i osod ar gyfer eich cyfrif
redactions:
edit:
heading: Golygu Gorchuddiad
fælleseje/uden ophavsret.
link text: hvad er dette?
not_agreed_with_pd: Du har ikke erklæret, at du anser dine ændringer for at
- være i det offentlige domæne, dvs. fælleseje/uden ophavsret.
+ være i det offentlige domæne (Public Domain), dvs. fælleseje/uden ophavsret.
pd_link_text: erklær
save changes button: Gem ændringer
delete_account: Slet konto
show:
title: Betragt mine bidrag for at være i det offentlige domæne
consider_pd: Jeg anser mine bidrag for at være i det offentlige domæne
- consider_pd_why: Hvorfor skulle jeg gerne have, at mine bidrag er i det offentlige
- domæne?
+ consider_pd_why: Hvorfor skulle jeg have et ønske om, at mine bidrag er i
+ det offentlige domæne?
confirm: Bekræft
create:
successfully_declared: Du har erklæret, at du anser dine redigeringer for
confirmed: Bekræftet
suspended: Suspenderet
deleted: Slettet
+ name_or_email: Navn eller e-mail
ip_address: IP-adresse
search: Søg
page:
closed_title: 'Løst bemærkning #%{note_name}'
hidden_title: 'Skjult bemærkning #%{note_name}'
description_when_author_is_deleted: slettet
+ description_when_there_is_no_opening_comment: ukendt
event_opened_by_html: Oprettet af %{user} %{time_ago}
event_opened_by_anonymous_html: Oprettet af anonym %{time_ago}
event_commented_by_html: Kommentar fra %{user} %{time_ago}
ninth: "9."
tenth: "10."
time: Tid
+ download: Download rute som GeoJSON
+ filename: rute
query:
node: Punkt
way: Vej
# Author: Manfredbrandl
# Author: Markobr
# Author: MarkusHD
+# Author: Marwin H.H.
# Author: McDutchie
# Author: Mcandri13
# Author: Mcliquid
confirmed: Bestätigt
suspended: Ausgesetzt
deleted: Gelöscht
+ name_or_email: Name oder E-Mail
ip_address: IP-Adresse
search: Suchen
page:
closed_title: Erledigter Hinweis Nr. %{note_name}
hidden_title: Versteckter Hinweis Nr. %{note_name}
description_when_author_is_deleted: gelöscht
+ description_when_there_is_no_opening_comment: unbekannt
event_opened_by_html: Erstellt von %{user} %{time_ago}
event_opened_by_anonymous_html: Erstellt von anonym %{time_ago}
event_commented_by_html: Kommentar von %{user} %{time_ago}
ninth: neunte
tenth: zehnte
time: Zeit
+ download: Route als GeoJSON herunterladen
+ filename: route
query:
node: Knoten
way: Linie
confirmed: Confirmed
suspended: Suspended
deleted: Deleted
+ name_or_email: Name or Email
ip_address: IP Address
search: Search
page:
closed_title: "Resolved note #%{note_name}"
hidden_title: "Hidden note #%{note_name}"
description_when_author_is_deleted: "deleted"
+ description_when_there_is_no_opening_comment: "unknown"
event_opened_by_html: "Created by %{user} %{time_ago}"
event_opened_by_anonymous_html: "Created by anonymous %{time_ago}"
event_commented_by_html: "Comment from %{user} %{time_ago}"
havaĵo.
consider_pd_why: Kiel vi volus, ke miaj kontribuaĵoj estu publikaj?
confirm: Konfirmi
+ create:
+ successfully_declared: Vi sukcese deklaris, por ke viaj redaktoj estu en la
+ publika havaĵo.
+ already_declared: Vi jam deklaris, por ke viaj redaktoj estu en la publika
+ havaĵo.
+ did_not_confirm: Vi malkonsentis, por ke viaj redaktoj estu en la publika
+ havaĵo.
browse:
deleted_ago_by_html: Forigita %{time_ago} de %{user}
edited_ago_by_html: Redaktita %{time_ago} de %{user}
bridleway: Ĉevalvojo
bus_guideway: Aŭtobus-trako
bus_stop: Haltejo aŭtobusa
+ busway: Aŭtobusa vojo
construction: Vojo konstruata
corridor: Koridoro
crossing: Trapasejo
reports: Raportoj
last_updated: Laste aktualigita
last_updated_time_ago_user_html: '%{time_ago} de %{user}'
+ reporting_users: Raportantaj uzantoj
reports_count:
one: '%{count} raporto'
other: '%{count} raportoj'
reopened: Problemo estas malfermita
comments:
comment_from_html: Komento fare de %{user_link} je %{comment_created_at}
+ reassign_to_moderators: Reasigni problemon al kontrolantoj
+ reassign_to_administrators: Reasigni problemon al administrantoj
reports:
reported_by_html: Raportita kiel %{category} fare de %{user} je %{updated_at}
helper:
communities: Komunumoj
learn_more: Ekscii pli
more: Pli
+ offline_flash:
+ osm_offline: La OpenStreetMap-datumbazo estas nuntempe eksterreta pro necesaj
+ laboroj de prizorgado.
+ osm_read_only: La OpenStreetMap-datumbazo estas nuntempe en nurlega reĝimo pro
+ necesaj laboroj de prizorgado.
+ expected_restore_html: La servoj probable estos restarigitaj je %{time}.
+ announcement: Vi povas legi la afiŝon tie ĉi.
user_mailer:
diary_comment_notification:
description: 'OpenStreetMap: taglibra afiŝo %{id}'
write_prefs: modifi preferojn de uzanto
write_diary: afiŝi en taglibro kaj komenti
write_api: redakti la mapon
+ write_changeset_comments: komenti ŝanĝarojn
read_gpx: legi privatajn GPS-spurojn
write_gpx: alŝuti GPS-spurojn
write_notes: modifi rimarkojn
write_redactions: Redakti map-datumojn
+ write_blocks: krei kaj nuligi blokadojn al uzantoj
read_email: legi retpoŝtan adreson de uzanto
consume_messages: legi, ŝanĝi staton kaj forigi mesaĝojn de uzanto
send_messages: sendi privatajn mesaĝojn al aliaj uzantoj
my notes: Miaj rimarkoj
my messages: Mesaĝoj
my profile: Profilo
+ my_account: Mia konto
my comments: Miaj komentoj
my_preferences: Preferoj
my_dashboard: Panelo
show:
title: Uzantoj
heading: Uzantoj
+ select_status: Elekti staton
+ states:
+ pending: pritraktata
+ active: aktiva
+ confirmed: konfirmita
+ suspended: blokita
+ deleted: forigita
+ name_or_email: Nomo aŭ retpoŝta adreso
+ ip_address: IP-adreso
+ search: Serĉi
page:
found_users:
one: '%{count} trovita uzanto'
comments:
index:
heading_html: Komentoj de %{user}
- changesets: pri ŝanĝaroj
- diary_entries: pri taglibraj afiŝoj
+ changesets: Ŝanĝaroj
+ diary_entries: Taglibroj
no_comments: Neniu komento
changeset_comments:
index:
when: Kiam
comment: Komento
suspended:
- title: Konto haltigita
- heading: Konto haltigita
+ title: Konto blokita
+ heading: Konto blokita
support: subtena teamo
automatically_suspended: Bedaŭrinde via konto estas aŭtomate blokita pro suspektinda
agado.
open_title: 'Nesolvita rimarko #%{note_name}'
closed_title: 'Solvita rimarko #%{note_name}'
hidden_title: 'Kaŝita rimarko #%{note_name}'
+ description_when_author_is_deleted: forigita
+ description_when_there_is_no_opening_comment: nekonata
event_opened_by_html: Kreita de %{user} %{time_ago}
event_opened_by_anonymous_html: Anonime kreita %{time_ago}
event_commented_by_html: Komento de %{time_ago} de %{user}
ninth: 9-an
tenth: 10-an
time: Tempo
+ download: Elŝuti kurson kiel GeoJSON
+ filename: kurso
query:
node: Nodo
way: Linio
show_address: Montri adreson
query_features: Informoj pri objektoj
centre_map: Centrigi mapon ĉi tien
+ home:
+ marker_title: Mia hejmloko
+ not_set: Hejmloko ne estas agordita por via konto
redactions:
edit:
heading: Redakti korekton
allow_write_prefs: modifier les préférences de l’utilisateur
allow_write_diary: créer des entrées du journal et des commentaires
allow_write_api: modifier la carte
+ allow_write_changeset_comments: commenter les changements
allow_read_gpx: lire ses traces GPS privées
allow_write_gpx: téléverser des traces GPS
allow_write_notes: modifier les notes
accounts:
show:
title: Editar a conta
+ my_account: A miña conta
current email address: Enderezo de correo electrónico actual
external auth: Autenticación externa
openid:
+ link: https://wiki.openstreetmap.org/wiki/OpenID
link text: que é isto?
contributor terms:
heading: Termos do colaborador
do colaborador.
agreed_with_pd: Tamén declaraches que consideras que as túas edicións pertencen
ó dominio público.
+ link: https://osmfoundation.org/wiki/Licence/Contributor_Terms
link text: que é isto?
+ not_agreed_with_pd: Non declaraches que consideras que as túas edicións pertencen
+ ó dominio público.
+ pd_link_text: declárao
save changes button: Gardar as modificacións
delete_account: Borrar a conta...
go_public:
terms_declined_url: https://wiki.openstreetmap.org/wiki/Contributor_Terms_Declined
pd_declarations:
show:
+ title: Considerar as miñas contribucións de dominio público
+ consider_pd: Considero que as miñas contribucións son de dominio público
+ consider_pd_why: Por que querería que as miñas contribucións sexan de dominio
+ público?
consider_pd_why_url: https://osmfoundation.org/wiki/Licence_and_Legal_FAQ/Why_would_I_want_my_contributions_to_be_public_domain
+ confirm: Confirmar
+ create:
+ successfully_declared: Declaraches que consideras que as túas edicións pertencen
+ ao dominio público.
+ already_declared: Xa declaraches que consideras que as túas edicións pertencen
+ ao dominio público.
+ did_not_confirm: Non confirmaches que consideras que as túas edicións pertencen
+ ao dominio público.
browse:
deleted_ago_by_html: Borrado %{time_ago} por %{user}
edited_ago_by_html: Editado %{time_ago} por %{user}
failure: Non foi posíbel actualizar o perfil.
sessions:
new:
- tab_title: Acceder ao sistema
+ tab_title: Iniciar a sesión
login_to_authorize_html: Inicia sesión no OpenStreetMap para acceder a %{client_app_name}.
email or username: Enderezo de correo electrónico ou nome de usuario
password: Contrasinal
write_gpx: Subir pistas GPS
write_notes: Modificar notas
write_redactions: Censurar datos do mapa
+ write_blocks: Crear e revogar bloqueos de usuarios
read_email: Ver os enderezos de correo electrónico dos usuarios
consume_messages: Ver, actualizar o estado e borrar mensaxes dos usuarios
send_messages: Enviar mensaxes privadas aos usuarios
my notes: As miñas notas do mapa
my messages: As miñas mensaxes
my profile: O meu perfil
+ my_account: A miña conta
my comments: Os meus comentarios
my_preferences: As miñas preferencias
my_dashboard: O meu panel de control
show:
title: Usuarios
heading: Usuarios
+ select_status: Seleccionar estado
+ states:
+ pending: Pendente
+ active: Activo
+ confirmed: Confirmado
+ suspended: Suspendido
+ deleted: Borrado
+ name_or_email: Nome ou correo electrónico
+ ip_address: Enderezo IP
+ search: Procurar
page:
found_users:
one: Atopouse %{count} usuario
closed_title: Nota resolta n.º %{note_name}
hidden_title: Nota agochada n.º %{note_name}
description_when_author_is_deleted: eliminado
+ description_when_there_is_no_opening_comment: descoñecido
event_opened_by_html: Creado por %{user} %{time_ago}
event_opened_by_anonymous_html: Creado por un usuario anónimo %{time_ago}
event_commented_by_html: Comentario de %{user} %{time_ago}
ninth: 9.ª
tenth: 10.ª
time: Tempo
+ download: Descargar a ruta como GeoJSON
+ filename: ruta
query:
node: Nó
way: Vía
show_address: Amosar enderezo
query_features: Consultar elementos
centre_map: Centrar o mapa aquí
+ home:
+ marker_title: Localización da miña casa
+ not_set: A localización da casa non está configurada para a túa conta
redactions:
edit:
heading: Editar a censura
accounts:
show:
title: Modifica profilo
- my_account: Il mio profilo
+ my_account: La mia utenza
current email address: Indirizzo email attuale
external auth: Autenticazione esterna
openid:
my notes: Le mie note
my messages: I miei messaggi
my profile: Il mio profilo
- my_account: Il mio profilo
+ my_account: La mia utenza
my comments: I miei commenti
my_preferences: Preferenze
my_dashboard: La mia dashboard
confirmed: Confermato
suspended: Sospeso
deleted: Cancellato
+ name_or_email: Nome o e-mail
ip_address: Indirizzo IP
search: Cerca
page:
closed_title: 'Nota risolta #%{note_name}'
hidden_title: 'Nota nascosta #%{note_name}'
description_when_author_is_deleted: cancellato
+ description_when_there_is_no_opening_comment: sconosciuto
event_opened_by_html: Creata da %{user} %{time_ago}
event_opened_by_anonymous_html: Creata da anonimo %{time_ago}
event_commented_by_html: Commento da %{user} %{time_ago}
ninth: 9ª
tenth: 10ª
time: Tempo
+ download: Scarica l'itinerario come GeoJson
+ filename: itinerario
query:
node: Nodo
way: Percorso
confirmed: 확인됨
suspended: 정지됨
deleted: 삭제됨
+ name_or_email: 이름 또는 이메일
ip_address: IP 주소
search: 검색
page:
open_title: '해결되지 않은 참고 #%{note_name}'
closed_title: '해결된 참고 #%{note_name}'
hidden_title: '숨겨진 참고 #%{note_name}'
+ description_when_there_is_no_opening_comment: 알 수 없음
event_opened_by_html: '%{time_ago} %{user}님이 생성함'
event_opened_by_anonymous_html: '%{time_ago} 익명의 사용자가 생성함'
event_commented_by_html: '%{time_ago} %{user}님의 댓글'
my notes: Meng Notizen
my messages: Meng Messagen
my profile: Mäi Profil
+ my_account: Mäi Benotzerkont
my comments: Meng Bemierkungen
my_preferences: Meng Benotzerastellungen
my_dashboard: Meng Iwwersiichtssäit
active: Aktiv
confirmed: Confirméiert
deleted: Geläscht
+ name_or_email: Numm oder E-Mail
ip_address: IP-Adress
search: Sichen
page:
closed_title: 'Geléisten Hiweis #%{note_name}'
hidden_title: Verstoppt Notiz N° %{note_name}
description_when_author_is_deleted: geläscht
+ description_when_there_is_no_opening_comment: onbekannt
report: Dësen Hiweis mellen
discussion: Diskussioun
subscribe: Abonéieren
ninth: néngt
tenth: zéngt
time: Zäit
+ download: Streck als GeoJSON eroflueden
+ filename: Streck
query:
way: Wee
relation: Relatioun
niet te onderschijven, maar moet ze wel gezien hebben.
settings_menu:
account_settings: Accountinstellingen
- oauth2_applications: OAuth 2 toepassingen
- oauth2_authorizations: OAuth 2 autorisaties
+ oauth2_applications: OAuth 2-toepassingen
+ oauth2_authorizations: OAuth 2-autorisaties
muted_users: Gedempte gebruikers
auth_providers:
openid_url: OpenID-URL
start_rjs:
feature_warning: Wczytywanie %{num_features} obiektów, może spowolnić lub zawiesić
przeglądarkę. Wyświetlić te dane?
+ feature_error: 'Błąd przy ładowaniu obiektów: %{message}'
load_data: Wczytaj dane
loading: Wczytywanie...
tag_details:
reports: Zgłoszenia
last_updated: Ostatnia aktualizacja
last_updated_time_ago_user_html: '%{time_ago} przez %{user}'
+ reporting_users: Raportowanie użytkowników
reports_count:
one: 1 zgłoszenie
few: '%{count} zgłoszenia'
many: '%{count} zgłoszeń'
other: '%{count} zgłoszenia'
+ more_reporters: i jeszcze %{count}
reported_item: Zgłoszony element
states:
ignored: Zignorowano
reopened: Status sprawy został ustawiony na „Otwarta”
comments:
comment_from_html: Komentarz od %{user_link} z %{comment_created_at}
+ reassign_to_moderators: Przydziel sprawę moderatorom
+ reassign_to_administrators: Przydziel sprawę administratorom
reports:
reported_by_html: Zgłoszone %{updated_at} jako %{category} przez %{user}
helper:
communities: Społeczności
learn_more: Dowiedz się więcej
more: Więcej
+ offline_flash:
+ osm_offline: Baza danych OpenStreetMap jest w trybie offline na czas ważnych
+ zadań administracyjnych, które są w tym momencie wykonywane.
+ osm_read_only: Baza danych OpenStreetMap jest w trybie tylko do odczytu na czas
+ ważnych zadań administracyjnych, które są w tym momencie wykonywane.
+ expected_restore_html: Przywrócenie usług spodziewane jest w ciągu %{time}.
+ announcement: Ogłoszenie można przeczytać tutaj.
user_mailer:
diary_comment_notification:
description: 'Wpis dziennika OpenStreetMap #%{id}'
show:
title: Użytkownicy
heading: Użytkownicy
+ select_status: Wybierz status
+ name_or_email: Nazwa lub e-mail
+ ip_address: Adres IP
+ search: Szukaj
page:
found_users:
one: Znaleziono %{count} użytkownika
ninth: "9."
tenth: "10."
time: Czas
+ download: Pobierz trasę jako GeoJSON
+ filename: trasa
query:
node: Węzeł
way: Linia
show_address: Pokaż adres
query_features: Wyświetl dane obiektów
centre_map: Wycentruj mapę tutaj
+ home:
+ marker_title: Położenie domu
+ not_set: Położenie domu nie jest ustawione w twoim profilu
redactions:
edit:
heading: Edytuj poprawkę
# Author: Anton Khorev
# Author: Ashed
# Author: Banonotit
+# Author: Borealex
# Author: BushmanK
# Author: Butko
# Author: CM3X
# Author: XnL
# Author: Yuri Nazarov
# Author: Yurik
+# Author: Yurina Tatiana
# Author: Yuryleb
# Author: Zverik
# Author: Александр Сигачёв
allow_write_prefs: изменять пользовательские настройки
allow_write_diary: создавать записи в дневнике и комментарии
allow_write_api: редактировать карту
+ allow_write_changeset_comments: комментировать пакеты правок
allow_read_gpx: читать частные GPS-треки
allow_write_gpx: загружать GPS-треки
allow_write_notes: исправлять заметки
accounts:
show:
title: Изменить учетную запись
+ my_account: Мой аккаунт
current email address: Текущий адрес электронной почты
external auth: 'Внешняя аутентификация:'
openid:
в общественном достоянии.
link: https://openstreetmap.org/wiki/RU:Open_Database_License/Contributor_Terms?uselang=ru
link text: что это?
+ not_agreed_with_pd: Вы не заявили, что считаете свои правки находящимися в
+ общественном достоянии.
+ pd_link_text: объявить
save changes button: Сохранить изменения
delete_account: Удалить учётную запись…
go_public:
start_rjs:
feature_warning: Необходимо загрузить %{num_features} объектов, что может замедлить
ваш браузер. Вы уверены, что хотите просмотреть эти данные?
+ feature_error: 'Не удалось загрузить объекты: %{message}'
load_data: Загрузить данные
loading: Загружается…
tag_details:
nearby users: Другие ближайшие пользователи
no nearby users: Пока нет других пользователей, которые признают, что занимаются
составлением карты поблизости.
+ followed_changesets: пакеты правок
+ followed_diaries: дневники
nearby_changesets: пакеты правок соседей
nearby_diaries: дневники соседей
diary_entries:
scopes:
read_prefs: Прочитать настройки пользователя
write_prefs: Изменить настройки пользователя
- write_diary: Создавать записи в дневнике, комментировать и заводить друзей
+ write_diary: Создавать записи в дневнике и комментарии
write_api: Изменить карту
read_gpx: Читать частные GPS-треки
write_gpx: Загрузить GPS-треки
my notes: Мои заметки
my messages: Мои сообщения
my profile: Мой профиль
+ my_account: Мой аккаунт
my comments: Мои комментарии
my_preferences: Мои предпочтения
my_dashboard: Мой пульт
heading: Пользователи
states:
pending: В ожидании
+ active: Активен
confirmed: Подтверждено
suspended: Приостановлено
deleted: Удалено
+ name_or_email: Имя или адрес эл. почты
ip_address: IP-адрес
search: Поиск
page:
summary_no_ip_html: '%{name} создан %{date}'
comments:
index:
+ heading_html: Комментарии пользователя %{user}
+ changesets: Пакеты правок
diary_entries: Записи в дневнике
+ no_comments: Нету комментариев
changeset_comments:
page:
+ changeset: Пакет правок
when: Когда
comment: Комментарий
diary_comments:
title: Комментарии к записям в дневнике, добавленные пользователем %{user}
page:
post: Сообщение
+ when: Когда
+ comment: Комментарий
suspended:
title: Учётная запись приостановлена
heading: Учётная запись приостановлена
query_features: Что здесь?
centre_map: Центрировать карту
home:
+ marker_title: Мой домашний адрес
not_set: Установка места нахождения не установлена для вашей учётной записи
redactions:
edit:
# Author: Ajeje Brazorf
# Author: Saraiki
# Author: Sayam Asjad
+# Author: Umar Shahid
---
skr-arab:
html:
eighth: ٨واں
ninth: ٩واں
tenth: ١٠واں
+ download: روٹ کوں GeoJSON دے طور تے ڈاؤن لوڈ کرو۔
redactions:
show:
confirm: بھلا تہاکوں پک ہے؟
ste jo dodali. Opomba je v bližini %{place}.'
commented_note_html: '%{commenter} je spet aktiviral_a opombo na zemljevidu,
ki ste jo dodali. Opomba je v bližini %{place}.'
- details: Več podatkov o opombi lahko najdete na %{url}.
+ details: Več podatkov o opombi je na voljo na %{url}.
details_html: Na opombo lahko odgovorite ali izveste več o njej na %{url}.
changeset_comment_notification:
description: Nabor sprememb OpenStreetMap št. %{id}
status: Stanje
navigation:
block: 'Blokiraj #%{id}'
+ new_block: Novo blokiranje
user_mutes:
index:
title: Utišani uporabniki
heading: Корисници
states:
deleted: Обрисано
+ name_or_email: Име или имејл
ip_address: IP адреса
search: Претрага
page:
closed_title: Решена белешка бр. %{note_name}
hidden_title: Скривена белешка бр. %{note_name}
description_when_author_is_deleted: обрисано
+ description_when_there_is_no_opening_comment: непознато
event_opened_by_html: Направио %{user} %{time_ago}
report: пријави ову белешку
anonymous_warning: Ова белешка садржи коментаре анонимних корисника које би
allow_write_prefs: ändra deras användaralternativ
allow_write_diary: skapa dagboksinlägg och kommentarer
allow_write_api: ändra kartan
+ allow_write_changeset_comments: kommentar på ändringsuppsättning
allow_read_gpx: läs deras privata GPS-spår
allow_write_gpx: ladda upp GPS-spår
allow_write_notes: ändra anteckningar
accounts:
show:
title: Redigera konto
+ my_account: Mitt konto
current email address: Nuvarande e-postadress
external auth: Extern autentisering
openid:
agreed_with_pd: Du har också förklarat att du anser att dina redigeringar
är inom Public Domain.
link text: vad är detta?
+ not_agreed_with_pd: Du har inte förklarat att du anser att dina redigeringar
+ är inom Public Domain.
+ pd_link_text: förklara
save changes button: Spara ändringar
delete_account: Radera konto...
go_public:
terms_declined_html: Vi beklagar att du bestämt dig för att inte acceptera
de nya användarvillkoren. För mer information, se %{terms_declined_link}.
terms_declined_link: denna wikisida
+ pd_declarations:
+ show:
+ title: Anse att mina bidrag är i public domain
+ consider_pd: Jag anser mina bidrag vara i public domain
+ consider_pd_why: Varför skulle jag vilja ha mina bidrag i public domain?
+ confirm: Bekräfta
+ create:
+ successfully_declared: Du har förklarat att du anser att dina redigeringar
+ är inom public domain.
browse:
deleted_ago_by_html: Raderades %{time_ago} av %{user}
edited_ago_by_html: Redigerades %{time_ago} av %{user}
my notes: Mina kartanteckningar
my messages: Mina meddelanden
my profile: Min profil
+ my_account: Mitt konto
my comments: Mina kommentarer
my_preferences: Mina alternativ
my_dashboard: Min kontrollpanel
show:
title: Användare
heading: Användare
+ select_status: Välj status
+ states:
+ pending: Pågående
+ active: Aktiv
+ confirmed: Bekräftad
+ suspended: Uppskjutet
+ deleted: Raderad
+ ip_address: IP-adress
+ search: Sök
page:
found_users:
one: '%{count} användare hittade'
closed_title: 'Avklarad anteckning #%{note_name}'
hidden_title: 'Dold anteckning #%{note_name}'
description_when_author_is_deleted: raderad
+ description_when_there_is_no_opening_comment: okänd
event_opened_by_html: Skapades av %{user} %{time_ago}
event_opened_by_anonymous_html: Skapades av anonym %{time_ago}
event_commented_by_html: Kommenterades från %{user} %{time_ago}
ninth: 9:e
tenth: 10:e
time: Tid
+ download: Ladda ner rutt som GeoJSON
+ filename: rutt
query:
node: Nod
way: Sträcka
show_address: Visa adress
query_features: Undersök kartobjekt
centre_map: Centrera kartan här
+ home:
+ marker_title: Min hemort
+ not_set: Hemort har inte angetts för ditt konto
redactions:
edit:
heading: Redigera maskering
accounts:
show:
title: แก้ไขบัญชี
+ my_account: บัญชีของฉัน
current email address: ที่อยู่อีเมลปัจจุบัน
external auth: การยืนยันตัวตนด้วยบริการภายนอก
openid:
review link text: โปรดเข้าลิงก์นี้ตามความสะดวกของคุณเพื่อตรวจสอบและยอมรับข้อกำหนดของผู้ร่วมให้ข้อมูลใหม่
agreed_with_pd: คุณยังได้ประกาศด้วยว่า คุณถือว่าการแก้ไขของคุณถือว่าเป็นสาธารณสมบัติ
link text: นี่คืออะไร?
+ pd_link_text: ประกาศ
save changes button: บันทึกการเปลี่ยนแปลง
delete_account: ลบบัญชี...
go_public:
contributor_terms_explain: ข้อตกลงนี้ใช้บังคับกับข้อกำหนดสำหรับการมีส่วนร่วมในปัจจุบันและในอนาคตของคุณ
read_ct: ฉันได้อ่านและยอมรับเงื่อนไขของผู้มีส่วนร่วมให้ข้อมูลข้างต้นแล้ว
read_tou: ข้าพเจ้าได้อ่านและเห็นด้วยในข้อกำหนดการใช้งาน
+ informal_translations: การแปลแบบไม่เป็นทางการ
continue: ถัดไป
cancel: ยกเลิก
you need to accept or decline: กรุณาตรวจทานและเลือกยอมรับหรือไม่ยอมรับข้อกำหนดของผู้ร่วมให้ข้อมูลเพื่อไปต่อ
rest_of_world: พื้นที่อื่น ๆ ในโลก
update:
terms accepted: ขอบคุณสำหรับการตอบรับเงื่อนไขผู้ร่วมให้ข้อมูล!
+ pd_declarations:
+ show:
+ confirm: ยืนยัน
browse:
deleted_ago_by_html: ลบเมื่อ %{time_ago} โดย %{user}
edited_ago_by_html: แก้ไขเมื่อ %{time_ago} โดย %{user}
wayside_shrine: ศาลเจ้าริมทาง
wreck: ซากปรักหักพัง
"yes": สถานที่ประวัติศาสตร์
+ information:
+ office: สำนักงานบริการนักท่องเที่ยว
junction:
"yes": ทางแยก
landuse:
building_passage: ทางลอดใต้อาคาร
culvert: ท่อระบายน้ำ
"yes": อุโมงค์
+ water:
+ lake: ทะเลสาบ
+ pond: สระน้ำ
+ reservoir: อ่างเก็บน้ำ
+ lagoon: ลากูน
+ wastewater: น้ำเสีย
+ oxbow: ทะเลสาบรูปแอก
waterway:
artificial: ทางน้ำที่มนุษย์สร้าง
boatyard: ที่จอดเรือ
เพิ่มข้อมูล หรือกระทำการให้เกิดสิ่งอื่นใดใหม่ขึ้นต่องานที่มีนี้ ท่านสามารถแจกจ่ายได้แต่เพียงภายใต้สัญญาอนุญาตเดียวกันเท่านั้น
โปรดดู%{copyright_license_link}สำหรับลายละเอียดเพิ่มเติม
legal_title: ข้อกำหนดทางกฎหมาย
+ legal_1_1_terms_of_use: ข้อกำหนดการใช้งาน
+ legal_1_1_aup: นโยบายการใช้งานที่ยอมรับได้
+ legal_1_1_privacy_policy: นโยบายความเป็นส่วนตัว
+ legal_2_1_html: โปรดไปที่ %{contact_the_osmf_link} หากคุณมีปัญหาหรือข้อสงสัยเกี่ยวกับการอนุญาตให้ใช้งาน
+ ลิขสิทธิ์ หรือข้อสงสัยด้านกฎหมายอื่น ๆ
partners_title: องค์กรพันธมิตร
copyright:
title: ลิขสิทธิ์และสัญญาอนุญาต
native_link: รุ่นภาษาTHIS_LANGUAGE_NAME_HERE
mapping_link: เริ่มการทำแผนที่
legal_babble:
+ introduction_1_open_data: ข้อมูลเปิดเผย
introduction_2_html: คุณสามารถคัดลอก แจกจ่าย ถ่ายทอด และดัดแปลงข้อมูลของเราได้อย่างเสรี
ตราบใดที่คุณให้อ้างอิงเครดิต OpenStreetMap และผู้ร่วมให้ข้อมูล ถ้าคุณแก้ไข
หรือสร้างข้อมูลต่อจากข้อมูลของเรา คุณสามารถเผยแพร่ผลลัพธ์ภายใต้สัญญาเดิมเท่านั้น
credit_1_html: |-
เราจำเป็นต้องให้ท่านแสดงที่มาหรือคำขอบคุณแก่ “© ผู้ร่วมสร้างสรรค์ OpenStreetMap
”.
+ credit_3_attribution_guidelines: แนวทางการระบุแหล่งที่มา
attribution_example:
alt: ตัวอย่างการอ้างอิง OpenStreetMap บนหน้าเว็บ
title: ตัวอย่างการอ้างอิง
contributors_at_stadt_wien: เมืองเวียนนา
contributors_at_land_vorarlberg: แลนด์ ฟอร์อาร์ลแบร์ค
contributors_at_cc_by_at_with_amendments: CC BY AT with amendments
+ contributors_cz_czechia: เช็กเกีย
+ contributors_fi_finland: ฟินแลนด์
+ contributors_fr_france: ฝรั่งเศส
+ contributors_hr_croatia: โครเอเชีย
+ contributors_si_slovenia: สโลวีเนีย
+ contributors_si_gu: หน่วยงานสำรวจและจัดทำแผนที่
+ contributors_si_mkgp: กระทรวงการเกษตร ป่าไม้ และอาหาร
+ contributors_es_credit_html: '%{spain}: ประกอบด้วยข้อมูลที่มาจากสถาบันภูมิศาสตร์แห่งชาติสเปน
+ (%{ign_link}) และระบบการทำแผนที่แห่งชาติสเปน (%{scne_link}) ซึ่งได้รับอนุญาตให้ทำซ้ำภายใต้สัญญา
+ %{cc_by_link}'
+ contributors_es_spain: สเปน
contributors_footer_2_html: การรวมข้อมูลใน OpenStreetMap ไม่ได้หมายความว่าผู้ให้บริการข้อมูลดั้งเดิมจะรับรอง
OpenStreetMap รับประกัน หรือรับผิดชอบใด ๆ
infringement_title_html: การละเมิดลิขสิทธิ์
infringement_1_html: ผู้ร่วมให้ข้อมูล OSM จะถูกเตือนไม่ให้เพิ่มข้อมูลจากแหล่งข้อมูลที่มีลิขสิทธิ์
(เช่น Google Maps หรือแผนที่แบบพิมพ์) โดยไม่ได้รับอนุญาตอย่างชัดเจนจากเจ้าของลิขสิทธิ์
+ trademarks_title: เครื่องหมายการค้า
index:
js_1: ท่านกำลังใช้เบราว์เซอร์ที่ไม่รองรับจาวาสคริปต์ หรือท่านปิดใช้งานจาวาสคริปต์
js_2: OpenStreetMap ใช้จาวาสคริปต์ในการแสดงแผนที่
taxiway: ทางขับเครื่องบิน
apron: โรงซ่อมบำรุงเครื่องบิน
admin: ขอบเขตการปกครอง
+ capital: เมืองหลวง
+ city: เมือง
+ orchard: สวนผลไม้
forest: ป่า
wood: ไม้
golf: สนามกอล์ฟ
heathland: ทุ่งไม้พุ่ม
lake: ทะเลสาบ
reservoir: อ่างเก็บน้ำ
+ glacier: ธารน้ำแข็ง
+ wetland: พื้นที่ชุ่มน้ำ
farm: ไร่นา
brownfield: พื้นที่อุตสาหกรรมเดิม
cemetery: สุสาน
allotments: ที่ดินแบ่งใช้
pitch: ลานกีฬา
centre: ศูนย์กีฬา
+ beach: ชายหาด
reserve: พื้นที่สงวนธรรมชาติ
military: เขตทหาร
school: โรงเรียน
university: มหาวิทยาลัย
+ hospital: โรงพยาบาล
building: อาคารสำคัญ
station: สถานีรถไฟ
+ railway_halt: ที่หยุดรถไฟ
+ subway_station: สถานีรถไฟใต้ดิน
+ tram_stop: ที่หยุดรถราง
summit: ยอดเขา
peak: ยอดเขา
tunnel: เส้นประ = อุโมงค์
private: พื้นที่ส่วนบุคคล
destination: การเข้าถึงที่จุดปลายทาง
construction: ถนนกำลังก่อสร้าง
+ bus_stop: ป้ายหยุดรถประจำทาง
bicycle_shop: ร้านขายและเช่าจักรยาน
+ bicycle_rental: บริการให้เช่าจักรยาน
bicycle_parking: ที่จอดจักรยาน
toilets: ห้องน้ำ
welcome:
# Author: Katpatuka
# Author: Khalvar
# Author: Kumkumuk
+# Author: Leo
# Author: LuCKY
# Author: Makina88
# Author: Mavrikant
support_url: Destek Bağlantısı
allow_read_prefs: kullanıcı tercihlerini okuyun
allow_write_prefs: kullanıcı tercihlerini değiştir
- allow_write_diary: günlük girdiler, yorumlar oluşturun ve arkadaş edinin
+ allow_write_diary: günlük kayıtları ve yorumları oluşturun
allow_write_api: haritayı değiştir
allow_read_gpx: özel GPS izlerini oku
allow_write_gpx: GPS izlerini yükle
allow_write_prefs: змінювати налаштування
allow_write_diary: створювати записи у щоденнику та залишати коментарі
allow_write_api: змінювати мапу
+ allow_write_changeset_comments: коментувати набори змін
allow_read_gpx: отримувати приватні GPS-треки.
allow_write_gpx: надсилати GPS-треки на сервер
allow_write_notes: змінювати нотатки
accounts:
show:
title: Редагувати обліковий запис
+ my_account: Обліковий запис
current email address: Поточна адреса електронної пошти
external auth: Стороння автентифікація
openid:
Надбанням.
link: https://wiki.openstreetmap.org/wiki/Uk:Open_Database_License/Contributor_Terms
link text: що це?
+ not_agreed_with_pd: Ви не заявили, що ви вважаєте свій внесок Суспільним Надбанням.
+ pd_link_text: заявляю
save changes button: Зберегти зміни
delete_account: Видалити обліковий запис…
go_public:
terms_declined_url: https://wiki.openstreetmap.org/wiki/Uk:Contributor_Terms_Declined
pd_declarations:
show:
+ title: Вважайте, що мій внесок є Суспільним Надбанням
+ consider_pd: Я вважаю, що мій внесок є суспільним надбанням
+ consider_pd_why: Чому я мав(ла) би хотіти, щоб мій внесок став Суспільним
+ Надбанням?
consider_pd_why_url: https://wiki.openstreetmap.org/wiki/Uk:Чому_я_хочу,_щоб_мої_внески_були_суспільним_надбанням
+ confirm: Підтвердити
+ create:
+ successfully_declared: Ви заявили, що вважаєте, що ваші правки є Суспільним
+ Надбанням.
+ already_declared: Ви вже заявили, що вважаєте, що ваші правки є Суспільним
+ Надбанням.
+ did_not_confirm: Ви не підтвердили, що вважаєте свої правки Суспільним Надбанням.
browse:
deleted_ago_by_html: Вилучив(ла) %{time_ago} %{user}
edited_ago_by_html: Змінено %{user} %{time_ago}
bridleway: Дорога для їзди верхи
bus_guideway: Рейковий автобус
bus_stop: Автобусна зупинка
+ busway: Дорога для автобусів
construction: Будівництво автомагістралі
corridor: Коридор
crossing: Перехід
reports: Скарги
last_updated: Останнє оновлення
last_updated_time_ago_user_html: '%{user} %{time_ago}'
+ reporting_users: Повідомлення про користувачів
reports_count:
one: '%{count} Скарга'
few: '%{count} Скарги'
reopened: Статус проблеми був змінений на 'Відкрито'
comments:
comment_from_html: Коментар від %{user_link}, %{comment_created_at}
+ reassign_to_moderators: Перепризначити звернення Модераторам
+ reassign_to_administrators: Перепризначити звернення Адміністраторам
reports:
reported_by_html: Повідомлено як %{category}, %{user}, %{updated_at}
helper:
communities: Спільноти
learn_more: Докладніше
more: Більше
+ offline_flash:
+ osm_offline: База даних OpenStreetMap наразі працює в режимі офлайн, поки проводяться
+ роботи з технічного обслуговування.
+ osm_read_only: База даних OpenStreetMap наразі працює в режимі тільки для читання,
+ поки проводяться роботи з технічного обслуговування.
+ expected_restore_html: Очікується, що роботу буде відновлено через %{time}.
+ announcement: Ознайомитися з оголошенням можна тут.
user_mailer:
diary_comment_notification:
description: 'Запис у щоденнику OpenStreetMap #%{id}'
failure: Неможливо зберегти оновлення профілю.
sessions:
new:
- tab_title: Ð\9bаÑ\81каво пÑ\80оÑ\81имо
+ tab_title: Ð\92Ñ\85Ñ\96д
login_to_authorize_html: Увійдіть до OpenStreetMap, щоб отримати доступ до %{client_app_name}.
email or username: Ел. пошта або прізвисько
password: Пароль
not_public_description_html: 'Ви не можете більше анонімно редагувати мапу.
Ви можете зробити ваші редагування загальнодоступними тут: %{user_page}.'
user_page_link: сторінка учасника
+ anon_edits_html: '%{link}'
+ anon_edits_link: https://wiki.openstreetmap.org/wiki/Uk:Анонімне_редагування
anon_edits_link_text: З’ясувати в чому справа.
edit:
id_not_configured: iD не був налаштований
погоджуватись, але ви повинні переглянути їх.
settings_menu:
account_settings: Налаштування облікового запису
- oauth2_applications: застосунки OAuth 2
- oauth2_authorizations: авторизації OAuth 2
+ oauth2_applications: Ð\97астосунки OAuth 2
+ oauth2_authorizations: Ð\90вторизації OAuth 2
muted_users: Стишені учасники
auth_providers:
openid_url: OpenID URL
write_prefs: Змінювати налаштування
write_diary: Створювати записи у щоденнику та залишати коментарі
write_api: Змінювати мапу
+ write_changeset_comments: Коментувати набори змін
read_gpx: Отримувати приватні GPS-треки
write_gpx: Завантажувати GPS-треки
write_notes: Змінювати нотатки
write_redactions: Виконувати очищення даних
+ write_blocks: Створювати та скасовувати блокування користувачів
read_email: Отримувати адресу е-пошти
consume_messages: Прочитати, оновити статус та видалити повідомлення користувача
send_messages: Надіслати приватне повідомлення іншим користувачам
title: Авторизовані застосунки
application: Застосунок
permissions: Дозволи
- last_authorized: Ð\9eÑ\81Ñ\82аннÑ\96й авÑ\82оÑ\80изований
+ last_authorized: Ð\92 оÑ\81Ñ\82аннÑ\94 авÑ\82оÑ\80изовано
no_applications_html: У вас ще немає застосунків авторизованих через %{oauth2}.
application:
revoke: Відкликати доступ
my notes: Мої нотатки
my messages: Повідомлення
my profile: Профіль
+ my_account: Обліковий запис
my comments: Мої коментарі
my_preferences: Вподобання
my_dashboard: Інфо панель
show:
title: Учасники
heading: Учасники
+ select_status: Обрати статус
+ states:
+ pending: В очікуванні
+ active: Активний
+ confirmed: Підтверджено
+ suspended: Призупинено
+ deleted: Вилучено
+ name_or_email: Імʼя або електронна пошта
+ ip_address: IP-адреса
+ search: Пошук
page:
found_users:
one: знайдено %{count} користувача
open_title: 'Неопрацьована нотатка #%{note_name}'
closed_title: 'Опрацьована нотатка #%{note_name}'
hidden_title: 'Прихована нотатка #%{note_name}'
+ description_when_author_is_deleted: вилучено
+ description_when_there_is_no_opening_comment: невідомо
event_opened_by_html: Створив(ла) %{user} %{time_ago}
event_opened_by_anonymous_html: Створено анонімом %{time_ago}
event_commented_by_html: Коментар від %{user} %{time_ago}
ninth: 9й
tenth: 10й
time: Час
+ download: Завантажити маршрут як GeoJSON
+ filename: маршрут
query:
node: Точка
way: Лінія
show_address: Показати адресу
query_features: Отримати об’єкти
centre_map: Центрувати мапу тут
+ home:
+ marker_title: Моє розташування
+ not_set: Для вашого облікового запису не вказано його розташування
redactions:
edit:
heading: Змінити редакцію
create: კომენტარი
diary_entry:
create: გუმობჟინაფა
- update: á\83\92á\83\9dá\83\90á\83®á\83\90á\83\9aá\83\90á\83¤ა
+ update: á\83\9bá\83\9dá\83\90á\83®á\83\90á\83\9aá\83\94á\83\91ა
issue_comment:
create: კომენტარიშ გეძინა
message:
create: ჯღონუა
oauth2_application:
create: რეგისტრაცია
- update: á\83\92á\83\9dá\83\90á\83®á\83\90á\83\9aá\83\90á\83¤ა
+ update: á\83\9bá\83\9dá\83\90á\83®á\83\90á\83\9aá\83\94á\83\91ა
redaction:
create: მიშათინუაშ გოჭყაფა
update: მიშათინუაშ ჩუალა
create: ბლოკირაფაშ გოჭყაფა
update: ბლოკირაფაშ გოახალაფა
activerecord:
+ errors:
+ models:
+ user_mute:
+ is_already_muted: უკვე აკორანგვილი რე
models:
acl: ხემეჭირნაფაშ კონტროლიშ ერკებული
changeset: თირაფეფიშ პაკეტი
message: გინაფა
node: ჭურჭული
node_tag: ჭურჭულიშ ხინტკი
+ note: ხვილაფა
old_node: ჯვეში ჭურჭული
old_node_tag: ჭურჭულიშ ჯვეში ხინტკი
old_relation: ჯვეში ურთიართობა
allow_write_diary: დღარეფიშ დინნაჭარეფიშ გოჭყაფა, კომენტირაფა დო მაჸალეეფიშ
გეძინა
allow_write_api: რუკაშ თირუა
+ allow_write_changeset_comments: თირუეფიშ პაკეტეფიშ კომენტირება
allow_read_gpx: კერზო GPS-ტრეკეფიშ კითხირი
allow_write_gpx: GPS-ტრეკეფიშ ეხარგუა
allow_write_notes: მოღანკუეფიშ მიშათინუა
retain_email: თქვან ელ-ფოშტა დიჩუალუაფუ.
confirm_delete: დასურო გონებჷნანო?
cancel: გოუქვაფა
+ terms:
+ show:
+ title: აპიჯალეფი
+ heading: წოროხანდაშ აპიჯალეფი
+ heading_ct: წოროხანდაშ აპიჯალეფი
+ continue: გაგჷნძორაფა
+ cancel: გოუქვაფა
+ legale_names:
+ france: საფრანგეთი
+ italy: იტალია
+ rest_of_world: დოსკილადირი მოსოფელი
+ terms_declined_flash:
+ terms_declined_link: თენა რე ვიკი ხასჷლა
+ pd_declarations:
+ show:
+ confirm: დოდასურება
browse:
+ deleted_ago_by_html: დილასჷ %{time_ago} მახვარებუქ %{user}
+ edited_ago_by_html: დარედაქტირჷ %{time_ago} მახვარებუქ %{user}
version: ვერსია
+ redacted_version: ვერსიაშ რედაქტირაფა
in_changeset: თირაფეფიშ პაკეტი
anonymous: ანონიმი
no_comment: (უკომენტარე)
wikimedia_commons_link: ელემენტი %{page} ვიკიოწკარუეს
telephone_link: რეკუა %{phone_number}
colour_preview: ფერი %{colour_value} გიწოთოლორაფა
+ email_link: ელექტრონული ფოშტა %{email}
query:
title: მუ რე თაქ?
introduction: უახოლაში ობიექტეფიშ ოგორალო ქეგუნჭირით რუკა.
title_html: 'ღოზიშ ისტორია: %{name}'
relation:
title_html: 'ურთიართობაშ ისტორია: %{name}'
+ actions:
+ view_redacted_data: რედაქტირებული მუნაჩემეფშა გინოჯინა
changeset_comments:
feeds:
comment:
join_discussion: გემშართით სისტემაშა, თიშენ ნამჷ-და, სხუნუას ქაკათათინ
still_open: თირუეფიშ პაკეტი დიო ღილე რე. სხუნუა ხემიოჭირინაფუ იჸი, მუჭო თირუეფიშ
პაკეტი დიკილუნ.
+ subscribe: გიშაჭარუა
+ unsubscribe: გიშაჭარუაშ გოუქვაფა
+ hide_comment: ტყობინაფა
+ unhide_comment: ძირაფა
+ comment: კომენტირება
changesetxml: თირუეფიშ პაკეტიშ XML
osmchangexml: osmChange XML
paging_nav:
show:
title: '%{user}შ დღარი | %{title}'
user_title: '%{user}შ დღარი'
+ subscribe: გიშაჭარუა
+ unsubscribe: გიშაჭარუაშ გოუქვაფა
leave_a_comment: კომენტარიშ დოტება
login_to_leave_a_comment_html: '%{login_link}, კომენტარიშ დატებელო'
login: მიშულა
title: OpenStreetMap დღარიშ დინნაჭარეფი გეჸვენჯი ნინაშა %{language_name}
all:
title: OpenStreetMap დღარიშ დინნაჭარეფი
+ doorkeeper:
+ flash:
+ applications:
+ create:
+ notice: აპლიკაცია რეგისტრირებული რე.
+ scopes:
+ profile: თქვანი ანგარიშიშ ინფორმაციაშ ძირაფა
errors:
contact:
contact: კონტაქტი
+ bad_request:
+ title: ჩილათერი მოთხირი
+ forbidden:
+ title: ჭირინაფა გოხურგელი
internal_server_error:
title: აპლიკაციაშ ჩილათა
not_found:
title: ფაილქ ვეგორჷ
geocoder:
+ search:
+ title:
+ latlon: დინოხოლენი
search_osm_nominatim:
prefix:
aerialway:
terminal: აეროპორტიშ ტერმინალი
windsock: ბორიამაძირაფალი
amenity:
+ animal_shelter: ჩხოლარეფიშ ხვაშია
arts_centre: ხელუანაფაშ ცენტრი
atm: ბანკომატი
bank: ბანკი
bench: დახუნალი
bicycle_parking: ველოსიპედეფიშ დგჷმილი
bicycle_rental: ველოსპიედეფიშ გაქირაფა
+ bicycle_repair_station: ველოსიპეტეფიშ აკანწყუალი დგჷმილი
biergarten: ლუდიშ ბაღი
blood_bank: ზისხირიშ ბანკი
boat_rental: ნიშეფიშ გაქირება
kindergarten: საბაღანო ბაღი
language_school: ნინაშ სკოლა
library: ბიბლიოთეკა
+ loading_dock: ოხარგუე დოკი
+ love_hotel: ჸოროფაშ სასუმარო
marketplace: ბაზარი
+ mobile_money_agent: მობილური ფარაშ აგენტი
monastery: მონასტერი
money_transfer: ფარაშ ჯღონუა
motorcycle_parking: მოტოციკლეტიშ პარკირაფა
ruins: აკოცჷმილი დგჷმილი
school: სკოლა
service: ონინალე დგჷმილი
+ stable: ცხენსაბეკი
static_caravan: ქერვანი
+ sty: ორეჯე
temple: ოხიდა
terrace: აკიბი
train_station: მახინწალიშ დგჷმილი
warehouse: ოწკარუე
"yes": ნოდგჷმი
club:
+ scout: სკაუტეფიშ ბაზა
sport: სპორტული კლუბი
"yes": კლუბი
craft:
ninth: 第9
tenth: 第10
time: 时间
+ download: 以GeoJSON格式下载路线
+ filename: 路线
query:
node: 节点
way: 路径
get "permissions" => "permissions#show"
post "changeset/:id/upload" => "changesets#upload", :as => :changeset_upload, :id => /\d+/
- get "changeset/:id/download" => "changesets#download", :as => :changeset_download, :id => /\d+/
- get "changeset/:id" => "changesets#show", :as => :changeset_show, :id => /\d+/
post "changeset/:id/subscribe" => "changesets#subscribe", :as => :api_changeset_subscribe, :id => /\d+/
post "changeset/:id/unsubscribe" => "changesets#unsubscribe", :as => :api_changeset_unsubscribe, :id => /\d+/
- put "changeset/:id" => "changesets#update", :id => /\d+/
put "changeset/:id/close" => "changesets#close", :as => :changeset_close, :id => /\d+/
- post "changeset/:id/comment" => "changeset_comments#create", :as => :changeset_comment, :id => /\d+/
- post "changeset/comment/:id/hide" => "changeset_comments#destroy", :as => :changeset_comment_hide, :id => /\d+/
- post "changeset/comment/:id/unhide" => "changeset_comments#restore", :as => :changeset_comment_unhide, :id => /\d+/
end
namespace :api, :path => "api/0.6" do
resources :changesets, :only => [:index, :create]
+ resources :changesets, :path => "changeset", :id => /\d+/, :only => [:show, :update] do
+ resource :download, :module => :changesets, :only => :show
+ resources :changeset_comments, :path => "comment", :only => :create
+ end
put "changeset/create" => "changesets#create", :as => nil
- resources :changeset_comments, :only => :index
+ resources :changeset_comments, :id => /\d+/, :only => :index do
+ resource :visibility, :module => :changeset_comments, :only => [:create, :destroy]
+ end
+ post "changeset/comment/:changeset_comment_id/unhide" => "changeset_comments/visibilities#create", :changeset_comment_id => /\d+/, :as => nil
+ post "changeset/comment/:changeset_comment_id/hide" => "changeset_comments/visibilities#destroy", :changeset_comment_id => /\d+/, :as => nil
resources :nodes, :only => [:index, :create]
resources :nodes, :path => "node", :id => /\d+/, :only => [:show, :update, :destroy] do
end
# Parse a float, raising a specified exception on failure
- def self.parse_float(str, klass, *args)
+ def self.parse_float(str, klass, *)
Float(str)
rescue StandardError
- raise klass.new(*args)
+ raise klass.new(*)
end
# Construct a random token of a given length
scopes = Set.new
ability = ApiAbility.new user, scopes
- [:create, :destroy, :restore].each do |action|
- assert ability.cannot? action, ChangesetComment
- end
+ assert ability.cannot? :create, ChangesetComment
+ assert ability.cannot? :create, :changeset_comment_visibility
+ assert ability.cannot? :destroy, :changeset_comment_visibility
end
test "as a normal user with write_changeset_comments scope" do
scopes = Set.new %w[write_changeset_comments]
ability = ApiAbility.new user, scopes
- [:destroy, :restore].each do |action|
- assert ability.cannot? action, ChangesetComment
- end
-
- [:create].each do |action|
- assert ability.can? action, ChangesetComment
- end
+ assert ability.can? :create, ChangesetComment
+ assert ability.cannot? :create, :changeset_comment_visibility
+ assert ability.cannot? :destroy, :changeset_comment_visibility
end
test "as a moderator without scopes" do
scopes = Set.new
ability = ApiAbility.new user, scopes
- [:create, :destroy, :restore].each do |action|
- assert ability.cannot? action, ChangesetComment
- end
+ assert ability.cannot? :create, ChangesetComment
+ assert ability.cannot? :create, :changeset_comment_visibility
+ assert ability.cannot? :destroy, :changeset_comment_visibility
end
test "as a moderator with write_changeset_comments scope" do
scopes = Set.new %w[write_changeset_comments]
ability = ApiAbility.new user, scopes
- [:create, :destroy, :restore].each do |action|
- assert ability.can? action, ChangesetComment
- end
+ assert ability.can? :create, ChangesetComment
+ assert ability.can? :create, :changeset_comment_visibility
+ assert ability.can? :destroy, :changeset_comment_visibility
end
end
--- /dev/null
+require "test_helper"
+
+module Api
+ module ChangesetComments
+ class VisibilitiesControllerTest < ActionDispatch::IntegrationTest
+ ##
+ # test all routes which lead to this controller
+ def test_routes
+ assert_routing(
+ { :path => "/api/0.6/changeset_comments/1/visibility", :method => :post },
+ { :controller => "api/changeset_comments/visibilities", :action => "create", :changeset_comment_id => "1" }
+ )
+ assert_routing(
+ { :path => "/api/0.6/changeset_comments/1/visibility.json", :method => :post },
+ { :controller => "api/changeset_comments/visibilities", :action => "create", :changeset_comment_id => "1", :format => "json" }
+ )
+ assert_routing(
+ { :path => "/api/0.6/changeset_comments/1/visibility", :method => :delete },
+ { :controller => "api/changeset_comments/visibilities", :action => "destroy", :changeset_comment_id => "1" }
+ )
+ assert_routing(
+ { :path => "/api/0.6/changeset_comments/1/visibility.json", :method => :delete },
+ { :controller => "api/changeset_comments/visibilities", :action => "destroy", :changeset_comment_id => "1", :format => "json" }
+ )
+
+ assert_recognizes(
+ { :controller => "api/changeset_comments/visibilities", :action => "create", :changeset_comment_id => "1" },
+ { :path => "/api/0.6/changeset/comment/1/unhide", :method => :post }
+ )
+ assert_recognizes(
+ { :controller => "api/changeset_comments/visibilities", :action => "create", :changeset_comment_id => "1", :format => "json" },
+ { :path => "/api/0.6/changeset/comment/1/unhide.json", :method => :post }
+ )
+ assert_recognizes(
+ { :controller => "api/changeset_comments/visibilities", :action => "destroy", :changeset_comment_id => "1" },
+ { :path => "/api/0.6/changeset/comment/1/hide", :method => :post }
+ )
+ assert_recognizes(
+ { :controller => "api/changeset_comments/visibilities", :action => "destroy", :changeset_comment_id => "1", :format => "json" },
+ { :path => "/api/0.6/changeset/comment/1/hide.json", :method => :post }
+ )
+ end
+
+ def test_create_by_unauthorized
+ comment = create(:changeset_comment, :visible => false)
+
+ post api_changeset_comment_visibility_path(comment)
+
+ assert_response :unauthorized
+ assert_not comment.reload.visible
+ end
+
+ def test_create_by_normal_user
+ comment = create(:changeset_comment, :visible => false)
+ auth_header = bearer_authorization_header
+
+ post api_changeset_comment_visibility_path(comment), :headers => auth_header
+
+ assert_response :forbidden
+ assert_not comment.reload.visible
+ end
+
+ def test_create_on_missing_comment
+ auth_header = bearer_authorization_header create(:moderator_user)
+
+ post api_changeset_comment_visibility_path(999111), :headers => auth_header
+
+ assert_response :not_found
+ end
+
+ def test_create_without_required_scope
+ comment = create(:changeset_comment, :visible => false)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[read_prefs]
+
+ post api_changeset_comment_visibility_path(comment), :headers => auth_header
+
+ assert_response :forbidden
+ assert_not comment.reload.visible
+ end
+
+ def test_create_with_write_changeset_comments_scope
+ comment = create(:changeset_comment, :visible => false)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_changeset_comments]
+
+ post api_changeset_comment_visibility_path(comment), :headers => auth_header
+
+ check_successful_response_xml(comment, :comment_visible => true)
+ end
+
+ def test_create_with_write_changeset_comments_scope_json
+ comment = create(:changeset_comment, :visible => false)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_changeset_comments]
+
+ post api_changeset_comment_visibility_path(comment, :format => "json"), :headers => auth_header
+
+ check_successful_response_json(comment, :comment_visible => true)
+ end
+
+ def test_create_with_write_api_scope
+ comment = create(:changeset_comment, :visible => false)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_api]
+
+ post api_changeset_comment_visibility_path(comment), :headers => auth_header
+
+ check_successful_response_xml(comment, :comment_visible => true)
+ end
+
+ def test_create_with_write_api_scope_json
+ comment = create(:changeset_comment, :visible => false)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_api]
+
+ post api_changeset_comment_visibility_path(comment, :format => "json"), :headers => auth_header
+
+ check_successful_response_json(comment, :comment_visible => true)
+ end
+
+ def test_create_at_legacy_route
+ comment = create(:changeset_comment, :visible => false)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_api]
+
+ post "/api/0.6/changeset/comment/#{comment.id}/unhide", :headers => auth_header
+
+ check_successful_response_xml(comment, :comment_visible => true)
+ end
+
+ def test_create_at_legacy_route_json
+ comment = create(:changeset_comment, :visible => false)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_api]
+
+ post "/api/0.6/changeset/comment/#{comment.id}/unhide.json", :headers => auth_header
+
+ check_successful_response_json(comment, :comment_visible => true)
+ end
+
+ def test_destroy_by_unauthorized
+ comment = create(:changeset_comment)
+
+ delete api_changeset_comment_visibility_path(comment)
+
+ assert_response :unauthorized
+ assert comment.reload.visible
+ end
+
+ def test_destroy_by_normal_user
+ comment = create(:changeset_comment)
+ auth_header = bearer_authorization_header
+
+ delete api_changeset_comment_visibility_path(comment), :headers => auth_header
+
+ assert_response :forbidden
+ assert comment.reload.visible
+ end
+
+ def test_destroy_on_missing_comment
+ auth_header = bearer_authorization_header create(:moderator_user)
+
+ delete api_changeset_comment_visibility_path(999111), :headers => auth_header
+
+ assert_response :not_found
+ end
+
+ def test_destroy_without_required_scope
+ comment = create(:changeset_comment)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[read_prefs]
+
+ delete api_changeset_comment_visibility_path(comment), :headers => auth_header
+
+ assert_response :forbidden
+ assert comment.reload.visible
+ end
+
+ def test_destroy_with_write_changeset_comments_scope
+ comment = create(:changeset_comment)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_changeset_comments]
+
+ delete api_changeset_comment_visibility_path(comment), :headers => auth_header
+
+ check_successful_response_xml(comment, :comment_visible => false)
+ end
+
+ def test_destroy_with_write_changeset_comments_scope_json
+ comment = create(:changeset_comment)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_changeset_comments]
+
+ delete api_changeset_comment_visibility_path(comment, :format => "json"), :headers => auth_header
+
+ check_successful_response_json(comment, :comment_visible => false)
+ end
+
+ def test_destroy_with_write_api_scope
+ comment = create(:changeset_comment)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_api]
+
+ delete api_changeset_comment_visibility_path(comment), :headers => auth_header
+
+ check_successful_response_xml(comment, :comment_visible => false)
+ end
+
+ def test_destroy_with_write_api_scope_json
+ comment = create(:changeset_comment)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_api]
+
+ delete api_changeset_comment_visibility_path(comment, :format => "json"), :headers => auth_header
+
+ check_successful_response_json(comment, :comment_visible => false)
+ end
+
+ def test_destroy_at_legacy_route
+ comment = create(:changeset_comment)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_api]
+
+ post "/api/0.6/changeset/comment/#{comment.id}/hide", :headers => auth_header
+
+ check_successful_response_xml(comment, :comment_visible => false)
+ end
+
+ def test_destroy_at_legacy_route_json
+ comment = create(:changeset_comment)
+ auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_api]
+
+ post "/api/0.6/changeset/comment/#{comment.id}/hide.json", :headers => auth_header
+
+ check_successful_response_json(comment, :comment_visible => false)
+ end
+
+ private
+
+ def check_successful_response_xml(comment, comment_visible:)
+ assert_response :success
+ assert_equal "application/xml", response.media_type
+ assert_dom "osm", 1 do
+ assert_dom "> changeset", 1 do
+ assert_dom "> @id", comment.changeset_id.to_s
+ assert_dom "> @comments_count", comment_visible ? "1" : "0"
+ end
+ end
+
+ assert_equal comment_visible, comment.reload.visible
+ end
+
+ def check_successful_response_json(comment, comment_visible:)
+ assert_response :success
+ assert_equal "application/json", response.media_type
+ js = ActiveSupport::JSON.decode(@response.body)
+ assert_not_nil js["changeset"]
+ assert_equal comment.changeset_id, js["changeset"]["id"]
+ assert_equal comment_visible ? 1 : 0, js["changeset"]["comments_count"]
+
+ assert_equal comment_visible, comment.reload.visible
+ end
+ end
+ end
+end
)
assert_routing(
{ :path => "/api/0.6/changeset/1/comment", :method => :post },
- { :controller => "api/changeset_comments", :action => "create", :id => "1" }
+ { :controller => "api/changeset_comments", :action => "create", :changeset_id => "1" }
)
assert_routing(
{ :path => "/api/0.6/changeset/1/comment.json", :method => :post },
- { :controller => "api/changeset_comments", :action => "create", :id => "1", :format => "json" }
- )
- assert_routing(
- { :path => "/api/0.6/changeset/comment/1/hide", :method => :post },
- { :controller => "api/changeset_comments", :action => "destroy", :id => "1" }
- )
- assert_routing(
- { :path => "/api/0.6/changeset/comment/1/hide.json", :method => :post },
- { :controller => "api/changeset_comments", :action => "destroy", :id => "1", :format => "json" }
- )
- assert_routing(
- { :path => "/api/0.6/changeset/comment/1/unhide", :method => :post },
- { :controller => "api/changeset_comments", :action => "restore", :id => "1" }
- )
- assert_routing(
- { :path => "/api/0.6/changeset/comment/1/unhide.json", :method => :post },
- { :controller => "api/changeset_comments", :action => "restore", :id => "1", :format => "json" }
+ { :controller => "api/changeset_comments", :action => "create", :changeset_id => "1", :format => "json" }
)
end
def test_create_by_unauthorized
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(create(:changeset, :closed), :text => "This is a comment")
+ post api_changeset_changeset_comments_path(create(:changeset, :closed), :text => "This is a comment")
assert_response :unauthorized
end
end
def test_create_on_missing_changeset
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(999111, :text => "This is a comment"), :headers => bearer_authorization_header
+ post api_changeset_changeset_comments_path(999111, :text => "This is a comment"), :headers => bearer_authorization_header
assert_response :not_found
end
end
def test_create_on_open_changeset
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(create(:changeset), :text => "This is a comment"), :headers => bearer_authorization_header
+ post api_changeset_changeset_comments_path(create(:changeset), :text => "This is a comment"), :headers => bearer_authorization_header
assert_response :conflict
end
end
def test_create_without_text
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(create(:changeset, :closed)), :headers => bearer_authorization_header
+ post api_changeset_changeset_comments_path(create(:changeset, :closed)), :headers => bearer_authorization_header
assert_response :bad_request
end
end
def test_create_with_empty_text
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(create(:changeset, :closed), :text => ""), :headers => bearer_authorization_header
+ post api_changeset_changeset_comments_path(create(:changeset, :closed), :text => ""), :headers => bearer_authorization_header
assert_response :bad_request
end
end
changeset = create(:changeset, :closed)
assert_difference "ChangesetComment.count", 0 do
- post changeset_comment_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
assert_response :forbidden
end
end
changeset = create(:changeset, :closed)
assert_difference "ChangesetComment.count", 0 do
- post changeset_comment_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
assert_response :forbidden
end
end
changeset = create(:changeset, :closed)
assert_difference "ChangesetComment.count", 1 do
- post changeset_comment_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
assert_response :success
end
changeset = create(:changeset, :closed)
assert_difference "ChangesetComment.count", 1 do
- post changeset_comment_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
assert_response :success
end
assert_difference "ChangesetComment.count", 1 do
assert_no_difference "ActionMailer::Base.deliveries.size" do
perform_enqueued_jobs do
- post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
assert_response :success
end
end
assert_difference "ChangesetComment.count", 1 do
assert_no_difference "ActionMailer::Base.deliveries.size" do
perform_enqueued_jobs do
- post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
assert_response :success
end
end
assert_difference "ChangesetComment.count", 1 do
assert_no_difference "ActionMailer::Base.deliveries.size" do
perform_enqueued_jobs do
- post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
assert_response :success
end
end
assert_difference "ChangesetComment.count", 1 do
assert_difference "ActionMailer::Base.deliveries.size", 1 do
perform_enqueued_jobs do
- post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
assert_response :success
end
end
assert_difference "ChangesetComment.count", 1 do
assert_difference "ActionMailer::Base.deliveries.size", 2 do
perform_enqueued_jobs do
- post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
assert_response :success
end
end
assert_difference "ChangesetComment.count", Settings.initial_changeset_comments_per_hour do
1.upto(Settings.initial_changeset_comments_per_hour) do |count|
- post changeset_comment_path(changeset, :text => "Comment #{count}"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
assert_response :success
end
end
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(changeset, :text => "One comment too many"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
assert_response :too_many_requests
end
end
assert_difference "ChangesetComment.count", Settings.max_changeset_comments_per_hour do
1.upto(Settings.max_changeset_comments_per_hour) do |count|
- post changeset_comment_path(changeset, :text => "Comment #{count}"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
assert_response :success
end
end
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(changeset, :text => "One comment too many"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
assert_response :too_many_requests
end
end
assert_difference "ChangesetComment.count", Settings.initial_changeset_comments_per_hour / 2 do
1.upto(Settings.initial_changeset_comments_per_hour / 2) do |count|
- post changeset_comment_path(changeset, :text => "Comment #{count}"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
assert_response :success
end
end
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(changeset, :text => "One comment too many"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
assert_response :too_many_requests
end
end
assert_difference "ChangesetComment.count", Settings.moderator_changeset_comments_per_hour do
1.upto(Settings.moderator_changeset_comments_per_hour) do |count|
- post changeset_comment_path(changeset, :text => "Comment #{count}"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
assert_response :success
end
end
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(changeset, :text => "One comment too many"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
assert_response :too_many_requests
end
end
- def test_hide_by_unauthorized
- comment = create(:changeset_comment)
-
- post changeset_comment_hide_path(comment)
-
- assert_response :unauthorized
- assert comment.reload.visible
- end
-
- def test_hide_by_normal_user
- comment = create(:changeset_comment)
- auth_header = bearer_authorization_header
-
- post changeset_comment_hide_path(comment), :headers => auth_header
-
- assert_response :forbidden
- assert comment.reload.visible
- end
-
- def test_hide_missing_comment
- auth_header = bearer_authorization_header create(:moderator_user)
-
- post changeset_comment_hide_path(999111), :headers => auth_header
-
- assert_response :not_found
- end
-
- def test_hide_without_required_scope
- comment = create(:changeset_comment)
- auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[read_prefs]
-
- post changeset_comment_hide_path(comment), :headers => auth_header
-
- assert_response :forbidden
- assert comment.reload.visible
- end
-
- def test_hide_with_write_changeset_comments_scope
- comment = create(:changeset_comment)
- auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_changeset_comments]
-
- post changeset_comment_hide_path(comment), :headers => auth_header
-
- assert_response :success
- assert_not comment.reload.visible
- end
-
- def test_hide_with_write_api_scope
- comment = create(:changeset_comment)
- auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_api]
-
- post changeset_comment_hide_path(comment), :headers => auth_header
-
- assert_response :success
- assert_not comment.reload.visible
- end
-
- def test_unhide_by_unauthorized
- comment = create(:changeset_comment, :visible => false)
-
- post changeset_comment_unhide_path(comment)
-
- assert_response :unauthorized
- assert_not comment.reload.visible
- end
-
- def test_unhide_by_normal_user
- comment = create(:changeset_comment, :visible => false)
- auth_header = bearer_authorization_header
-
- post changeset_comment_unhide_path(comment), :headers => auth_header
-
- assert_response :forbidden
- assert_not comment.reload.visible
- end
-
- def test_unhide_missing_comment
- auth_header = bearer_authorization_header create(:moderator_user)
-
- post changeset_comment_unhide_path(999111), :headers => auth_header
-
- assert_response :not_found
- end
-
- def test_unhide_without_required_scope
- comment = create(:changeset_comment, :visible => false)
- auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[read_prefs]
-
- post changeset_comment_unhide_path(comment), :headers => auth_header
-
- assert_response :forbidden
- assert_not comment.reload.visible
- end
-
- def test_unhide_with_write_changeset_comments_scope
- comment = create(:changeset_comment, :visible => false)
- auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_changeset_comments]
-
- post changeset_comment_unhide_path(comment), :headers => auth_header
-
- assert_response :success
- assert comment.reload.visible
- end
-
- def test_unhide_with_write_api_scope
- comment = create(:changeset_comment, :visible => false)
- auth_header = bearer_authorization_header create(:moderator_user), :scopes => %w[write_api]
-
- post changeset_comment_unhide_path(comment), :headers => auth_header
-
- assert_response :success
- assert comment.reload.visible
- end
-
private
##
--- /dev/null
+require "test_helper"
+
+module Api
+ module Changesets
+ class DownloadsControllerTest < ActionDispatch::IntegrationTest
+ ##
+ # test all routes which lead to this controller
+ def test_routes
+ assert_routing(
+ { :path => "/api/0.6/changeset/1/download", :method => :get },
+ { :controller => "api/changesets/downloads", :action => "show", :changeset_id => "1" }
+ )
+ end
+
+ def test_show_empty
+ changeset = create(:changeset)
+
+ get api_changeset_download_path(changeset)
+
+ assert_response :success
+ assert_dom "osmChange[version='#{Settings.api_version}'][generator='#{Settings.generator}']" do
+ assert_dom "create", 0
+ assert_dom "modify", 0
+ assert_dom "delete", 0
+ end
+ end
+
+ def test_show_created_elements
+ changeset = create(:changeset)
+ old_node1 = create(:old_node, :changeset => changeset, :version => 1, :latitude => (60.12345 * OldNode::SCALE).to_i, :longitude => (30.54321 * OldNode::SCALE).to_i)
+ create(:old_node_tag, :old_node => old_node1, :k => "highway", :v => "crossing")
+ create(:old_node_tag, :old_node => old_node1, :k => "crossing", :v => "marked")
+ old_node2 = create(:old_node, :changeset => changeset, :version => 1, :latitude => (60.23456 * OldNode::SCALE).to_i, :longitude => (30.65432 * OldNode::SCALE).to_i)
+ create(:old_node_tag, :old_node => old_node2, :k => "highway", :v => "traffic_signals")
+ old_way = create(:old_way, :changeset => changeset, :version => 1)
+ create(:old_way_tag, :old_way => old_way, :k => "highway", :v => "secondary")
+ create(:old_way_tag, :old_way => old_way, :k => "name", :v => "Some Street")
+ create(:old_way_node, :old_way => old_way, :node => old_node1.current_node, :sequence_id => 1)
+ create(:old_way_node, :old_way => old_way, :node => old_node2.current_node, :sequence_id => 2)
+ old_relation = create(:old_relation, :changeset => changeset, :version => 1)
+ create(:old_relation_tag, :old_relation => old_relation, :k => "type", :v => "restriction")
+ create(:old_relation_member, :old_relation => old_relation, :member => old_way.current_way, :member_role => "from", :sequence_id => 1)
+ create(:old_relation_member, :old_relation => old_relation, :member => old_node2.current_node, :member_role => "via", :sequence_id => 2)
+
+ get api_changeset_download_path(changeset)
+
+ assert_response :success
+ assert_dom "osmChange[version='#{Settings.api_version}'][generator='#{Settings.generator}']" do
+ assert_dom "create", 4 do
+ assert_dom "node", 2
+ assert_dom "node[id='#{old_node1.node_id}']", 1 do
+ assert_dom "> @version", "1"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 2
+ assert_dom "tag[k='highway'][v='crossing']"
+ assert_dom "tag[k='crossing'][v='marked']"
+ assert_dom "> @lat", "60.1234500"
+ assert_dom "> @lon", "30.5432100"
+ end
+ assert_dom "node[id='#{old_node2.node_id}']", 1 do
+ assert_dom "> @version", "1"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 1
+ assert_dom "tag[k='highway'][v='traffic_signals']"
+ assert_dom "> @lat", "60.2345600"
+ assert_dom "> @lon", "30.6543200"
+ end
+ assert_dom "way", 1
+ assert_dom "way[id='#{old_way.way_id}']", 1 do
+ assert_dom "> @version", "1"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 2
+ assert_dom "tag[k='highway'][v='secondary']"
+ assert_dom "tag[k='name'][v='Some Street']"
+ assert_dom "nd", 2 do |dom_nds|
+ assert_dom dom_nds[0], "> @ref", old_node1.node_id.to_s
+ assert_dom dom_nds[1], "> @ref", old_node2.node_id.to_s
+ end
+ end
+ assert_dom "relation", 1
+ assert_dom "relation[id='#{old_relation.relation_id}']", 1 do
+ assert_dom "> @version", "1"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 1
+ assert_dom "tag[k='type'][v='restriction']"
+ assert_dom "member", 2 do |dom_members|
+ assert_dom dom_members[0], "> @type", "way"
+ assert_dom dom_members[0], "> @ref", old_way.way_id.to_s
+ assert_dom dom_members[0], "> @role", "from"
+ assert_dom dom_members[1], "> @type", "node"
+ assert_dom dom_members[1], "> @ref", old_node2.node_id.to_s
+ assert_dom dom_members[1], "> @role", "via"
+ end
+ end
+ end
+ end
+ end
+
+ def test_show_edited_elements
+ changeset = create(:changeset)
+ old_node1 = create(:old_node, :changeset => changeset, :version => 2, :latitude => (60.12345 * OldNode::SCALE).to_i, :longitude => (30.54321 * OldNode::SCALE).to_i)
+ create(:old_node_tag, :old_node => old_node1, :k => "highway", :v => "crossing")
+ create(:old_node_tag, :old_node => old_node1, :k => "crossing", :v => "marked")
+ old_node2 = create(:old_node, :changeset => changeset, :version => 2, :latitude => (60.23456 * OldNode::SCALE).to_i, :longitude => (30.65432 * OldNode::SCALE).to_i)
+ create(:old_node_tag, :old_node => old_node2, :k => "highway", :v => "traffic_signals")
+ old_way = create(:old_way, :changeset => changeset, :version => 2)
+ create(:old_way_tag, :old_way => old_way, :k => "highway", :v => "secondary")
+ create(:old_way_tag, :old_way => old_way, :k => "name", :v => "Some Street")
+ create(:old_way_node, :old_way => old_way, :node => old_node1.current_node, :sequence_id => 1)
+ create(:old_way_node, :old_way => old_way, :node => old_node2.current_node, :sequence_id => 2)
+ old_relation = create(:old_relation, :changeset => changeset, :version => 2)
+ create(:old_relation_tag, :old_relation => old_relation, :k => "type", :v => "restriction")
+ create(:old_relation_member, :old_relation => old_relation, :member => old_way.current_way, :member_role => "from", :sequence_id => 1)
+ create(:old_relation_member, :old_relation => old_relation, :member => old_node2.current_node, :member_role => "via", :sequence_id => 2)
+
+ get api_changeset_download_path(changeset)
+
+ assert_response :success
+ assert_dom "osmChange[version='#{Settings.api_version}'][generator='#{Settings.generator}']" do
+ assert_dom "modify", 4 do
+ assert_dom "node", 2
+ assert_dom "node[id='#{old_node1.node_id}']", 1 do
+ assert_dom "> @version", "2"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 2
+ assert_dom "tag[k='highway'][v='crossing']"
+ assert_dom "tag[k='crossing'][v='marked']"
+ assert_dom "> @lat", "60.1234500"
+ assert_dom "> @lon", "30.5432100"
+ end
+ assert_dom "node[id='#{old_node2.node_id}']", 1 do
+ assert_dom "> @version", "2"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 1
+ assert_dom "tag[k='highway'][v='traffic_signals']"
+ assert_dom "> @lat", "60.2345600"
+ assert_dom "> @lon", "30.6543200"
+ end
+ assert_dom "way", 1
+ assert_dom "way[id='#{old_way.way_id}']", 1 do
+ assert_dom "> @version", "2"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 2
+ assert_dom "tag[k='highway'][v='secondary']"
+ assert_dom "tag[k='name'][v='Some Street']"
+ assert_dom "nd", 2 do |dom_nds|
+ assert_dom dom_nds[0], "> @ref", old_node1.node_id.to_s
+ assert_dom dom_nds[1], "> @ref", old_node2.node_id.to_s
+ end
+ end
+ assert_dom "relation", 1
+ assert_dom "relation[id='#{old_relation.relation_id}']", 1 do
+ assert_dom "> @version", "2"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 1
+ assert_dom "tag[k='type'][v='restriction']"
+ assert_dom "member", 2 do |dom_members|
+ assert_dom dom_members[0], "> @type", "way"
+ assert_dom dom_members[0], "> @ref", old_way.way_id.to_s
+ assert_dom dom_members[0], "> @role", "from"
+ assert_dom dom_members[1], "> @type", "node"
+ assert_dom dom_members[1], "> @ref", old_node2.node_id.to_s
+ assert_dom dom_members[1], "> @role", "via"
+ end
+ end
+ end
+ end
+ end
+
+ def test_show_deleted_elements
+ changeset = create(:changeset)
+ old_node1 = create(:old_node, :changeset => changeset, :version => 3, :visible => false)
+ old_node2 = create(:old_node, :changeset => changeset, :version => 3, :visible => false)
+ old_way = create(:old_way, :changeset => changeset, :version => 3, :visible => false)
+ old_relation = create(:old_relation, :changeset => changeset, :version => 3, :visible => false)
+
+ get api_changeset_download_path(changeset)
+
+ assert_response :success
+ assert_dom "osmChange[version='#{Settings.api_version}'][generator='#{Settings.generator}']" do
+ assert_dom "delete", 4 do
+ assert_dom "node", 2
+ assert_dom "node[id='#{old_node1.node_id}']", 1 do
+ assert_dom "> @version", "3"
+ assert_dom "> @visible", "false"
+ end
+ assert_dom "node[id='#{old_node2.node_id}']", 1 do
+ assert_dom "> @version", "3"
+ assert_dom "> @visible", "false"
+ end
+ assert_dom "way", 1
+ assert_dom "way[id='#{old_way.way_id}']", 1 do
+ assert_dom "> @version", "3"
+ assert_dom "> @visible", "false"
+ end
+ assert_dom "relation", 1
+ assert_dom "relation[id='#{old_relation.relation_id}']", 1 do
+ assert_dom "> @version", "3"
+ assert_dom "> @visible", "false"
+ end
+ end
+ end
+ end
+
+ def test_show_should_sort_by_timestamp
+ changeset = create(:changeset)
+ node1 = create(:old_node, :version => 2, :timestamp => "2020-02-01", :changeset => changeset)
+ node0 = create(:old_node, :version => 2, :timestamp => "2020-01-01", :changeset => changeset)
+
+ get api_changeset_download_path(changeset)
+
+ assert_response :success
+ assert_dom "modify", :count => 2 do |modify|
+ assert_dom modify[0], ">node", :count => 1 do |node|
+ assert_dom node, ">@id", node0.node_id.to_s
+ end
+ assert_dom modify[1], ">node", :count => 1 do |node|
+ assert_dom node, ">@id", node1.node_id.to_s
+ end
+ end
+ end
+
+ def test_show_should_sort_by_version
+ changeset = create(:changeset)
+ node1 = create(:old_node, :version => 3, :timestamp => "2020-01-01", :changeset => changeset)
+ node0 = create(:old_node, :version => 2, :timestamp => "2020-01-01", :changeset => changeset)
+
+ get api_changeset_download_path(changeset)
+
+ assert_response :success
+ assert_dom "modify", :count => 2 do |modify|
+ assert_dom modify[0], ">node", :count => 1 do |node|
+ assert_dom node, ">@id", node0.node_id.to_s
+ end
+ assert_dom modify[1], ">node", :count => 1 do |node|
+ assert_dom node, ">@id", node1.node_id.to_s
+ end
+ end
+ end
+
+ ##
+ # check that the changeset download for a changeset with a redacted
+ # element in it doesn't contain that element.
+ def test_show_redacted
+ check_redacted do |changeset|
+ get api_changeset_download_path(changeset)
+ end
+ end
+
+ def test_show_redacted_unauthorized
+ check_redacted do |changeset|
+ get api_changeset_download_path(changeset, :show_redactions => "true")
+ end
+ end
+
+ def test_show_redacted_normal_user
+ auth_header = bearer_authorization_header
+
+ check_redacted do |changeset|
+ get api_changeset_download_path(changeset, :show_redactions => "true"), :headers => auth_header
+ end
+ end
+
+ def test_show_redacted_moderator_without_show_redactions
+ auth_header = bearer_authorization_header create(:moderator_user)
+
+ check_redacted do |changeset|
+ get api_changeset_download_path(changeset), :headers => auth_header
+ end
+ end
+
+ def test_show_redacted_moderator
+ auth_header = bearer_authorization_header create(:moderator_user)
+
+ check_redacted(:redacted_included => true) do |changeset|
+ get api_changeset_download_path(changeset, :show_redactions => "true"), :headers => auth_header
+ end
+ end
+
+ private
+
+ def check_redacted(redacted_included: false)
+ redaction = create(:redaction)
+ changeset = create(:changeset)
+ node = create(:node, :with_history, :version => 2, :changeset => changeset)
+ node_v1 = node.old_nodes.find_by(:version => 1)
+ node_v1.redact!(redaction)
+ way = create(:way, :with_history, :version => 2, :changeset => changeset)
+ way_v1 = way.old_ways.find_by(:version => 1)
+ way_v1.redact!(redaction)
+ relation = create(:relation, :with_history, :version => 2, :changeset => changeset)
+ relation_v1 = relation.old_relations.find_by(:version => 1)
+ relation_v1.redact!(redaction)
+
+ yield changeset
+
+ assert_response :success
+ assert_dom "osmChange", 1 do
+ assert_dom "node[id='#{node.id}'][version='1']", redacted_included ? 1 : 0
+ assert_dom "node[id='#{node.id}'][version='2']", 1
+ assert_dom "way[id='#{way.id}'][version='1']", redacted_included ? 1 : 0
+ assert_dom "way[id='#{way.id}'][version='2']", 1
+ assert_dom "relation[id='#{relation.id}'][version='1']", redacted_included ? 1 : 0
+ assert_dom "relation[id='#{relation.id}'][version='2']", 1
+ end
+ end
+ end
+ end
+end
{ :path => "/api/0.6/changesets", :method => :post },
{ :controller => "api/changesets", :action => "create" }
)
- assert_routing(
- { :path => "/api/0.6/changeset/1/upload", :method => :post },
- { :controller => "api/changesets", :action => "upload", :id => "1" }
- )
- assert_routing(
- { :path => "/api/0.6/changeset/1/download", :method => :get },
- { :controller => "api/changesets", :action => "download", :id => "1" }
- )
assert_routing(
{ :path => "/api/0.6/changeset/1", :method => :get },
{ :controller => "api/changesets", :action => "show", :id => "1" }
{ :path => "/api/0.6/changeset/1.json", :method => :get },
{ :controller => "api/changesets", :action => "show", :id => "1", :format => "json" }
)
+ assert_routing(
+ { :path => "/api/0.6/changeset/1", :method => :put },
+ { :controller => "api/changesets", :action => "update", :id => "1" }
+ )
+ assert_routing(
+ { :path => "/api/0.6/changeset/1/upload", :method => :post },
+ { :controller => "api/changesets", :action => "upload", :id => "1" }
+ )
assert_routing(
{ :path => "/api/0.6/changeset/1/subscribe", :method => :post },
{ :controller => "api/changesets", :action => "subscribe", :id => "1" }
{ :path => "/api/0.6/changeset/1/unsubscribe.json", :method => :post },
{ :controller => "api/changesets", :action => "unsubscribe", :id => "1", :format => "json" }
)
- assert_routing(
- { :path => "/api/0.6/changeset/1", :method => :put },
- { :controller => "api/changesets", :action => "update", :id => "1" }
- )
assert_routing(
{ :path => "/api/0.6/changeset/1/close", :method => :put },
{ :controller => "api/changesets", :action => "close", :id => "1" }
def test_show
changeset = create(:changeset)
- get changeset_show_path(changeset)
+ get api_changeset_path(changeset)
assert_response :success, "cannot get first changeset"
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
assert_dom "> discussion", 0
end
- get changeset_show_path(changeset), :params => { :include_discussion => true }
+ get api_changeset_path(changeset, :include_discussion => true)
assert_response :success, "cannot get first changeset with comments"
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
changeset = create(:changeset, :closed)
comment1, comment2, comment3 = create_list(:changeset_comment, 3, :changeset_id => changeset.id)
- get changeset_show_path(changeset), :params => { :include_discussion => true }
+ get api_changeset_path(changeset, :include_discussion => true)
assert_response :success, "cannot get closed changeset with comments"
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
comment2.update(:visible => false)
changeset.reload
- get changeset_show_path(changeset), :params => { :include_discussion => true }
+ get api_changeset_path(changeset, :include_discussion => true)
assert_response :success, "cannot get closed changeset with comments"
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
end
# one hidden comment not included because no permissions
- get changeset_show_path(changeset), :params => { :include_discussion => true, :show_hidden_comments => true }
+ get api_changeset_path(changeset, :include_discussion => true, :show_hidden_comments => true)
assert_response :success, "cannot get closed changeset with comments"
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
# one hidden comment shown to moderators
moderator_user = create(:moderator_user)
auth_header = bearer_authorization_header moderator_user
- get changeset_show_path(changeset), :params => { :include_discussion => true, :show_hidden_comments => true },
- :headers => auth_header
+ get api_changeset_path(changeset, :include_discussion => true, :show_hidden_comments => true), :headers => auth_header
assert_response :success, "cannot get closed changeset with comments"
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
create(:changeset_tag, :changeset => changeset, :k => "created_by", :v => "JOSM/1.5 (18364)")
create(:changeset_tag, :changeset => changeset, :k => "comment", :v => "changeset comment")
- get changeset_show_path(changeset)
+ get api_changeset_path(changeset)
assert_response :success
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
def test_show_json
changeset = create(:changeset)
- get changeset_show_path(changeset), :params => { :format => "json" }
+ get api_changeset_path(changeset, :format => "json")
assert_response :success, "cannot get first changeset"
js = ActiveSupport::JSON.decode(@response.body)
assert_equal changeset.user.id, js["changeset"]["uid"]
assert_equal changeset.user.display_name, js["changeset"]["user"]
- get changeset_show_path(changeset), :params => { :format => "json", :include_discussion => true }
+ get api_changeset_path(changeset, :format => "json", :include_discussion => true)
assert_response :success, "cannot get first changeset with comments"
js = ActiveSupport::JSON.decode(@response.body)
changeset = create(:changeset, :closed)
comment0, comment1, comment2 = create_list(:changeset_comment, 3, :changeset_id => changeset.id)
- get changeset_show_path(changeset), :params => { :format => "json", :include_discussion => true }
+ get api_changeset_path(changeset, :format => "json", :include_discussion => true)
assert_response :success, "cannot get closed changeset with comments"
js = ActiveSupport::JSON.decode(@response.body)
comment1.update(:visible => false)
changeset.reload
- get changeset_show_path(changeset), :params => { :format => "json", :include_discussion => true }
+ get api_changeset_path(changeset, :format => "json", :include_discussion => true)
assert_response :success, "cannot get closed changeset with comments"
js = ActiveSupport::JSON.decode(@response.body)
assert js["changeset"]["comments"][1]["visible"]
# one hidden comment not included because no permissions
- get changeset_show_path(changeset), :params => { :format => "json", :include_discussion => true, :show_hidden_comments => true }
+ get api_changeset_path(changeset, :format => "json", :include_discussion => true, :show_hidden_comments => true)
assert_response :success, "cannot get closed changeset with comments"
js = ActiveSupport::JSON.decode(@response.body)
# one hidden comment shown to moderators
moderator_user = create(:moderator_user)
auth_header = bearer_authorization_header moderator_user
- get changeset_show_path(changeset), :params => { :format => "json", :include_discussion => true, :show_hidden_comments => true },
- :headers => auth_header
+ get api_changeset_path(changeset, :format => "json", :include_discussion => true, :show_hidden_comments => true), :headers => auth_header
assert_response :success, "cannot get closed changeset with comments"
js = ActiveSupport::JSON.decode(@response.body)
create(:changeset_tag, :changeset => changeset, :k => "created_by", :v => "JOSM/1.5 (18364)")
create(:changeset_tag, :changeset => changeset, :k => "comment", :v => "changeset comment")
- get changeset_show_path(changeset, :format => "json")
+ get api_changeset_path(changeset, :format => "json")
assert_response :success
js = ActiveSupport::JSON.decode(@response.body)
changeset = create(:changeset, :min_lat => (-5 * GeoRecord::SCALE).round, :min_lon => (5 * GeoRecord::SCALE).round,
:max_lat => (15 * GeoRecord::SCALE).round, :max_lon => (12 * GeoRecord::SCALE).round)
- get changeset_show_path(changeset), :params => { :format => "json" }
+ get api_changeset_path(changeset, :format => "json")
assert_response :success, "cannot get first changeset"
js = ActiveSupport::JSON.decode(@response.body)
# check that a changeset that doesn't exist returns an appropriate message
def test_show_not_found
[0, -32, 233455644, "afg", "213"].each do |id|
- get changeset_show_path(id)
+ get api_changeset_path(id)
assert_response :not_found, "should get a not found"
rescue ActionController::UrlGenerationError => e
assert_match(/No route matches/, e.to_s)
assert_response :success,
"can't upload multiple versions of an element in a diff: #{@response.body}"
- get changeset_download_path(changeset_id)
+ get api_changeset_download_path(changeset_id)
assert_response :success
assert_select "osmChange", 1
assert_response :success,
"can't upload a diff from JOSM: #{@response.body}"
- get changeset_download_path(changeset_id)
+ get api_changeset_download_path(changeset_id)
assert_response :success
assert_select "osmChange", 1
assert_response :success,
"can't upload multiple versions of an element in a diff: #{@response.body}"
- get changeset_download_path(changeset_id)
+ get api_changeset_download_path(changeset_id)
assert_response :success
assert_select "osmChange", 1
assert_select "osmChange>modify>way", 1
end
- def test_changeset_download
- changeset = create(:changeset)
- node = create(:node, :with_history, :version => 1, :changeset => changeset)
- tag = create(:old_node_tag, :old_node => node.old_nodes.find_by(:version => 1))
- node2 = create(:node, :with_history, :version => 1, :changeset => changeset)
- _node3 = create(:node, :with_history, :deleted, :version => 1, :changeset => changeset)
- _relation = create(:relation, :with_history, :version => 1, :changeset => changeset)
- _relation2 = create(:relation, :with_history, :deleted, :version => 1, :changeset => changeset)
-
- get changeset_download_path(changeset)
-
- assert_response :success
-
- # FIXME: needs more assert_select tests
- assert_select "osmChange[version='#{Settings.api_version}'][generator='#{Settings.generator}']" do
- assert_select "create", :count => 5
- assert_select "create>node[id='#{node.id}'][visible='#{node.visible?}'][version='#{node.version}']" do
- assert_select "tag[k='#{tag.k}'][v='#{tag.v}']"
- end
- assert_select "create>node[id='#{node2.id}']"
- end
- end
-
- test "sorts downloaded elements by timestamp" do
- changeset = create(:changeset)
- node1 = create(:old_node, :version => 2, :timestamp => "2020-02-01", :changeset => changeset)
- node0 = create(:old_node, :version => 2, :timestamp => "2020-01-01", :changeset => changeset)
-
- get changeset_download_path(changeset)
- assert_response :success
- assert_dom "modify", :count => 2 do |modify|
- assert_dom modify[0], ">node", :count => 1 do |node|
- assert_dom node, ">@id", node0.node_id.to_s
- end
- assert_dom modify[1], ">node", :count => 1 do |node|
- assert_dom node, ">@id", node1.node_id.to_s
- end
- end
- end
-
- test "sorts downloaded elements by version" do
- changeset = create(:changeset)
- node1 = create(:old_node, :version => 3, :timestamp => "2020-01-01", :changeset => changeset)
- node0 = create(:old_node, :version => 2, :timestamp => "2020-01-01", :changeset => changeset)
-
- get changeset_download_path(changeset)
- assert_response :success
- assert_dom "modify", :count => 2 do |modify|
- assert_dom modify[0], ">node", :count => 1 do |node|
- assert_dom node, ">@id", node0.node_id.to_s
- end
- assert_dom modify[1], ">node", :count => 1 do |node|
- assert_dom node, ">@id", node1.node_id.to_s
- end
- end
- end
-
##
# check that the bounding box of a changeset gets updated correctly
# FIXME: This should really be moded to a integration test due to the with_controller
end
# get the bounding box back from the changeset
- get changeset_show_path(changeset_id)
+ get api_changeset_path(changeset_id)
assert_response :success, "Couldn't read back changeset."
assert_select "osm>changeset[min_lon='0.1000000']", 1
assert_select "osm>changeset[max_lon='0.1000000']", 1
end
# get the bounding box back from the changeset
- get changeset_show_path(changeset_id)
+ get api_changeset_path(changeset_id)
assert_response :success, "Couldn't read back changeset for the second time."
assert_select "osm>changeset[min_lon='0.1000000']", 1
assert_select "osm>changeset[max_lon='0.2000000']", 1
end
# get the bounding box back from the changeset
- get changeset_show_path(changeset_id)
+ get api_changeset_path(changeset_id)
assert_response :success, "Couldn't read back changeset for the third time."
assert_select "osm>changeset[min_lon='0.1000000']", 1
assert_select "osm>changeset[max_lon='0.3000000']", 1
new_changeset.find("//osm/changeset").first << new_tag
# try without any authorization
- put changeset_show_path(private_changeset), :params => new_changeset.to_s
+ put api_changeset_path(private_changeset), :params => new_changeset.to_s
assert_response :unauthorized
# try with the wrong authorization
auth_header = bearer_authorization_header
- put changeset_show_path(private_changeset), :params => new_changeset.to_s, :headers => auth_header
+ put api_changeset_path(private_changeset), :params => new_changeset.to_s, :headers => auth_header
assert_response :conflict
# now this should get an unauthorized
auth_header = bearer_authorization_header private_user
- put changeset_show_path(private_changeset), :params => new_changeset.to_s, :headers => auth_header
+ put api_changeset_path(private_changeset), :params => new_changeset.to_s, :headers => auth_header
assert_require_public_data "user with their data non-public, shouldn't be able to edit their changeset"
## Now try with the public user
new_changeset.find("//osm/changeset").first << new_tag
# try without any authorization
- put changeset_show_path(changeset), :params => new_changeset.to_s
+ put api_changeset_path(changeset), :params => new_changeset.to_s
assert_response :unauthorized
# try with the wrong authorization
auth_header = bearer_authorization_header
- put changeset_show_path(changeset), :params => new_changeset.to_s, :headers => auth_header
+ put api_changeset_path(changeset), :params => new_changeset.to_s, :headers => auth_header
assert_response :conflict
# now this should work...
auth_header = bearer_authorization_header user
- put changeset_show_path(changeset), :params => new_changeset.to_s, :headers => auth_header
+ put api_changeset_path(changeset), :params => new_changeset.to_s, :headers => auth_header
assert_response :success
assert_select "osm>changeset[id='#{changeset.id}']", 1
new_tag["v"] = "testing"
new_changeset.find("//osm/changeset").first << new_tag
- put changeset_show_path(changeset), :params => new_changeset.to_s, :headers => auth_header
+ put api_changeset_path(changeset), :params => new_changeset.to_s, :headers => auth_header
assert_response :conflict
end
"element limit.")
end
- ##
- # check that the changeset download for a changeset with a redacted
- # element in it doesn't contain that element.
- def test_diff_download_redacted
- changeset = create(:changeset)
- node = create(:node, :with_history, :version => 2, :changeset => changeset)
- node_v1 = node.old_nodes.find_by(:version => 1)
- node_v1.redact!(create(:redaction))
-
- get changeset_download_path(changeset)
- assert_response :success
-
- assert_select "osmChange", 1
- # this changeset contains the node in versions 1 & 2, but 1 should
- # be hidden.
- assert_select "osmChange node[id='#{node.id}']", 1
- assert_select "osmChange node[id='#{node.id}'][version='1']", 0
- end
-
##
# test subscribe success
def test_subscribe_success
# now download the changeset to check its bounding box
with_controller(Api::ChangesetsController.new) do
- get changeset_show_path(changeset_id)
+ get api_changeset_path(changeset_id)
assert_response :success, "can't re-read changeset for modify test"
assert_select "osm>changeset", 1, "Changeset element doesn't exist in #{@response.body}"
assert_select "osm>changeset[id='#{changeset_id}']", 1, "Changeset id=#{changeset_id} doesn't exist in #{@response.body}"
def test_read_note_suspended_opener_and_comment
note = create(:note)
create(:note_comment, :note => note, :author => create(:user, :suspended))
- create(:note_comment, :note => note)
+ create(:note_comment, :note => note, :event => "commented")
sidebar_browse_check :note_path, note.id, "notes/show"
assert_select "div.note-comments ul li", :count => 1
user = create(:user)
moderator_user = create(:moderator_user)
administrator_user = create(:administrator_user)
- _suspended_user = create(:user, :suspended)
- _ip_user = create(:user, :creation_address => "1.2.3.4")
+ suspended_user = create(:user, :suspended)
+ name_user = create(:user, :display_name => "Test User")
+ email_user = create(:user, :email => "test@example.com")
+ ip_user = create(:user, :creation_address => "1.2.3.4")
- # There are now 7 users - the five above, plus two extra "granters" for the
+ # There are now 9 users - the 7 above, plus two extra "granters" for the
# moderator_user and administrator_user
- assert_equal 7, User.count
+ assert_equal 9, User.count
# Shouldn't work when not logged in
get users_list_path
get users_list_path
assert_response :success
assert_template :show
- assert_select "table#user_list tbody tr", :count => 7
+ assert_select "table#user_list tbody tr", :count => 9
# Should be able to limit by status
get users_list_path, :params => { :status => "suspended" }
assert_response :success
assert_template :show
- assert_select "table#user_list tbody tr", :count => 1
+ assert_select "table#user_list tbody tr", :count => 1 do
+ assert_select "a[href='#{user_path(suspended_user)}']", :count => 1
+ end
+
+ # Should be able to limit by name
+ get users_list_path, :params => { :username => "Test User" }
+ assert_response :success
+ assert_template :show
+ assert_select "table#user_list tbody tr", :count => 1 do
+ assert_select "a[href='#{user_path(name_user)}']", :count => 1
+ end
+
+ # Should be able to limit by name ignoring case
+ get users_list_path, :params => { :username => "test user" }
+ assert_response :success
+ assert_template :show
+ assert_select "table#user_list tbody tr", :count => 1 do
+ assert_select "a[href='#{user_path(name_user)}']", :count => 1
+ end
+
+ # Should be able to limit by email
+ get users_list_path, :params => { :username => "test@example.com" }
+ assert_response :success
+ assert_template :show
+ assert_select "table#user_list tbody tr", :count => 1 do
+ assert_select "a[href='#{user_path(email_user)}']", :count => 1
+ end
+
+ # Should be able to limit by email ignoring case
+ get users_list_path, :params => { :username => "TEST@example.com" }
+ assert_response :success
+ assert_template :show
+ assert_select "table#user_list tbody tr", :count => 1 do
+ assert_select "a[href='#{user_path(email_user)}']", :count => 1
+ end
# Should be able to limit by IP address
get users_list_path, :params => { :ip => "1.2.3.4" }
assert_response :success
assert_template :show
- assert_select "table#user_list tbody tr", :count => 1
+ assert_select "table#user_list tbody tr", :count => 1 do
+ assert_select "a[href='#{user_path(ip_user)}']", :count => 1
+ end
end
def test_show_paginated
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0"
integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==
-"@eslint/config-array@^0.19.0":
- version "0.19.0"
- resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.0.tgz#3251a528998de914d59bb21ba4c11767cf1b3519"
- integrity sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==
+"@eslint/config-array@^0.19.2":
+ version "0.19.2"
+ resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.2.tgz#3060b809e111abfc97adb0bb1172778b90cb46aa"
+ integrity sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==
dependencies:
- "@eslint/object-schema" "^2.1.4"
+ "@eslint/object-schema" "^2.1.6"
debug "^4.3.1"
minimatch "^3.1.2"
-"@eslint/core@^0.10.0":
- version "0.10.0"
- resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.10.0.tgz#23727063c21b335f752dbb3a16450f6f9cbc9091"
- integrity sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==
+"@eslint/core@^0.12.0":
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.12.0.tgz#5f960c3d57728be9f6c65bd84aa6aa613078798e"
+ integrity sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==
dependencies:
"@types/json-schema" "^7.0.15"
-"@eslint/core@^0.11.0":
- version "0.11.0"
- resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.11.0.tgz#7a9226e850922e42cbd2ba71361eacbe74352a12"
- integrity sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==
- dependencies:
- "@types/json-schema" "^7.0.15"
-
-"@eslint/eslintrc@^3.2.0":
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.2.0.tgz#57470ac4e2e283a6bf76044d63281196e370542c"
- integrity sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==
+"@eslint/eslintrc@^3.3.0":
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.0.tgz#96a558f45842989cca7ea1ecd785ad5491193846"
+ integrity sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
-"@eslint/js@9.20.0":
- version "9.20.0"
- resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.20.0.tgz#7421bcbe74889fcd65d1be59f00130c289856eb4"
- integrity sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==
+"@eslint/js@9.21.0":
+ version "9.21.0"
+ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.21.0.tgz#4303ef4e07226d87c395b8fad5278763e9c15c08"
+ integrity sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==
-"@eslint/object-schema@^2.1.4":
- version "2.1.4"
- resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.4.tgz#9e69f8bb4031e11df79e03db09f9dbbae1740843"
- integrity sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==
+"@eslint/object-schema@^2.1.6":
+ version "2.1.6"
+ resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.6.tgz#58369ab5b5b3ca117880c0f6c0b0f32f6950f24f"
+ integrity sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==
-"@eslint/plugin-kit@^0.2.5":
- version "0.2.5"
- resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz#ee07372035539e7847ef834e3f5e7b79f09e3a81"
- integrity sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==
+"@eslint/plugin-kit@^0.2.7":
+ version "0.2.7"
+ resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz#9901d52c136fb8f375906a73dcc382646c3b6a27"
+ integrity sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==
dependencies:
- "@eslint/core" "^0.10.0"
+ "@eslint/core" "^0.12.0"
levn "^0.4.1"
"@humanfs/core@^0.19.1":
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a"
integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==
-"@humanwhocodes/retry@^0.4.1":
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.1.tgz#9a96ce501bc62df46c4031fbd970e3cc6b10f07b"
- integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==
+"@humanwhocodes/retry@^0.4.2":
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.2.tgz#1860473de7dfa1546767448f333db80cb0ff2161"
+ integrity sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==
"@stylistic/eslint-plugin-js@^4.0.0":
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin-js/-/eslint-plugin-js-4.0.1.tgz#c55e59ad2f00914f9eb103ba9e7be00aff7715dd"
- integrity sha512-2EGKM6WHnZSidWKCu6ePJCqdpgWiEU1Bt26ktWEfTpCmRP+2vRQ6ViK8X6DLwu4+F0zPLy/Txe2HhI3qJFUvqA==
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin-js/-/eslint-plugin-js-4.1.0.tgz#cb3fcc6bef022f1af8245a6cda404d290358c260"
+ integrity sha512-YOe+dChNoR26JVVt+7BjyebsPIQF05OLNmHCXivq8lLZ4ZeVs4+wXaW+pREVboDiAaSRznauAdAU8f+iQouw6Q==
dependencies:
eslint-visitor-keys "^4.2.0"
espree "^10.3.0"
integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==
eslint@^9.0.0:
- version "9.20.1"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.20.1.tgz#923924c078f5226832449bac86662dd7e53c91d6"
- integrity sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==
+ version "9.21.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.21.0.tgz#b1c9c16f5153ff219791f627b94ab8f11f811591"
+ integrity sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==
dependencies:
"@eslint-community/eslint-utils" "^4.2.0"
"@eslint-community/regexpp" "^4.12.1"
- "@eslint/config-array" "^0.19.0"
- "@eslint/core" "^0.11.0"
- "@eslint/eslintrc" "^3.2.0"
- "@eslint/js" "9.20.0"
- "@eslint/plugin-kit" "^0.2.5"
+ "@eslint/config-array" "^0.19.2"
+ "@eslint/core" "^0.12.0"
+ "@eslint/eslintrc" "^3.3.0"
+ "@eslint/js" "9.21.0"
+ "@eslint/plugin-kit" "^0.2.7"
"@humanfs/node" "^0.16.6"
"@humanwhocodes/module-importer" "^1.0.1"
- "@humanwhocodes/retry" "^0.4.1"
+ "@humanwhocodes/retry" "^0.4.2"
"@types/estree" "^1.0.6"
"@types/json-schema" "^7.0.15"
ajv "^6.12.4"