Merge pull request #546 from owncloud/cleanup

Make classes non-static
pull/1/head
VicDeo 9 years ago
commit d9f17872d4

@ -53,7 +53,7 @@ if (isset($request->server['REQUEST_URI'])) {
} }
} }
if (Config::getConverter() !== 'off'){ if ($c->query('AppConfig')->isConverterEnabled()){
$docFilter = new Office( $docFilter = new Office(
[ [
'read' => 'read' =>

@ -17,6 +17,7 @@ use \OCA\Documents\Controller\UserController;
use \OCA\Documents\Controller\SessionController; use \OCA\Documents\Controller\SessionController;
use \OCA\Documents\Controller\DocumentController; use \OCA\Documents\Controller\DocumentController;
use \OCA\Documents\Controller\SettingsController; use \OCA\Documents\Controller\SettingsController;
use \OCA\Documents\AppConfig;
class Application extends App { class Application extends App {
public function __construct (array $urlParams = array()) { public function __construct (array $urlParams = array()) {
@ -54,12 +55,18 @@ class Application extends App {
return new SettingsController( return new SettingsController(
$c->query('AppName'), $c->query('AppName'),
$c->query('Request'), $c->query('Request'),
$c->query('CoreConfig'),
$c->query('L10N'), $c->query('L10N'),
$c->query('AppConfig'),
$c->query('UserId') $c->query('UserId')
); );
}); });
$container->registerService('AppConfig', function($c) {
return new AppConfig(
$c->query('CoreConfig')
);
});
/** /**
* Core * Core
*/ */

@ -19,10 +19,12 @@ $application->registerRoutes($this, [
['name' => 'user#disconnectUser', 'url' => 'ajax/user/disconnect', 'verb' => 'POST'], ['name' => 'user#disconnectUser', 'url' => 'ajax/user/disconnect', 'verb' => 'POST'],
['name' => 'user#disconnectGuest', 'url' => 'ajax/user/disconnectGuest', 'verb' => 'POST'], ['name' => 'user#disconnectGuest', 'url' => 'ajax/user/disconnectGuest', 'verb' => 'POST'],
//session //session
['name' => 'session#joinAsUser', 'url' => 'ajax/session/joinasuser/{fileId}', 'verb' => 'POST'], ['name' => 'session#join', 'url' => 'session/user/join/{fileId}', 'verb' => 'POST'],
['name' => 'session#joinAsGuest', 'url' => 'ajax/session/joinasguest/{token}', 'verb' => 'POST'], ['name' => 'session#poll', 'url' => 'session/user/poll', 'verb' => 'POST'],
['name' => 'session#save', 'url' => 'ajax/session/save', 'verb' => 'POST'], ['name' => 'session#save', 'url' => 'session/user/save', 'verb' => 'POST'],
['name' => 'session#poll', 'url' => 'ajax/otpoll.php', 'verb' => 'POST'], ['name' => 'session#joinAsGuest', 'url' => 'session/guest/join/{token}', 'verb' => 'POST'],
['name' => 'session#pollAsGuest', 'url' => 'session/guest/poll/{token}', 'verb' => 'POST'],
['name' => 'session#saveAsGuest', 'url' => 'session/guest/save/{token}', 'verb' => 'POST'],
//documents //documents
['name' => 'document#index', 'url' => 'index', 'verb' => 'GET'], ['name' => 'document#index', 'url' => 'index', 'verb' => 'GET'],
['name' => 'document#create', 'url' => 'ajax/documents/create', 'verb' => 'POST'], ['name' => 'document#create', 'url' => 'ajax/documents/create', 'verb' => 'POST'],

@ -16,7 +16,6 @@ use \OCP\IRequest;
use \OCP\AppFramework\Http; use \OCP\AppFramework\Http;
use \OCP\AppFramework\Http\JSONResponse; use \OCP\AppFramework\Http\JSONResponse;
use \OCA\Documents\Db; use \OCA\Documents\Db;
use \OCA\Documents\File; use \OCA\Documents\File;
use \OCA\Documents\Helper; use \OCA\Documents\Helper;
@ -40,6 +39,7 @@ class SessionController extends Controller{
protected $uid; protected $uid;
protected $logger; protected $logger;
protected $shareToken;
public function __construct($appName, IRequest $request, $logger, $uid){ public function __construct($appName, IRequest $request, $logger, $uid){
parent::__construct($appName, $request); parent::__construct($appName, $request);
@ -62,13 +62,11 @@ class SessionController extends Controller{
$response = array_merge( $response = array_merge(
Db\Session::start($uid, $file), Db\Session::start($uid, $file),
array('status'=>'success') [ 'status'=>'success' ]
); );
} catch (\Exception $e){ } catch (\Exception $e){
$this->logger->warning('Starting a session failed. Reason: ' . $e->getMessage(), array('app' => $this->appName)); $this->logger->warning('Starting a session failed. Reason: ' . $e->getMessage(), ['app' => $this->appName]);
$response = array ( $response = [ 'status'=>'error' ];
'status'=>'error'
);
} }
return $response; return $response;
@ -76,8 +74,27 @@ class SessionController extends Controller{
/** /**
* @NoAdminRequired * @NoAdminRequired
* @PublicPage
*/
public function pollAsGuest($command, $args){
$this->shareToken = $this->request->getParam('token');
return $this->poll($command, $args);
}
/**
* Store the document content to its origin
* @NoAdminRequired
* @PublicPage
*/ */
public function joinAsUser($fileId){ public function saveAsGuest(){
$this->shareToken = $this->request->getParam('token');
return $this->save();
}
/**
* @NoAdminRequired
*/
public function join($fileId){
try { try {
$view = \OC\Files\Filesystem::getView(); $view = \OC\Files\Filesystem::getView();
$path = $view->getPath($fileId); $path = $view->getPath($fileId);
@ -87,20 +104,18 @@ class SessionController extends Controller{
$response = Db\Session::start($this->uid, $file); $response = Db\Session::start($this->uid, $file);
} else { } else {
$info = $view->getFileInfo($path); $info = $view->getFileInfo($path);
$response = array( $response = [
'permissions' => $info['permissions'], 'permissions' => $info['permissions'],
'id' => $fileId 'id' => $fileId
); ];
} }
$response = array_merge( $response = array_merge(
$response, $response,
array('status'=>'success') [ 'status'=>'success' ]
); );
} catch (\Exception $e){ } catch (\Exception $e){
$this->logger->warning('Starting a session failed. Reason: ' . $e->getMessage(), array('app' => $this->appName)); $this->logger->warning('Starting a session failed. Reason: ' . $e->getMessage(), [ 'app' => $this->appName ]);
$response = array ( $response = [ 'status'=>'error' ];
'status'=>'error'
);
} }
return $response; return $response;
@ -108,41 +123,24 @@ class SessionController extends Controller{
/** /**
* @NoAdminRequired * @NoAdminRequired
* @PublicPage
*/ */
public function poll($command, $args){ public function poll($command, $args){
$response = new JSONResponse(); $response = new JSONResponse();
try{ try{
$esId = isset($args['es_id']) ? $args['es_id'] : null; $esId = isset($args['es_id']) ? $args['es_id'] : null;
$session = $this->loadSession($esId);
$session = new Db\Session();
$session->load($esId);
$memberId = isset($args['member_id']) ? $args['member_id'] : null; $memberId = isset($args['member_id']) ? $args['member_id'] : null;
$member = new Db\Member(); $member = $this->loadMember($memberId);
$member->load($memberId);
if (!$member->getIsGuest()){
\OCP\JSON::checkLoggedIn();
}
try { $this->validateSession($session);
new File($session->getFileId());
} catch (\Exception $e){
$this->logger->warning('Error. Session no longer exists. ' . $e->getMessage(), array('app' => $this->appName));
$ex = new BadRequestException();
$ex->setBody(
implode(',', $this->request->getParams())
);
throw $ex;
}
switch ($command){ switch ($command){
case 'sync_ops': case 'sync_ops':
$seqHead = (string) isset($args['seq_head']) ? $args['seq_head'] : null; $seqHead = (string) isset($args['seq_head']) ? $args['seq_head'] : null;
if (!is_null($seqHead)){ if (!is_null($seqHead)){
$ops = isset($args['client_ops']) ? $args['client_ops'] : array(); $ops = isset($args['client_ops']) ? $args['client_ops'] : [];
$op = new Db\Op(); $op = new Db\Op();
$currentHead = $op->getHeadSeq($esId); $currentHead = $op->getHeadSeq($esId);
@ -177,33 +175,24 @@ class SessionController extends Controller{
} catch (BadRequestException $e){ } catch (BadRequestException $e){
$response->setStatus(Http::STATUS_BAD_REQUEST); $response->setStatus(Http::STATUS_BAD_REQUEST);
$response->setData( $response->setData(
array('err' => 'bad request:[' . $e->getBody() . ']') [ 'err' => 'bad request:[' . $e->getBody() . ']' ]
); );
} }
return $response; return $response;
} }
/** /**
* @NoAdminRequired
* @PublicPage
* Store the document content to its origin * Store the document content to its origin
* @NoAdminRequired
*/ */
public function save(){ public function save(){
$response = new JSONResponse();
try { try {
$esId = $this->request->server['HTTP_WEBODF_SESSION_ID']; $esId = $this->request->server['HTTP_WEBODF_SESSION_ID'];
if (!$esId){ $session = $this->loadSession($esId);
throw new \Exception('Session id can not be empty');
}
$memberId = $this->request->server['HTTP_WEBODF_MEMBER_ID']; $memberId = $this->request->server['HTTP_WEBODF_MEMBER_ID'];
$currentMember = new Db\Member(); $currentMember = $this->loadMember($memberId, $esId);
$currentMember->load($memberId);
//check if member belongs to the session
if ($esId != $currentMember->getEsId()){
throw new \Exception($memberId . ' does not belong to session ' . $esId);
}
// Extra info for future usage // Extra info for future usage
// $sessionRevision = $this->request->server['HTTP_WEBODF_SESSION_REVISION']; // $sessionRevision = $this->request->server['HTTP_WEBODF_SESSION_REVISION'];
@ -215,13 +204,6 @@ class SessionController extends Controller{
} }
$content = stream_get_contents($stream); $content = stream_get_contents($stream);
$session = new Db\Session();
$session->load($esId);
if (!$session->getEsId()){
throw new \Exception('Session does not exist');
}
try { try {
if ($currentMember->getIsGuest()){ if ($currentMember->getIsGuest()){
$file = File::getByShareToken($currentMember->getToken()); $file = File::getByShareToken($currentMember->getToken());
@ -229,7 +211,8 @@ class SessionController extends Controller{
$file = new File($session->getFileId()); $file = new File($session->getFileId());
} }
list($view, $path) = $file->getOwnerViewAndPath(true); $view = $file->getOwnerView(true);
$path = $file->getPath(true);
} catch (\Exception $e){ } catch (\Exception $e){
//File was deleted or unshared. We need to save content as new file anyway //File was deleted or unshared. We need to save content as new file anyway
//Sorry, but for guests it would be lost :( //Sorry, but for guests it would be lost :(
@ -256,7 +239,7 @@ class SessionController extends Controller{
$memberCount = count($memberIds) - 1; $memberCount = count($memberIds) - 1;
if ($view->file_exists($path)){ if ($view->file_exists($path)){
$currentHash = sha1($view->file_get_contents($path)); $currentHash = $view->hash('sha1', $path, false);
if (!Helper::isVersionsEnabled() && $currentHash !== $session->getGenesisHash()){ if (!Helper::isVersionsEnabled() && $currentHash !== $session->getGenesisHash()){
// Original file was modified externally. Save to a new one // Original file was modified externally. Save to a new one
@ -274,7 +257,7 @@ class SessionController extends Controller{
// Not a last user // Not a last user
if ($memberCount>0){ if ($memberCount>0){
// Update genesis hash to prevent conflicts // Update genesis hash to prevent conflicts
$this->logger->debug('Update hash', array('app' => $this->appName)); $this->logger->debug('Update hash', [ 'app' => $this->appName ]);
$session->updateGenesisHash($esId, sha1($data['content'])); $session->updateGenesisHash($esId, sha1($data['content']));
} else { } else {
// Last user. Kill session data // Last user. Kill session data
@ -283,13 +266,56 @@ class SessionController extends Controller{
$view->touch($path); $view->touch($path);
} }
$response = array('status'=>'success'); $response->setData(['status'=>'success']);
} catch (\Exception $e){ } catch (\Exception $e){
$this->logger->warning('Saving failed. Reason:' . $e->getMessage(), array('app' => $this->appName)); $response->setStatus(Http::STATUS_INTERNAL_SERVER_ERROR);
\OC_Response::setStatus(500); $response->setData([]);
$response = array(); $this->logger->warning('Saving failed. Reason:' . $e->getMessage(), [ 'app' => $this->appName ]);
} }
return $response; return $response;
} }
protected function validateSession($session){
try {
if (is_null($this->shareToken)) {
new File($session->getFileId());
} else {
File::getByShareToken($this->shareToken);
}
} catch (\Exception $e){
$this->logger->warning('Error. Session no longer exists. ' . $e->getMessage(), [ 'app' => $this->appName ]);
$ex = new BadRequestException();
$ex->setBody(
implode(',', $this->request->getParams())
);
throw $ex;
}
}
protected function loadSession($esId){
if (!$esId){
throw new \Exception('Session id can not be empty');
}
$session = new Db\Session();
$session->load($esId);
if (!$session->getEsId()){
throw new \Exception('Session does not exist');
}
return $session;
}
protected function loadMember($memberId, $expectedEsId = null){
if (!$memberId){
throw new \Exception('Member id can not be empty');
}
$member = new Db\Member();
$member->load($memberId);
//check if member belongs to the session
if (!is_null($expectedEsId) && $expectedEsId !== $member->getEsId()){
throw new \Exception($memberId . ' does not belong to session ' . $expectedEsId);
}
return $member;
}
} }

@ -13,26 +13,25 @@ namespace OCA\Documents\Controller;
use \OCP\AppFramework\Controller; use \OCP\AppFramework\Controller;
use \OCP\IRequest; use \OCP\IRequest;
use \OCP\IConfig;
use \OCP\IL10N; use \OCP\IL10N;
use \OCP\AppFramework\Http\JSONResponse; use \OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Http\TemplateResponse;
use OCA\Documents\AppConfig;
use OCA\Documents\Converter; use OCA\Documents\Converter;
use OCA\Documents\Config;
use OCA\Documents\Filter; use OCA\Documents\Filter;
class SettingsController extends Controller{ class SettingsController extends Controller{
private $userId; private $userId;
private $settings;
private $l10n; private $l10n;
private $appConfig;
public function __construct($appName, IRequest $request, IConfig $settings, IL10N $l10n, $userId){ public function __construct($appName, IRequest $request, IL10N $l10n, AppConfig $appConfig, $userId){
parent::__construct($appName, $request); parent::__construct($appName, $request);
$this->userId = $userId; $this->userId = $userId;
$this->settings = $settings;
$this->l10n = $l10n; $this->l10n = $l10n;
$this->appConfig = $appConfig;
} }
/** /**
@ -51,9 +50,9 @@ class SettingsController extends Controller{
*/ */
public function personalIndex(){ public function personalIndex(){
return new TemplateResponse( return new TemplateResponse(
'documents', $this->appName,
'personal', 'personal',
[ 'save_path' => $this->settings->getUserValue($this->userId, 'documents', 'save_path', '/') ], [ 'save_path' => $this->appConfig->getUserValue($this->userId, 'save_path') ],
'blank' 'blank'
); );
} }
@ -63,9 +62,9 @@ class SettingsController extends Controller{
*/ */
public function settingsIndex(){ public function settingsIndex(){
return new TemplateResponse( return new TemplateResponse(
'documents', $this->appName,
'settings', 'settings',
[ 'unstable' => $this->settings->getAppValue('documents', 'unstable', 'false') ], [ 'unstable' => $this->appConfig->getAppValue('unstable') ],
'blank' 'blank'
); );
} }
@ -75,11 +74,11 @@ class SettingsController extends Controller{
*/ */
public function adminIndex(){ public function adminIndex(){
return new TemplateResponse( return new TemplateResponse(
'documents', $this->appName,
'admin', 'admin',
[ [
'converter' => Config::getConverter(), 'converter' => $this->appConfig->getAppValue('converter'),
'converter_url' => Config::getConverterUrl(), 'converter_url' => $this->appConfig->getAppValue('converter_url'),
], ],
'blank' 'blank'
); );
@ -98,7 +97,7 @@ class SettingsController extends Controller{
} }
if ($status){ if ($status){
$this->settings->setUserValue($this->userId, $this->appName, 'save_path', $savePath); $this->appConfig->setUserValue($this->userId, 'save_path', $savePath);
$response = array( $response = array(
'status' => 'success', 'status' => 'success',
'data' => array('message'=> $this->l10n->t('Directory saved successfully.')) 'data' => array('message'=> $this->l10n->t('Directory saved successfully.'))
@ -116,18 +115,18 @@ class SettingsController extends Controller{
public function setUnstable($unstable){ public function setUnstable($unstable){
if (!is_null($unstable)){ if (!is_null($unstable)){
$this->settings->setAppValue($this->appName, 'unstable', $unstable); $this->appConfig->setAppValue('unstable', $unstable);
} }
return array('status' => 'success'); return array('status' => 'success');
} }
public function setConverter($converter, $url){ public function setConverter($converter, $url){
if (!is_null($converter)){ if (!is_null($converter)){
$this->settings->setAppValue($this->appName, 'converter', $converter); $this->appConfig->setAppValue('converter', $converter);
} }
if (!is_null($url)){ if (!is_null($url)){
$this->settings->setAppValue($this->appName, 'converter_url', $url); $this->appConfig->setAppValue('converter_url', $url);
} }
$response = array( $response = array(
@ -135,7 +134,7 @@ class SettingsController extends Controller{
'data' => array('message' => (string) $this->l10n->t('Saved')) 'data' => array('message' => (string) $this->l10n->t('Saved'))
); );
$currentConverter = $this->settings->getAppValue($this->appName, 'converter', 'off'); $currentConverter = $this->appConfig->getAppValue('converter');
if ($currentConverter == 'external'){ if ($currentConverter == 'external'){
if (!Converter::checkConnection()){ if (!Converter::checkConnection()){
\OC::$server->getLogger()->warning( \OC::$server->getLogger()->warning(
@ -150,7 +149,7 @@ class SettingsController extends Controller{
} }
} elseif ($currentConverter === 'local') { } elseif ($currentConverter === 'local') {
try { try {
if (!Config::testConversion()){ if (!Converter::testConversion()){
$response = array( $response = array(
'status' => 'error', 'status' => 'error',
'data'=> 'data'=>

@ -40,8 +40,6 @@ define("owncloud/ServerFactory", [
this.createServer = function (args) { this.createServer = function (args) {
var server; var server;
args = args || {}; args = args || {};
args.url = OC.filePath('documents', 'ajax', 'otpoll.php');
args.sessionStateToFileUrl = OC.generateUrl('apps/documents/ajax/session/save');
server = new PullBoxServer(args); server = new PullBoxServer(args);
server.getGenesisUrl = function(sid) { server.getGenesisUrl = function(sid) {

@ -328,6 +328,13 @@ var documentsMain = {
return; return;
} }
var pollUrl = documentsMain.isGuest
? OC.generateUrl('apps/documents/session/guest/poll/{token}', {'token' : $("[name='document']").val()})
: OC.generateUrl('apps/documents/session/user/poll'),
saveUrl = documentsMain.isGuest
? OC.generateUrl('apps/documents/session/guest/save/{token}', {'token' : $("[name='document']").val()})
: OC.generateUrl('apps/documents/session/user/save')
;
documentsMain.canShare = !documentsMain.isGuest documentsMain.canShare = !documentsMain.isGuest
&& typeof OC.Share !== 'undefined' && response.permissions & OC.PERMISSION_SHARE; && typeof OC.Share !== 'undefined' && response.permissions & OC.PERMISSION_SHARE;
require({ }, ["owncloud/ServerFactory", "webodf/editor/Editor"], function (ServerFactory, Editor) { require({ }, ["owncloud/ServerFactory", "webodf/editor/Editor"], function (ServerFactory, Editor) {
@ -347,8 +354,10 @@ var documentsMain = {
documentsMain.memberId = response.member_id; documentsMain.memberId = response.member_id;
// TODO: set webodf translation system, by passing a proper function translate(!string):!string in "runtime.setTranslator(translate);" // TODO: set webodf translation system, by passing a proper function translate(!string):!string in "runtime.setTranslator(translate);"
documentsMain.webodfServerInstance = serverFactory.createServer({
documentsMain.webodfServerInstance = serverFactory.createServer(); url : pollUrl,
sessionStateToFileUrl : saveUrl
});
documentsMain.webodfServerInstance.setToken(oc_requesttoken); documentsMain.webodfServerInstance.setToken(oc_requesttoken);
documentsMain.webodfEditorInstance = new Editor( documentsMain.webodfEditorInstance = new Editor(
{ {
@ -383,9 +392,9 @@ var documentsMain = {
console.log('joining session '+fileId); console.log('joining session '+fileId);
var url; var url;
if (documentsMain.isGuest){ if (documentsMain.isGuest){
url = OC.generateUrl('apps/documents/ajax/session/joinasguest/{token}', {token: fileId}); url = OC.generateUrl('apps/documents/session/guest/join/{token}', {token: fileId});
} else { } else {
url = OC.generateUrl('apps/documents/ajax/session/joinasuser/{file_id}', {file_id: fileId}); url = OC.generateUrl('apps/documents/session/user/join/{file_id}', {file_id: fileId});
} }
$.post( $.post(
url, url,

@ -42,7 +42,7 @@ define("owncloud/widgets/ocToolbar",
ocClose.startup(); ocClose.startup();
}); });
return callback(ocToolbar); return callback(ocToolbar);
}; }
// init // init
makeWidget(function (widget) { makeWidget(function (widget) {
return callback(widget); return callback(widget);

@ -0,0 +1,86 @@
<?php
/**
* ownCloud - Documents App
*
* @author Victor Dubiniuk
* @copyright 2015 Victor Dubiniuk victor.dubiniuk@gmail.com
*
* This file is licensed under the Affero General Public License version 3 or
* later.
*/
namespace OCA\Documents;
use \OCP\IConfig;
class AppConfig{
private $appName = 'documents';
private $defaults = [
'converter' => 'off',
'converter_url' => 'http://localhost:16080',
'unstable' => 'false'
];
private $config;
public function __construct(IConfig $config) {
$this->config = $config;
}
/**
* Can we convert anything to odt?
* @return bool
*/
public function isConverterEnabled(){
return $this->getAppValue('converter') !== 'off';
}
/**
* Get a value by key
* @param string $key
* @return string
*/
public function getAppValue($key) {
$defaultValue = null;
if (array_key_exists($key, $this->defaults)){
$defaultValue = $this->defaults[$key];
}
return $this->config->getAppValue($this->appName, $key, $defaultValue);
}
/**
* Set a value by key
* @param string $key
* @param string $value
* @return string
*/
public function setAppValue($key, $value) {
return $this->config->setAppValue($this->appName, $key, $value);
}
/**
* Get a value by key for a user
* @param string $userId
* @param string $key
* @return string
*/
public function getUserValue($userId, $key) {
$defaultValue = null;
if (array_key_exists($key, $this->defaults)){
$defaultValue = $this->defaults[$key];
}
return $this->config->getUserValue($userId, $this->appName, $key, $defaultValue);
}
/**
* Set a value by key for a user
* @param string $userId
* @param string $key
* @param string $value
* @return string
*/
public function setUserValue($userId, $key, $value) {
return $this->config->setAppValue($userId, $this->appName, $key, $value);
}
}

@ -1,76 +0,0 @@
<?php
/**
* ownCloud - Documents App
*
* @author Victor Dubiniuk
* @copyright 2014 Victor Dubiniuk victor.dubiniuk@gmail.com
*
* This file is licensed under the Affero General Public License version 3 or
* later.
*/
namespace OCA\Documents;
class Config {
const APP_NAME = 'documents';
const TEST_DOC_PATH = '/assets/test.doc';
public static function testConversion(){
$targetFilter = 'odt:writer8';
$targetExtension = 'odt';
$input = file_get_contents(dirname(__DIR__) . self::TEST_DOC_PATH);
$infile = \OC::$server->getTempManager()->getTemporaryFile();
$outdir = \OC::$server->getTempManager()->getTemporaryFolder();
$outfile = $outdir . '/' . basename($infile) . '.' . $targetExtension;
$cmd = Helper::findOpenOffice();
$params = ' --headless --convert-to ' . escapeshellarg($targetFilter) . ' --outdir '
. escapeshellarg($outdir)
. ' --writer '. escapeshellarg($infile)
. ' -env:UserInstallation=file://'
. escapeshellarg(get_temp_dir() . '/owncloud-' . \OC_Util::getInstanceId().'/') . ' 2>&1'
;
file_put_contents($infile, $input);
$result = shell_exec($cmd . $params);
$exists = file_exists($outfile);
if (!$exists){
Helper::warnLog('Conversion test failed. Raw output:' . $result);
return false;
} else {
unlink($outfile);
}
return true;
}
public static function getL10n(){
return \OCP\Util::getL10N(self::APP_NAME);
}
public static function getConverter(){
return self::getAppValue('converter', 'off');
}
public static function setConverter($value){
return self::setAppValue('converter', $value);
}
public static function getConverterUrl(){
return self::getAppValue('converter_url', 'http://localhost:16080');
}
public static function setConverterUrl($value){
return self::setAppValue('converter_url', $value);
}
protected static function getAppValue($key, $default){
return \OC::$server->getConfig()->getAppValue(self::APP_NAME, $key, $default);
}
protected static function setAppValue($key, $value){
return \OC::$server->getConfig()->setAppValue(self::APP_NAME, $key, $value);
}
}

@ -12,17 +12,58 @@
namespace OCA\Documents; namespace OCA\Documents;
use OCA\Documents\AppInfo\Application;
class Converter { class Converter {
const TEST_DOC_PATH = '/assets/test.doc';
public static function testConversion(){
$targetFilter = 'odt:writer8';
$targetExtension = 'odt';
$input = file_get_contents(dirname(__DIR__) . self::TEST_DOC_PATH);
$infile = \OC::$server->getTempManager()->getTemporaryFile();
$outdir = \OC::$server->getTempManager()->getTemporaryFolder();
$outfile = $outdir . '/' . basename($infile) . '.' . $targetExtension;
$cmd = Helper::findOpenOffice();
$params = ' --headless --convert-to ' . escapeshellarg($targetFilter) . ' --outdir '
. escapeshellarg($outdir)
. ' --writer '. escapeshellarg($infile)
. ' -env:UserInstallation=file://'
. escapeshellarg(\OC::$server->getTempManager()->getTempBaseDir() . '/owncloud-' . \OC_Util::getInstanceId().'/') . ' 2>&1'
;
file_put_contents($infile, $input);
$result = shell_exec($cmd . $params);
$exists = file_exists($outfile);
if (!$exists){
\OC::$server->getLogger()->warn(
'Conversion test failed. Raw output:' . $result,
['app' => 'documents']
);
return false;
} else {
unlink($outfile);
}
return true;
}
public static function convert($input, $targetFilter, $targetExtension){ public static function convert($input, $targetFilter, $targetExtension){
if (Config::getConverter() == 'local'){ if (self::getAppConfig()->getAppValue('converter') === 'local'){
$output = self::convertLocal($input, $targetFilter, $targetExtension); $output = self::convertLocal($input, $targetFilter, $targetExtension);
} else { } else {
$output = self::convertExternal($input, $targetExtension); $output = self::convertExternal($input, $targetExtension);
} }
if (empty($output)){ if (empty($output)){
Helper::warnLog('Empty conversion output'); \OC::$server->getLogger()->warn(
'Empty conversion output',
['app' => 'documents']
);
throw new \RuntimeException('Empty conversion output'); throw new \RuntimeException('Empty conversion output');
} }
return $output; return $output;
@ -82,15 +123,25 @@ class Converter {
CURLOPT_VERBOSE => 1 CURLOPT_VERBOSE => 1
); );
$ch = curl_init(Config::getConverterUrl() . '?target_format=' . $targetExtension); $ch = curl_init(self::getAppConfig()->getAppValue('converter_url') . '?target_format=' . $targetExtension);
curl_setopt_array($ch, $options); curl_setopt_array($ch, $options);
$content = curl_exec($ch); $content = curl_exec($ch);
if (curl_errno($ch)){ if (curl_errno($ch)){
Helper::debugLog('cURL error' . curl_errno($ch) . ':' . curl_error($ch)); \OC::$server->getLogger()->debug(
'cURL error' . curl_errno($ch) . ':' . curl_error($ch),
['app' => 'documents']
);
} }
curl_close($ch); curl_close($ch);
return $content; return $content;
} }
protected static function getAppConfig(){
$app = new Application();
$c = $app->getContainer();
return $c->query('AppConfig');
}
} }

@ -36,7 +36,7 @@ class Member extends \OCA\Documents\Db{
protected $loadStatement = 'SELECT * FROM `*PREFIX*documents_member` WHERE `member_id`= ?'; protected $loadStatement = 'SELECT * FROM `*PREFIX*documents_member` WHERE `member_id`= ?';
public static function getGuestPostfix(){ public static function getGuestPostfix(){
return '(' . \OCA\Documents\Config::getL10n()->t('guest') . ')'; return '(' . \OC::$server->getL10n('documents')->t('guest') . ')';
} }

@ -78,7 +78,7 @@ class Op extends \OCA\Documents\Db {
AND `seq`>? AND `seq`>?
ORDER BY `seq` ASC ORDER BY `seq` ASC
'); ');
$result = $query->execute(array($esId, $seq)); $query->execute(array($esId, $seq));
return $query->fetchAll(); return $query->fetchAll();
} }

@ -49,12 +49,7 @@ class Session extends \OCA\Documents\Db {
public static function start($uid, $file){ public static function start($uid, $file){
// Create a directory to store genesis // Create a directory to store genesis
$genesis = new \OCA\Documents\Genesis($file); $genesis = new \OCA\Documents\Genesis($file);
list($ownerView, $path) = $file->getOwnerViewAndPath();
$mimetype = $ownerView->getMimeType($path);
if (!Filter::isSupportedMimetype($mimetype)){
throw new \Exception( $path . ' is ' . $mimetype . ' and is not supported by Documents app');
}
$oldSession = new Session(); $oldSession = new Session();
$oldSession->loadBy('file_id', $file->getFileId()); $oldSession->loadBy('file_id', $file->getFileId());
@ -78,14 +73,14 @@ class Session extends \OCA\Documents\Db {
; ;
$memberColor = \OCA\Documents\Helper::getMemberColor($uid); $memberColor = \OCA\Documents\Helper::getMemberColor($uid);
$member = new \OCA\Documents\Db\Member(array( $member = new \OCA\Documents\Db\Member([
$sessionData['es_id'], $sessionData['es_id'],
$uid, $uid,
$memberColor, $memberColor,
time(), time(),
intval($file->isPublicShare()), intval($file->isPublicShare()),
$file->getToken() $file->getToken()
)); ]);
if (!$member->insert()){ if (!$member->insert()){
throw new \Exception('Failed to add member into database'); throw new \Exception('Failed to add member into database');
@ -113,10 +108,9 @@ class Session extends \OCA\Documents\Db {
$memberColor, $memberColor,
$imageUrl $imageUrl
); );
$sessionData['title'] = basename($path); $sessionData['title'] = basename($file->getPath());
$fileInfo = $ownerView->getFileInfo($path); $sessionData['permissions'] = $file->getPermissions();
$sessionData['permissions'] = $fileInfo->getPermissions();
return $sessionData; return $sessionData;
} }

@ -32,12 +32,12 @@ class DownloadResponse extends \OCP\AppFramework\Http\Response {
$this->view = new View('/' . $user); $this->view = new View('/' . $user);
if (!$this->view->file_exists($path)){ if (!$this->view->file_exists($path)){
parent::setStatus(Http::STATUS_NOT_FOUND); $this->setStatus(Http::STATUS_NOT_FOUND);
} }
} }
public function render(){ public function render(){
if (parent::getStatus() === Http::STATUS_NOT_FOUND){ if ($this->getStatus() === Http::STATUS_NOT_FOUND){
return ''; return '';
} }
$info = $this->view->getFileInfo($this->path); $info = $this->view->getFileInfo($this->path);

@ -27,19 +27,39 @@ use \OC\Files\View;
class File { class File {
protected $fileId; protected $fileId;
protected $owner; protected $owner;
protected $path;
protected $sharing; protected $sharing;
protected $token =''; protected $token;
protected $passwordProtected = false; protected $passwordProtected = false;
protected $ownerView;
protected $ownerViewFiles;
protected $path;
protected $pathFiles;
public function __construct($fileId, $shareOps = null, $token = ''){
public function __construct($fileId, $shareOps = null){
if (!$fileId){ if (!$fileId){
throw new \Exception('No valid file has been passed'); throw new \Exception('No valid file has been passed');
} }
$this->fileId = $fileId; $this->fileId = $fileId;
$this->sharing = $shareOps; $this->sharing = $shareOps;
$this->token = $token;
if ($this->isPublicShare()) {
if (isset($this->sharing['uid_owner'])){
$this->owner = $this->sharing['uid_owner'];
if (!\OC::$server->getUserManager()->userExists($this->sharing['uid_owner'])) {
throw new \Exception('Share owner' . $this->sharing['uid_owner'] . ' does not exist ');
}
\OC_Util::tearDownFS();
\OC_Util::setupFS($this->sharing['uid_owner']);
} else {
throw new \Exception($this->fileId . ' is a broken share');
}
} else {
$this->owner = \OC::$server->getUserSession()->getUser()->getUID();
}
$this->initViews();
} }
@ -52,8 +72,7 @@ class File {
throw new \Exception('This file was probably unshared'); throw new \Exception('This file was probably unshared');
} }
$file = new File($rootLinkItem['file_source'], $rootLinkItem); $file = new File($rootLinkItem['file_source'], $rootLinkItem, $token);
$file->setToken($token);
if (isset($linkItem['share_with']) && !empty($linkItem['share_with'])){ if (isset($linkItem['share_with']) && !empty($linkItem['share_with'])){
$file->setPasswordProtected(true); $file->setPasswordProtected(true);
@ -70,14 +89,6 @@ class File {
return $this->fileId; return $this->fileId;
} }
public function setOwner($owner){
$this->owner = $owner;
}
public function setPath($path){
$this->path = $path;
}
public function setToken($token){ public function setToken($token){
$this->token = $token; $this->token = $token;
} }
@ -137,58 +148,52 @@ class File {
$this->passwordProtected = $value; $this->passwordProtected = $value;
} }
public function getOwner(){
/** return $this->owner;
* }
* @return string owner of the current file item
* @throws \Exception public function getOwnerView($relativeToFiles = false){
*/ return $relativeToFiles ? $this->ownerViewFiles : $this->ownerView;
public function getOwnerViewAndPath($useDefaultRoot = false){ }
if ($this->isPublicShare()){
if (isset($this->sharing['uid_owner'])){ public function getPath($relativeToFiles = false){
$owner = $this->sharing['uid_owner']; return $relativeToFiles ? $this->pathFiles : $this->path;
if (!\OC::$server->getUserManager()->userExists($this->sharing['uid_owner'])) { }
throw new \Exception('Share owner' . $this->sharing['uid_owner'] . ' does not exist ');
} public function getPermissions(){
$fileInfo = $this->ownerView->getFileInfo($this->path);
\OC_Util::tearDownFS(); return $fileInfo->getPermissions();
\OC_Util::setupFS($this->sharing['uid_owner']); }
} else {
throw new \Exception($this->fileId . ' is a broken share'); protected function initViews(){
} $this->ownerView = new View('/' . $this->owner);
$view = new View('/' . $owner . '/files'); $this->ownerViewFiles = new View('/' . $this->owner . '/files');
} else { $this->path = $this->ownerView->getPath($this->fileId);
$owner = \OC::$server->getUserSession()->getUser()->getUID(); $this->pathFiles = $this->ownerViewFiles->getPath($this->fileId);
$root = '/' . $owner;
if ($useDefaultRoot){ if (!$this->path || !$this->pathFiles) {
$root .= '/' . 'files';
}
$view = new View($root);
}
$path = $view->getPath($this->fileId);
if (!$path){
throw new \Exception($this->fileId . ' can not be resolved'); throw new \Exception($this->fileId . ' can not be resolved');
} }
$this->path = $path;
$this->owner = $owner;
if (!$view->file_exists($this->path)){ if (!$this->ownerView->file_exists($this->path)) {
throw new \Exception($this->path . ' doesn\'t exist'); throw new \Exception($this->path . ' doesn\'t exist');
} }
return array($view, $this->path); if (!$this->ownerViewFiles->file_exists($this->pathFiles)) {
} throw new \Exception($this->pathFiles . ' doesn\'t exist');
}
public function getOwner(){ if (!$this->ownerView->is_file($this->path)){
if (!$this->owner){ throw new \Exception('Object ' . $this->path . ' is not a file.');
$this->getOwnerViewAndPath(); }
//TODO check if it is a valid odt
$mimetype = $this->ownerView->getMimeType($this->path);
if (!Filter::isSupportedMimetype($mimetype)){
throw new \Exception( $this->path . ' is ' . $mimetype . ' and is not supported by Documents app');
} }
return $this->owner;
} }
protected function getPassword(){ protected function getPassword(){
return $this->sharing['share_with']; return $this->sharing['share_with'];
} }

@ -40,7 +40,8 @@ class Genesis {
* @param File $file * @param File $file
* */ * */
public function __construct(File $file){ public function __construct(File $file){
list($view, $path) = $file->getOwnerViewAndPath(); $view = $file->getOwnerView();
$path = $file->getPath();
$owner = $file->getOwner(); $owner = $file->getOwner();
$this->view = new View('/' . $owner); $this->view = new View('/' . $owner);
@ -48,8 +49,9 @@ class Genesis {
if (!$this->view->file_exists(self::DOCUMENTS_DIRNAME)){ if (!$this->view->file_exists(self::DOCUMENTS_DIRNAME)){
$this->view->mkdir(self::DOCUMENTS_DIRNAME ); $this->view->mkdir(self::DOCUMENTS_DIRNAME );
} }
$this->validate($view, $path);
$this->hash = $this->getDocumentHash($view, $path); $this->hash = $view->hash('sha1', $path, false);
$this->path = self::DOCUMENTS_DIRNAME . '/' . $this->hash . '.odt'; $this->path = self::DOCUMENTS_DIRNAME . '/' . $this->hash . '.odt';
if (!$this->view->file_exists($this->path)){ if (!$this->view->file_exists($this->path)){
//copy new genesis to /user/documents/{hash}.odt //copy new genesis to /user/documents/{hash}.odt
@ -76,16 +78,6 @@ class Genesis {
return $this->hash; return $this->hash;
} }
public static function getHashByPath($path){
return preg_replace('|([a-zA-Z0-9])*\..*$|', '\1', $path);
}
protected function getDocumentHash($view, $path){
$this->validate($view, $path);
$hash = sha1($view->file_get_contents($path));
return $hash;
}
/** /**
* Check if genesis is valid * Check if genesis is valid
* @param \OC\Files\View $view * @param \OC\Files\View $view

@ -54,24 +54,6 @@ class Helper {
return '#' . self::convertHSLToRGB($hue, 90, 60); return '#' . self::convertHSLToRGB($hue, 90, 60);
} }
/**
* @param string $message
*/
public static function debugLog($message){
self::log($message, \OCP\Util::DEBUG);
}
/**
* @param string $message
*/
public static function warnLog($message){
self::log($message, \OCP\Util::WARN);
}
public static function log($message, $level){
\OCP\Util::writeLog(self::APP_ID, $message, $level);
}
/** /**
* @param integer $iH * @param integer $iH
* @param integer $iS * @param integer $iS
@ -178,8 +160,16 @@ class Helper {
} }
if (empty($cmd)){ if (empty($cmd)){
Helper::warnLog('Pure configuration issue. Missing open office binary that is mandatory for conversion.'); \OC::$server->getLogger()->warn(
Helper::debugLog('If openoffice or libreoffice is already installed please specify the path to it using preview_libreoffice_path config. Refer to admin manual for details.'); 'Pure configuration issue. Missing open office binary that is mandatory for conversion.',
['app' => 'documents']
);
\OC::$server->getLogger()->debug(
'If openoffice or libreoffice is already installed please specify the path to it using preview_libreoffice_path config. Refer to admin manual for details.',
['app' => 'documents']
);
throw new \RuntimeException('Missing open office binary that is mandatory for conversion.'); throw new \RuntimeException('Missing open office binary that is mandatory for conversion.');
} }

@ -100,7 +100,7 @@ class Storage {
public static function getSupportedMimetypes(){ public static function getSupportedMimetypes(){
return array_merge( return array_merge(
array(self::MIMETYPE_LIBREOFFICE_WORDPROCESSOR), array(self::MIMETYPE_LIBREOFFICE_WORDPROCESSOR),
Filter::getAll() Filter::getAll()
); );
} }
} }

@ -9,5 +9,5 @@ require_once __DIR__.'/../../../lib/base.php';
if(!class_exists('PHPUnit_Framework_TestCase')) { if(!class_exists('PHPUnit_Framework_TestCase')) {
require_once('PHPUnit/Autoload.php'); require_once('PHPUnit/Autoload.php');
} }
\OC_App::loadApp('documents');
OC_Hook::clear(); OC_Hook::clear();

@ -51,10 +51,6 @@ class DocumentControllerTest extends \PHPUnit_Framework_TestCase {
\OC_Util::setupFS(); \OC_Util::setupFS();
} }
public static function tearDownAfterClass(){
\OC_User::deleteUser(\OC_User::getUserSession()->getUser()->getUID());
}
public function testRename(){ public function testRename(){
$result = array( $result = array(
'status' => 'error', 'status' => 'error',

Loading…
Cancel
Save