diff options
Diffstat (limited to 'lib')
60 files changed, 1041 insertions, 418 deletions
diff --git a/lib/base.php b/lib/base.php index 107ae059bb1..da4b3a47c75 100644 --- a/lib/base.php +++ b/lib/base.php @@ -80,6 +80,10 @@ class OC { */ public static $server = null; + /** + * @throws \RuntimeException when the 3rdparty directory is missing or + * the app path list is empty or contains an invalid path + */ public static function initPaths() { // calculate the root directories OC::$SERVERROOT = str_replace("\\", '/', substr(__DIR__, 0, -4)); @@ -155,10 +159,9 @@ class OC { } } if (empty(OC::$THIRDPARTYROOT) || !file_exists(OC::$THIRDPARTYROOT)) { - echo('3rdparty directory not found! Please put the ownCloud 3rdparty' + throw new \RuntimeException('3rdparty directory not found! Please put the ownCloud 3rdparty' . ' folder in the ownCloud folder or the folder above.' . ' You can also configure the location in the config.php file.'); - return; } // search the apps folder @@ -182,12 +185,17 @@ class OC { } if (empty(OC::$APPSROOTS)) { - throw new Exception('apps directory not found! Please put the ownCloud apps folder in the ownCloud folder' + throw new \RuntimeException('apps directory not found! Please put the ownCloud apps folder in the ownCloud folder' . ' or the folder above. You can also configure the location in the config.php file.'); } $paths = array(); foreach (OC::$APPSROOTS as $path) { $paths[] = $path['path']; + if (!is_dir($path['path'])) { + throw new \RuntimeException(sprintf('App directory "%s" not found! Please put the ownCloud apps folder in the' + . ' ownCloud folder or the folder above. You can also configure the location in the' + . ' config.php file.', $path['path'])); + } } // set the right include path @@ -407,6 +415,7 @@ class OC { } // if session cant be started break with http 500 error } catch (Exception $e) { + \OCP\Util::logException('base', $e); //show the user a detailed error page OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR); OC_Template::printExceptionErrorPage($e); @@ -465,17 +474,20 @@ class OC { self::$CLI = (php_sapi_name() == 'cli'); - self::initPaths(); - - // setup 3rdparty autoloader - $vendorAutoLoad = OC::$THIRDPARTYROOT . '/3rdparty/autoload.php'; - if (file_exists($vendorAutoLoad)) { + try { + self::initPaths(); + // setup 3rdparty autoloader + $vendorAutoLoad = OC::$THIRDPARTYROOT . '/3rdparty/autoload.php'; + if (!file_exists($vendorAutoLoad)) { + throw new \RuntimeException('Composer autoloader not found, unable to continue. Check the folder "3rdparty".'); + } require_once $vendorAutoLoad; - } else { + + } catch (\RuntimeException $e) { OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE); // we can't use the template error page here, because this needs the // DI container which isn't available yet - print('Composer autoloader not found, unable to continue. Check the folder "3rdparty".'); + print($e->getMessage()); exit(); } diff --git a/lib/l10n/cs_CZ.js b/lib/l10n/cs_CZ.js index 6702c2ff05a..95ca9b9e121 100644 --- a/lib/l10n/cs_CZ.js +++ b/lib/l10n/cs_CZ.js @@ -101,6 +101,7 @@ OC.L10N.register( "Setting permissions for %s failed, because the item was not found" : "Nastavení práv pro %s selhalo, protože položka nebyla nalezena", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Nelze nastavit datum vypršení platnosti. Sdílení nemůže vypršet později než za %s po zveřejnění", "Cannot set expiration date. Expiration date is in the past" : "Nelze nastavit datum vypršení platnosti. Datum vypršení je v minulosti", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Nelze smazat datum vypršení platnosti. Sdílená data vyžadují datum vypršení platnosti odkazu.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Úložiště pro sdílení %s musí implementovat rozhraní OCP\\Share_Backend", "Sharing backend %s not found" : "Úložiště sdílení %s nenalezeno", "Sharing backend for %s not found" : "Úložiště sdílení pro %s nenalezeno", diff --git a/lib/l10n/cs_CZ.json b/lib/l10n/cs_CZ.json index a629c66e99b..1c7650dbfa6 100644 --- a/lib/l10n/cs_CZ.json +++ b/lib/l10n/cs_CZ.json @@ -99,6 +99,7 @@ "Setting permissions for %s failed, because the item was not found" : "Nastavení práv pro %s selhalo, protože položka nebyla nalezena", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Nelze nastavit datum vypršení platnosti. Sdílení nemůže vypršet později než za %s po zveřejnění", "Cannot set expiration date. Expiration date is in the past" : "Nelze nastavit datum vypršení platnosti. Datum vypršení je v minulosti", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Nelze smazat datum vypršení platnosti. Sdílená data vyžadují datum vypršení platnosti odkazu.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Úložiště pro sdílení %s musí implementovat rozhraní OCP\\Share_Backend", "Sharing backend %s not found" : "Úložiště sdílení %s nenalezeno", "Sharing backend for %s not found" : "Úložiště sdílení pro %s nenalezeno", diff --git a/lib/l10n/da.js b/lib/l10n/da.js index d7572bcec0d..17e67fdeb76 100644 --- a/lib/l10n/da.js +++ b/lib/l10n/da.js @@ -42,6 +42,8 @@ OC.L10N.register( "Dot files are not allowed" : "Filer med punktummer er ikke tilladt", "4-byte characters are not supported in file names" : "Tegn med 4-byte understøttes ikke i filnavne", "File name is a reserved word" : "Filnavnet er et reserveret ord", + "File name contains at least one invalid character" : "Filnavnet indeholder mindst ét ugyldigt tegn", + "File name is too long" : "Filnavnet er for langt", "App directory already exists" : "App-mappe findes allerede", "Can't create app folder. Please fix permissions. %s" : "Kan ikke oprette app-mappe. Ret tilladelser. %s", "No source specified when installing app" : "Ingen kilde angivet under installation af app", @@ -99,6 +101,7 @@ OC.L10N.register( "Setting permissions for %s failed, because the item was not found" : "Angivelse af tilladelser for %s mislykkedes, fordi artiklen ikke blev fundet", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Kan ikke angive udløbsdato. Delinger kan ikke udløbe senere end %s efter at de er blevet delt", "Cannot set expiration date. Expiration date is in the past" : "Kan ikke angive udløbsdato. Udløbsdato er allerede passeret", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Kan ikke rydde udløbsdatoen. Det er et krav til delinger, at de har en udløbsdato.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Delingsbackend'en %s skal implementere grænsefladen OCP\\Share_Backend", "Sharing backend %s not found" : "Delingsbackend'en %s blev ikke fundet", "Sharing backend for %s not found" : "Delingsbackend'en for %s blev ikke fundet", diff --git a/lib/l10n/da.json b/lib/l10n/da.json index 9bd03e3e92b..c7b0bb9296d 100644 --- a/lib/l10n/da.json +++ b/lib/l10n/da.json @@ -40,6 +40,8 @@ "Dot files are not allowed" : "Filer med punktummer er ikke tilladt", "4-byte characters are not supported in file names" : "Tegn med 4-byte understøttes ikke i filnavne", "File name is a reserved word" : "Filnavnet er et reserveret ord", + "File name contains at least one invalid character" : "Filnavnet indeholder mindst ét ugyldigt tegn", + "File name is too long" : "Filnavnet er for langt", "App directory already exists" : "App-mappe findes allerede", "Can't create app folder. Please fix permissions. %s" : "Kan ikke oprette app-mappe. Ret tilladelser. %s", "No source specified when installing app" : "Ingen kilde angivet under installation af app", @@ -97,6 +99,7 @@ "Setting permissions for %s failed, because the item was not found" : "Angivelse af tilladelser for %s mislykkedes, fordi artiklen ikke blev fundet", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Kan ikke angive udløbsdato. Delinger kan ikke udløbe senere end %s efter at de er blevet delt", "Cannot set expiration date. Expiration date is in the past" : "Kan ikke angive udløbsdato. Udløbsdato er allerede passeret", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Kan ikke rydde udløbsdatoen. Det er et krav til delinger, at de har en udløbsdato.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Delingsbackend'en %s skal implementere grænsefladen OCP\\Share_Backend", "Sharing backend %s not found" : "Delingsbackend'en %s blev ikke fundet", "Sharing backend for %s not found" : "Delingsbackend'en for %s blev ikke fundet", diff --git a/lib/l10n/es.js b/lib/l10n/es.js index a31f215d094..783cd8d6e3b 100644 --- a/lib/l10n/es.js +++ b/lib/l10n/es.js @@ -99,8 +99,9 @@ OC.L10N.register( "Share type %s is not valid for %s" : "Compartir tipo %s no es válido para %s", "Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "La configuración de permisos para %s ha fallado, ya que los permisos superan los permisos dados a %s", "Setting permissions for %s failed, because the item was not found" : "La configuración de permisos para %s ha fallado, ya que no se encontró el elemento ", - "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "No se puede fijar fecha de caducidad. Los archivos compartidos no pueden caducar luego de %s de ser compartidos", + "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "No se puede fijar fecha de caducidad. Los archivos compartidos no pueden caducar más tarde de %s de ser compartidos", "Cannot set expiration date. Expiration date is in the past" : "No se puede fijar la fecha de caducidad. La fecha de caducidad está en el pasado.", + "Cannot clear expiration date. Shares are required to have an expiration date." : "No se puede eliminar la fecha de caducidad. Los archivos compartidos deben tener una fecha de caducidad.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "El motor compartido %s debe implementar la interfaz OCP\\Share_Backend", "Sharing backend %s not found" : "El motor compartido %s no se ha encontrado", "Sharing backend for %s not found" : "Motor compartido para %s no encontrado", diff --git a/lib/l10n/es.json b/lib/l10n/es.json index 52f7cbfd5e5..3b5f6ea2f39 100644 --- a/lib/l10n/es.json +++ b/lib/l10n/es.json @@ -97,8 +97,9 @@ "Share type %s is not valid for %s" : "Compartir tipo %s no es válido para %s", "Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "La configuración de permisos para %s ha fallado, ya que los permisos superan los permisos dados a %s", "Setting permissions for %s failed, because the item was not found" : "La configuración de permisos para %s ha fallado, ya que no se encontró el elemento ", - "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "No se puede fijar fecha de caducidad. Los archivos compartidos no pueden caducar luego de %s de ser compartidos", + "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "No se puede fijar fecha de caducidad. Los archivos compartidos no pueden caducar más tarde de %s de ser compartidos", "Cannot set expiration date. Expiration date is in the past" : "No se puede fijar la fecha de caducidad. La fecha de caducidad está en el pasado.", + "Cannot clear expiration date. Shares are required to have an expiration date." : "No se puede eliminar la fecha de caducidad. Los archivos compartidos deben tener una fecha de caducidad.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "El motor compartido %s debe implementar la interfaz OCP\\Share_Backend", "Sharing backend %s not found" : "El motor compartido %s no se ha encontrado", "Sharing backend for %s not found" : "Motor compartido para %s no encontrado", diff --git a/lib/l10n/fr.js b/lib/l10n/fr.js index 574f8e53998..9591b8671f4 100644 --- a/lib/l10n/fr.js +++ b/lib/l10n/fr.js @@ -101,6 +101,7 @@ OC.L10N.register( "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", diff --git a/lib/l10n/fr.json b/lib/l10n/fr.json index 3107d0b3e69..612a0dec8f7 100644 --- a/lib/l10n/fr.json +++ b/lib/l10n/fr.json @@ -99,6 +99,7 @@ "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", diff --git a/lib/l10n/gl.js b/lib/l10n/gl.js index cb908f4f619..ee6b5f19687 100644 --- a/lib/l10n/gl.js +++ b/lib/l10n/gl.js @@ -101,6 +101,7 @@ OC.L10N.register( "Setting permissions for %s failed, because the item was not found" : "Non é posíbel estabelecer permisos para %s, non se atopa o elemento", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Non é posíbel estabelecer a data de caducidade. As comparticións non poden caducar máis aló de %s após de seren compartidas", "Cannot set expiration date. Expiration date is in the past" : "Non é posíbel estabelecer a data de caducidade. A data de caducidade está no pasado.", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Non é posíbel limpar a data de caducidade. É necesaria algunha compartición para ter unha data de caducidade.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "A infraestrutura de compartición %s ten que implementar a interface OCP\\Share_Backend", "Sharing backend %s not found" : "Non se atopou a infraestrutura de compartición %s", "Sharing backend for %s not found" : "Non se atopou a infraestrutura de compartición para %s", diff --git a/lib/l10n/gl.json b/lib/l10n/gl.json index 0fd5fe083e6..ccdba66446c 100644 --- a/lib/l10n/gl.json +++ b/lib/l10n/gl.json @@ -99,6 +99,7 @@ "Setting permissions for %s failed, because the item was not found" : "Non é posíbel estabelecer permisos para %s, non se atopa o elemento", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Non é posíbel estabelecer a data de caducidade. As comparticións non poden caducar máis aló de %s após de seren compartidas", "Cannot set expiration date. Expiration date is in the past" : "Non é posíbel estabelecer a data de caducidade. A data de caducidade está no pasado.", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Non é posíbel limpar a data de caducidade. É necesaria algunha compartición para ter unha data de caducidade.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "A infraestrutura de compartición %s ten que implementar a interface OCP\\Share_Backend", "Sharing backend %s not found" : "Non se atopou a infraestrutura de compartición %s", "Sharing backend for %s not found" : "Non se atopou a infraestrutura de compartición para %s", diff --git a/lib/l10n/it.js b/lib/l10n/it.js index 4d1ab41bd55..4a2deab9b51 100644 --- a/lib/l10n/it.js +++ b/lib/l10n/it.js @@ -101,6 +101,7 @@ OC.L10N.register( "Setting permissions for %s failed, because the item was not found" : "Impostazione permessi per %s non riuscita, poiché l'elemento non è stato trovato", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Impossibile impostare la data di scadenza. Le condivisioni non possono scadere più tardi di %s dalla loro attivazione", "Cannot set expiration date. Expiration date is in the past" : "Impossibile impostare la data di scadenza. La data di scadenza è nel passato.", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Impossibile cancellare la data di scadenza. Le condivisioni devono avere una data di scadenza.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Il motore di condivisione %s deve implementare l'interfaccia OCP\\Share_Backend", "Sharing backend %s not found" : "Motore di condivisione %s non trovato", "Sharing backend for %s not found" : "Motore di condivisione di %s non trovato", diff --git a/lib/l10n/it.json b/lib/l10n/it.json index f4e34cc9f33..07e20706e3e 100644 --- a/lib/l10n/it.json +++ b/lib/l10n/it.json @@ -99,6 +99,7 @@ "Setting permissions for %s failed, because the item was not found" : "Impostazione permessi per %s non riuscita, poiché l'elemento non è stato trovato", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Impossibile impostare la data di scadenza. Le condivisioni non possono scadere più tardi di %s dalla loro attivazione", "Cannot set expiration date. Expiration date is in the past" : "Impossibile impostare la data di scadenza. La data di scadenza è nel passato.", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Impossibile cancellare la data di scadenza. Le condivisioni devono avere una data di scadenza.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Il motore di condivisione %s deve implementare l'interfaccia OCP\\Share_Backend", "Sharing backend %s not found" : "Motore di condivisione %s non trovato", "Sharing backend for %s not found" : "Motore di condivisione di %s non trovato", diff --git a/lib/l10n/nl.js b/lib/l10n/nl.js index 67dea9f0f83..32fd1933487 100644 --- a/lib/l10n/nl.js +++ b/lib/l10n/nl.js @@ -43,6 +43,7 @@ OC.L10N.register( "4-byte characters are not supported in file names" : "4-byte tekens in bestandsnamen worden niet ondersteund", "File name is a reserved word" : "Bestandsnaam is een gereserveerd woord", "File name contains at least one invalid character" : "De bestandsnaam bevat ten minste één verboden teken", + "File name is too long" : "De bestandsnaam is te lang", "App directory already exists" : "App directory bestaat al", "Can't create app folder. Please fix permissions. %s" : "Kan de app map niet aanmaken, Herstel de permissies. %s", "No source specified when installing app" : "Geen bron opgegeven bij installatie van de app", @@ -100,6 +101,7 @@ OC.L10N.register( "Setting permissions for %s failed, because the item was not found" : "Instellen van de permissies voor %s is mislukt, omdat het object niet is gevonden", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Kon vervaldatum niet instellen. Shares kunnen niet langer dan %s vervallen na het moment van delen", "Cannot set expiration date. Expiration date is in the past" : "Kon vervaldatum niet instellen. De vervaldatum ligt in het verleden", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Kon vervaldatum niet weghalen. Shares moeten een vervaldatum hebben.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Het share-backend %s moet de OCP\\Share_Backend interface implementeren", "Sharing backend %s not found" : "Het share-backend %s is niet gevonden", "Sharing backend for %s not found" : "Het share-backend voor %s is niet gevonden", diff --git a/lib/l10n/nl.json b/lib/l10n/nl.json index 35961c075d3..380c3da46c7 100644 --- a/lib/l10n/nl.json +++ b/lib/l10n/nl.json @@ -41,6 +41,7 @@ "4-byte characters are not supported in file names" : "4-byte tekens in bestandsnamen worden niet ondersteund", "File name is a reserved word" : "Bestandsnaam is een gereserveerd woord", "File name contains at least one invalid character" : "De bestandsnaam bevat ten minste één verboden teken", + "File name is too long" : "De bestandsnaam is te lang", "App directory already exists" : "App directory bestaat al", "Can't create app folder. Please fix permissions. %s" : "Kan de app map niet aanmaken, Herstel de permissies. %s", "No source specified when installing app" : "Geen bron opgegeven bij installatie van de app", @@ -98,6 +99,7 @@ "Setting permissions for %s failed, because the item was not found" : "Instellen van de permissies voor %s is mislukt, omdat het object niet is gevonden", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Kon vervaldatum niet instellen. Shares kunnen niet langer dan %s vervallen na het moment van delen", "Cannot set expiration date. Expiration date is in the past" : "Kon vervaldatum niet instellen. De vervaldatum ligt in het verleden", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Kon vervaldatum niet weghalen. Shares moeten een vervaldatum hebben.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Het share-backend %s moet de OCP\\Share_Backend interface implementeren", "Sharing backend %s not found" : "Het share-backend %s is niet gevonden", "Sharing backend for %s not found" : "Het share-backend voor %s is niet gevonden", diff --git a/lib/l10n/pt_BR.js b/lib/l10n/pt_BR.js index 456189f3cc6..07d1eb39fbf 100644 --- a/lib/l10n/pt_BR.js +++ b/lib/l10n/pt_BR.js @@ -42,6 +42,8 @@ OC.L10N.register( "Dot files are not allowed" : "Dot arquivos não são permitidos", "4-byte characters are not supported in file names" : "Caracteres de 4-bytes não são suportados em nomes de arquivos", "File name is a reserved word" : "O nome do arquivo é uma palavra reservada", + "File name contains at least one invalid character" : "O nome do arquivo contém pelo menos um caractere inválido", + "File name is too long" : "O nome do arquivo é muito longo", "App directory already exists" : "Diretório App já existe", "Can't create app folder. Please fix permissions. %s" : "Não é possível criar pasta app. Corrija as permissões. %s", "No source specified when installing app" : "Nenhuma fonte foi especificada enquanto instalava o aplicativo", diff --git a/lib/l10n/pt_BR.json b/lib/l10n/pt_BR.json index 7915a8f715a..8b356bd88fc 100644 --- a/lib/l10n/pt_BR.json +++ b/lib/l10n/pt_BR.json @@ -40,6 +40,8 @@ "Dot files are not allowed" : "Dot arquivos não são permitidos", "4-byte characters are not supported in file names" : "Caracteres de 4-bytes não são suportados em nomes de arquivos", "File name is a reserved word" : "O nome do arquivo é uma palavra reservada", + "File name contains at least one invalid character" : "O nome do arquivo contém pelo menos um caractere inválido", + "File name is too long" : "O nome do arquivo é muito longo", "App directory already exists" : "Diretório App já existe", "Can't create app folder. Please fix permissions. %s" : "Não é possível criar pasta app. Corrija as permissões. %s", "No source specified when installing app" : "Nenhuma fonte foi especificada enquanto instalava o aplicativo", diff --git a/lib/l10n/pt_PT.js b/lib/l10n/pt_PT.js index 7d586b4d628..6b8f05413f3 100644 --- a/lib/l10n/pt_PT.js +++ b/lib/l10n/pt_PT.js @@ -101,6 +101,7 @@ OC.L10N.register( "Setting permissions for %s failed, because the item was not found" : "Definir permissões para %s falhou, porque o item não foi encontrado", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Não é possível definir data de expiração. As partilhas não podem expirar mais de %s depois de terem sido partilhadas", "Cannot set expiration date. Expiration date is in the past" : "Não é possivel definir data de expiração. A data de expiração está no passado", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Não é possível limpar a data de expiração. As partilhas devem ter uma data de expiração.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Ao partilhar a interface %s deve implementar a interface OCP\\Share_Backend", "Sharing backend %s not found" : "Não foi encontrada a partilha da interface %s", "Sharing backend for %s not found" : "Não foi encontrada a partilha da interface para %s", diff --git a/lib/l10n/pt_PT.json b/lib/l10n/pt_PT.json index 444e8ff4b1f..d171e3585c6 100644 --- a/lib/l10n/pt_PT.json +++ b/lib/l10n/pt_PT.json @@ -99,6 +99,7 @@ "Setting permissions for %s failed, because the item was not found" : "Definir permissões para %s falhou, porque o item não foi encontrado", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Não é possível definir data de expiração. As partilhas não podem expirar mais de %s depois de terem sido partilhadas", "Cannot set expiration date. Expiration date is in the past" : "Não é possivel definir data de expiração. A data de expiração está no passado", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Não é possível limpar a data de expiração. As partilhas devem ter uma data de expiração.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Ao partilhar a interface %s deve implementar a interface OCP\\Share_Backend", "Sharing backend %s not found" : "Não foi encontrada a partilha da interface %s", "Sharing backend for %s not found" : "Não foi encontrada a partilha da interface para %s", diff --git a/lib/l10n/sr.js b/lib/l10n/sr.js index f46c88770ac..b28071912f7 100644 --- a/lib/l10n/sr.js +++ b/lib/l10n/sr.js @@ -1,11 +1,21 @@ OC.L10N.register( "lib", { + "See %s" : "Погледајте %s", + "PHP %s or higher is required." : "Потребан је ПХП %s или новији.", + "PHP with a version lower than %s is required." : "Потребан је ПХП старији од %s.", + "Following databases are supported: %s" : "Следеће базе података су подржане: %s", + "The library %s is not available." : "Библиотека %s није доступна.", + "Following platforms are supported: %s" : "Следеће платформе су подржане: %s", + "ownCloud %s or higher is required." : "Оунклауд %s или новији је потребан.", "Help" : "Помоћ", "Personal" : "Лично", "Users" : "Корисници", "Admin" : "Администратор", "Recommended" : "Препоручено", + "App \"%s\" cannot be installed because it is not compatible with this version of ownCloud." : "Апликација „%s“ не може бити инсталирана јер није компатибилна са овим издањем Оунклауда.", + "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "Апликација „%s“ не може бити инсталирана јер следеће зависности нису испуњене: %s", + "No app name specified" : "Није наведен назив апликације", "Unknown filetype" : "Непознат тип фајла", "Invalid image" : "Неисправна слика", "today" : "данас", @@ -14,20 +24,44 @@ OC.L10N.register( "last month" : "прошлог месеца", "_%n month ago_::_%n months ago_" : ["пре %n месец","пре %n месеца","пре %n месеци"], "last year" : "прошле године", - "_%n year ago_::_%n years ago_" : ["","",""], - "_%n hour ago_::_%n hours ago_" : ["","",""], - "_%n minute ago_::_%n minutes ago_" : ["","",""], + "_%n year ago_::_%n years ago_" : ["пре %n годину","пре %n године","пре %n година"], + "_%n hour ago_::_%n hours ago_" : ["пре %n сат","пре %n сата","пре %n сати"], + "_%n minute ago_::_%n minutes ago_" : ["пре %n минут","пре %n минута","пре %n минута"], "seconds ago" : "пре неколико секунди", "web services under your control" : "веб сервиси под вашом контролом", + "Empty filename is not allowed" : "Празан назив није дозвољен", + "Dot files are not allowed" : "Фајлови са почетном тачком нису дозвољени", + "4-byte characters are not supported in file names" : "4-бајтни знакови нису подржани у називу фајлова", + "File name is a reserved word" : "Назив фајла је резервисана реч", + "File name contains at least one invalid character" : "Назив фајла садржи бар један недозвољен знак", + "File name is too long" : "Назив фајла је предугачак", + "App directory already exists" : "Директоријум апликација већ постоји", + "Archives of type %s are not supported" : "%s архиве нису подржане", "Application is not enabled" : "Апликација није укључена", "Authentication error" : "Грешка аутентификације", "Token expired. Please reload page." : "Жетон је истекао. Поново учитајте страницу.", + "Unknown user" : "Непознат корисник", "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Мек ОС Икс није подржан и %s неће радити исправно на овој платформи. Користите га на сопствени ризик!", "For the best results, please consider using a GNU/Linux server instead." : "За најбоље резултате, размотрите употребу ГНУ/Линукс сервера.", "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." : "Изгледа да %s ради у 32-битном ПХП окружењу а open_basedir је подешен у php.ini фајлу. То може довести до проблема са фајловима већим од 4 GB те стога није препоручљиво.", "Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "Уклоните open_basedir поставку из php.ini фајла или пређите на 64-битни ПХП.", + "Set an admin username." : "Поставите име за администратора.", + "Set an admin password." : "Поставите лозинку за администратора.", + "%s shared »%s« with you" : "%s подели „%s“ са вама", + "You are not allowed to share %s" : "Није вам дозвољено да делите %s", "Could not find category \"%s\"" : "Не могу да пронађем категорију „%s“.", + "Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"" : "Само су следећи знакови дозвољени за корисничко име: „a-z“, „A-Z“, „0-9“ и „_.@-“", "A valid username must be provided" : "Морате унети исправно корисничко име", - "A valid password must be provided" : "Морате унети исправну лозинку" + "A valid password must be provided" : "Морате унети исправну лозинку", + "The username is already being used" : "Корисничко име се већ користи", + "No database drivers (sqlite, mysql, or postgresql) installed." : "Нема драјвера базе података (скулајт, мајскул или постгрескул).", + "Setting locale to %s failed" : "Постављање локалитета на %s није успело", + "Please install one of these locales on your system and restart your webserver." : "Инсталирајте неки од ових локалитета на ваш систем и поново покрените веб сервер.", + "Please ask your server administrator to install the module." : "Замолите администратора вашег сервера да инсталира тај модул.", + "PHP module %s not installed." : "ПХП модул %s није инсталиран.", + "PHP setting \"%s\" is not set to \"%s\"." : "ПХП поставка „%s“ није постављена на „%s“.", + "PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "ПХП је очигледно подешен да се скида уметнуте док блокова. То ће учинити неколико кључних апликација недоступним.", + "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Ово је вероватно изазвано кешом или акцелератором као што су ЗендОПкеш или еАкцелератор.", + "PostgreSQL >= 9 required" : "Захтеван је ПостгреСкул >= 9" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/lib/l10n/sr.json b/lib/l10n/sr.json index fcae89b69fd..e4cc7d27608 100644 --- a/lib/l10n/sr.json +++ b/lib/l10n/sr.json @@ -1,9 +1,19 @@ { "translations": { + "See %s" : "Погледајте %s", + "PHP %s or higher is required." : "Потребан је ПХП %s или новији.", + "PHP with a version lower than %s is required." : "Потребан је ПХП старији од %s.", + "Following databases are supported: %s" : "Следеће базе података су подржане: %s", + "The library %s is not available." : "Библиотека %s није доступна.", + "Following platforms are supported: %s" : "Следеће платформе су подржане: %s", + "ownCloud %s or higher is required." : "Оунклауд %s или новији је потребан.", "Help" : "Помоћ", "Personal" : "Лично", "Users" : "Корисници", "Admin" : "Администратор", "Recommended" : "Препоручено", + "App \"%s\" cannot be installed because it is not compatible with this version of ownCloud." : "Апликација „%s“ не може бити инсталирана јер није компатибилна са овим издањем Оунклауда.", + "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "Апликација „%s“ не може бити инсталирана јер следеће зависности нису испуњене: %s", + "No app name specified" : "Није наведен назив апликације", "Unknown filetype" : "Непознат тип фајла", "Invalid image" : "Неисправна слика", "today" : "данас", @@ -12,20 +22,44 @@ "last month" : "прошлог месеца", "_%n month ago_::_%n months ago_" : ["пре %n месец","пре %n месеца","пре %n месеци"], "last year" : "прошле године", - "_%n year ago_::_%n years ago_" : ["","",""], - "_%n hour ago_::_%n hours ago_" : ["","",""], - "_%n minute ago_::_%n minutes ago_" : ["","",""], + "_%n year ago_::_%n years ago_" : ["пре %n годину","пре %n године","пре %n година"], + "_%n hour ago_::_%n hours ago_" : ["пре %n сат","пре %n сата","пре %n сати"], + "_%n minute ago_::_%n minutes ago_" : ["пре %n минут","пре %n минута","пре %n минута"], "seconds ago" : "пре неколико секунди", "web services under your control" : "веб сервиси под вашом контролом", + "Empty filename is not allowed" : "Празан назив није дозвољен", + "Dot files are not allowed" : "Фајлови са почетном тачком нису дозвољени", + "4-byte characters are not supported in file names" : "4-бајтни знакови нису подржани у називу фајлова", + "File name is a reserved word" : "Назив фајла је резервисана реч", + "File name contains at least one invalid character" : "Назив фајла садржи бар један недозвољен знак", + "File name is too long" : "Назив фајла је предугачак", + "App directory already exists" : "Директоријум апликација већ постоји", + "Archives of type %s are not supported" : "%s архиве нису подржане", "Application is not enabled" : "Апликација није укључена", "Authentication error" : "Грешка аутентификације", "Token expired. Please reload page." : "Жетон је истекао. Поново учитајте страницу.", + "Unknown user" : "Непознат корисник", "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Мек ОС Икс није подржан и %s неће радити исправно на овој платформи. Користите га на сопствени ризик!", "For the best results, please consider using a GNU/Linux server instead." : "За најбоље резултате, размотрите употребу ГНУ/Линукс сервера.", "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." : "Изгледа да %s ради у 32-битном ПХП окружењу а open_basedir је подешен у php.ini фајлу. То може довести до проблема са фајловима већим од 4 GB те стога није препоручљиво.", "Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "Уклоните open_basedir поставку из php.ini фајла или пређите на 64-битни ПХП.", + "Set an admin username." : "Поставите име за администратора.", + "Set an admin password." : "Поставите лозинку за администратора.", + "%s shared »%s« with you" : "%s подели „%s“ са вама", + "You are not allowed to share %s" : "Није вам дозвољено да делите %s", "Could not find category \"%s\"" : "Не могу да пронађем категорију „%s“.", + "Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"" : "Само су следећи знакови дозвољени за корисничко име: „a-z“, „A-Z“, „0-9“ и „_.@-“", "A valid username must be provided" : "Морате унети исправно корисничко име", - "A valid password must be provided" : "Морате унети исправну лозинку" + "A valid password must be provided" : "Морате унети исправну лозинку", + "The username is already being used" : "Корисничко име се већ користи", + "No database drivers (sqlite, mysql, or postgresql) installed." : "Нема драјвера базе података (скулајт, мајскул или постгрескул).", + "Setting locale to %s failed" : "Постављање локалитета на %s није успело", + "Please install one of these locales on your system and restart your webserver." : "Инсталирајте неки од ових локалитета на ваш систем и поново покрените веб сервер.", + "Please ask your server administrator to install the module." : "Замолите администратора вашег сервера да инсталира тај модул.", + "PHP module %s not installed." : "ПХП модул %s није инсталиран.", + "PHP setting \"%s\" is not set to \"%s\"." : "ПХП поставка „%s“ није постављена на „%s“.", + "PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "ПХП је очигледно подешен да се скида уметнуте док блокова. То ће учинити неколико кључних апликација недоступним.", + "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Ово је вероватно изазвано кешом или акцелератором као што су ЗендОПкеш или еАкцелератор.", + "PostgreSQL >= 9 required" : "Захтеван је ПостгреСкул >= 9" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" }
\ No newline at end of file diff --git a/lib/l10n/tr.js b/lib/l10n/tr.js index 8987e7726af..a54c5f49057 100644 --- a/lib/l10n/tr.js +++ b/lib/l10n/tr.js @@ -22,7 +22,7 @@ OC.L10N.register( "Users" : "Kullanıcılar", "Admin" : "Yönetici", "Recommended" : "Önerilen", - "App \"%s\" cannot be installed because it is not compatible with this version of ownCloud." : "ownCloud yazılımının bu sürümü ile uyumlu olmadığı için \"%s\" uygulaması kurulamaz.", + "App \"%s\" cannot be installed because it is not compatible with this version of ownCloud." : "ownCloud yazılımının bu sürümü ile uyumlu olmadığı için \"%s\" uygulaması kurulamaz.", "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "\"%s\" uygulaması, şu bağımlılıklar sağlanmadığı için yüklenemiyor: %s", "No app name specified" : "Uygulama adı belirtilmedi", "Unknown filetype" : "Bilinmeyen dosya türü", @@ -40,8 +40,8 @@ OC.L10N.register( "web services under your control" : "denetiminizdeki web hizmetleri", "Empty filename is not allowed" : "Boş dasya adına izin verilmiyor", "Dot files are not allowed" : "Nokta dosyalarına izin verilmiyor", - "4-byte characters are not supported in file names" : "4-bayt karakterler dosya adlarında desteklenmez", - "File name is a reserved word" : "Dosya adı ayrılmış bir sözcüktür", + "4-byte characters are not supported in file names" : "4 bayt karakterler dosya adlarında desteklenmez", + "File name is a reserved word" : "Bu dosya adı özel bir kullanıma aittir", "File name contains at least one invalid character" : "Dosya adı en az bir geçersiz karakter içeriyor", "File name is too long" : "Dosya adı çok uzun", "App directory already exists" : "Uygulama dizini zaten mevcut", @@ -101,6 +101,7 @@ OC.L10N.register( "Setting permissions for %s failed, because the item was not found" : "%s için izinler öge bulunamadığından ayarlanamadı", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Son kullanma tarihi ayarlanamıyor. Paylaşımlar, paylaşıldıkları süreden %s sonra dolamaz.", "Cannot set expiration date. Expiration date is in the past" : "Son kullanma tarihi ayarlanamıyor. Son kullanma tarihi geçmişte", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Son kullanım tarihi temizlenemiyor. Paylaşımların bir son kullanma tarihi olmalı.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Paylaşma arka ucu %s OCP\\Share_Backend arayüzünü desteklemeli", "Sharing backend %s not found" : "Paylaşım arka ucu %s bulunamadı", "Sharing backend for %s not found" : "%s için paylaşım arka ucu bulunamadı", diff --git a/lib/l10n/tr.json b/lib/l10n/tr.json index 95a4c7e48d9..c97b318b334 100644 --- a/lib/l10n/tr.json +++ b/lib/l10n/tr.json @@ -20,7 +20,7 @@ "Users" : "Kullanıcılar", "Admin" : "Yönetici", "Recommended" : "Önerilen", - "App \"%s\" cannot be installed because it is not compatible with this version of ownCloud." : "ownCloud yazılımının bu sürümü ile uyumlu olmadığı için \"%s\" uygulaması kurulamaz.", + "App \"%s\" cannot be installed because it is not compatible with this version of ownCloud." : "ownCloud yazılımının bu sürümü ile uyumlu olmadığı için \"%s\" uygulaması kurulamaz.", "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "\"%s\" uygulaması, şu bağımlılıklar sağlanmadığı için yüklenemiyor: %s", "No app name specified" : "Uygulama adı belirtilmedi", "Unknown filetype" : "Bilinmeyen dosya türü", @@ -38,8 +38,8 @@ "web services under your control" : "denetiminizdeki web hizmetleri", "Empty filename is not allowed" : "Boş dasya adına izin verilmiyor", "Dot files are not allowed" : "Nokta dosyalarına izin verilmiyor", - "4-byte characters are not supported in file names" : "4-bayt karakterler dosya adlarında desteklenmez", - "File name is a reserved word" : "Dosya adı ayrılmış bir sözcüktür", + "4-byte characters are not supported in file names" : "4 bayt karakterler dosya adlarında desteklenmez", + "File name is a reserved word" : "Bu dosya adı özel bir kullanıma aittir", "File name contains at least one invalid character" : "Dosya adı en az bir geçersiz karakter içeriyor", "File name is too long" : "Dosya adı çok uzun", "App directory already exists" : "Uygulama dizini zaten mevcut", @@ -99,6 +99,7 @@ "Setting permissions for %s failed, because the item was not found" : "%s için izinler öge bulunamadığından ayarlanamadı", "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Son kullanma tarihi ayarlanamıyor. Paylaşımlar, paylaşıldıkları süreden %s sonra dolamaz.", "Cannot set expiration date. Expiration date is in the past" : "Son kullanma tarihi ayarlanamıyor. Son kullanma tarihi geçmişte", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Son kullanım tarihi temizlenemiyor. Paylaşımların bir son kullanma tarihi olmalı.", "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Paylaşma arka ucu %s OCP\\Share_Backend arayüzünü desteklemeli", "Sharing backend %s not found" : "Paylaşım arka ucu %s bulunamadı", "Sharing backend for %s not found" : "%s için paylaşım arka ucu bulunamadı", diff --git a/lib/l10n/uk.js b/lib/l10n/uk.js index 0689e6b1fb2..2d830eb0d85 100644 --- a/lib/l10n/uk.js +++ b/lib/l10n/uk.js @@ -8,25 +8,42 @@ OC.L10N.register( "Sample configuration detected" : "Виявлено приклад конфігурації", "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" : "Була виявлена конфігурація з прикладу. Це може нашкодити вашій системі та не підтримується. Будь ласка, зверніться до документації перед внесенням змін в файл config.php", "PHP %s or higher is required." : "Необхідно PHP %s або вище", + "PHP with a version lower than %s is required." : "Потрібна версія PHP нижче %s ", + "Following databases are supported: %s" : "Підтримуються наступні сервери баз даних: %s", + "The command line tool %s could not be found" : "Утиліту командного рядка %s не знайдено", + "The library %s is not available." : "Бібліотека %s недоступна.", + "Library %s with a version higher than %s is required - available version %s." : "Потрібна бібліотека %s версії не більше %s, встановлена версія %s.", + "Library %s with a version lower than %s is required - available version %s." : "Потрібна бібліотека %s версії менш ніж %s, встановлена версія %s.", + "Following platforms are supported: %s" : "Підтримуються наступні платформи: %s", + "ownCloud %s or higher is required." : "Потрібен ownCloud %s або вище.", + "ownCloud with a version lower than %s is required." : "Потрібна версія ownCloud нижче %s.", "Help" : "Допомога", "Personal" : "Особисте", "Users" : "Користувачі", "Admin" : "Адмін", "Recommended" : "Рекомендуємо", + "App \"%s\" cannot be installed because it is not compatible with this version of ownCloud." : "Додаток \"%s\" не може бути встановлено, так як він не сумісний з цією версією ownCloud.", + "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "Додаток \"%s\" не може бути встановлений, так як наступні залежності не виконано: %s", "No app name specified" : "Не вказано ім'я додатку", "Unknown filetype" : "Невідомий тип файлу", "Invalid image" : "Невірне зображення", "today" : "сьогодні", "yesterday" : "вчора", - "_%n day ago_::_%n days ago_" : ["","",""], + "_%n day ago_::_%n days ago_" : ["%n день тому","%n днів тому","%n днів тому"], "last month" : "минулого місяця", "_%n month ago_::_%n months ago_" : ["","","%n місяців тому"], "last year" : "минулого року", - "_%n year ago_::_%n years ago_" : ["","",""], + "_%n year ago_::_%n years ago_" : ["%n рік тому","%n років тому","%n років тому"], "_%n hour ago_::_%n hours ago_" : ["","","%n годин тому"], "_%n minute ago_::_%n minutes ago_" : ["","","%n хвилин тому"], "seconds ago" : "секунди тому", "web services under your control" : "підконтрольні Вам веб-сервіси", + "Empty filename is not allowed" : "Порожні імена файлів не допускаються", + "Dot files are not allowed" : "Файли які починаються з крапки не допустимі", + "4-byte characters are not supported in file names" : "4-х байтові символи в імені файлів не допустимі", + "File name is a reserved word" : "Ім’я файлу є зарезервованим словом", + "File name contains at least one invalid character" : "Ім’я файлу містить принаймні один некоректний символ", + "File name is too long" : "Ім’я файлу занадто довге", "App directory already exists" : "Тека додатку вже існує", "Can't create app folder. Please fix permissions. %s" : "Неможливо створити теку додатку. Будь ласка, виправте права доступу. %s", "No source specified when installing app" : "Не вказано джерело при встановлені додатку", @@ -61,11 +78,13 @@ OC.L10N.register( "PostgreSQL username and/or password not valid" : "PostgreSQL ім'я користувача та/або пароль не дійсні", "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Mac OS X не підтримується і %s не буде коректно працювати на цій платформі. Випробовуєте на свій риск!", "For the best results, please consider using a GNU/Linux server instead." : "Для кращих результатів розгляньте можливість використання 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." : "Здається що екземпляр цього %s працює в 32-бітному PHP середовищі і open_basedir повинен бути налаштований в php.ini. Це призведе до проблем з файлами більше 4 ГБ і це дуже не рекомендується.", "Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "Будь ласка, видаліть параметр open_basedir у вашому php.ini або перейдіть на 64-бітний PHP.", "Set an admin username." : "Встановіть ім'я адміністратора.", "Set an admin password." : "Встановіть пароль адміністратора.", "Can't create or write into the data directory %s" : "Неможливо створити або записати каталог даних %s", "%s shared »%s« with you" : "%s розподілено »%s« з тобою", + "Sharing %s failed, because the backend does not allow shares from type %i" : "Не вдалося поділитися %s, загальний доступ не допускає публікації з елементів типу %i", "Sharing %s failed, because the file does not exist" : "Не вдалося поділитися %s, оскільки файл не існує", "You are not allowed to share %s" : "Вам заборонено поширювати %s", "Sharing %s failed, because the user %s is the item owner" : "Не вдалося поділитися з %s, оскільки %s вже є володарем", @@ -76,17 +95,54 @@ OC.L10N.register( "Sharing %s failed, because %s is not a member of the group %s" : "Не вдалося поділитися %s, оскільки %s не є членом групи %s", "You need to provide a password to create a public link, only protected links are allowed" : "Вам необхідно задати пароль для створення публічного посилання. Дозволені лише захищені посилання", "Sharing %s failed, because sharing with links is not allowed" : "Не вдалося поділитися %s, оскільки публічний доступ через посилання заборонений", + "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Не вдалося поділитися %s, не вдалося знайти %s, можливо, сервер не доступний.", + "Share type %s is not valid for %s" : "Тип загального доступу %s неприпустимий для %s", + "Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "Не вдалося налаштувати права доступу для %s, зазначені права доступу перевищують надані для %s", + "Setting permissions for %s failed, because the item was not found" : "Не вдалося налаштувати права доступу для %s, елемент не знайдений.", + "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Неможливо встановити дату закінчення. Загальні ресурси не можуть застаріти пізніше %s з моменту їх публікації.", + "Cannot set expiration date. Expiration date is in the past" : "Неможливо встановити дату закінчення. Дата закінчення в минулому.", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Неможливо очистити дату закінчення. Загальні ресурси повинні мати термін придатності.", + "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Backend загального доступу %s повинен реалізовувати інтерфейс OCP\\Share_Backend", + "Sharing backend %s not found" : "Backend загального доступу %s не знайдено", + "Sharing backend for %s not found" : "Бекенд загального доступу для %s не знайдено", + "Sharing %s failed, because the user %s is the original sharer" : "Не вдалося поділитися %s, спочатку елементом поділився %s", + "Sharing %s failed, because the permissions exceed permissions granted to %s" : "Не вдалося поділитися %s, права перевищують надані права доступу %s", + "Sharing %s failed, because resharing is not allowed" : "Не вдалося поділитися %s, перевідкриття доступу заборонено", + "Sharing %s failed, because the sharing backend for %s could not find its source" : "Не вдалося поділитися %s, backend загального доступу не знайшов шлях до %s", + "Sharing %s failed, because the file could not be found in the file cache" : "Не вдалося поділитися %s, елемент не знайдено у файловому кеші.", "Could not find category \"%s\"" : "Не вдалося знайти категорію \"%s\"", + "Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"" : "Тільки такі символи допускаються в імені користувача: \"az\", \"AZ\", \"0-9\", і \"_.@ -\"", "A valid username must be provided" : "Потрібно задати вірне ім'я користувача", "A valid password must be provided" : "Потрібно задати вірний пароль", "The username is already being used" : "Ім'я користувача вже використовується", "No database drivers (sqlite, mysql, or postgresql) installed." : "Не встановлено драйвер бази даних (sqlite, mysql, or postgresql).", "Cannot write into \"config\" directory" : "Не можу писати у теку \"config\"", "Cannot write into \"apps\" directory" : "Не можу писати у теку \"apps\"", + "This can usually be fixed by %sgiving the webserver write access to the apps directory%s or disabling the appstore in the config file." : "Зазвичай це можна виправити, %s надавши веб-серверу права на запис в каталог додатків %s або відключивши сховище програм у файлі конфігурації.", + "Cannot create \"data\" directory (%s)" : "Неможливо створити каталог \"data\" (%s)", + "This can usually be fixed by <a href=\"%s\" target=\"_blank\">giving the webserver write access to the root directory</a>." : "Зазвичай це можна виправити, <a href=\"%s\" target=\"_blank\"> надавши веб-серверу права на запис в кореневому каталозі</a>.", + "Permissions can usually be fixed by %sgiving the webserver write access to the root directory%s." : "Зазвичай це можна виправити, %s надавши веб-серверу права на запис в кореневому каталозі %s.", + "Setting locale to %s failed" : "Установка локалі %s не вдалася", + "Please install one of these locales on your system and restart your webserver." : "Встановіть один із цих мовних пакетів в вашу систему і перезапустіть веб-сервер.", "Please ask your server administrator to install the module." : "Будь ласка, зверніться до адміністратора, щоб встановити модуль.", "PHP module %s not installed." : "%s модуль PHP не встановлено.", + "PHP setting \"%s\" is not set to \"%s\"." : "Параметр PHP \"%s\" не встановлено в \"%s\".", + "Adjusting this setting in php.ini will make ownCloud run again" : "Установка цього параметру в php.ini дозволяє запуститися ownCloud знову.", + "Please ask your server administrator to update PHP to the latest version. Your PHP version is no longer supported by ownCloud and the PHP community." : "Будь ласка, зверніться до адміністратора серверу, щоб оновити PHP до останньої версії. Встановлена версія PHP більше не підтримується ownCloud і співтовариством PHP.", + "PHP is configured to populate raw post data. Since PHP 5.6 this will lead to PHP throwing notices for perfectly valid code." : "У PHP включена директива \"always_populate_raw_post_data\". PHP версії 5.6 і вище, при включеній директиві, додає повідомлення в журнал навіть для абсолютно робочого коду.", + "To fix this issue set <code>always_populate_raw_post_data</code> to <code>-1</code> in your php.ini" : "Щоб виправити цю помилку, вкажіть значення <code> -1 </ code> як значення параметра <code> always_populate_raw_post_data </ code> у вашому php.ini", "PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "Схоже, що PHP налаштовано на вичищення блоків вбудованої документації. Це зробить кілька основних додатків недоступними.", "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Це, ймовірно, обумовлено використанням кеша/прискорювача такого як Zend OPcache або eAccelerator.", - "Please ask your server administrator to restart the web server." : "Будь ласка, зверніться до адміністратора, щоб перезавантажити сервер." + "PHP modules have been installed, but they are still listed as missing?" : "Модулі PHP були встановлені, але вони все ще перераховані як відсутні?", + "Please ask your server administrator to restart the web server." : "Будь ласка, зверніться до адміністратора, щоб перезавантажити сервер.", + "PostgreSQL >= 9 required" : "Потрібно PostgreSQL> = 9", + "Please upgrade your database version" : "Оновіть версію бази даних", + "Error occurred while checking PostgreSQL version" : "Сталася помилка при перевірці версії PostgreSQL", + "Please make sure you have PostgreSQL >= 9 or check the logs for more information about the error" : "Переконайтеся що версія PostgreSQL> = 9 або перевірте журнали для отримання додаткової інформацією про помилку", + "Please change the permissions to 0770 so that the directory cannot be listed by other users." : "Змініть права доступу на 0770, щоб інші користувачі не могли отримати список файлів цього каталогу.", + "Data directory (%s) is readable by other users" : "Каталог даних (%s) доступний для читання іншим користувачам", + "Data directory (%s) is invalid" : "Каталог даних (%s) невірний", + "Please check that the data directory contains a file \".ocdata\" in its root." : "Переконайтеся, що файл \".ocdata\" присутній у корені каталогу даних.", + "Could not obtain lock type %d on \"%s\"." : "Не вдалося отримати блокування типу %d для \"%s\"" }, "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); diff --git a/lib/l10n/uk.json b/lib/l10n/uk.json index 587d30c1bc3..8bb598eb219 100644 --- a/lib/l10n/uk.json +++ b/lib/l10n/uk.json @@ -6,25 +6,42 @@ "Sample configuration detected" : "Виявлено приклад конфігурації", "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" : "Була виявлена конфігурація з прикладу. Це може нашкодити вашій системі та не підтримується. Будь ласка, зверніться до документації перед внесенням змін в файл config.php", "PHP %s or higher is required." : "Необхідно PHP %s або вище", + "PHP with a version lower than %s is required." : "Потрібна версія PHP нижче %s ", + "Following databases are supported: %s" : "Підтримуються наступні сервери баз даних: %s", + "The command line tool %s could not be found" : "Утиліту командного рядка %s не знайдено", + "The library %s is not available." : "Бібліотека %s недоступна.", + "Library %s with a version higher than %s is required - available version %s." : "Потрібна бібліотека %s версії не більше %s, встановлена версія %s.", + "Library %s with a version lower than %s is required - available version %s." : "Потрібна бібліотека %s версії менш ніж %s, встановлена версія %s.", + "Following platforms are supported: %s" : "Підтримуються наступні платформи: %s", + "ownCloud %s or higher is required." : "Потрібен ownCloud %s або вище.", + "ownCloud with a version lower than %s is required." : "Потрібна версія ownCloud нижче %s.", "Help" : "Допомога", "Personal" : "Особисте", "Users" : "Користувачі", "Admin" : "Адмін", "Recommended" : "Рекомендуємо", + "App \"%s\" cannot be installed because it is not compatible with this version of ownCloud." : "Додаток \"%s\" не може бути встановлено, так як він не сумісний з цією версією ownCloud.", + "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "Додаток \"%s\" не може бути встановлений, так як наступні залежності не виконано: %s", "No app name specified" : "Не вказано ім'я додатку", "Unknown filetype" : "Невідомий тип файлу", "Invalid image" : "Невірне зображення", "today" : "сьогодні", "yesterday" : "вчора", - "_%n day ago_::_%n days ago_" : ["","",""], + "_%n day ago_::_%n days ago_" : ["%n день тому","%n днів тому","%n днів тому"], "last month" : "минулого місяця", "_%n month ago_::_%n months ago_" : ["","","%n місяців тому"], "last year" : "минулого року", - "_%n year ago_::_%n years ago_" : ["","",""], + "_%n year ago_::_%n years ago_" : ["%n рік тому","%n років тому","%n років тому"], "_%n hour ago_::_%n hours ago_" : ["","","%n годин тому"], "_%n minute ago_::_%n minutes ago_" : ["","","%n хвилин тому"], "seconds ago" : "секунди тому", "web services under your control" : "підконтрольні Вам веб-сервіси", + "Empty filename is not allowed" : "Порожні імена файлів не допускаються", + "Dot files are not allowed" : "Файли які починаються з крапки не допустимі", + "4-byte characters are not supported in file names" : "4-х байтові символи в імені файлів не допустимі", + "File name is a reserved word" : "Ім’я файлу є зарезервованим словом", + "File name contains at least one invalid character" : "Ім’я файлу містить принаймні один некоректний символ", + "File name is too long" : "Ім’я файлу занадто довге", "App directory already exists" : "Тека додатку вже існує", "Can't create app folder. Please fix permissions. %s" : "Неможливо створити теку додатку. Будь ласка, виправте права доступу. %s", "No source specified when installing app" : "Не вказано джерело при встановлені додатку", @@ -59,11 +76,13 @@ "PostgreSQL username and/or password not valid" : "PostgreSQL ім'я користувача та/або пароль не дійсні", "Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " : "Mac OS X не підтримується і %s не буде коректно працювати на цій платформі. Випробовуєте на свій риск!", "For the best results, please consider using a GNU/Linux server instead." : "Для кращих результатів розгляньте можливість використання 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." : "Здається що екземпляр цього %s працює в 32-бітному PHP середовищі і open_basedir повинен бути налаштований в php.ini. Це призведе до проблем з файлами більше 4 ГБ і це дуже не рекомендується.", "Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP." : "Будь ласка, видаліть параметр open_basedir у вашому php.ini або перейдіть на 64-бітний PHP.", "Set an admin username." : "Встановіть ім'я адміністратора.", "Set an admin password." : "Встановіть пароль адміністратора.", "Can't create or write into the data directory %s" : "Неможливо створити або записати каталог даних %s", "%s shared »%s« with you" : "%s розподілено »%s« з тобою", + "Sharing %s failed, because the backend does not allow shares from type %i" : "Не вдалося поділитися %s, загальний доступ не допускає публікації з елементів типу %i", "Sharing %s failed, because the file does not exist" : "Не вдалося поділитися %s, оскільки файл не існує", "You are not allowed to share %s" : "Вам заборонено поширювати %s", "Sharing %s failed, because the user %s is the item owner" : "Не вдалося поділитися з %s, оскільки %s вже є володарем", @@ -74,17 +93,54 @@ "Sharing %s failed, because %s is not a member of the group %s" : "Не вдалося поділитися %s, оскільки %s не є членом групи %s", "You need to provide a password to create a public link, only protected links are allowed" : "Вам необхідно задати пароль для створення публічного посилання. Дозволені лише захищені посилання", "Sharing %s failed, because sharing with links is not allowed" : "Не вдалося поділитися %s, оскільки публічний доступ через посилання заборонений", + "Sharing %s failed, could not find %s, maybe the server is currently unreachable." : "Не вдалося поділитися %s, не вдалося знайти %s, можливо, сервер не доступний.", + "Share type %s is not valid for %s" : "Тип загального доступу %s неприпустимий для %s", + "Setting permissions for %s failed, because the permissions exceed permissions granted to %s" : "Не вдалося налаштувати права доступу для %s, зазначені права доступу перевищують надані для %s", + "Setting permissions for %s failed, because the item was not found" : "Не вдалося налаштувати права доступу для %s, елемент не знайдений.", + "Cannot set expiration date. Shares cannot expire later than %s after they have been shared" : "Неможливо встановити дату закінчення. Загальні ресурси не можуть застаріти пізніше %s з моменту їх публікації.", + "Cannot set expiration date. Expiration date is in the past" : "Неможливо встановити дату закінчення. Дата закінчення в минулому.", + "Cannot clear expiration date. Shares are required to have an expiration date." : "Неможливо очистити дату закінчення. Загальні ресурси повинні мати термін придатності.", + "Sharing backend %s must implement the interface OCP\\Share_Backend" : "Backend загального доступу %s повинен реалізовувати інтерфейс OCP\\Share_Backend", + "Sharing backend %s not found" : "Backend загального доступу %s не знайдено", + "Sharing backend for %s not found" : "Бекенд загального доступу для %s не знайдено", + "Sharing %s failed, because the user %s is the original sharer" : "Не вдалося поділитися %s, спочатку елементом поділився %s", + "Sharing %s failed, because the permissions exceed permissions granted to %s" : "Не вдалося поділитися %s, права перевищують надані права доступу %s", + "Sharing %s failed, because resharing is not allowed" : "Не вдалося поділитися %s, перевідкриття доступу заборонено", + "Sharing %s failed, because the sharing backend for %s could not find its source" : "Не вдалося поділитися %s, backend загального доступу не знайшов шлях до %s", + "Sharing %s failed, because the file could not be found in the file cache" : "Не вдалося поділитися %s, елемент не знайдено у файловому кеші.", "Could not find category \"%s\"" : "Не вдалося знайти категорію \"%s\"", + "Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-\"" : "Тільки такі символи допускаються в імені користувача: \"az\", \"AZ\", \"0-9\", і \"_.@ -\"", "A valid username must be provided" : "Потрібно задати вірне ім'я користувача", "A valid password must be provided" : "Потрібно задати вірний пароль", "The username is already being used" : "Ім'я користувача вже використовується", "No database drivers (sqlite, mysql, or postgresql) installed." : "Не встановлено драйвер бази даних (sqlite, mysql, or postgresql).", "Cannot write into \"config\" directory" : "Не можу писати у теку \"config\"", "Cannot write into \"apps\" directory" : "Не можу писати у теку \"apps\"", + "This can usually be fixed by %sgiving the webserver write access to the apps directory%s or disabling the appstore in the config file." : "Зазвичай це можна виправити, %s надавши веб-серверу права на запис в каталог додатків %s або відключивши сховище програм у файлі конфігурації.", + "Cannot create \"data\" directory (%s)" : "Неможливо створити каталог \"data\" (%s)", + "This can usually be fixed by <a href=\"%s\" target=\"_blank\">giving the webserver write access to the root directory</a>." : "Зазвичай це можна виправити, <a href=\"%s\" target=\"_blank\"> надавши веб-серверу права на запис в кореневому каталозі</a>.", + "Permissions can usually be fixed by %sgiving the webserver write access to the root directory%s." : "Зазвичай це можна виправити, %s надавши веб-серверу права на запис в кореневому каталозі %s.", + "Setting locale to %s failed" : "Установка локалі %s не вдалася", + "Please install one of these locales on your system and restart your webserver." : "Встановіть один із цих мовних пакетів в вашу систему і перезапустіть веб-сервер.", "Please ask your server administrator to install the module." : "Будь ласка, зверніться до адміністратора, щоб встановити модуль.", "PHP module %s not installed." : "%s модуль PHP не встановлено.", + "PHP setting \"%s\" is not set to \"%s\"." : "Параметр PHP \"%s\" не встановлено в \"%s\".", + "Adjusting this setting in php.ini will make ownCloud run again" : "Установка цього параметру в php.ini дозволяє запуститися ownCloud знову.", + "Please ask your server administrator to update PHP to the latest version. Your PHP version is no longer supported by ownCloud and the PHP community." : "Будь ласка, зверніться до адміністратора серверу, щоб оновити PHP до останньої версії. Встановлена версія PHP більше не підтримується ownCloud і співтовариством PHP.", + "PHP is configured to populate raw post data. Since PHP 5.6 this will lead to PHP throwing notices for perfectly valid code." : "У PHP включена директива \"always_populate_raw_post_data\". PHP версії 5.6 і вище, при включеній директиві, додає повідомлення в журнал навіть для абсолютно робочого коду.", + "To fix this issue set <code>always_populate_raw_post_data</code> to <code>-1</code> in your php.ini" : "Щоб виправити цю помилку, вкажіть значення <code> -1 </ code> як значення параметра <code> always_populate_raw_post_data </ code> у вашому php.ini", "PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "Схоже, що PHP налаштовано на вичищення блоків вбудованої документації. Це зробить кілька основних додатків недоступними.", "This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "Це, ймовірно, обумовлено використанням кеша/прискорювача такого як Zend OPcache або eAccelerator.", - "Please ask your server administrator to restart the web server." : "Будь ласка, зверніться до адміністратора, щоб перезавантажити сервер." + "PHP modules have been installed, but they are still listed as missing?" : "Модулі PHP були встановлені, але вони все ще перераховані як відсутні?", + "Please ask your server administrator to restart the web server." : "Будь ласка, зверніться до адміністратора, щоб перезавантажити сервер.", + "PostgreSQL >= 9 required" : "Потрібно PostgreSQL> = 9", + "Please upgrade your database version" : "Оновіть версію бази даних", + "Error occurred while checking PostgreSQL version" : "Сталася помилка при перевірці версії PostgreSQL", + "Please make sure you have PostgreSQL >= 9 or check the logs for more information about the error" : "Переконайтеся що версія PostgreSQL> = 9 або перевірте журнали для отримання додаткової інформацією про помилку", + "Please change the permissions to 0770 so that the directory cannot be listed by other users." : "Змініть права доступу на 0770, щоб інші користувачі не могли отримати список файлів цього каталогу.", + "Data directory (%s) is readable by other users" : "Каталог даних (%s) доступний для читання іншим користувачам", + "Data directory (%s) is invalid" : "Каталог даних (%s) невірний", + "Please check that the data directory contains a file \".ocdata\" in its root." : "Переконайтеся, що файл \".ocdata\" присутній у корені каталогу даних.", + "Could not obtain lock type %d on \"%s\"." : "Не вдалося отримати блокування типу %d для \"%s\"" },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" }
\ No newline at end of file diff --git a/lib/private/app.php b/lib/private/app.php index d30ada0391a..1b004154173 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -42,6 +42,7 @@ class OC_App { static private $appTypes = array(); static private $loadedApps = array(); static private $altLogin = array(); + private static $shippedApps = null; /** * clean the appId @@ -182,12 +183,18 @@ class OC_App { * Check if an app that is installed is a shipped app or installed from the appstore. */ public static function isShipped($appId) { - $info = self::getAppInfo($appId); - if (isset($info['shipped']) && $info['shipped'] == 'true') { - return true; - } else { - return false; + if (is_null(self::$shippedApps)) { + $shippedJson = \OC::$SERVERROOT . '/core/shipped.json'; + if (file_exists($shippedJson)) { + self::$shippedApps = json_decode(file_get_contents($shippedJson), true); + self::$shippedApps = self::$shippedApps['shippedApps']; + } else { + self::$shippedApps = ['files', 'files_encryption', 'files_external', + 'files_sharing', 'files_trashbin', 'files_versions', 'provisioning_api', + 'user_ldap', 'user_webdavauth']; + } } + return in_array($appId, self::$shippedApps); } /** diff --git a/lib/private/avatar.php b/lib/private/avatar.php index 23b3c82771a..da9c84d84a4 100644 --- a/lib/private/avatar.php +++ b/lib/private/avatar.php @@ -29,7 +29,7 @@ class Avatar implements \OCP\IAvatar { /** * get the users avatar * @param int $size size in px of the avatar, avatars are square, defaults to 64 - * @return boolean|\OC_Image containing the avatar or false if there's no image + * @return boolean|\OCP\IImage containing the avatar or false if there's no image */ public function get ($size = 64) { if ($this->view->file_exists('avatar.jpg')) { @@ -57,14 +57,14 @@ class Avatar implements \OCP\IAvatar { /** * sets the users avatar - * @param \OC_Image|resource|string $data OC_Image, imagedata or path to set a new avatar + * @param \OCP\IImage|resource|string $data An image object, imagedata or path to set a new avatar * @throws \Exception if the provided file is not a jpg or png image * @throws \Exception if the provided image is not valid * @throws \OC\NotSquareException if the image is not square * @return void */ public function set ($data) { - if($data instanceOf OC_Image) { + if($data instanceOf \OCP\IImage) { $img = $data; $data = $img->data(); } else { diff --git a/lib/private/cache/fileglobalgc.php b/lib/private/cache/fileglobalgc.php index 039992718ab..b07e886f652 100644 --- a/lib/private/cache/fileglobalgc.php +++ b/lib/private/cache/fileglobalgc.php @@ -6,6 +6,9 @@ use OC\BackgroundJob\Job; use OCP\IConfig; class FileGlobalGC extends Job { + // only do cleanup every 5 minutes + const CLEANUP_TTL_SEC = 300; + public function run($argument) { $this->gc(\OC::$server->getConfig(), $this->getCacheDir()); } @@ -39,8 +42,7 @@ class FileGlobalGC extends Job { public function gc(IConfig $config, $cacheDir) { $lastRun = $config->getAppValue('core', 'global_cache_gc_lastrun', 0); $now = time(); - if (($now - $lastRun) < 300) { - // only do cleanup every 5 minutes + if (($now - $lastRun) < self::CLEANUP_TTL_SEC) { return; } $config->setAppValue('core', 'global_cache_gc_lastrun', $now); @@ -48,6 +50,8 @@ class FileGlobalGC extends Job { return; } $paths = $this->getExpiredPaths($cacheDir, $now); - array_walk($paths, 'unlink'); + array_walk($paths, function($file) { + unlink($file); + }); } } diff --git a/lib/private/connector/sabre/custompropertiesbackend.php b/lib/private/connector/sabre/custompropertiesbackend.php index 76ac8b84ef9..6827cb9ae0d 100644 --- a/lib/private/connector/sabre/custompropertiesbackend.php +++ b/lib/private/connector/sabre/custompropertiesbackend.php @@ -29,6 +29,7 @@ use Sabre\DAV\PropertyStorage\Backend\BackendInterface; use Sabre\DAV\PropFind; use Sabre\DAV\PropPatch; use Sabre\DAV\Tree; +use Sabre\DAV\Exception\NotFound; class CustomPropertiesBackend implements BackendInterface { @@ -94,8 +95,19 @@ class CustomPropertiesBackend implements BackendInterface { * @return void */ public function propFind($path, PropFind $propFind) { - $node = $this->tree->getNodeForPath($path); - if (!($node instanceof Node)) { + try { + $node = $this->tree->getNodeForPath($path); + if (!($node instanceof Node)) { + return; + } + } catch (NotFound $e) { + // in some rare (buggy) cases the node might not be found, + // we catch the exception to prevent breaking the whole list with a 404 + // (soft fail) + \OC::$server->getLogger()->warning( + 'Could not get node for path: \"' . $path . '\" : ' . $e->getMessage(), + array('app' => 'files') + ); return; } diff --git a/lib/private/db/connection.php b/lib/private/db/connection.php index 8748f66b369..dd1a9da6747 100644 --- a/lib/private/db/connection.php +++ b/lib/private/db/connection.php @@ -30,7 +30,7 @@ class Connection extends \Doctrine\DBAL\Connection implements IDBConnection { return parent::connect(); } catch (DBALException $e) { // throw a new exception to prevent leaking info from the stacktrace - throw new DBALException($e->getMessage(), $e->getCode()); + throw new DBALException('Failed to connect to the database: ' . $e->getMessage(), $e->getCode()); } } diff --git a/lib/private/fileproxy/fileoperations.php b/lib/private/fileproxy/fileoperations.php deleted file mode 100644 index b2ff2e7e5e9..00000000000 --- a/lib/private/fileproxy/fileoperations.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * ownCloud - * - * @author Bjoern Schiessle - * @copyright 2012 Bjoern Schiessle <schiessle@owncloud.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library 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 AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - * - */ - -/** - * check if standard file operations - */ - -class OC_FileProxy_FileOperations extends OC_FileProxy{ - static $rootView; - - public function premkdir($path) { - if(!self::$rootView) { - self::$rootView = new \OC\Files\View(''); - } - return !self::$rootView->file_exists($path); - } - -} diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php index 64661ca1157..670ac2ec524 100644 --- a/lib/private/files/cache/cache.php +++ b/lib/private/files/cache/cache.php @@ -245,9 +245,6 @@ class Cache { $queryParts[] = '`storage`'; $params[] = $this->getNumericStorageId(); - $params = array_map(function($item) { - return trim($item, "`"); - }, $params); $queryParts = array_map(function($item) { return trim($item, "`"); }, $queryParts); diff --git a/lib/private/files/cache/watcher.php b/lib/private/files/cache/watcher.php index f4572895b09..22c3fb202c3 100644 --- a/lib/private/files/cache/watcher.php +++ b/lib/private/files/cache/watcher.php @@ -52,6 +52,13 @@ class Watcher { } /** + * @return int either \OC\Files\Cache\Watcher::CHECK_NEVER, \OC\Files\Cache\Watcher::CHECK_ONCE, \OC\Files\Cache\Watcher::CHECK_ALWAYS + */ + public function getPolicy() { + return $this->watchPolicy; + } + + /** * check $path for updates * * @param string $path diff --git a/lib/private/files/mount/mountpoint.php b/lib/private/files/mount/mountpoint.php index 85edb7cb570..a187f4db109 100644 --- a/lib/private/files/mount/mountpoint.php +++ b/lib/private/files/mount/mountpoint.php @@ -71,9 +71,10 @@ class MountPoint implements IMountPoint { } $mountpoint = $this->formatPath($mountpoint); + $this->mountPoint = $mountpoint; if ($storage instanceof Storage) { $this->class = get_class($storage); - $this->storage = $this->loader->wrap($mountpoint, $storage); + $this->storage = $this->loader->wrap($this, $storage); } else { // Update old classes to new namespace if (strpos($storage, 'OC_Filestorage_') !== false) { @@ -82,7 +83,6 @@ class MountPoint implements IMountPoint { $this->class = $storage; $this->arguments = $arguments; } - $this->mountPoint = $mountpoint; } /** @@ -113,7 +113,7 @@ class MountPoint implements IMountPoint { if (class_exists($this->class)) { try { - return $this->loader->getInstance($this->mountPoint, $this->class, $this->arguments); + return $this->loader->getInstance($this, $this->class, $this->arguments); } catch (\Exception $exception) { $this->invalidStorage = true; if ($this->mountPoint === '/') { @@ -195,7 +195,7 @@ class MountPoint implements IMountPoint { $storage = $this->getStorage(); // storage can be null if it couldn't be initialized if ($storage != null) { - $this->storage = $wrapper($this->mountPoint, $storage); + $this->storage = $wrapper($this->mountPoint, $storage, $this); } } @@ -209,4 +209,13 @@ class MountPoint implements IMountPoint { public function getOption($name, $default) { return isset($this->mountOptions[$name]) ? $this->mountOptions[$name] : $default; } + + /** + * Get all options for the mount + * + * @return array + */ + public function getOptions() { + return $this->mountOptions; + } } diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php index 5de243e177a..11cf3405fd9 100644 --- a/lib/private/files/storage/common.php +++ b/lib/private/files/storage/common.php @@ -35,6 +35,8 @@ abstract class Common implements \OC\Files\Storage\Storage { protected $watcher; protected $storageCache; + protected $mountOptions = []; + /** * @var string[] */ @@ -330,7 +332,8 @@ abstract class Common implements \OC\Files\Storage\Storage { } if (!isset($this->watcher)) { $this->watcher = new Watcher($storage); - $this->watcher->setPolicy(\OC::$server->getConfig()->getSystemValue('filesystem_check_changes', Watcher::CHECK_ONCE)); + $globalPolicy = \OC::$server->getConfig()->getSystemValue('filesystem_check_changes', Watcher::CHECK_ONCE); + $this->watcher->setPolicy($this->getMountOption('filesystem_check_changes', $globalPolicy)); } return $this->watcher; } @@ -517,4 +520,20 @@ abstract class Common implements \OC\Files\Storage\Storage { throw new InvalidCharacterInPathException(); } } + + /** + * @param array $options + */ + public function setMountOptions(array $options) { + $this->mountOptions = $options; + } + + /** + * @param string $name + * @param mixed $default + * @return mixed + */ + public function getMountOption($name, $default = null) { + return isset($this->mountOptions[$name]) ? $this->mountOptions[$name] : $default; + } } diff --git a/lib/private/files/storage/storagefactory.php b/lib/private/files/storage/storagefactory.php index fa6dea2537c..51972791290 100644 --- a/lib/private/files/storage/storagefactory.php +++ b/lib/private/files/storage/storagefactory.php @@ -8,6 +8,7 @@ namespace OC\Files\Storage; +use OCP\Files\Mount\IMountPoint; use OCP\Files\Storage\IStorageFactory; class StorageFactory implements IStorageFactory { @@ -55,23 +56,23 @@ class StorageFactory implements IStorageFactory { /** * Create an instance of a storage and apply the registered storage wrappers * - * @param string|boolean $mountPoint + * @param \OCP\Files\Mount\IMountPoint $mountPoint * @param string $class * @param array $arguments * @return \OCP\Files\Storage */ - public function getInstance($mountPoint, $class, $arguments) { + public function getInstance(IMountPoint $mountPoint, $class, $arguments) { return $this->wrap($mountPoint, new $class($arguments)); } /** - * @param string|boolean $mountPoint + * @param \OCP\Files\Mount\IMountPoint $mountPoint * @param \OCP\Files\Storage $storage * @return \OCP\Files\Storage */ - public function wrap($mountPoint, $storage) { + public function wrap(IMountPoint $mountPoint, $storage) { foreach ($this->storageWrappers as $wrapper) { - $storage = $wrapper($mountPoint, $storage); + $storage = $wrapper($mountPoint->getMountPoint(), $storage, $mountPoint); } return $storage; } diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 53e13396621..c95e0545810 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -1133,7 +1133,7 @@ class View { } if ($mount instanceof MoveableMount && $internalPath === '') { - $data['permissions'] |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE; + $data['permissions'] |= \OCP\Constants::PERMISSION_DELETE; } $data = \OC_FileProxy::runPostProxies('getFileInfo', $path, $data); diff --git a/lib/private/image.php b/lib/private/image.php index 2484aeecc63..c8509c61286 100644 --- a/lib/private/image.php +++ b/lib/private/image.php @@ -15,7 +15,7 @@ /** * Class for basic image manipulation */ -class OC_Image { +class OC_Image implements \OCP\IImage { protected $resource = false; // tmp resource. protected $imageType = IMAGETYPE_PNG; // Default to png if file type isn't evident. protected $mimeType = "image/png"; // Default to png @@ -285,7 +285,7 @@ class OC_Image { /** * @return null|string Returns the raw image data. */ - function data() { + public function data() { if (!$this->valid()) { return null; } @@ -949,6 +949,9 @@ class OC_Image { return true; } + /** + * Destroys the current image and resets the object + */ public function destroy() { if ($this->valid()) { imagedestroy($this->resource); diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php index c051c0eded2..af2c651cf80 100644 --- a/lib/private/mimetypes.list.php +++ b/lib/private/mimetypes.list.php @@ -81,6 +81,7 @@ return array( 'impress' => array('text/impress', null), 'jpeg' => array('image/jpeg', null), 'jpg' => array('image/jpeg', null), + 'jps' => array('image/jpeg', null), 'js' => array('application/javascript', 'text/plain'), 'json' => array('application/json', 'text/plain'), 'k25' => array('image/x-dcraw', null), @@ -103,6 +104,7 @@ return array( 'mp4' => array('video/mp4', null), 'mpeg' => array('video/mpeg', null), 'mpg' => array('video/mpeg', null), + 'mpo' => array('image/jpeg', null), 'msi' => array('application/x-msi', null), 'nef' => array('image/x-dcraw', null), 'numbers' => array('application/x-iwork-numbers-sffnumbers', null), diff --git a/lib/private/preview.php b/lib/private/preview.php index 6af1586293f..f69b0d6c971 100644 --- a/lib/private/preview.php +++ b/lib/private/preview.php @@ -46,15 +46,10 @@ class Preview { /** * preview images object * - * @var \OC_Image + * @var \OCP\IImage */ private $preview; - //preview providers - static private $providers = array(); - static private $registeredProviders = array(); - static private $enabledProviders = array(); - /** * @var \OCP\Files\FileInfo */ @@ -95,11 +90,7 @@ class Preview { $this->preview = null; //check if there are preview backends - if (empty(self::$providers)) { - self::initProviders(); - } - - if (empty(self::$providers) && \OC::$server->getConfig()->getSystemValue('enable_previews', true)) { + if (!\OC::$server->getPreviewManager()->hasProviders() && \OC::$server->getConfig()->getSystemValue('enable_previews', true)) { \OC_Log::write('core', 'No preview providers exist', \OC_Log::ERROR); throw new \Exception('No preview providers'); } @@ -474,7 +465,7 @@ class Preview { /** * return a preview of a file - * @return \OC_Image + * @return \OCP\IImage */ public function getPreview() { if (!is_null($this->preview) && $this->preview->valid()) { @@ -510,37 +501,45 @@ class Preview { if (is_null($this->preview)) { $preview = null; - foreach (self::$providers as $supportedMimeType => $provider) { + $previewProviders = \OC::$server->getPreviewManager()->getProviders(); + foreach ($previewProviders as $supportedMimeType => $providers) { if (!preg_match($supportedMimeType, $this->mimeType)) { continue; } - \OC_Log::write('core', 'Generating preview for "' . $file . '" with "' . get_class($provider) . '"', \OC_Log::DEBUG); + foreach ($providers as $closure) { + $provider = $closure(); + if (!($provider instanceof \OCP\Preview\IProvider)) { + continue; + } - /** @var $provider Provider */ - $preview = $provider->getThumbnail($file, $maxX, $maxY, $scalingUp, $this->fileView); + \OC_Log::write('core', 'Generating preview for "' . $file . '" with "' . get_class($provider) . '"', \OC_Log::DEBUG); - if (!($preview instanceof \OC_Image)) { - continue; - } + /** @var $provider Provider */ + $preview = $provider->getThumbnail($file, $maxX, $maxY, $scalingUp, $this->fileView); - $this->preview = $preview; - $this->resizeAndCrop(); + if (!($preview instanceof \OCP\IImage)) { + continue; + } - $previewPath = $this->getPreviewPath($fileId); - $cachePath = $this->buildCachePath($fileId); + $this->preview = $preview; + $this->resizeAndCrop(); - if ($this->userView->is_dir($this->getThumbnailsFolder() . '/') === false) { - $this->userView->mkdir($this->getThumbnailsFolder() . '/'); - } + $previewPath = $this->getPreviewPath($fileId); + $cachePath = $this->buildCachePath($fileId); - if ($this->userView->is_dir($previewPath) === false) { - $this->userView->mkdir($previewPath); - } + if ($this->userView->is_dir($this->getThumbnailsFolder() . '/') === false) { + $this->userView->mkdir($this->getThumbnailsFolder() . '/'); + } + + if ($this->userView->is_dir($previewPath) === false) { + $this->userView->mkdir($previewPath); + } - $this->userView->file_put_contents($cachePath, $preview->data()); + $this->userView->file_put_contents($cachePath, $preview->data()); - break; + break 2; + } } } @@ -565,7 +564,7 @@ class Preview { if (is_null($this->preview)) { $this->getPreview(); } - if ($this->preview instanceof \OC_Image) { + if ($this->preview instanceof \OCP\IImage) { $this->preview->show($mimeType); } } @@ -581,8 +580,8 @@ class Preview { $scalingUp = $this->getScalingUp(); $maxScaleFactor = $this->getMaxScaleFactor(); - if (!($image instanceof \OC_Image)) { - \OC_Log::write('core', '$this->preview is not an instance of OC_Image', \OC_Log::DEBUG); + if (!($image instanceof \OCP\IImage)) { + \OC_Log::write('core', '$this->preview is not an instance of \OCP\IImage', \OC_Log::DEBUG); return; } @@ -686,146 +685,6 @@ class Preview { } /** - * register a new preview provider to be used - * @param string $class - * @param array $options - */ - public static function registerProvider($class, $options = array()) { - /** - * Only register providers that have been explicitly enabled - * - * The following providers are enabled by default: - * - OC\Preview\Image - * - OC\Preview\MP3 - * - OC\Preview\TXT - * - OC\Preview\MarkDown - * - * The following providers are disabled by default due to performance or privacy concerns: - * - OC\Preview\MSOfficeDoc - * - OC\Preview\MSOffice2003 - * - OC\Preview\MSOffice2007 - * - OC\Preview\OpenDocument - * - OC\Preview\StarOffice - * - OC\Preview\SVG - * - OC\Preview\Movie - * - OC\Preview\PDF - * - OC\Preview\TIFF - * - OC\Preview\Illustrator - * - OC\Preview\Postscript - * - OC\Preview\Photoshop - * - OC\Preview\Font - */ - if(empty(self::$enabledProviders)) { - self::$enabledProviders = \OC::$server->getConfig()->getSystemValue('enabledPreviewProviders', array( - 'OC\Preview\Image', - 'OC\Preview\MP3', - 'OC\Preview\TXT', - 'OC\Preview\MarkDown', - )); - } - - if(in_array($class, self::$enabledProviders)) { - self::$registeredProviders[] = array('class' => $class, 'options' => $options); - } - } - - /** - * create instances of all the registered preview providers - * @return void - */ - private static function initProviders() { - if (!\OC::$server->getConfig()->getSystemValue('enable_previews', true)) { - self::$providers = array(); - return; - } - - if (!empty(self::$providers)) { - return; - } - - self::registerCoreProviders(); - foreach (self::$registeredProviders as $provider) { - $class = $provider['class']; - $options = $provider['options']; - - /** @var $object Provider */ - $object = new $class($options); - self::$providers[$object->getMimeType()] = $object; - } - - $keys = array_map('strlen', array_keys(self::$providers)); - array_multisort($keys, SORT_DESC, self::$providers); - } - - protected static function registerCoreProviders() { - self::registerProvider('OC\Preview\TXT'); - self::registerProvider('OC\Preview\MarkDown'); - self::registerProvider('OC\Preview\Image'); - self::registerProvider('OC\Preview\MP3'); - - // SVG, Office and Bitmap require imagick - if (extension_loaded('imagick')) { - $checkImagick = new \Imagick(); - - $imagickProviders = array( - 'SVG' => 'OC\Preview\SVG', - 'TIFF' => 'OC\Preview\TIFF', - 'PDF' => 'OC\Preview\PDF', - 'AI' => 'OC\Preview\Illustrator', - 'PSD' => 'OC\Preview\Photoshop', - 'EPS' => 'OC\Preview\Postscript', - 'TTF' => 'OC\Preview\Font', - ); - - foreach ($imagickProviders as $queryFormat => $provider) { - if (count($checkImagick->queryFormats($queryFormat)) === 1) { - self::registerProvider($provider); - } - } - - if (count($checkImagick->queryFormats('PDF')) === 1) { - // Office previews are currently not supported on Windows - if (!\OC_Util::runningOnWindows() && \OC_Helper::is_function_enabled('shell_exec')) { - $officeFound = is_string(\OC::$server->getConfig()->getSystemValue('preview_libreoffice_path', null)); - - if (!$officeFound) { - //let's see if there is libreoffice or openoffice on this machine - $whichLibreOffice = shell_exec('command -v libreoffice'); - $officeFound = !empty($whichLibreOffice); - if (!$officeFound) { - $whichOpenOffice = shell_exec('command -v openoffice'); - $officeFound = !empty($whichOpenOffice); - } - } - - if ($officeFound) { - self::registerProvider('OC\Preview\MSOfficeDoc'); - self::registerProvider('OC\Preview\MSOffice2003'); - self::registerProvider('OC\Preview\MSOffice2007'); - self::registerProvider('OC\Preview\OpenDocument'); - self::registerProvider('OC\Preview\StarOffice'); - } - } - } - } - - // Video requires avconv or ffmpeg and is therefor - // currently not supported on Windows. - if (!\OC_Util::runningOnWindows()) { - $avconvBinary = \OC_Helper::findBinaryPath('avconv'); - $ffmpegBinary = ($avconvBinary) ? null : \OC_Helper::findBinaryPath('ffmpeg'); - - if ($avconvBinary || $ffmpegBinary) { - // FIXME // a bit hacky but didn't want to use subclasses - \OC\Preview\Movie::$avconvBinary = $avconvBinary; - \OC\Preview\Movie::$ffmpegBinary = $ffmpegBinary; - - self::registerProvider('OC\Preview\Movie'); - } - } - } - - /** * @param array $args */ public static function post_write($args) { @@ -915,60 +774,6 @@ class Preview { } /** - * Check if a preview can be generated for a file - * - * @param \OC\Files\FileInfo $file - * @return bool - */ - public static function isAvailable(\OC\Files\FileInfo $file) { - if (!\OC_Config::getValue('enable_previews', true)) { - return false; - } - - $mount = $file->getMountPoint(); - if ($mount and !$mount->getOption('previews', true)){ - return false; - } - - //check if there are preview backends - if (empty(self::$providers)) { - self::initProviders(); - } - - foreach (self::$providers as $supportedMimeType => $provider) { - /** - * @var \OC\Preview\Provider $provider - */ - if (preg_match($supportedMimeType, $file->getMimetype())) { - return $provider->isAvailable($file); - } - } - return false; - } - - /** - * @param string $mimeType - * @return bool - */ - public static function isMimeSupported($mimeType) { - if (!\OC_Config::getValue('enable_previews', true)) { - return false; - } - - //check if there are preview backends - if (empty(self::$providers)) { - self::initProviders(); - } - - foreach(self::$providers as $supportedMimetype => $provider) { - if(preg_match($supportedMimetype, $mimeType)) { - return true; - } - } - return false; - } - - /** * @param int $fileId * @return string */ diff --git a/lib/private/preview/movie.php b/lib/private/preview/movie.php index 06353ddebb7..85151f5dbaa 100644 --- a/lib/private/preview/movie.php +++ b/lib/private/preview/movie.php @@ -61,7 +61,7 @@ class Movie extends Provider { * @param int $maxY * @param string $absPath * @param int $second - * @return bool|\OC_Image + * @return bool|\OCP\IImage */ private function generateThumbNail($maxX, $maxY, $absPath, $second) { $tmpPath = \OC_Helper::tmpFile(); diff --git a/lib/private/preview/mp3.php b/lib/private/preview/mp3.php index f1a50d99e13..19360f4f036 100644 --- a/lib/private/preview/mp3.php +++ b/lib/private/preview/mp3.php @@ -39,8 +39,7 @@ class MP3 extends Provider { /** * Generates a default image when the file has no cover * - * @return false|\OC_Image False if the default image is missing or invalid, - * otherwise the image is returned as \OC_Image + * @return bool|\OCP\IImage false if the default image is missing or invalid */ private function getNoCoverThumbnail() { $icon = \OC::$SERVERROOT . '/core/img/filetypes/audio.png'; diff --git a/lib/private/preview/provider.php b/lib/private/preview/provider.php index ead67eaeef7..1d6fac13965 100644 --- a/lib/private/preview/provider.php +++ b/lib/private/preview/provider.php @@ -1,10 +1,17 @@ <?php namespace OC\Preview; -abstract class Provider { +use OCP\Preview\IProvider; + +abstract class Provider implements IProvider { private $options; - public function __construct($options) { + /** + * Constructor + * + * @param array $options + */ + public function __construct(array $options = []) { $this->options = $options; } @@ -16,10 +23,10 @@ abstract class Provider { /** * Check if a preview can be generated for $path * - * @param \OC\Files\FileInfo $file + * @param \OCP\Files\FileInfo $file * @return bool */ - public function isAvailable($file) { + public function isAvailable(\OCP\Files\FileInfo $file) { return true; } @@ -30,9 +37,7 @@ abstract class Provider { * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image * @param bool $scalingup Disable/Enable upscaling of previews * @param \OC\Files\View $fileview fileview object of user folder - * @return mixed - * false if no preview was generated - * OC_Image object of the preview + * @return bool|\OCP\IImage false if no preview was generated */ abstract public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview); } diff --git a/lib/private/preview/txt.php b/lib/private/preview/txt.php index 8b414dc5726..772b56c72cc 100644 --- a/lib/private/preview/txt.php +++ b/lib/private/preview/txt.php @@ -18,7 +18,7 @@ class TXT extends Provider { /** * {@inheritDoc} */ - public function isAvailable($file) { + public function isAvailable(\OCP\Files\FileInfo $file) { return $file->getSize() > 5; } diff --git a/lib/private/previewmanager.php b/lib/private/previewmanager.php index 85bf609743d..9f78379ba0f 100644 --- a/lib/private/previewmanager.php +++ b/lib/private/previewmanager.php @@ -8,10 +8,87 @@ */ namespace OC; -use OCP\image; use OCP\IPreview; +use OCP\Preview\IProvider; class PreviewManager implements IPreview { + /** @var \OCP\IConfig */ + protected $config; + + /** @var bool */ + protected $providerListDirty = false; + + /** @var bool */ + protected $registeredCoreProviders = false; + + /** @var array */ + protected $providers = []; + + /** @var array mime type => support status */ + protected $mimeTypeSupportMap = []; + + /** @var array */ + protected $defaultProviders; + + /** + * Constructor + * + * @param \OCP\IConfig $config + */ + public function __construct(\OCP\IConfig $config) { + $this->config = $config; + } + + /** + * In order to improve lazy loading a closure can be registered which will be + * called in case preview providers are actually requested + * + * $callable has to return an instance of \OCP\Preview\IProvider + * + * @param string $mimeTypeRegex Regex with the mime types that are supported by this provider + * @param \Closure $callable + * @return void + */ + public function registerProvider($mimeTypeRegex, \Closure $callable) { + if (!$this->config->getSystemValue('enable_previews', true)) { + return; + } + + if (!isset($this->providers[$mimeTypeRegex])) { + $this->providers[$mimeTypeRegex] = []; + } + $this->providers[$mimeTypeRegex][] = $callable; + $this->providerListDirty = true; + } + + /** + * Get all providers + * @return array + */ + public function getProviders() { + if (!$this->config->getSystemValue('enable_previews', true)) { + return []; + } + + $this->registerCoreProviders(); + if ($this->providerListDirty) { + $keys = array_map('strlen', array_keys($this->providers)); + array_multisort($keys, SORT_DESC, $this->providers); + $this->providerListDirty = false; + } + + return $this->providers; + } + + /** + * Does the manager have any providers + * @return bool + */ + public function hasProviders() { + $this->registerCoreProviders(); + return !empty($this->providers); + } + /** * return a preview of a file * @@ -19,9 +96,9 @@ class PreviewManager implements IPreview { * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image * @param boolean $scaleUp Scale smaller images up to the thumbnail size or not. Might look ugly - * @return \OCP\Image + * @return \OCP\IImage */ - function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false) { + public function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false) { $preview = new \OC\Preview('', '/', $file, $maxX, $maxY, $scaleUp); return $preview->getPreview(); } @@ -32,17 +109,198 @@ class PreviewManager implements IPreview { * @param string $mimeType * @return boolean */ - function isMimeSupported($mimeType = '*') { - return \OC\Preview::isMimeSupported($mimeType); + public function isMimeSupported($mimeType = '*') { + if (!$this->config->getSystemValue('enable_previews', true)) { + return false; + } + + if (isset($this->mimeTypeSupportMap[$mimeType])) { + return $this->mimeTypeSupportMap[$mimeType]; + } + + $this->registerCoreProviders(); + $providerMimeTypes = array_keys($this->providers); + foreach ($providerMimeTypes as $supportedMimeType) { + if (preg_match($supportedMimeType, $mimeType)) { + $this->mimeTypeSupportMap[$mimeType] = true; + return true; + } + } + $this->mimeTypeSupportMap[$mimeType] = false; + return false; } /** * Check if a preview can be generated for a file * - * @param \OC\Files\FileInfo $file + * @param \OCP\Files\FileInfo $file * @return bool */ - function isAvailable($file) { - return \OC\Preview::isAvailable($file); + public function isAvailable(\OCP\Files\FileInfo $file) { + if (!$this->config->getSystemValue('enable_previews', true)) { + return false; + } + + $this->registerCoreProviders(); + if (!$this->isMimeSupported($file->getMimetype())) { + return false; + } + + $mount = $file->getMountPoint(); + if ($mount and !$mount->getOption('previews', true)){ + return false; + } + + foreach ($this->providers as $supportedMimeType => $providers) { + if (preg_match($supportedMimeType, $file->getMimetype())) { + foreach ($providers as $closure) { + $provider = $closure(); + if (!($provider instanceof IProvider)) { + continue; + } + + /** @var $provider IProvider */ + if ($provider->isAvailable($file)) { + return true; + } + } + } + } + return false; + } + + /** + * List of enabled default providers + * + * The following providers are enabled by default: + * - OC\Preview\Image + * - OC\Preview\MarkDown + * - OC\Preview\MP3 + * - OC\Preview\TXT + * + * The following providers are disabled by default due to performance or privacy concerns: + * - OC\Preview\Font + * - OC\Preview\Illustrator + * - OC\Preview\Movie + * - OC\Preview\MSOfficeDoc + * - OC\Preview\MSOffice2003 + * - OC\Preview\MSOffice2007 + * - OC\Preview\OpenDocument + * - OC\Preview\PDF + * - OC\Preview\Photoshop + * - OC\Preview\Postscript + * - OC\Preview\StarOffice + * - OC\Preview\SVG + * - OC\Preview\TIFF + * + * @return array + */ + protected function getEnabledDefaultProvider() { + if ($this->defaultProviders !== null) { + return $this->defaultProviders; + } + + $this->defaultProviders = $this->config->getSystemValue('enabledPreviewProviders', [ + 'OC\Preview\Image', + 'OC\Preview\MarkDown', + 'OC\Preview\MP3', + 'OC\Preview\TXT', + ]); + return $this->defaultProviders; + } + + /** + * Register the default providers (if enabled) + * + * @param string $class + * @param string $mimeType + */ + protected function registerCoreProvider($class, $mimeType, $options = []) { + if (in_array(trim($class, '\\'), $this->getEnabledDefaultProvider())) { + $this->registerProvider($mimeType, function () use ($class, $options) { + return new $class($options); + }); + } + } + + /** + * Register the default providers (if enabled) + */ + protected function registerCoreProviders() { + if ($this->registeredCoreProviders) { + return; + } + $this->registeredCoreProviders = true; + + $this->registerCoreProvider('OC\Preview\TXT', '/text\/plain/'); + $this->registerCoreProvider('OC\Preview\MarkDown', '/text\/(x-)?markdown/'); + $this->registerCoreProvider('OC\Preview\Image', '/image\/(?!tiff$)(?!svg.*).*/'); + $this->registerCoreProvider('OC\Preview\MP3', '/audio\/mpeg/'); + + // SVG, Office and Bitmap require imagick + if (extension_loaded('imagick')) { + $checkImagick = new \Imagick(); + + $imagickProviders = [ + 'SVG' => ['mimetype' => '/image\/svg\+xml/', 'class' => '\OC\Preview\SVG'], + 'TIFF' => ['mimetype' => '/image\/tiff/', 'class' => '\OC\Preview\TIFF'], + 'PDF' => ['mimetype' => '/application\/pdf/', 'class' => '\OC\Preview\PDF'], + 'AI' => ['mimetype' => '/application\/illustrator/', 'class' => '\OC\Preview\Illustrator'], + 'PSD' => ['mimetype' => '/application\/x-photoshop/', 'class' => '\OC\Preview\Photoshop'], + 'EPS' => ['mimetype' => '/application\/postscript/', 'class' => '\OC\Preview\Postscript'], + 'TTF' => ['mimetype' => '/application\/(?:font-sfnt|x-font$)/', 'class' => '\OC\Preview\Font'], + ]; + + foreach ($imagickProviders as $queryFormat => $provider) { + $class = $provider['class']; + if (!in_array(trim($class, '\\'), $this->getEnabledDefaultProvider())) { + continue; + } + + if (count($checkImagick->queryFormats($queryFormat)) === 1) { + $this->registerCoreProvider($class, $provider['mimetype']); + } + } + + if (count($checkImagick->queryFormats('PDF')) === 1) { + // Office previews are currently not supported on Windows + if (!\OC_Util::runningOnWindows() && \OC_Helper::is_function_enabled('shell_exec')) { + $officeFound = is_string($this->config->getSystemValue('preview_libreoffice_path', null)); + + if (!$officeFound) { + //let's see if there is libreoffice or openoffice on this machine + $whichLibreOffice = shell_exec('command -v libreoffice'); + $officeFound = !empty($whichLibreOffice); + if (!$officeFound) { + $whichOpenOffice = shell_exec('command -v openoffice'); + $officeFound = !empty($whichOpenOffice); + } + } + + if ($officeFound) { + $this->registerCoreProvider('\OC\Preview\MSOfficeDoc', '/application\/msword/'); + $this->registerCoreProvider('\OC\Preview\MSOffice2003', '/application\/vnd.ms-.*/'); + $this->registerCoreProvider('\OC\Preview\MSOffice2007', '/application\/vnd.openxmlformats-officedocument.*/'); + $this->registerCoreProvider('\OC\Preview\OpenDocument', '/application\/vnd.oasis.opendocument.*/'); + $this->registerCoreProvider('\OC\Preview\StarOffice', '/application\/vnd.sun.xml.*/'); + } + } + } + } + + // Video requires avconv or ffmpeg and is therefor + // currently not supported on Windows. + if (in_array('OC\Preview\Movie', $this->getEnabledDefaultProvider()) && !\OC_Util::runningOnWindows()) { + $avconvBinary = \OC_Helper::findBinaryPath('avconv'); + $ffmpegBinary = ($avconvBinary) ? null : \OC_Helper::findBinaryPath('ffmpeg'); + + if ($avconvBinary || $ffmpegBinary) { + // FIXME // a bit hacky but didn't want to use subclasses + \OC\Preview\Movie::$avconvBinary = $avconvBinary; + \OC\Preview\Movie::$ffmpegBinary = $ffmpegBinary; + + $this->registerCoreProvider('\OC\Preview\Movie', '/video\/.*/'); + } + } } } diff --git a/lib/private/server.php b/lib/private/server.php index c55817bb6b3..fd7a2bea2d1 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -12,6 +12,7 @@ use OC\Diagnostics\NullQueryLogger; use OC\Diagnostics\EventLogger; use OC\Diagnostics\QueryLogger; use OC\Mail\Mailer; +use OC\Memcache\ArrayCache; use OC\Security\CertificateManager; use OC\Files\Node\Root; use OC\Files\View; @@ -44,8 +45,8 @@ class Server extends SimpleContainer implements IServerContainer { $this->registerService('ContactsManager', function ($c) { return new ContactsManager(); }); - $this->registerService('PreviewManager', function ($c) { - return new PreviewManager(); + $this->registerService('PreviewManager', function (Server $c) { + return new PreviewManager($c->getConfig()); }); $this->registerService('TagMapper', function(Server $c) { return new TagMapper($c->getDatabaseConnection()); @@ -159,17 +160,25 @@ class Server extends SimpleContainer implements IServerContainer { $this->registerService('UserCache', function ($c) { return new UserCache(); }); - $this->registerService('MemCacheFactory', function ($c) { + $this->registerService('MemCacheFactory', function (Server $c) { $config = $c->getConfig(); - $v = \OC_App::getAppVersions(); - $v['core'] = implode('.', \OC_Util::getVersion()); - $version = implode(',', $v); - $instanceId = \OC_Util::getInstanceId(); - $path = \OC::$SERVERROOT; - $prefix = md5($instanceId.'-'.$version.'-'.$path); - return new \OC\Memcache\Factory($prefix, - $config->getSystemValue('memcache.local', null), - $config->getSystemValue('memcache.distributed', null) + + if($config->getSystemValue('installed', false)) { + $v = \OC_App::getAppVersions(); + $v['core'] = implode('.', \OC_Util::getVersion()); + $version = implode(',', $v); + $instanceId = \OC_Util::getInstanceId(); + $path = \OC::$SERVERROOT; + $prefix = md5($instanceId.'-'.$version.'-'.$path); + return new \OC\Memcache\Factory($prefix, + $config->getSystemValue('memcache.local', null), + $config->getSystemValue('memcache.distributed', null) + ); + } + + return new \OC\Memcache\Factory('', + new ArrayCache(), + new ArrayCache() ); }); $this->registerService('ActivityManager', function ($c) { diff --git a/lib/private/session/internal.php b/lib/private/session/internal.php index 8fda6b3b3ee..acd93630f40 100644 --- a/lib/private/session/internal.php +++ b/lib/private/session/internal.php @@ -18,7 +18,9 @@ namespace OC\Session; class Internal extends Session { public function __construct($name) { session_name($name); + set_error_handler(array($this, 'trapError')); session_start(); + restore_error_handler(); if (!isset($_SESSION)) { throw new \Exception('Failed to start session'); } @@ -82,7 +84,11 @@ class Internal extends Session { throw new \Exception('The session cannot be reopened - reopen() is ony to be used in unit testing.'); } - private function validateSession() { + public function trapError($errorNumber, $errorString) { + throw new \ErrorException($errorString); + } + + private function validateSession() { if ($this->sessionClosed) { throw new \Exception('Session has been closed - no further changes to the session as allowed'); } diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 974ebf41f93..dff3af56f40 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -1097,9 +1097,17 @@ class Share extends \OC\Share\Constants { */ public static function setExpirationDate($itemType, $itemSource, $date, $shareTime = null) { $user = \OC_User::getUser(); + $l = \OC::$server->getL10N('lib'); if ($date == '') { - $date = null; + if (\OCP\Util::isDefaultExpireDateEnforced()) { + $warning = 'Cannot clear expiration date. Shares are required to have an expiration date.'; + $warning_t = $l->t('Cannot clear expiration date. Shares are required to have an expiration date.'); + \OCP\Util::writeLog('OCP\Share', $warning, \OCP\Util::WARN); + throw new \Exception($warning_t); + } else { + $date = null; + } } else { $date = self::validateExpireDate($date, $shareTime, $itemType, $itemSource); } diff --git a/lib/private/template.php b/lib/private/template.php index b0d212c6f53..e6b76cc664e 100644 --- a/lib/private/template.php +++ b/lib/private/template.php @@ -217,6 +217,7 @@ class OC_Template extends \OC\Template\Base { public static function printExceptionErrorPage(Exception $exception) { $request = \OC::$server->getRequest(); $content = new \OC_Template('', 'exception', 'error', false); + $content->assign('errorClass', get_class($exception)); $content->assign('errorMsg', $exception->getMessage()); $content->assign('errorCode', $exception->getCode()); $content->assign('file', $exception->getFile()); diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php index 3220d9d969c..3f8422b9f0b 100644 --- a/lib/private/templatelayout.php +++ b/lib/private/templatelayout.php @@ -242,7 +242,11 @@ class OC_TemplateLayout extends OC_Template { private static function hashFileNames($files) { foreach($files as $i => $file) { - $files[$i] = self::convertToRelativePath($file[0]).'/'.$file[2]; + try { + $files[$i] = self::convertToRelativePath($file[0]).'/'.$file[2]; + } catch (\Exception $e) { + $files[$i] = $file[0].'/'.$file[2]; + } } sort($files); diff --git a/lib/private/updater.php b/lib/private/updater.php index 4d813ee3d39..419cd7db6c0 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -10,6 +10,7 @@ namespace OC; use OC\Hooks\BasicEmitter; use OC_App; +use OC_Installer; use OC_Util; use OCP\IConfig; use OC\Setup; @@ -233,9 +234,14 @@ class Updater extends BasicEmitter { if ($this->updateStepEnabled) { $this->doCoreUpgrade(); - $this->checkAppsRequirements(); + // update all shipped apps + $disabledApps = $this->checkAppsRequirements(); $this->doAppUpgrade(); + // upgrade appstore apps + $this->upgradeAppStoreApps($disabledApps); + + // post-upgrade repairs $repair = new Repair(Repair::getRepairSteps()); $this->emitRepairMessages($repair); @@ -356,6 +362,7 @@ class Updater extends BasicEmitter { $isCoreUpgrade = $this->isCodeUpgrade(); $apps = OC_App::getEnabledApps(); $version = OC_Util::getVersion(); + $disabledApps = []; foreach ($apps as $app) { // check if the app is compatible with this version of ownCloud $info = OC_App::getAppInfo($app); @@ -378,8 +385,10 @@ class Updater extends BasicEmitter { // disable any other 3rd party apps \OC_App::disable($app); + $disabledApps[]= $app; $this->emit('\OC\Updater', 'thirdPartyAppDisabled', array($app)); } + return $disabledApps; } private function isCodeUpgrade() { @@ -390,5 +399,16 @@ class Updater extends BasicEmitter { } return false; } + + private function upgradeAppStoreApps($disabledApps) { + foreach($disabledApps as $app) { + if (OC_Installer::isUpdateAvailable($app)) { + $ocsId = \OC::$server->getConfig()->getAppValue($app, 'ocsid', ''); + + $this->emit('\OC\Updater', 'upgradeAppStoreApp', array($app)); + OC_Installer::updateAppByOCSId($ocsId); + } + } + } } diff --git a/lib/private/util.php b/lib/private/util.php index 11366d450a9..a048996da6e 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -98,6 +98,14 @@ class OC_Util { return false; } + \OC\Files\Filesystem::addStorageWrapper('mount_options', function($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) { + if($storage->instanceOfStorage('\OC\Files\Storage\Common')) { + /** @var \OC\Files\Storage\Common $storage */ + $storage->setMountOptions($mount->getOptions()); + } + return $storage; + }); + //if we aren't logged in, there is no use to set up the filesystem if ($user != "") { \OC\Files\Filesystem::addStorageWrapper('oc_quota', function ($mountPoint, $storage) { @@ -127,9 +135,6 @@ class OC_Util { //jail the user into his "home" directory \OC\Files\Filesystem::init($user, $userDir); - $fileOperationProxy = new OC_FileProxy_FileOperations(); - OC_FileProxy::register($fileOperationProxy); - //trigger creation of user home and /files folder \OC::$server->getUserFolder($user); diff --git a/lib/public/appframework/db/mapper.php b/lib/public/appframework/db/mapper.php index 5143547c8e8..9a5d6e819b9 100644 --- a/lib/public/appframework/db/mapper.php +++ b/lib/public/appframework/db/mapper.php @@ -26,7 +26,8 @@ namespace OCP\AppFramework\Db; -use \OCP\IDBConnection; +use OCP\IDBConnection; +use OCP\IDb; /** @@ -183,6 +184,31 @@ abstract class Mapper { return $entity; } + /** + * Checks if an array is associative + * @param array $array + * @return bool true if associative + */ + private function isAssocArray(array $array) { + return array_values($array) !== $array; + } + + /** + * Returns the correct PDO constant based on the value type + * @param $value + * @return PDO constant + */ + private function getPDOType($value) { + switch (gettype($value)) { + case 'integer': + return \PDO::PARAM_INT; + case 'boolean': + return \PDO::PARAM_BOOL; + default: + return \PDO::PARAM_STR; + } + } + /** * Runs an sql query @@ -193,32 +219,37 @@ abstract class Mapper { * @return \PDOStatement the database query result */ protected function execute($sql, array $params=[], $limit=null, $offset=null){ - $query = $this->db->prepare($sql, $limit, $offset); - - $index = 1; // bindParam is 1 indexed - foreach($params as $param) { - - switch (gettype($param)) { - case 'integer': - $pdoConstant = \PDO::PARAM_INT; - break; - - case 'boolean': - $pdoConstant = \PDO::PARAM_BOOL; - break; + if ($this->db instanceof IDb) { + $query = $this->db->prepareQuery($sql, $limit, $offset); + } else { + $query = $this->db->prepare($sql, $limit, $offset); + } - default: - $pdoConstant = \PDO::PARAM_STR; - break; + if ($this->isAssocArray($params)) { + foreach ($params as $key => $param) { + $pdoConstant = $this->getPDOType($param); + $query->bindValue($key, $param, $pdoConstant); } + } else { + $index = 1; // bindParam is 1 indexed + foreach ($params as $param) { + $pdoConstant = $this->getPDOType($param); + $query->bindValue($index, $param, $pdoConstant); + $index++; + } + } - $query->bindValue($index, $param, $pdoConstant); + $result = $query->execute(); - $index++; + // this is only for backwards compatibility reasons and can be removed + // in owncloud 10. IDb returns a StatementWrapper from execute, PDO, + // Doctrine and IDbConnection don't so this needs to be done in order + // to stay backwards compatible for the things that rely on the + // StatementWrapper being returned + if ($result instanceof \OC_DB_StatementWrapper) { + return $result; } - $query->execute(); - return $query; } diff --git a/lib/public/files/mount/imountpoint.php b/lib/public/files/mount/imountpoint.php index af7819ae160..2ec0cca1dce 100644 --- a/lib/public/files/mount/imountpoint.php +++ b/lib/public/files/mount/imountpoint.php @@ -64,4 +64,11 @@ interface IMountPoint { * @return mixed */ public function getOption($name, $default); + + /** + * Get all options for the mount + * + * @return array + */ + public function getOptions(); } diff --git a/lib/public/files/storage/istoragefactory.php b/lib/public/files/storage/istoragefactory.php index 50c844af2e6..7d4fa55e418 100644 --- a/lib/public/files/storage/istoragefactory.php +++ b/lib/public/files/storage/istoragefactory.php @@ -7,6 +7,7 @@ */ namespace OCP\Files\Storage; +use OCP\Files\Mount\IMountPoint; /** * Creates storage instances and manages and applies storage wrappers @@ -25,10 +26,10 @@ interface IStorageFactory { public function addStorageWrapper($wrapperName, $callback); /** - * @param string|boolean $mountPoint + * @param \OCP\Files\Mount\IMountPoint $mountPoint * @param string $class * @param array $arguments * @return \OCP\Files\Storage */ - public function getInstance($mountPoint, $class, $arguments); + public function getInstance(IMountPoint $mountPoint, $class, $arguments); } diff --git a/lib/public/iavatar.php b/lib/public/iavatar.php index 8f432c23fb8..984fe1075b4 100644 --- a/lib/public/iavatar.php +++ b/lib/public/iavatar.php @@ -16,7 +16,7 @@ interface IAvatar { /** * get the users avatar * @param int $size size in px of the avatar, avatars are square, defaults to 64 - * @return boolean|\OC_Image containing the avatar or false if there's no image + * @return boolean|\OCP\IImage containing the avatar or false if there's no image */ function get($size = 64); @@ -29,7 +29,7 @@ interface IAvatar { /** * sets the users avatar - * @param \OC_Image|resource|string $data OC_Image, imagedata or path to set a new avatar + * @param \OCP\IImage|resource|string $data An image object, imagedata or path to set a new avatar * @throws \Exception if the provided file is not a jpg or png image * @throws \Exception if the provided image is not valid * @throws \OC\NotSquareException if the image is not square diff --git a/lib/public/iimage.php b/lib/public/iimage.php new file mode 100644 index 00000000000..01d8e101330 --- /dev/null +++ b/lib/public/iimage.php @@ -0,0 +1,146 @@ +<?php +/** + * ownCloud + * + * @author Joas Schilling + * @copyright 2015 Joas Schilling nickvergessen@owncloud.com + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCP; + +/** + * Class for basic image manipulation + */ +interface IImage { + /** + * Determine whether the object contains an image resource. + * + * @return bool + */ + public function valid(); + + /** + * Returns the MIME type of the image or an empty string if no image is loaded. + * + * @return string + */ + public function mimeType(); + + /** + * Returns the width of the image or -1 if no image is loaded. + * + * @return int + */ + public function width(); + + /** + * Returns the height of the image or -1 if no image is loaded. + * + * @return int + */ + public function height(); + + /** + * Returns the width when the image orientation is top-left. + * + * @return int + */ + public function widthTopLeft(); + + /** + * Returns the height when the image orientation is top-left. + * + * @return int + */ + public function heightTopLeft(); + + /** + * Outputs the image. + * + * @param string $mimeType + * @return bool + */ + public function show($mimeType = null); + + /** + * Saves the image. + * + * @param string $filePath + * @param string $mimeType + * @return bool + */ + public function save($filePath = null, $mimeType = null); + + /** + * @return resource Returns the image resource in any. + */ + public function resource(); + + /** + * @return string Returns the raw image data. + */ + public function data(); + + /** + * (I'm open for suggestions on better method name ;) + * Get the orientation based on EXIF data. + * + * @return int The orientation or -1 if no EXIF data is available. + */ + public function getOrientation(); + + /** + * (I'm open for suggestions on better method name ;) + * Fixes orientation based on EXIF data. + * + * @return bool. + */ + public function fixOrientation(); + + /** + * Resizes the image preserving ratio. + * + * @param integer $maxSize The maximum size of either the width or height. + * @return bool + */ + public function resize($maxSize); + + /** + * @param int $width + * @param int $height + * @return bool + */ + public function preciseResize($width, $height); + + /** + * Crops the image to the middle square. If the image is already square it just returns. + * + * @param int $size maximum size for the result (optional) + * @return bool for success or failure + */ + public function centerCrop($size = 0); + + /** + * Crops the image from point $x$y with dimension $wx$h. + * + * @param int $x Horizontal position + * @param int $y Vertical position + * @param int $w Width + * @param int $h Height + * @return bool for success or failure + */ + public function crop($x, $y, $w, $h); + + /** + * Resizes the image to fit within a boundary while preserving ratio. + * + * @param integer $maxWidth + * @param integer $maxHeight + * @return bool + */ + public function fitIn($maxWidth, $maxHeight); +} diff --git a/lib/public/ipreview.php b/lib/public/ipreview.php index cc756ef80d3..202b0d03948 100644 --- a/lib/public/ipreview.php +++ b/lib/public/ipreview.php @@ -36,8 +36,30 @@ namespace OCP; /** * This class provides functions to render and show thumbnails and previews of files */ -interface IPreview -{ +interface IPreview { + /** + * In order to improve lazy loading a closure can be registered which will be + * called in case preview providers are actually requested + * + * $callable has to return an instance of \OCP\Preview\IProvider + * + * @param string $mimeTypeRegex Regex with the mime types that are supported by this provider + * @param \Closure $callable + * @return void + */ + public function registerProvider($mimeTypeRegex, \Closure $callable); + + /** + * Get all providers + * @return array + */ + public function getProviders(); + + /** + * Does the manager have any providers + * @return bool + */ + public function hasProviders(); /** * Return a preview of a file @@ -45,9 +67,9 @@ interface IPreview * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image * @param boolean $scaleUp Scale smaller images up to the thumbnail size or not. Might look ugly - * @return \OCP\Image + * @return \OCP\IImage */ - function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false); + public function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false); /** @@ -55,7 +77,7 @@ interface IPreview * @param string $mimeType * @return boolean */ - function isMimeSupported($mimeType = '*'); + public function isMimeSupported($mimeType = '*'); /** * Check if a preview can be generated for a file @@ -63,5 +85,5 @@ interface IPreview * @param \OCP\Files\FileInfo $file * @return bool */ - function isAvailable($file); + public function isAvailable(\OCP\Files\FileInfo $file); } diff --git a/lib/public/preview/iprovider.php b/lib/public/preview/iprovider.php new file mode 100644 index 00000000000..4318ecd37ac --- /dev/null +++ b/lib/public/preview/iprovider.php @@ -0,0 +1,39 @@ +<?php +/** + * ownCloud + * + * @author Joas Schilling + * @copyright 2015 Joas Schilling nickvergessen@owncloud.com + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +namespace OCP\Preview; + +interface IProvider { + /** + * @return string Regex with the mimetypes that are supported by this provider + */ + public function getMimeType(); + + /** + * Check if a preview can be generated for $path + * + * @param \OCP\Files\FileInfo $file + * @return bool + */ + public function isAvailable(\OCP\Files\FileInfo $file); + + /** + * get thumbnail for file at path $path + * + * @param string $path Path of file + * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image + * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image + * @param bool $scalingup Disable/Enable upscaling of previews + * @param \OC\Files\View $fileview fileview object of user folder + * @return bool|\OCP\IImage false if no preview was generated + */ + public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview); +} diff --git a/lib/repair/repairmimetypes.php b/lib/repair/repairmimetypes.php index ad55c63c21a..e9ce4c73a42 100644 --- a/lib/repair/repairmimetypes.php +++ b/lib/repair/repairmimetypes.php @@ -17,7 +17,7 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { public function getName() { return 'Repair mime types'; } - + private static function existsStmt() { return \OC_DB::prepare(' SELECT count(`mimetype`) @@ -51,14 +51,14 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { ) WHERE `mimetype` = ? '); } - + private static function deleteStmt() { return \OC_DB::prepare(' DELETE FROM `*PREFIX*mimetypes` WHERE `id` = ? '); - } - + } + private static function updateByNameStmt() { return \OC_DB::prepare(' UPDATE `*PREFIX*filecache` @@ -66,10 +66,10 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ? - ) WHERE `name` LIKE ? + ) WHERE `name` ILIKE ? '); } - + private function repairMimetypes($wrongMimetypes) { foreach ($wrongMimetypes as $wrong => $correct) { // do we need to remove a wrong mimetype? @@ -81,8 +81,8 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { $result = \OC_DB::executeAudited(self::existsStmt(), array($correct)); $exists = $result->fetchOne(); - if ( ! is_null($correct) ) { - if ( ! $exists ) { + if (!is_null($correct)) { + if (!$exists) { // insert mimetype \OC_DB::executeAudited(self::insertStmt(), array($correct)); } @@ -90,27 +90,27 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { // change wrong mimetype to correct mimetype in filecache \OC_DB::executeAudited(self::updateWrongStmt(), array($correct, $wrongId)); } - + // delete wrong mimetype \OC_DB::executeAudited(self::deleteStmt(), array($wrongId)); } } } - + private function updateMimetypes($updatedMimetypes) { - - foreach ($updatedMimetypes as $extension => $mimetype ) { + + foreach ($updatedMimetypes as $extension => $mimetype) { $result = \OC_DB::executeAudited(self::existsStmt(), array($mimetype)); $exists = $result->fetchOne(); - if ( ! $exists ) { + if (!$exists) { // insert mimetype \OC_DB::executeAudited(self::insertStmt(), array($mimetype)); } // change mimetype for files with x extension - \OC_DB::executeAudited(self::updateByNameStmt(), array($mimetype, '%.'.$extension)); + \OC_DB::executeAudited(self::updateByNameStmt(), array($mimetype, '%.' . $extension)); } } @@ -132,9 +132,9 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { // separate doc from docx etc self::updateMimetypes($updatedMimetypes); - + } - + private function fixApkMimeType() { $updatedMimetypes = array( 'apk' => 'application/vnd.android.package-archive', @@ -142,7 +142,7 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { self::updateMimetypes($updatedMimetypes); } - + private function fixFontsMimeTypes() { // update wrong mimetypes $wrongMimetypes = array( @@ -152,7 +152,7 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { ); self::repairMimetypes($wrongMimetypes); - + $updatedMimetypes = array( 'ttf' => 'application/font-sfnt', 'otf' => 'application/font-sfnt', @@ -161,7 +161,7 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { self::updateMimetypes($updatedMimetypes); } - + private function fixPostscriptMimeType() { $updatedMimetypes = array( 'eps' => 'application/postscript', @@ -195,6 +195,15 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { self::updateMimetypes($updatedMimetypes); } + private function introduce3dImagesMimeType() { + $updatedMimetypes = array( + 'jps' => 'image/jpeg', + 'mpo' => 'image/jpeg', + ); + + self::updateMimetypes($updatedMimetypes); + } + /** * Fix mime types */ @@ -202,15 +211,15 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { if ($this->fixOfficeMimeTypes()) { $this->emit('\OC\Repair', 'info', array('Fixed office mime types')); } - + if ($this->fixApkMimeType()) { $this->emit('\OC\Repair', 'info', array('Fixed APK mime type')); } - + if ($this->fixFontsMimeTypes()) { $this->emit('\OC\Repair', 'info', array('Fixed fonts mime types')); } - + if ($this->fixPostscriptMimeType()) { $this->emit('\OC\Repair', 'info', array('Fixed Postscript mime types')); } @@ -218,5 +227,9 @@ class RepairMimeTypes extends BasicEmitter implements \OC\RepairStep { if ($this->introduceRawMimeType()) { $this->emit('\OC\Repair', 'info', array('Fixed Raw mime types')); } + + if ($this->introduce3dImagesMimeType()) { + $this->emit('\OC\Repair', 'info', array('Fixed 3D images mime types')); + } } } |