Completed
Push — stable8.2 ( 55f9f7...6a1434 )
by
unknown
36:37
created

Scan::reconnectToDatabase()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 13
nc 6
nop 1
dl 0
loc 18
ccs 0
cts 0
cp 0
crap 20
rs 9.2
c 1
b 0
f 0
1
<?php
2
/**
3
 * @author Bart Visscher <[email protected]>
4
 * @author Jörn Friedrich Dreyer <[email protected]>
5
 * @author Morris Jobke <[email protected]>
6
 * @author Robin Appelman <[email protected]>
7
 * @author Vincent Petry <[email protected]>
8
 *
9
 * @copyright Copyright (c) 2015, ownCloud, Inc.
10
 * @license AGPL-3.0
11
 *
12
 * This code is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License, version 3,
14
 * as published by the Free Software Foundation.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License, version 3,
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
23
 *
24
 */
25
26
namespace OCA\Files\Command;
27
28
use OC\ForbiddenException;
29
use OCP\Files\StorageNotAvailableException;
30
use Symfony\Component\Console\Command\Command;
31
use Doctrine\DBAL\Connection;
32
use OCP\IDBConnection;
33
use Symfony\Component\Console\Input\InputArgument;
34
use Symfony\Component\Console\Input\InputInterface;
35
use Symfony\Component\Console\Input\InputOption;
36
use Symfony\Component\Console\Output\OutputInterface;
37
38
class Scan extends Command {
39
40
	/**
41
	 * @var \OC\User\Manager $userManager
42
	 */
43
	private $userManager;
44
45
	public function __construct(\OC\User\Manager $userManager) {
46
		$this->userManager = $userManager;
47
		parent::__construct();
48
	}
49
50
	protected function configure() {
51
		$this
52
			->setName('files:scan')
53
			->setDescription('rescan filesystem')
54
			->addArgument(
55
				'user_id',
56
				InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
57
				'will rescan all files of the given user(s)'
58
			)
59
			->addOption(
60
				'path',
61
				'p',
62
				InputArgument::OPTIONAL,
63
				'limit rescan to this path, eg. --path="/alice/files/Music", the user_id is determined by the path and the user_id parameter and --all are ignored'
64
			)
65
			->addOption(
66
				'quiet',
67
				'q',
68
				InputOption::VALUE_NONE,
69
				'suppress output'
70
			)
71
			->addOption(
72
				'all',
73
				null,
74
				InputOption::VALUE_NONE,
75
				'will rescan all files of all known users'
76
			);
77
	}
78
79
	protected function scanFiles($user, $path, $quiet, OutputInterface $output) {
80
		$connection = $this->reconnectToDatabase($output);
81
		$scanner = new \OC\Files\Utils\Scanner($user, $connection, \OC::$server->getLogger());
82
		if (!$quiet) {
83
			$scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function ($path) use ($output) {
84
				$output->writeln("Scanning file   <info>$path</info>");
85
			});
86
			$scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function ($path) use ($output) {
87
				$output->writeln("Scanning folder <info>$path</info>");
88
			});
89
			$scanner->listen('\OC\Files\Utils\Scanner', 'StorageNotAvailable', function (StorageNotAvailableException $e) use ($output) {
90
				$output->writeln("Error while scanning, storage not available (" . $e->getMessage() . ")");
91
			});
92
		}
93
		try {
94
			$scanner->scan($path);
95
		} catch (ForbiddenException $e) {
96
			$output->writeln("<error>Home storage for user $user not writable</error>");
97
			$output->writeln("Make sure you're running the scan command only as the user the web server runs as");
98
		}
99
	}
100
101
	protected function execute(InputInterface $input, OutputInterface $output) {
102
		$inputPath = $input->getOption('path');
103
		if ($inputPath) {
104
			$inputPath = '/' . trim($inputPath, '/');
105
			list (, $user,) = explode('/', $inputPath, 3);
106
			$users = array($user);
107
		} else if ($input->getOption('all')) {
108
			$users = $this->userManager->search('');
109
		} else {
110
			$users = $input->getArgument('user_id');
111
		}
112
		$quiet = $input->getOption('quiet');
113
114
115
		if (count($users) === 0) {
116
			$output->writeln("<error>Please specify the user id to scan, \"--all\" to scan for all users or \"--path=...\"</error>");
117
			return;
118
		}
119
120
		foreach ($users as $user) {
121
			if (is_object($user)) {
122
				$user = $user->getUID();
123
			}
124
			$path = $inputPath ? $inputPath : '/' . $user;
125
			if ($this->userManager->userExists($user)) {
126
				$this->scanFiles($user, $path, $quiet, $output);
127
			} else {
128
				$output->writeln("<error>Unknown user $user</error>");
129
			}
130
		}
131
	}
132
133
	/**
134
	 * @return \OCP\IDBConnection
135
	 */
136
	protected function reconnectToDatabase(OutputInterface $output) {
137
		/** @var Connection | IDBConnection $connection*/
138
		$connection = \OC::$server->getDatabaseConnection();
139
		try {
140
			$connection->close();
141
		} catch (\Exception $ex) {
142
			$output->writeln("<info>Error while disconnecting from database: {$ex->getMessage()}</info>");
143
		}
144
		while (!$connection->isConnected()) {
0 ignored issues
show
Bug introduced by
The method isConnected() does not exist on OCP\IDBConnection. Did you maybe mean connect()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
145
			try {
146
				$connection->connect();
147
			} catch (\Exception $ex) {
148
				$output->writeln("<info>Error while re-connecting to database: {$ex->getMessage()}</info>");
149
				sleep(60);
150
			}
151
		}
152
		return $connection;
153
	}
154
155
}
156