summaryrefslogtreecommitdiffstats
path: root/app/controllers/repositories_controller.rb
blob: a35e2956cf6b52338675d17b510c1b8b8ce5993b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
# frozen_string_literal: true

# Redmine - project management software
# Copyright (C) 2006-2019  Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

require 'digest/sha1'
require 'redmine/scm/adapters'

class ChangesetNotFound < StandardError; end
class InvalidRevisionParam < StandardError; end

class RepositoriesController < ApplicationController
  menu_item :repository
  menu_item :settings, :only => [:new, :create, :edit, :update, :destroy, :committers]
  default_search_scope :changesets

  before_action :find_project_by_project_id, :only => [:new, :create]
  before_action :build_new_repository_from_params, :only => [:new, :create]
  before_action :find_repository, :only => [:edit, :update, :destroy, :committers]
  before_action :find_project_repository, :except => [:new, :create, :edit, :update, :destroy, :committers]
  before_action :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue]
  before_action :authorize
  accept_rss_auth :revisions

  rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed

  def new
    @repository.is_default = @project.repository.nil?
  end

  def create
    if @repository.save
      redirect_to settings_project_path(@project, :tab => 'repositories')
    else
      render :action => 'new'
    end
  end

  def edit
  end

  def update
    @repository.safe_attributes = params[:repository]
    if @repository.save
      redirect_to settings_project_path(@project, :tab => 'repositories')
    else
      render :action => 'edit'
    end
  end

  def committers
    @committers = @repository.committers
    @users = @project.users.to_a
    additional_user_ids = @committers.collect(&:last).collect(&:to_i) - @users.collect(&:id)
    @users += User.where(:id => additional_user_ids).to_a unless additional_user_ids.empty?
    @users.compact!
    @users.sort!
    if request.post? && params[:committers].present?
      # Build a hash with repository usernames as keys and corresponding user ids as values
      @repository.committer_ids = params[:committers].values.inject({}) {|h, c| h[c.first] = c.last; h}
      flash[:notice] = l(:notice_successful_update)
      redirect_to settings_project_path(@project, :tab => 'repositories')
    end
  end

  def destroy
    @repository.destroy if request.delete?
    redirect_to settings_project_path(@project, :tab => 'repositories')
  end

  def show
    @repository.fetch_changesets if @project.active? && Setting.autofetch_changesets? && @path.empty?

    @entries = @repository.entries(@path, @rev)
    @changeset = @repository.find_changeset_by_name(@rev)
    if request.xhr?
      @entries ? render(:partial => 'dir_list_content') : head(200)
    else
      (show_error_not_found; return) unless @entries
      @changesets = @repository.latest_changesets(@path, @rev)
      @properties = @repository.properties(@path, @rev)
      @repositories = @project.repositories
      render :action => 'show'
    end
  end

  alias_method :browse, :show

  def changes
    @entry = @repository.entry(@path, @rev)
    (show_error_not_found; return) unless @entry
    @changesets = @repository.latest_changesets(@path, @rev, Setting.repository_log_display_limit.to_i)
    @properties = @repository.properties(@path, @rev)
    @changeset = @repository.find_changeset_by_name(@rev)
  end

  def revisions
    @changeset_count = @repository.changesets.count
    @changeset_pages = Paginator.new @changeset_count,
                                     per_page_option,
                                     params['page']
    @changesets = @repository.changesets.
      limit(@changeset_pages.per_page).
      offset(@changeset_pages.offset).
      includes(:user, :repository, :parents).
      to_a

    respond_to do |format|
      format.html { render :layout => false if request.xhr? }
      format.atom { render_feed(@changesets, :title => "#{@project.name}: #{l(:label_revision_plural)}") }
    end
  end

  def raw
    entry_and_raw(true)
  end

  def entry
    entry_and_raw(false)
  end

  def entry_and_raw(is_raw)
    @entry = @repository.entry(@path, @rev)
    (show_error_not_found; return) unless @entry

    # If the entry is a dir, show the browser
    (show; return) if @entry.is_dir?

    if is_raw
      # Force the download
      send_opt = { :filename => filename_for_content_disposition(@path.split('/').last) }
      send_type = Redmine::MimeType.of(@path)
      send_opt[:type] = send_type.to_s if send_type
      send_opt[:disposition] = disposition(@path)
      send_data @repository.cat(@path, @rev), send_opt
    else
      # set up pagination from entry to entry
      parent_path = @path.split('/')[0...-1].join('/')
      @entries = @repository.entries(parent_path, @rev).reject(&:is_dir?)
      if index = @entries.index{|e| e.name == @entry.name}
        @paginator = Redmine::Pagination::Paginator.new(@entries.size, 1, index+1)
      end

      if !@entry.size || @entry.size <= Setting.file_max_size_displayed.to_i.kilobyte
        content = @repository.cat(@path, @rev)
        (show_error_not_found; return) unless content

        if content.size <= Setting.file_max_size_displayed.to_i.kilobyte &&
           is_entry_text_data?(content, @path)
          # TODO: UTF-16
          # Prevent empty lines when displaying a file with Windows style eol
          # Is this needed? AttachmentsController simply reads file.
          @content = content.gsub("\r\n", "\n")
        end
      end
      @changeset = @repository.find_changeset_by_name(@rev)
    end
  end
  private :entry_and_raw

  def is_entry_text_data?(ent, path)
    # UTF-16 contains "\x00".
    # It is very strict that file contains less than 30% of ascii symbols
    # in non Western Europe.
    return true if Redmine::MimeType.is_type?('text', path)
    # Ruby 1.8.6 has a bug of integer divisions.
    # http://apidock.com/ruby/v1_8_6_287/String/is_binary_data%3F
    return false if Redmine::Scm::Adapters::ScmData.binary?(ent)
    true
  end
  private :is_entry_text_data?

  def annotate
    @entry = @repository.entry(@path, @rev)
    (show_error_not_found; return) unless @entry

    @annotate = @repository.scm.annotate(@path, @rev)
    if @annotate.nil? || @annotate.empty?
      @annotate = nil
      @error_message = l(:error_scm_annotate)
    else
      ann_buf_size = 0
      @annotate.lines.each do |buf|
        ann_buf_size += buf.size
      end
      if ann_buf_size > Setting.file_max_size_displayed.to_i.kilobyte
        @annotate = nil
        @error_message = l(:error_scm_annotate_big_text_file)
      end
    end
    @changeset = @repository.find_changeset_by_name(@rev)
  end

  def revision
    respond_to do |format|
      format.html
      format.js {render :layout => false}
    end
  end

  # Adds a related issue to a changeset
  # POST /projects/:project_id/repository/(:repository_id/)revisions/:rev/issues
  def add_related_issue
    issue_id = params[:issue_id].to_s.sub(/^#/,'')
    @issue = @changeset.find_referenced_issue_by_id(issue_id)
    if @issue && (!@issue.visible? || @changeset.issues.include?(@issue))
      @issue = nil
    end

    if @issue
      @changeset.issues << @issue
    end
  end

  # Removes a related issue from a changeset
  # DELETE /projects/:project_id/repository/(:repository_id/)revisions/:rev/issues/:issue_id
  def remove_related_issue
    @issue = Issue.visible.find_by_id(params[:issue_id])
    if @issue
      @changeset.issues.delete(@issue)
    end
  end

  def diff
    if params[:format] == 'diff'
      @diff = @repository.diff(@path, @rev, @rev_to)
      (show_error_not_found; return) unless @diff
      filename = +"changeset_r#{@rev}"
      filename << "_r#{@rev_to}" if @rev_to
      send_data @diff.join, :filename => "#{filename}.diff",
                            :type => 'text/x-patch',
                            :disposition => 'attachment'
    else
      @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
      @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)

      # Save diff type as user preference
      if User.current.logged? && @diff_type != User.current.pref[:diff_type]
        User.current.pref[:diff_type] = @diff_type
        User.current.preference.save
      end
      @cache_key = "repositories/diff/#{@repository.id}/" +
                      Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}-#{current_language}")
      unless read_fragment(@cache_key)
        @diff = @repository.diff(@path, @rev, @rev_to)
        show_error_not_found unless @diff
      end

      @changeset = @repository.find_changeset_by_name(@rev)
      @changeset_to = @rev_to ? @repository.find_changeset_by_name(@rev_to) : nil
      @diff_format_revisions = @repository.diff_format_revisions(@changeset, @changeset_to)
    end
  end

  def stats
  end

  # Returns JSON data for repository graphs
  def graph
    data = nil
    case params[:graph]
    when "commits_per_month"
      data = graph_commits_per_month(@repository)
    when "commits_per_author"
      data = graph_commits_per_author(@repository)
    end
    if data
      render :json => data
    else
      render_404
    end
  end

  private

  def build_new_repository_from_params
    scm = params[:repository_scm] || (Redmine::Scm::Base.all & Setting.enabled_scm).first
    unless @repository = Repository.factory(scm)
      render_404
      return
    end

    @repository.project = @project
    @repository.safe_attributes = params[:repository]
    @repository
  end

  def find_repository
    @repository = Repository.find(params[:id])
    @project = @repository.project
  rescue ActiveRecord::RecordNotFound
    render_404
  end

  REV_PARAM_RE = %r{\A[a-f0-9]*\Z}i

  def find_project_repository
    @project = Project.find(params[:id])
    if params[:repository_id].present?
      @repository = @project.repositories.find_by_identifier_param(params[:repository_id])
    else
      @repository = @project.repository
    end
    (render_404; return false) unless @repository
    @path = params[:path].is_a?(Array) ? params[:path].join('/') : params[:path].to_s
    @rev = params[:rev].blank? ? @repository.default_branch : params[:rev].to_s.strip
    @rev_to = params[:rev_to]

    unless REV_PARAM_RE.match?(@rev.to_s) && REV_PARAM_RE.match?(@rev_to.to_s)
      if @repository.branches.blank?
        raise InvalidRevisionParam
      end
    end
  rescue ActiveRecord::RecordNotFound
    render_404
  rescue InvalidRevisionParam
    show_error_not_found
  end

  def find_changeset
    if @rev.present?
      @changeset = @repository.find_changeset_by_name(@rev)
    end
    show_error_not_found unless @changeset
  end

  def show_error_not_found
    render_error :message => l(:error_scm_not_found), :status => 404
  end

  # Handler for Redmine::Scm::Adapters::CommandFailed exception
  def show_error_command_failed(exception)
    render_error l(:error_scm_command_failed, exception.message)
  end

  def graph_commits_per_month(repository)
    date_to = User.current.today
    date_from = date_to << 11
    date_from = Date.civil(date_from.year, date_from.month, 1)
    commits_by_day = Changeset.
      where("repository_id = ? AND commit_date BETWEEN ? AND ?", repository.id, date_from, date_to).
      group(:commit_date).
      count
    commits_by_month = [0] * 12
    commits_by_day.each {|c| commits_by_month[(date_to.month - c.first.to_date.month) % 12] += c.last }

    changes_by_day = Change.
      joins(:changeset).
      where("#{Changeset.table_name}.repository_id = ? AND #{Changeset.table_name}.commit_date BETWEEN ? AND ?", repository.id, date_from, date_to).
      group(:commit_date).
      count
    changes_by_month = [0] * 12
    changes_by_day.each {|c| changes_by_month[(date_to.month - c.first.to_date.month) % 12] += c.last }

    fields = []
    today = User.current.today
    12.times {|m| fields << month_name(((today.month - 1 - m) % 12) + 1)}

    data = {
      :labels => fields.reverse,
      :commits => commits_by_month[0..11].reverse,
      :changes => changes_by_month[0..11].reverse
    }
  end

  def graph_commits_per_author(repository)
    #data
    stats = repository.stats_by_author
    fields, commits_data, changes_data = [], [], []
    stats.each do |name, hsh|
      fields << name
      commits_data << hsh[:commits_count]
      changes_data << hsh[:changes_count]
    end

    #expand to 10 values if needed
    fields = fields + [""]*(10 - fields.length) if fields.length<10
    commits_data = commits_data + [0]*(10 - commits_data.length) if commits_data.length<10
    changes_data = changes_data + [0]*(10 - changes_data.length) if changes_data.length<10

    # Remove email address in usernames
    fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') }

    data = {
      :labels => fields.reverse,
      :commits => commits_data.reverse,
      :changes => changes_data.reverse
    }
  end

  def disposition(path)
    if Redmine::MimeType.of(@path) == "application/pdf"
      'inline'
    else
      'attachment'
    end
  end
