aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/lua/bayes_expiry.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/lua/bayes_expiry.lua')
-rw-r--r--src/plugins/lua/bayes_expiry.lua420
1 files changed, 186 insertions, 234 deletions
diff --git a/src/plugins/lua/bayes_expiry.lua b/src/plugins/lua/bayes_expiry.lua
index d922f3f55..af955465d 100644
--- a/src/plugins/lua/bayes_expiry.lua
+++ b/src/plugins/lua/bayes_expiry.lua
@@ -20,280 +20,232 @@ if confighelp then
end
local N = 'bayes_expiry'
+local E = {}
local logger = require "rspamd_logger"
-local mempool = require "rspamd_mempool"
-local util = require "rspamd_util"
local lutil = require "lua_util"
local lredis = require "lua_redis"
-local pool = mempool.create()
local settings = {
- interval = 604800,
- statefile = string.format('%s/%s', rspamd_paths['DBDIR'], 'bayes_expired'),
- variables = {
- ot_bayes_ttl = 31536000, -- one year
- ot_min_age = 7776000, -- 90 days
- ot_min_count = 5,
- },
- symbols = {},
- timeout = 60,
+ interval = 60, -- one iteration step per minute
+ count = 1000, -- check up to 1000 keys on each iteration
+ threshold = 10, -- require at least 10 occurrences to increase expire
+ epsilon_common = 0.01, -- eliminate common if spam to ham rate is equal to this epsilon
+ common_ttl_divisor = 100, -- how should we discriminate common elements
+ significant_factor = 3.0 / 4.0, -- which tokens should we update
+ classifiers = {},
}
-local VAR_NAME = 'bayes_expired'
-local EXPIRE_SCRIPT_TMPL = [[local result = {}
-local OT_BAYES_TTL = ${ot_bayes_ttl}
-local OT_MIN_AGE = ${ot_min_age}
-local OT_MIN_COUNT = ${ot_min_count}
-local symbol = ARGV[1]
-local prefixes = redis.call('SMEMBERS', symbol .. '_keys')
-for _, pfx in ipairs(prefixes) do
- local res = redis.call('SCAN', '0', 'MATCH', pfx .. '_*')
- local cursor, data = res[1], res[2]
- while data do
- local key_name = table.remove(data)
- if key_name then
- local h, s = redis.call('HMGET', key_name, 'H', 'S')
- if (h or s) then
- if not s then s = 0 else s = tonumber(s) end
- if not h then h = 0 else h = tonumber(h) end
- if s < OT_MIN_COUNT and h < OT_MIN_COUNT then
- local ttl = redis.call('TTL', key_name)
- if ttl > 0 then
- local age = OT_BAYES_TTL - ttl
- if age > OT_MIN_AGE then
- table.insert(result, key_name)
- end
- end
+local template = {
+
+}
+
+local function check_redis_classifier(cls, cfg)
+ -- Skip old classifiers
+ if cls.new_schema then
+ local symbol_spam, symbol_ham
+ local expiry = (cls.expiry or cls.expire)
+ -- Load symbols from statfiles
+ local statfiles = cls.statfile
+ for _,stf in ipairs(statfiles) do
+ local symbol = stf.symbol or 'undefined'
+
+ local spam
+ if stf.spam then
+ spam = stf.spam
+ else
+ if string.match(symbol:upper(), 'SPAM') then
+ spam = true
+ else
+ spam = false
end
end
- else
- if cursor == "0" then
- data = nil
+
+ if spam then
+ symbol_spam = symbol
else
- local res = redis.call('SCAN', tostring(cursor), 'MATCH', pfx .. '_*')
- cursor, data = res[1], res[2]
+ symbol_ham = symbol
+ end
+ end
+
+ if not symbol_spam or not symbol_ham or not expiry then
+ return
+ end
+ -- Now try to load redis_params if needed
+
+ local redis_params = {}
+ if not lredis.try_load_redis_servers(cls, rspamd_config, redis_params) then
+ if not lredis.try_load_redis_servers(cfg[N] or E, rspamd_config, redis_params) then
+ if not lredis.try_load_redis_servers(cfg['redis'] or E, rspamd_config, redis_params) then
+ return false
+ end
end
end
+
+ table.insert(settings.classifiers, {
+ symbol_spam = symbol_spam,
+ symbol_ham = symbol_ham,
+ redis_params = redis_params,
+ expiry = expiry
+ })
end
end
-return table.concat(result, string.char(31))]]
-local function configure_bayes_expiry()
- local opts = rspamd_config:get_all_opt(N)
- if not type(opts) == 'table' then return false end
- for k, v in pairs(opts) do
- settings[k] = v
+-- Check classifiers and try find the appropriate ones
+local obj = rspamd_config:get_ucl()
+
+local classifier = obj.classifier
+
+if classifier then
+ if classifier[1] then
+ for _,cls in ipairs(classifier) do
+ if cls.bayes then cls = cls.bayes end
+ if cls.backend and cls.backend == 'redis' then
+ check_redis_classifier(cls, obj)
+ end
+ end
+ else
+ if classifier.bayes then
+
+ classifier = classifier.bayes
+ if classifier[1] then
+ for _,cls in ipairs(classifier) do
+ if cls.backend and cls.backend == 'redis' then
+ check_redis_classifier(cls, obj)
+ end
+ end
+ else
+ if classifier.backend and classifier.backend == 'redis' then
+ check_redis_classifier(classifier, obj)
+ end
+ end
+ end
end
- if not settings.symbols[1] then
- logger.warn('No symbols configured, not enabling expiry')
- return false
+end
+
+
+local opts = rspamd_config:get_all_opt(N)
+
+if opts then
+ for k,v in pairs(opts) do
+ settings[k] = v
end
- return true
end
-if not configure_bayes_expiry() then
- lutil.disable_module(N, 'config')
- return
+-- Fill template
+template.count = settings.count
+template.threshold = settings.threshold
+template.common_ttl_divisor = settings.common_ttl_divisor
+template.epsilon_common = settings.epsilon_common
+template.significant_factor = settings.significant_factor
+
+for k,v in pairs(template) do
+ template[k] = tostring(v)
end
-local function get_redis_params(ev_base, symbol)
- local redis_params
- local copts = rspamd_config:get_all_opt('classifier')
- if not type(copts) == 'table' then
- logger.errx(ev_base, "Couldn't get classifier configuration")
- return
- end
- if type(copts.backend) == 'table' then
- redis_params = lredis.rspamd_parse_redis_server(nil, copts.backend, true)
+-- Arguments:
+-- [1] = symbol pattern
+-- [2] = expire value
+-- [3] = cursor
+-- returns new cursor
+local expiry_script = [[
+ local ret = redis.call('SCAN', KEYS[3], 'MATCH', KEYS[1], 'COUNT', '${count}')
+ local next = ret[1]
+ local keys = ret[2]
+ local nelts = 0
+ local extended = 0
+ local discriminated = 0
+
+ for _,key in ipairs(keys) do
+ local values = redis.call('HMGET', key, 'H', 'S')
+ local ham = tonumber(values[1]) or 0
+ local spam = tonumber(values[2]) or 0
+
+ if ham > ${threshold} or spam > ${threshold} then
+ local total = ham + spam
+
+ if total > 0 then
+ if ham / total > ${significant_factor} or spam / total > ${significant_factor} then
+ redis.replicate_commands()
+ redis.call('EXPIRE', key, KEYS[2])
+ extended = extended + 1
+ elseif math.abs(ham - spam) <= total * ${epsilon_common} then
+ local ttl = redis.call('TTL', key)
+ redis.replicate_commands()
+ redis.call('EXPIRE', key, tonumber(ttl) / ${common_ttl_divisor})
+ discriminated = discriminated + 1
+ end
+ end
+ end
+ nelts = nelts + 1
end
- if redis_params then return redis_params end
- if type(copts.statfile) == 'table' then
- for _, stf in ipairs(copts.statfile) do
- if stf.name == symbol then
- redis_params = lredis.rspamd_parse_redis_server(nil, copts.backend, true)
+
+ return {next, nelts, extended, discriminated}
+]]
+
+local cur = 0
+
+local function expire_step(cls, ev_base, worker)
+
+ local function redis_step_cb(err, data)
+ if err then
+ logger.errx(rspamd_config, 'cannot perform expiry step: %s', err)
+ elseif type(data) == 'table' then
+ local next,nelts,extended,discriminated = tonumber(data[1]), tonumber(data[2]),
+ tonumber(data[3]),tonumber(data[4])
+
+ if next ~= 0 then
+ logger.infox(rspamd_config, 'executed expiry step for bayes: %s items checked, %s extended, %s discriminated',
+ nelts, extended, discriminated)
+ else
+ logger.infox(rspamd_config, 'executed final expiry step for bayes: %s items checked, %s extended, %s discriminated',
+ nelts, extended, discriminated)
end
+
+ cur = next
end
end
- if redis_params then return redis_params end
- redis_params = lredis.rspamd_parse_redis_server(nil, copts, false)
- redis_params.timeout = settings.timeout
- return redis_params
+ lredis.exec_redis_script(cls.script,
+ {ev_base = ev_base, is_write = true},
+ redis_step_cb,
+ {'RS*_*', cls.expiry, cur}
+ )
end
rspamd_config:add_on_load(function (_, ev_base, worker)
- local processed_symbols, expire_script_sha
-- Exit unless we're the first 'controller' worker
if not (worker:get_name() == 'controller' and worker:get_index() == 0) then return end
- -- Persist mempool variable to statefile on shutdown
- rspamd_config:register_finish_script(function ()
- local stamp = pool:get_variable(VAR_NAME, 'double')
- if not stamp then
- logger.warnx(ev_base, 'No last bayes expiry to persist to disk')
- return
- end
- local f, err = io.open(settings['statefile'], 'w')
- if err then
- logger.errx(ev_base, 'Unable to write statefile to disk: %s', err)
- return
- end
- if f then
- f:write(pool:get_variable(VAR_NAME, 'double'))
- f:close()
- end
- end)
- local expire_symbol
- local function load_scripts(redis_params, cont, p1, p2)
- local function load_script_cb(err, data)
- if err then
- logger.errx(ev_base, 'Error loading script: %s', err)
- else
- if type(data) == 'string' then
- expire_script_sha = data
- logger.debugm(N, ev_base, 'expire_script_sha: %s', expire_script_sha)
- if type(cont) == 'function' then
- cont(p1, p2)
- end
- end
+
+ local unique_redis_params = {}
+ -- Push redis script to all unique redis servers
+ for _,cls in ipairs(settings.classifiers) do
+ local seen = false
+ for _,rp in ipairs(unique_redis_params) do
+ if lutil.table_cmp(rp, cls.redis_params) then
+ seen = true
end
end
- local scripttxt = lutil.template(EXPIRE_SCRIPT_TMPL, settings.variables)
- local ret = lredis.redis_make_request_taskless(ev_base,
- rspamd_config,
- redis_params,
- nil,
- true, -- is write
- load_script_cb, --callback
- 'SCRIPT', -- command
- {'LOAD', scripttxt}
- )
- if not ret then
- logger.errx(ev_base, 'Error loading script')
- end
- end
- local function continue_expire()
- for _, symbol in ipairs(settings.symbols) do
- if not processed_symbols[symbol] then
- local redis_params = get_redis_params(ev_base, symbol)
- if not redis_params then
- processed_symbols[symbol] = true
- logger.errx(ev_base, "Couldn't get redis params")
- else
- load_scripts(redis_params, expire_symbol, redis_params, symbol)
- break
- end
- end
+
+ if not seen then
+ table.insert(unique_redis_params, cls.redis_params)
end
end
- expire_symbol = function(redis_params, symbol)
- local function del_keys_cb(err, data)
- if err then
- logger.errx(ev_base, 'Redis request failed: %s', err)
- end
- processed_symbols[symbol] = true
- continue_expire()
- end
- local function get_keys_cb(err, data)
- if err then
- logger.errx(ev_base, 'Redis request failed: %s', err)
- processed_symbols[symbol] = true
- continue_expire()
- else
- if type(data) == 'string' then
- if data == "" then
- data = {}
- else
- data = lutil.rspamd_str_split(data, string.char(31))
- end
- end
- if type(data) == 'table' then
- if not data[1] then
- logger.warnx(ev_base, 'No keys to delete: %s', symbol)
- processed_symbols[symbol] = true
- continue_expire()
- else
- local ret = lredis.redis_make_request_taskless(ev_base,
- rspamd_config,
- redis_params,
- nil,
- true, -- is write
- del_keys_cb, --callback
- 'DEL', -- command
- data
- )
- if not ret then
- logger.errx(ev_base, 'Redis request failed')
- processed_symbols[symbol] = true
- continue_expire()
- end
- end
- else
- logger.warnx(ev_base, 'No keys to delete: %s', symbol)
- processed_symbols[symbol] = true
- continue_expire()
- end
+
+ for _,rp in ipairs(unique_redis_params) do
+ local script_id = lredis.add_redis_script(lutil.template(expiry_script,
+ template), rp)
+
+ for _,cls in ipairs(settings.classifiers) do
+ if lutil.table_cmp(rp, cls.redis_params) then
+ cls.script = script_id
end
end
- local ret = lredis.redis_make_request_taskless(ev_base,
- rspamd_config,
- redis_params,
- nil,
- false, -- is write
- get_keys_cb, --callback
- 'EVALSHA', -- command
- {expire_script_sha, 0, symbol}
- )
- if not ret then
- logger.errx(ev_base, 'Redis request failed')
- processed_symbols[symbol] = true
- continue_expire()
- end
- end
- local function begin_expire(time)
- local stamp = time or util.get_time()
- pool:set_variable(VAR_NAME, stamp)
- processed_symbols = {}
- continue_expire()
end
+
-- Expire tokens at regular intervals
- local function schedule_regular_expiry()
+ for _,cls in ipairs(settings.classifiers) do
rspamd_config:add_periodic(ev_base, settings['interval'], function ()
- begin_expire()
+ expire_step(cls, ev_base, worker)
return true
end)
end
- -- Expire tokens and reschedule expiry
- local function schedule_intermediate_expiry(when)
- rspamd_config:add_periodic(ev_base, when, function ()
- begin_expire()
- schedule_regular_expiry()
- return false
- end)
- end
- -- Try read statefile on startup
- local stamp
- local f, err = io.open(settings['statefile'], 'r')
- if err then
- logger.warnx(ev_base, 'Failed to open statefile: %s', err)
- end
- if f then
- io.input(f)
- stamp = tonumber(io.read())
- pool:set_variable(VAR_NAME, stamp)
- end
- local time = util.get_time()
- if not stamp then
- logger.debugm(N, ev_base, 'No state found - expiring stats immediately')
- begin_expire(time)
- schedule_regular_expiry()
- return
- end
- local delta = stamp - time + settings['interval']
- if delta <= 0 then
- logger.debugm(N, ev_base, 'Last expiry is too old - expiring stats immediately')
- begin_expire(time)
- schedule_regular_expiry()
- return
- end
- logger.debugm(N, ev_base, 'Scheduling next expiry in %s seconds', delta)
- schedule_intermediate_expiry(delta)
end)
Nextcloud server, a safe home for all your data: https://github.com/nextcloud/serverwww-data
summaryrefslogtreecommitdiffstats
path: root/core/l10n/it.js
blob: f41cea18d85fb1995f52a8601956f637e6dc6db2 (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
OC.L10N.register(
    "core",
    {
    "Couldn't send mail to following users: %s " : "Impossibile inviare email ai seguenti utenti: %s",
    "Turned on maintenance mode" : "Modalità di manutenzione attivata",
    "Turned off maintenance mode" : "Modalità di manutenzione disattivata",
    "Updated database" : "Database aggiornato",
    "Checked database schema update" : "Verificato l'aggiornamento dello schema del database",
    "Checked database schema update for apps" : "Verificato l'aggiornamento dello schema del database per le applicazioni",
    "Updated \"%s\" to %s" : "Aggiornato \"%s\" a %s",
    "Disabled incompatible apps: %s" : "Applicazione incompatibili disabilitate: %s",
    "No image or file provided" : "Non è stata fornita alcun immagine o file",
    "Unknown filetype" : "Tipo di file sconosciuto",
    "Invalid image" : "Immagine non valida",
    "No temporary profile picture available, try again" : "Nessuna immagine di profilo provvisoria disponibile, riprova",
    "No crop data provided" : "Dati di ritaglio non forniti",
    "Sunday" : "Domenica",
    "Monday" : "Lunedì",
    "Tuesday" : "Martedì",
    "Wednesday" : "Mercoledì",
    "Thursday" : "Giovedì",
    "Friday" : "Venerdì",
    "Saturday" : "Sabato",
    "January" : "Gennaio",
    "February" : "Febbraio",
    "March" : "Marzo",
    "April" : "Aprile",
    "May" : "Maggio",
    "June" : "Giugno",
    "July" : "Luglio",
    "August" : "Agosto",
    "September" : "Settembre",
    "October" : "Ottobre",
    "November" : "Novembre",
    "December" : "Dicembre",
    "Settings" : "Impostazioni",
    "Saving..." : "Salvataggio in corso...",
    "Couldn't send reset email. Please contact your administrator." : "Impossibile inviare l'email di reimpostazione. Contatta il tuo amministratore.",
    "The link to reset your password has been sent to your email. If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator." : "Il collegamento per reimpostare la password è stato inviato al tuo indirizzo di posta. Se non lo ricevi in tempi ragionevoli, controlla le cartelle della posta indesiderata.<br>Se non dovesse essere nemmeno lì, contatta il tuo amministratore locale.",
    "Your files are encrypted. If you haven't enabled the recovery key, there will be no way to get your data back after your password is reset.<br />If you are not sure what to do, please contact your administrator before you continue. <br />Do you really want to continue?" : "I tuoi file sono cifrati. Se non hai precedentemente abilitato la chiave di recupero, non sarà più possibile ritrovare i tuoi dati una volta che la password sarà reimpostata.<br />Se non sei sicuro, per favore contatta l'amministratore prima di proseguire.<br />Vuoi davvero continuare?",
    "I know what I'm doing" : "So cosa sto facendo",
    "Password can not be changed. Please contact your administrator." : "La password non può essere cambiata. Contatta il tuo amministratore.",
    "No" : "No",
    "Yes" : "Sì",
    "Choose" : "Scegli",
    "Error loading file picker template: {error}" : "Errore durante il caricamento del modello del selettore file: {error}",
    "Ok" : "Ok",
    "Error loading message template: {error}" : "Errore durante il caricamento del modello di messaggio: {error}",
    "read-only" : "sola lettura",
    "_{count} file conflict_::_{count} file conflicts_" : ["{count} file in conflitto","{count} file in conflitto"],
    "One file conflict" : "Un file in conflitto",
    "New Files" : "File nuovi",
    "Already existing files" : "File già esistenti",
    "Which files do you want to keep?" : "Quali file vuoi mantenere?",
    "If you select both versions, the copied file will have a number added to its name." : "Se selezioni entrambe le versioni, sarà aggiunto un numero al nome del file copiato.",
    "Cancel" : "Annulla",
    "Continue" : "Continua",
    "(all selected)" : "(tutti i selezionati)",
    "({count} selected)" : "({count} selezionati)",
    "Error loading file exists template" : "Errore durante il caricamento del modello del file esistente",
    "Very weak password" : "Password molto debole",
    "Weak password" : "Password debole",
    "So-so password" : "Password così-così",
    "Good password" : "Password buona",
    "Strong password" : "Password forte",
    "Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." : "Il tuo server web non è configurato correttamente per consentire la sincronizzazione dei file poiché l'interfaccia WebDAV sembra no funzionare correttamente.",
    "This server has no working internet connection. This means that some of the features like mounting of external storage, notifications about updates or installation of 3rd party apps don´t work. Accessing files from remote and sending of notification emails might also not work. We suggest to enable internet connection for this server if you want to have all features." : "Questo server non ha una connessione a Internet funzionante. Ciò significa che alcune delle funzionalità come il montaggio di archivi esterni, le notifiche degli aggiornamenti o l'installazione di applicazioni di terze parti non funzioneranno. L'accesso remoto ai file e l'invio di email di notifica potrebbero non funzionare. Ti suggeriamo di abilitare la connessione a Internet del server se desideri disporre di tutte le funzionalità.",
    "Your data directory and your files are probably accessible from the internet. The .htaccess file is not working. We strongly suggest that you configure your webserver in a way that the data directory is no longer accessible or you move the data directory outside the webserver document root." : "La cartella dei dati e i tuoi file sono probabilmente accessibili da Internet.\nIl file .htaccess non funziona. Ti consigliamo vivamente di configurare il server web in modo che la cartella dei dati non sia più accessibile o spostare la cartella fuori dalla radice del server web.",
    "Error occurred while checking server setup" : "Si è verificato un errore durante il controllo della configurazione del server",
    "Shared" : "Condiviso",
    "Shared with {recipients}" : "Condiviso con {recipients}",
    "Share" : "Condividi",
    "Error" : "Errore",
    "Error while sharing" : "Errore durante la condivisione",
    "Error while unsharing" : "Errore durante la rimozione della condivisione",
    "Error while changing permissions" : "Errore durante la modifica dei permessi",
    "Shared with you and the group {group} by {owner}" : "Condiviso con te e con il gruppo {group} da {owner}",
    "Shared with you by {owner}" : "Condiviso con te da {owner}",
    "Share with user or group …" : "Condividi con utente o gruppo ...",
    "Share link" : "Condividi collegamento",
    "The public link will expire no later than {days} days after it is created" : "Il collegamento pubblico scadrà non più tardi di {days} giorni dopo la sua creazione",
    "Link" : "Collegamento",
    "Password protect" : "Proteggi con password",
    "Password" : "Password",
    "Choose a password for the public link" : "Scegli una password per il collegamento pubblico",
    "Allow editing" : "Consenti la modifica",
    "Email link to person" : "Invia collegamento via email",
    "Send" : "Invia",
    "Set expiration date" : "Imposta data di scadenza",
    "Expiration" : "Scadenza",
    "Expiration date" : "Data di scadenza",
    "Adding user..." : "Aggiunta utente in corso...",
    "group" : "gruppo",
    "remote" : "remota",
    "Resharing is not allowed" : "La ri-condivisione non è consentita",
    "Shared in {item} with {user}" : "Condiviso in {item} con {user}",
    "Unshare" : "Rimuovi condivisione",
    "notify by email" : "notifica tramite email",
    "can share" : "può condividere",
    "can edit" : "può modificare",
    "access control" : "controllo d'accesso",
    "create" : "creare",
    "change" : "cambia",
    "delete" : "elimina",
    "Password protected" : "Protetta da password",
    "Error unsetting expiration date" : "Errore durante la rimozione della data di scadenza",
    "Error setting expiration date" : "Errore durante l'impostazione della data di scadenza",
    "Sending ..." : "Invio in corso...",
    "Email sent" : "Messaggio inviato",
    "Warning" : "Avviso",
    "The object type is not specified." : "Il tipo di oggetto non è specificato.",
    "Enter new" : "Inserisci nuovo",
    "Delete" : "Elimina",
    "Add" : "Aggiungi",
    "Edit tags" : "Modifica etichette",
    "Error loading dialog template: {error}" : "Errore durante il caricamento del modello di finestra: {error}",
    "No tags selected for deletion." : "Nessuna etichetta selezionata per l'eliminazione.",
    "unknown text" : "testo sconosciuto",
    "Hello world!" : "Ciao mondo!",
    "sunny" : "soleggiato",
    "Hello {name}, the weather is {weather}" : "Ciao {name}, il tempo è {weather}",
    "Hello {name}" : "Ciao {name}",
    "_download %n file_::_download %n files_" : ["scarica %n file","scarica %s file"],
    "Updating {productName} to version {version}, this may take a while." : "Aggiornamento di {productName} alla versione {version}, potrebbe richiedere del tempo.",
    "Please reload the page." : "Ricarica la pagina.",
    "The update was unsuccessful. " : "L'aggiornamento non è riuscito.",
    "The update was successful. Redirecting you to ownCloud now." : "L'aggiornamento è stato effettuato correttamente. Stai per essere reindirizzato a ownCloud.",
    "Couldn't reset password because the token is invalid" : "Impossibile reimpostare la password poiché il token non è valido",
    "Couldn't send reset email. Please make sure your username is correct." : "Impossibile inviare l'email di reimpostazione. Assicurati che il nome utente sia corretto.",
    "Couldn't send reset email because there is no email address for this username. Please contact your administrator." : "Impossibile inviare l'email di reimpostazione poiché non è presente un indirizzo email per questo nome utente. Contatta il tuo amministratore.",
    "%s password reset" : "Ripristino password di %s",
    "Use the following link to reset your password: {link}" : "Usa il collegamento seguente per ripristinare la password: {link}",
    "New password" : "Nuova password",
    "New Password" : "Nuova password",
    "Reset password" : "Ripristina la password",
    "Searching other places" : "Ricerca in altre posizioni",
    "No search result in other places" : "Nessun risultato di ricerca in altre posizioni",
    "_{count} search result in other places_::_{count} search results in other places_" : ["{count} risultato di ricerca in altre posizioni","{count} risultati di ricerca in altre posizioni"],
    "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Mac OS X non è supportato e %s non funzionerà correttamente su questa piattaforma. Usalo a tuo rischio!",
    "For the best results, please consider using a GNU/Linux server instead." : "Per avere il risultato migliore, prendi in considerazione l'utilizzo di un server 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 4GB and is highly discouraged." : "Sembra che questa istanza di %s sia in esecuzione in un ambiente PHP a 32 bit e che open_basedir sia stata configurata in php.ini. Ciò comporterà problemi con i file più grandi di 4 GB ed è vivamente sconsigliato.",
    "Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "Rimuovi l'impostazione di open_basedir nel tuo php.ini o passa alla versione a 64 bit di PHP.",
    "It seems that this %s instance is running on a 32-bit PHP environment and cURL is not installed. This will lead to problems with files over 4GB and is highly discouraged." : "Sembra che questa istanza di %s sia in esecuzione in un ambiente PHP a 32 bit e che cURL non sia installato. Ciò comporterà problemi con i file più grandi di 4 GB ed è vivamente sconsigliato.",
    "Please install the cURL extension and restart your webserver." : "Installa l'estensione cURL e riavvia il server web.",
    "Personal" : "Personale",
    "Users" : "Utenti",
    "Apps" : "Applicazioni",
    "Admin" : "Admin",
    "Help" : "Aiuto",
    "Error loading tags" : "Errore di caricamento delle etichette",
    "Tag already exists" : "L'etichetta esiste già",
    "Error deleting tag(s)" : "Errore di eliminazione delle etichette",
    "Error tagging" : "Errore di assegnazione delle etichette",
    "Error untagging" : "Errore di rimozione delle etichette",
    "Error favoriting" : "Errore di creazione dei preferiti",
    "Error unfavoriting" : "Errore di rimozione dai preferiti",
    "Access forbidden" : "Accesso negato",
    "File not found" : "File non trovato",
    "The specified document has not been found on the server." : "Il documento specificato non è stato trovato sul server.",
    "You can click here to return to %s." : "Puoi fare clic qui per tornare a %s.",
    "Hey there,\n\njust letting you know that %s shared %s with you.\nView it: %s\n\n" : "Ciao,\n\nvolevo informarti che %s ha condiviso %s con te.\nVedi: %s\n\n",
    "The share will expire on %s." : "La condivisione scadrà il %s.",
    "Cheers!" : "Saluti!",
    "Internal Server Error" : "Errore interno del server",
    "The server encountered an internal error and was unable to complete your request." : "Il server ha riscontrato un errore interno e non è stato in grado di completare la tua richiesta.",
    "Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report." : "Contatta l'amministratore del server se questo errore riappare più volte, includendo i dettagli tecnici sotto riportati nella tua segnalazione.",
    "More details can be found in the server log." : "Ulteriori dettagli sono disponibili nel log del server.",
    "Technical details" : "Dettagli tecnici",
    "Remote Address: %s" : "Indirizzo remoto: %s",
    "Request ID: %s" : "ID richiesta: %s",
    "Code: %s" : "Codice: %s",
    "Message: %s" : "Messaggio: %s",
    "File: %s" : "File: %s",
    "Line: %s" : "Riga: %s",
    "Trace" : "Traccia",
    "Security Warning" : "Avviso di sicurezza",
    "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." : "La cartella dei dati e i file sono probabilmente accessibili da Internet poiché il file .htaccess non funziona.",
    "For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." : "Per informazioni su come configurare correttamente il tuo server, vedi la <a href=\"%s\" target=\"_blank\">documentazione</a>.",
    "Create an <strong>admin account</strong>" : "Crea un <strong>account amministratore</strong>",
    "Username" : "Nome utente",
    "Storage & database" : "Archiviazione e database",
    "Data folder" : "Cartella dati",
    "Configure the database" : "Configura il database",
    "Only %s is available." : "È disponibile solo %s.",
    "Database user" : "Utente del database",
    "Database password" : "Password del database",
    "Database name" : "Nome del database",
    "Database tablespace" : "Spazio delle tabelle del database",
    "Database host" : "Host del database",
    "Performance Warning" : "Avviso di prestazioni",
    "SQLite will be used as database." : "SQLite sarà utilizzato come database.",
    "For larger installations we recommend to choose a different database backend." : "Per installazioni più grandi consigliamo di scegliere un motore di database diverso.",
    "Especially when using the desktop client for file syncing the use of SQLite is discouraged." : "In particolar modo, quando si utilizza il client desktop per la sincronizzazione dei file, l'uso di SQLite è sconsigliato.",
    "Finish setup" : "Termina configurazione",
    "Finishing …" : "Completamento...",
    "This application requires JavaScript for correct operation. Please {linkstart}enable JavaScript{linkend} and reload the page." : "Questa applicazione richiede JavaScript per un corretto funzionamento. {linkstart}Abilita JavaScript{linkend} e ricarica la pagina.",
    "%s is available. Get more information on how to update." : "%s è disponibile. Ottieni ulteriori informazioni sull'aggiornamento.",
    "Log out" : "Esci",
    "Search" : "Cerca",
    "Server side authentication failed!" : "Autenticazione lato server non riuscita!",
    "Please contact your administrator." : "Contatta il tuo amministratore di sistema.",
    "Forgot your password? Reset it!" : "Hai dimenticato la password? Reimpostala!",
    "remember" : "ricorda",
    "Log in" : "Accedi",
    "Alternative Logins" : "Accessi alternativi",
    "Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" : "Ciao,<br><br>volevo informarti che %s ha condiviso <strong>%s</strong> con te.<br><a href=\"%s\">Guarda!</a><br><br>",
    "This ownCloud instance is currently in single user mode." : "Questa istanza di ownCloud è in modalità utente singolo.",
    "This means only administrators can use the instance." : "Ciò significa che solo gli amministratori possono utilizzare l'istanza.",
    "Contact your system administrator if this message persists or appeared unexpectedly." : "Contatta il tuo amministratore di sistema se questo messaggio persiste o appare inaspettatamente.",
    "Thank you for your patience." : "Grazie per la pazienza.",
    "You are accessing the server from an untrusted domain." : "Stai accedendo al server da un dominio non attendibile.",
    "Please contact your administrator. If you are an administrator of this instance, configure the \"trusted_domain\" setting in config/config.php. An example configuration is provided in config/config.sample.php." : "Contatta il tuo amministratore di sistema. Se sei un amministratore di questa istanza, configura l'impostazione \"trusted_domain\" in config/config.php. Un esempio di configurazione è disponibile in config/config.sample.php.",
    "Depending on your configuration, as an administrator you might also be able to use the button below to trust this domain." : "In base alla tua configurazione, come amministratore potrai utilizzare anche il pulsante in basso per rendere attendibile questo dominio.",
    "Add \"%s\" as trusted domain" : "Aggiungi \"%s\" come dominio attendibile",
    "%s will be updated to version %s." : "%s sarà aggiornato alla versione %s.",
    "The following apps will be disabled:" : "Le seguenti applicazioni saranno disabilitate:",
    "The theme %s has been disabled." : "Il tema %s è stato disabilitato.",
    "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Assicurati di aver creato una copia di sicurezza del database, della cartella config e della cartella data prima di procedere. ",
    "Start update" : "Avvia l'aggiornamento",
    "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Per evitare timeout con installazioni di grandi dimensioni, puoi eseguire il comando che segue dalla cartella di installazione:",
    "This %s instance is currently being updated, which may take a while." : "Questa istanza di %s è in fase di aggiornamento, potrebbe richiedere del tempo.",
    "This page will refresh itself when the %s instance is available again." : "Questa pagina si aggiornerà quando l'istanza di %s sarà nuovamente disponibile."
},
"nplurals=2; plural=(n != 1);");