end
fix/download-non-files-view Nextcloud server, a safe home for all your data: https://github.com/nextcloud/serverwww-data
summaryrefslogtreecommitdiffstats
path: root/lib/l10n/fr.json
blob: 639eed6cb7aa626e5415f5571fd08aa080637598 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
{ "translations": {
    "Cannot write into \"config\" directory!" : "Impossible d’écrire dans le répertoire « config » !",
    "This can usually be fixed by giving the webserver write access to the config directory" : "Ce problème est généralement résolu en donnant au serveur web un accès en écriture au répertoire \"config\"",
    "See %s" : "Voir %s",
    "This can usually be fixed by giving the webserver write access to the config directory. See %s" : "Ce problème est généralement résolu en donnant au serveur web un accès en écriture au répertoire \"config\". Voir %s",
    "The files of the app %$1s were not replaced correctly. Make sure it is a version compatible with the server." : "Les fichiers de l'application %$1s n'ont pas été remplacés correctement. Veuillez vérifier que c'est une version compatible avec le serveur.",
    "Sample configuration detected" : "Configuration d'exemple détectée",
    "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Il a été détecté que la configuration donnée à titre d'exemple a été copiée. Cela peut rendre votre installation inopérante et n'est pas pris en charge. Veuillez lire la documentation avant d'effectuer des modifications dans config.php",
    "%1$s and %2$s" : "%1$s et %2$s",
    "%1$s, %2$s and %3$s" : "%1$s, %2$s et %3$s",
    "%1$s, %2$s, %3$s and %4$s" : "%1$s, %2$s, %3$s et %4$s",
    "%1$s, %2$s, %3$s, %4$s and %5$s" : "%1$s, %2$s, %3$s, %4$s et %5$s",
    "Enterprise bundle" : "Pack pour entreprise",
    "Groupware bundle" : "Pack pour travail collaboratif",
    "Social sharing bundle" : "Pack pour partage social",
    "PHP %s or higher is required." : "PHP %s ou supérieur est requis.",
    "PHP with a version lower than %s is required." : "PHP avec une version antérieure à %s est requis.",
    "%sbit or higher PHP required." : "PHP %sbits ou supérieur est requis.",
    "Following databases are supported: %s" : "Les bases de données suivantes sont supportées : %s",
    "The command line tool %s could not be found" : "La commande %s est introuvable",
    "The library %s is not available." : "La librairie %s n'est pas disponible.",
    "Library %s with a version higher than %s is required - available version %s." : "La librairie %s doit être au moins à la version %s. Version disponible : %s.",
    "Library %s with a version lower than %s is required - available version %s." : "La librairie %s doit avoir une version antérieure à %s. Version disponible : %s.",
    "Following platforms are supported: %s" : "Les plateformes suivantes sont prises en charge : %s",
    "Server version %s or higher is required." : "Un serveur de version %s ou supérieure est requis.",
    "Server version %s or lower is required." : "Un serveur de version %s ou inférieure est requis.",
    "Unknown filetype" : "Type de fichier inconnu",
    "Invalid image" : "Image non valable",
    "Avatar image is not square" : "L'image d'avatar n'est pas carré",
    "today" : "aujourd'hui",
    "yesterday" : "hier",
    "_%n day ago_::_%n days ago_" : ["il y a %n jour","il y a %n jours"],
    "last month" : "le mois dernier",
    "_%n month ago_::_%n months ago_" : ["Il y a %n mois","Il y a %n mois"],
    "last year" : "l'année dernière",
    "_%n year ago_::_%n years ago_" : ["il y a %n an","il y a %n ans"],
    "_%n hour ago_::_%n hours ago_" : ["Il y a %n heure","Il y a %n heures"],
    "_%n minute ago_::_%n minutes ago_" : ["il y a %n minute","il y a %n minutes"],
    "seconds ago" : "il y a quelques secondes",
    "Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Le module avec l'ID: %s n'existe pas. Merci de l'activer dans les paramètres d'applications ou de contacter votre administrateur.",
    "File name is a reserved word" : "Ce nom de fichier est un mot réservé",
    "File name contains at least one invalid character" : "Le nom de fichier contient un (des) caractère(s) non valide(s)",
    "File name is too long" : "Nom de fichier trop long",
    "Dot files are not allowed" : "Le nom de fichier ne peut pas commencer par un point",
    "Empty filename is not allowed" : "Le nom de fichier ne peut pas être vide",
    "App \"%s\" cannot be installed because appinfo file cannot be read." : "L'application \"%s\" ne peut pas être installée car le fichier appinfo ne peut pas être lu.",
    "App \"%s\" cannot be installed because it is not compatible with this version of the server." : "L'application \"%s\" ne peut être installée car elle n'est pas compatible avec cette version du serveur",
    "This is an automatically sent email, please do not reply." : "Ceci est un e-mail envoyé automatiquement, veuillez ne pas y répondre.",
    "Help" : "Aide",
    "Apps" : "Applications",
    "Personal" : "Personnel",
    "Log out" : "Se déconnecter",
    "Users" : "Utilisateurs",
    "Admin" : "Administration",
    "APCu" : "APCu",
    "Redis" : "Redis",
    "Basic settings" : "Paramètres de base",
    "Sharing" : "Partage",
    "Security" : "Sécurité",
    "Encryption" : "Chiffrement",
    "Additional settings" : "Paramètres supplémentaires",
    "Tips & tricks" : "Trucs et astuces",
    "%s enter the database username and name." : "%s entrez le nom d'utilisateur et le nom de la base de données.",
    "%s enter the database username." : "%s entrez le nom d'utilisateur de la base de données.",
    "%s enter the database name." : "%s entrez le nom de la base de données.",
    "%s you may not use dots in the database name" : "%s vous ne pouvez pas utiliser de points dans le nom de la base de données",
    "Oracle connection could not be established" : "La connexion Oracle ne peut être établie",
    "Oracle username and/or password not valid" : "Nom d'utilisateur et/ou mot de passe de la base Oracle non valide(s)",
    "DB Error: \"%s\"" : "Erreur de la base de données : \"%s\"",
    "Offending command was: \"%s\"" : "La requête en cause est : \"%s\"",
    "You need to enter details of an existing account." : "Vous devez indiquer les détails d'un compte existant.",
    "Offending command was: \"%s\", name: %s, password: %s" : "La requête en cause est : \"%s\", nom : %s, mot de passe : %s",
    "PostgreSQL username and/or password not valid" : "Nom d'utilisateur et/ou mot de passe de la base PostgreSQL non valide(s)",
    "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Mac OS X n'est pas pris en charge et %s ne fonctionnera pas correctement sur cette plate-forme. Son utilisation est à vos risques et périls !",
    "For the best results, please consider using a GNU/Linux server instead." : "Pour obtenir les meilleurs résultats, vous devriez utiliser un serveur GNU/Linux.",
    "It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. This will lead to problems with files over 4 GB and is highly discouraged." : "Il semble que cette instance %s fonctionne sur un environnement PHP 32-bit et open_basedir a été configuré dans php.ini. Cela engendre des problèmes avec les fichiers de taille supérieure à 4 Go et est donc fortement déconseillé.",
    "Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "Veuillez supprimer la configuration open_basedir de votre php.ini ou utiliser une version PHP 64-bit.",
    "Set an admin username." : "Spécifiez un nom d'utilisateur pour l'administrateur.",
    "Set an admin password." : "Spécifiez un mot de passe pour l'administrateur.",
    "Can't create or write into the data directory %s" : "Impossible de créer, ou d'écrire dans, le répertoire des données %s",
    "Invalid Federated Cloud ID" : "ID Federated Cloud incorrect",
    "Sharing %s failed, because the backend does not allow shares from type %i" : "Le partage de %s a échoué car l’infrastructure n'autorise pas les partages de type %i",
    "Sharing %s failed, because the file does not exist" : "Le partage de %s a échoué car le fichier n'existe pas",
    "You are not allowed to share %s" : "Vous n'êtes pas autorisé à partager %s",
    "Sharing %s failed, because you can not share with yourself" : "Le partage de %s a échoué car vous ne pouvez pas partager avec vous-même",
    "Sharing %s failed, because the user %s does not exist" : "Le partage de %s a échoué car l'utilisateur %s n'existe pas",
    "Sharing %s failed, because the user %s is not a member of any groups that %s is a member of" : "Le partage de %s a échoué car l'utilisateur %s n'est membre d'aucun groupe auquel %s appartient",
    "Sharing %s failed, because this item is already shared with %s" : "Le partage de %s a échoué car cet objet est déjà partagé avec %s",
    "Sharing %s failed, because this item is already shared with user %s" : "Le partage de %s a échoué car cet élément est déjà partagé avec l'utilisateur %s",
    "Sharing %s failed, because the group %s does not exist" : "Le partage de %s a échoué car le groupe %s n'existe pas",
    "Sharing %s failed, because %s is not a member of the group %s" : "Le partage de %s a échoué car %s n'est pas membre du groupe %s",
    "You need to provide a password to create a public link, only protected links are allowed" : "Vous devez fournir un mot de passe pour créer un lien public, seuls les liens protégés sont autorisées.",
    "Sharing %s failed, because sharing with links is not allowed" : "Le partage de %s a échoué car le partage par lien n'est pas permis",
    "Not allowed to create a federated share with the same user" : "Non autorisé à créer un partage fédéré avec le même utilisateur",
    "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Le partage de %s a échoué : impossible de trouver %s. Peut-être le serveur est-il momentanément injoignable.",
    "Share type %s is not valid for %s" : "Le type de partage %s n'est pas valide pour %s",
    "Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "Le réglage des permissions pour %s a échoué car les permissions dépassent celles accordées à %s",
    "Setting permissions for %s failed, because the item was not found" : "Le réglage des permissions pour %s a échoué car l'objet n'a pas été trouvé",
    "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Impossible de configurer la date d'expiration. Un partage ne peut expirer plus de %s après sa création",
    "Cannot set expiration date. Expiration date is in the past" : "Impossible de configurer la date d'expiration : elle est dans le passé.",
    "Cannot clear expiration date. Shares are required to have an expiration date." : "Impossible de supprimer la date d'expiration. Les partages doivent avoir une date d'expiration.",
    "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Le service de partage %s doit implémenter l'interface OCP\\Share_Backend",
    "Sharing backend %s not found" : "Service de partage %s non trouvé",
    "Sharing backend for %s not found" : "Le service de partage pour %s est introuvable",
    "Sharing failed, because the user %s is the original sharer" : "Le partage a échoué car l'utilisateur %s est le propriétaire original",
    "Sharing %s failed, because the permissions exceed permissions granted to %s" : "Le partage de %s a échoué car les permissions dépassent celles accordées à %s",
    "Sharing %s failed, because resharing is not allowed" : "Le partage de %s a échoué car le repartage n'est pas autorisé",
    "Sharing %s failed, because the sharing backend for %s could not find its source" : "Le partage de %s a échoué car le service %s n'a pas trouvé sa source..",
    "Sharing %s failed, because the file could not be found in the file cache" : "Le partage de %s a échoué car le fichier n'a pas été trouvé dans les fichiers mis en cache.",
    "Cannot increase permissions of %s" : "Impossible d'augmenter les permissions de %s",
    "Files can't be shared with delete permissions" : "Les fichiers ne peuvent pas être partagés avec les autorisations de suppression",
    "Files can't be shared with create permissions" : "Les fichiers ne peuvent pas être partagés avec les autorisations de création",
    "Expiration date is in the past" : "La date d'expiration est dans le passé",
    "Cannot set expiration date more than %s days in the future" : "Impossible de définir la date d'expiration à plus de %s jours dans le futur",
    "Could not find category \"%s\"" : "Impossible de trouver la catégorie \"%s\"",
    "Sunday" : "Dimanche",
    "Monday" : "Lundi",
    "Tuesday" : "Mardi",
    "Wednesday" : "Mercredi",
    "Thursday" : "Jeudi",
    "Friday" : "Vendredi",
    "Saturday" : "Samedi",
    "Sun." : "Dim.",
    "Mon." : "Lun.",
    "Tue." : "Mar.",
    "Wed." : "Mer.",
    "Thu." : "Jeu.",
    "Fri." : "Ven.",
    "Sat." : "Sam.",
    "Su" : "Di",
    "Mo" : "Lu",
    "Tu" : "Ma",
    "We" : "Me",
    "Th" : "Je",
    "Fr" : "Ve",
    "Sa" : "Sa",
    "January" : "Janvier",
    "February" : "Février",
    "March" : "Mars",
    "April" : "Avril",
    "May" : "Mai",
    "June" : "Juin",
    "July" : "Juillet",
    "August" : "Août",
    "September" : "Septembre",
    "October" : "Octobre",
    "November" : "Novembre",
    "December" : "Décembre",
    "Jan." : "Jan.",
    "Feb." : "Fév.",
    "Mar." : "Mars",
    "Apr." : "Avr.",
    "May." : "Mai",
    "Jun." : "Juin",
    "Jul." : "Juil.",
    "Aug." : "Août",
    "Sep." : "Sep.",
    "Oct." : "Oct.",
    "Nov." : "Nov.",
    "Dec." : "Déc.",
    "Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"" : "Seuls les caractères suivants sont autorisés dans un nom d'utilisateur : \"a-z\", \"A-Z\", \"0-9\", \"_@-\" et \".\" (le point)",
    "A valid username must be provided" : "Un nom d'utilisateur valide doit être saisi",
    "Username contains whitespace at the beginning or at the end" : "Le nom d'utilisateur contient des espaces au début ou à la fin",
    "Username must not consist of dots only" : "Le nom d'utilisateur ne doit pas être composé uniquement de points",
    "A valid password must be provided" : "Un mot de passe valide doit être saisi",
    "The username is already being used" : "Ce nom d'utilisateur est déjà utilisé",
    "User disabled" : "Utilisateur désactivé",
    "Login canceled by app" : "L'authentification a été annulé par l'application",
    "No app name specified" : "Aucun nom d'application spécifié",
    "App '%s' could not be installed!" : "L'application \"%s\" ne peut pas être installée !",
    "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "L'application \"%s\" ne peut pas être installée à cause des dépendances suivantes non satisfaites : %s",
    "a safe home for all your data" : "un endroit sûr pour toutes vos données",
    "File is currently busy, please try again later" : "Le fichier est actuellement utilisé, veuillez réessayer plus tard",
    "Can't read file" : "Impossible de lire le fichier",
    "Application is not enabled" : "L'application n'est pas activée",
    "Authentication error" : "Erreur d'authentification",
    "Token expired. Please reload page." : "La session a expiré. Veuillez recharger la page.",
    "Unknown user" : "Utilisateur inconnu",
    "No database drivers (sqlite, mysql, or postgresql) installed." : "Aucun pilote de base de données n’est installé (sqlite, mysql ou postgresql).",
    "Cannot write into \"config\" directory" : "Impossible d’écrire dans le répertoire \"config\"",
    "Cannot write into \"apps\" directory" : "Impossible d’écrire dans le répertoire \"apps\"",
    "This can usually be fixed by giving the webserver write access to the apps directory or disabling the appstore in the config file. See %s" : "Ce problème est généralement résolu en donnant au serveur web un accès en écriture au répertoire \"apps\" ou en désactivant l'appstore dans le fichier de configuration. Voir %s",
    "Cannot create \"data\" directory" : "Impossible de créer le dossier \"data\"",
    "This can usually be fixed by giving the webserver write access to the root directory. See %s" : "Ce problème est généralement résolu en donnant au serveur web un accès en écriture au répertoire racine. Voir %s",
    "Permissions can usually be fixed by giving the webserver write access to the root directory. See %s." : "Le problème de permissions peut généralement être résolu en donnant au serveur web un accès en écriture au répertoire racine. Voir %s.",
    "Setting locale to %s failed" : "Echec de la spécification des paramètres régionaux à %s",
    "Please install one of these locales on your system and restart your webserver." : "Veuillez installer l'un de ces paramètres régionaux sur votre système et redémarrer votre serveur web.",
    "Please ask your server administrator to install the module." : "Veuillez demander à votre administrateur d’installer le module.",
    "PHP module %s not installed." : "Le module PHP %s n’est pas installé.",
    "PHP setting \"%s\" is not set to \"%s\"." : "Le paramètre PHP \"%s\" n'est pas \"%s\".",
    "Adjusting this setting in php.ini will make Nextcloud run again" : "Ajuster ce paramètre dans php.ini fera fonctionner Nextcould à nouveau",
    "mbstring.func_overload is set to \"%s\" instead of the expected value \"0\"" : "mbstring.func_overload est à \"%s\" alors que la valeur \"0\" est attendue",
    "To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini" : "Pour corriger ce problème mettez <code>mbstring.func_overload</code> à <code>0</code> dans votre php.ini",
    "libxml2 2.7.0 is at least required. Currently %s is installed." : "libxml2 2.7.0 au moins est requis. Actuellement %s est installé.",
    "To fix this issue update your libxml2 version and restart your web server." : "Pour régler ce problème, mettez à jour votre version de libxml2 et redémarrez votre serveur web.",
    "PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible." : "PHP semble configuré de manière à supprimer les blocs PHPdoc du code. Cela rendra plusieurs applications de base inaccessibles.",
    "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "La raison est probablement l'utilisation d'un cache / accélérateur tel que Zend OPcache ou eAccelerator.",
    "PHP modules have been installed, but they are still listed as missing?" : "Les modules PHP ont été installés mais sont toujours indiqués comme manquants ?",
    "Please ask your server administrator to restart the web server." : "Veuillez demander à votre administrateur serveur de redémarrer le serveur web.",
    "PostgreSQL >= 9 required" : "PostgreSQL >= 9 requis",
    "Please upgrade your database version" : "Veuillez mettre à jour votre gestionnaire de base de données",
    "Please change the permissions to 0770 so that the directory cannot be listed by other users." : "Veuillez changer les permissions du répertoire en mode 0770 afin que son contenu ne puisse pas être listé par les autres utilisateurs.",
    "Your data directory is readable by other users" : "Votre répertoire est lisible par les autres utilisateurs",
    "Your data directory must be an absolute path" : "Le chemin de votre répertoire doit être un lien absolu",
    "Check the value of \"datadirectory\" in your configuration" : "Verifiez la valeur de \"datadirectory\" dans votre configuration",
    "Your data directory is invalid" : "Votre répertoire n'est pas valide",
    "Please check that the data directory contains a file \".ocdata\" in its root." : "Veuillez vérifier que le répertoire de données contient un fichier \".ocdata\" à sa racine.",
    "Could not obtain lock type %d on \"%s\"." : "Impossible d'obtenir le verrouillage de type %d sur \"%s\".",
    "Storage unauthorized. %s" : "Espace de stockage non autorisé. %s",
    "Storage incomplete configuration. %s" : "Configuration de l'espace de stockage incomplète. %s",
    "Storage connection error. %s" : "Erreur de connexion à l'espace stockage. %s",
    "Storage is temporarily not available" : "Le support de stockage est temporairement indisponible",
    "Storage connection timeout. %s" : "Le délai d'attente pour la connexion à l'espace de stockage a été dépassé. %s",
    "This can usually be fixed by %sgiving the webserver write access to the config directory%s." : "Ce problème est généralement résolu %sen donnant au serveur web un accès en écriture au répertoire de configuration%s.",
    "Module with id: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Le module avec l'id: %s n'existe pas. Merci de l'activer dans les paramètres d'applications ou de contacter votre administrateur.",
    "Server settings" : "Paramètres serveur",
    "You need to enter either an existing account or the administrator." : "Vous devez indiquer un compte existant ou celui de l'administrateur.",
    "%s shared »%s« with you" : "%s a partagé «%s» avec vous",
    "%s via %s" : "%s via %s",
    "This can usually be fixed by %sgiving the webserver write access to the apps directory%s or disabling the appstore in the config file." : "Ce problème est généralement résolu %sen donnant au serveur web un accès en écriture au répertoire apps%s ou en désactivant l'appstore dans le fichier de configuration.",
    "Cannot create \"data\" directory (%s)" : "Impossible de créer le répertoire \"data\" (%s)",
    "This can usually be fixed by <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">giving the webserver write access to the root directory</a>." : "Ce problème est généralement résolu <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">en donnant au serveur web un accès en écriture au répertoire racine</a>.",
    "Permissions can usually be fixed by %sgiving the webserver write access to the root directory%s." : "Le problème de permissions peut généralement être résolu %sen donnant au serveur web un accès en écriture au répertoire racine%s",
    "Data directory (%s) is readable by other users" : "Le répertoire de données (%s) est lisible par les autres utilisateurs",
    "Data directory (%s) must be an absolute path" : "Le chemin du dossier de données (%s) doit être absolu",
    "Data directory (%s) is invalid" : "Le répertoire (%s) n'est pas valide"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
}