Completed
Pull Request — master (#9787)
by Robin
175:16 queued 143:38
created
apps/files_external/lib/Command/Notify.php 1 patch
Indentation   +180 added lines, -180 removed lines patch added patch discarded remove patch
@@ -41,186 +41,186 @@
 block discarded – undo
41 41
 use Symfony\Component\Console\Output\OutputInterface;
42 42
 
43 43
 class Notify extends Base {
44
-	/** @var GlobalStoragesService */
45
-	private $globalService;
46
-	/** @var IDBConnection */
47
-	private $connection;
48
-	/** @var \OCP\DB\QueryBuilder\IQueryBuilder */
49
-	private $updateQuery;
50
-
51
-	function __construct(GlobalStoragesService $globalService, IDBConnection $connection) {
52
-		parent::__construct();
53
-		$this->globalService = $globalService;
54
-		$this->connection = $connection;
55
-		// the query builder doesn't really like subqueries with parameters
56
-		$this->updateQuery = $this->connection->prepare(
57
-			'UPDATE *PREFIX*filecache SET size = -1
44
+    /** @var GlobalStoragesService */
45
+    private $globalService;
46
+    /** @var IDBConnection */
47
+    private $connection;
48
+    /** @var \OCP\DB\QueryBuilder\IQueryBuilder */
49
+    private $updateQuery;
50
+
51
+    function __construct(GlobalStoragesService $globalService, IDBConnection $connection) {
52
+        parent::__construct();
53
+        $this->globalService = $globalService;
54
+        $this->connection = $connection;
55
+        // the query builder doesn't really like subqueries with parameters
56
+        $this->updateQuery = $this->connection->prepare(
57
+            'UPDATE *PREFIX*filecache SET size = -1
58 58
 			WHERE `path` = ?
59 59
 			AND `storage` IN (SELECT storage_id FROM *PREFIX*mounts WHERE mount_id = ?)'
60
-		);
61
-	}
62
-
63
-	protected function configure() {
64
-		$this
65
-			->setName('files_external:notify')
66
-			->setDescription('Listen for active update notifications for a configured external mount')
67
-			->addArgument(
68
-				'mount_id',
69
-				InputArgument::REQUIRED,
70
-				'the mount id of the mount to listen to'
71
-			)->addOption(
72
-				'user',
73
-				'u',
74
-				InputOption::VALUE_REQUIRED,
75
-				'The username for the remote mount (required only for some mount configuration that don\'t store credentials)'
76
-			)->addOption(
77
-				'password',
78
-				'p',
79
-				InputOption::VALUE_REQUIRED,
80
-				'The password for the remote mount (required only for some mount configuration that don\'t store credentials)'
81
-			)->addOption(
82
-				'path',
83
-				'',
84
-				InputOption::VALUE_REQUIRED,
85
-				'The directory in the storage to listen for updates in',
86
-				'/'
87
-			);
88
-		parent::configure();
89
-	}
90
-
91
-	protected function execute(InputInterface $input, OutputInterface $output) {
92
-		$mount = $this->globalService->getStorage($input->getArgument('mount_id'));
93
-		if (is_null($mount)) {
94
-			$output->writeln('<error>Mount not found</error>');
95
-			return 1;
96
-		}
97
-		$noAuth = false;
98
-		try {
99
-			$authBackend = $mount->getAuthMechanism();
100
-			$authBackend->manipulateStorageConfig($mount);
101
-		} catch (InsufficientDataForMeaningfulAnswerException $e) {
102
-			$noAuth = true;
103
-		} catch (StorageNotAvailableException $e) {
104
-			$noAuth = true;
105
-		}
106
-
107
-		if ($input->getOption('user')) {
108
-			$mount->setBackendOption('user', $input->getOption('user'));
109
-		} else if (isset($_ENV['NOTIFY_USER'])) {
110
-			$mount->setBackendOption('user', $_ENV['NOTIFY_USER']);
111
-		} else if (isset($_SERVER['NOTIFY_USER'])) {
112
-			$mount->setBackendOption('user', $_SERVER['NOTIFY_USER']);
113
-		}
114
-		if ($input->getOption('password')) {
115
-			$mount->setBackendOption('password', $input->getOption('password'));
116
-		} else if (isset($_ENV['NOTIFY_PASSWORD'])) {
117
-			$mount->setBackendOption('password', $_ENV['NOTIFY_PASSWORD']);
118
-		} else if (isset($_SERVER['NOTIFY_PASSWORD'])) {
119
-			$mount->setBackendOption('password', $_SERVER['NOTIFY_PASSWORD']);
120
-		}
121
-
122
-		try {
123
-			$storage = $this->createStorage($mount);
124
-		} catch (\Exception $e) {
125
-			$output->writeln('<error>Error while trying to create storage</error>');
126
-			if ($noAuth) {
127
-				$output->writeln('<error>Username and/or password required</error>');
128
-			}
129
-			return 1;
130
-		}
131
-		if (!$storage instanceof INotifyStorage) {
132
-			$output->writeln('<error>Mount of type "' . $mount->getBackend()->getText() . '" does not support active update notifications</error>');
133
-			return 1;
134
-		}
135
-
136
-		$verbose = $input->getOption('verbose');
137
-
138
-		$path = trim($input->getOption('path'), '/');
139
-		$notifyHandler = $storage->notify($path);
140
-		$this->selfTest($storage, $notifyHandler, $verbose, $output);
141
-		$notifyHandler->listen(function (IChange $change) use ($mount, $verbose, $output) {
142
-			if ($verbose) {
143
-				$this->logUpdate($change, $output);
144
-			}
145
-			if ($change instanceof IRenameChange) {
146
-				$this->markParentAsOutdated($mount->getId(), $change->getTargetPath());
147
-			}
148
-			$this->markParentAsOutdated($mount->getId(), $change->getPath());
149
-		});
150
-	}
151
-
152
-	private function createStorage(StorageConfig $mount) {
153
-		$class = $mount->getBackend()->getStorageClass();
154
-		return new $class($mount->getBackendOptions());
155
-	}
156
-
157
-	private function markParentAsOutdated($mountId, $path) {
158
-		$parent = dirname($path);
159
-		if ($parent === '.') {
160
-			$parent = '';
161
-		}
162
-		$this->updateQuery->execute([$parent, $mountId]);
163
-	}
164
-
165
-	private function logUpdate(IChange $change, OutputInterface $output) {
166
-		switch ($change->getType()) {
167
-			case INotifyStorage::NOTIFY_ADDED:
168
-				$text = 'added';
169
-				break;
170
-			case INotifyStorage::NOTIFY_MODIFIED:
171
-				$text = 'modified';
172
-				break;
173
-			case INotifyStorage::NOTIFY_REMOVED:
174
-				$text = 'removed';
175
-				break;
176
-			case INotifyStorage::NOTIFY_RENAMED:
177
-				$text = 'renamed';
178
-				break;
179
-			default:
180
-				return;
181
-		}
182
-
183
-		$text .= ' ' . $change->getPath();
184
-		if ($change instanceof IRenameChange) {
185
-			$text .= ' to ' . $change->getTargetPath();
186
-		}
187
-
188
-		$output->writeln($text);
189
-	}
190
-
191
-	private function selfTest(IStorage $storage, INotifyHandler $notifyHandler, $verbose, OutputInterface $output) {
192
-		usleep(100 * 1000); //give time for the notify to start
193
-		$storage->file_put_contents('/.nc_test_file.txt', 'test content');
194
-		$storage->mkdir('/.nc_test_folder');
195
-		$storage->file_put_contents('/.nc_test_folder/subfile.txt', 'test content');
196
-
197
-		usleep(100 * 1000); //time for all changes to be processed
198
-		$changes = $notifyHandler->getChanges();
199
-
200
-		$storage->unlink('/.nc_test_file.txt');
201
-		$storage->unlink('/.nc_test_folder/subfile.txt');
202
-		$storage->rmdir('/.nc_test_folder');
203
-
204
-		usleep(100 * 1000); //time for all changes to be processed
205
-		$notifyHandler->getChanges(); // flush
206
-
207
-		$foundRootChange = false;
208
-		$foundSubfolderChange = false;
209
-
210
-		foreach ($changes as $change) {
211
-			if ($change->getPath() === '/.nc_test_file.txt' || $change->getPath() === '.nc_test_file.txt') {
212
-				$foundRootChange = true;
213
-			} else if ($change->getPath() === '/.nc_test_folder/subfile.txt' || $change->getPath() === '.nc_test_folder/subfile.txt') {
214
-				$foundSubfolderChange = true;
215
-			}
216
-		}
217
-
218
-		if ($foundRootChange && $foundSubfolderChange && $verbose) {
219
-			$output->writeln('<info>Self-test successful</info>');
220
-		} else if ($foundRootChange && !$foundSubfolderChange) {
221
-			$output->writeln('<error>Error while running self-test, change is subfolder not detected</error>');
222
-		} else if (!$foundRootChange) {
223
-			$output->writeln('<error>Error while running self-test, no changes detected</error>');
224
-		}
225
-	}
60
+        );
61
+    }
62
+
63
+    protected function configure() {
64
+        $this
65
+            ->setName('files_external:notify')
66
+            ->setDescription('Listen for active update notifications for a configured external mount')
67
+            ->addArgument(
68
+                'mount_id',
69
+                InputArgument::REQUIRED,
70
+                'the mount id of the mount to listen to'
71
+            )->addOption(
72
+                'user',
73
+                'u',
74
+                InputOption::VALUE_REQUIRED,
75
+                'The username for the remote mount (required only for some mount configuration that don\'t store credentials)'
76
+            )->addOption(
77
+                'password',
78
+                'p',
79
+                InputOption::VALUE_REQUIRED,
80
+                'The password for the remote mount (required only for some mount configuration that don\'t store credentials)'
81
+            )->addOption(
82
+                'path',
83
+                '',
84
+                InputOption::VALUE_REQUIRED,
85
+                'The directory in the storage to listen for updates in',
86
+                '/'
87
+            );
88
+        parent::configure();
89
+    }
90
+
91
+    protected function execute(InputInterface $input, OutputInterface $output) {
92
+        $mount = $this->globalService->getStorage($input->getArgument('mount_id'));
93
+        if (is_null($mount)) {
94
+            $output->writeln('<error>Mount not found</error>');
95
+            return 1;
96
+        }
97
+        $noAuth = false;
98
+        try {
99
+            $authBackend = $mount->getAuthMechanism();
100
+            $authBackend->manipulateStorageConfig($mount);
101
+        } catch (InsufficientDataForMeaningfulAnswerException $e) {
102
+            $noAuth = true;
103
+        } catch (StorageNotAvailableException $e) {
104
+            $noAuth = true;
105
+        }
106
+
107
+        if ($input->getOption('user')) {
108
+            $mount->setBackendOption('user', $input->getOption('user'));
109
+        } else if (isset($_ENV['NOTIFY_USER'])) {
110
+            $mount->setBackendOption('user', $_ENV['NOTIFY_USER']);
111
+        } else if (isset($_SERVER['NOTIFY_USER'])) {
112
+            $mount->setBackendOption('user', $_SERVER['NOTIFY_USER']);
113
+        }
114
+        if ($input->getOption('password')) {
115
+            $mount->setBackendOption('password', $input->getOption('password'));
116
+        } else if (isset($_ENV['NOTIFY_PASSWORD'])) {
117
+            $mount->setBackendOption('password', $_ENV['NOTIFY_PASSWORD']);
118
+        } else if (isset($_SERVER['NOTIFY_PASSWORD'])) {
119
+            $mount->setBackendOption('password', $_SERVER['NOTIFY_PASSWORD']);
120
+        }
121
+
122
+        try {
123
+            $storage = $this->createStorage($mount);
124
+        } catch (\Exception $e) {
125
+            $output->writeln('<error>Error while trying to create storage</error>');
126
+            if ($noAuth) {
127
+                $output->writeln('<error>Username and/or password required</error>');
128
+            }
129
+            return 1;
130
+        }
131
+        if (!$storage instanceof INotifyStorage) {
132
+            $output->writeln('<error>Mount of type "' . $mount->getBackend()->getText() . '" does not support active update notifications</error>');
133
+            return 1;
134
+        }
135
+
136
+        $verbose = $input->getOption('verbose');
137
+
138
+        $path = trim($input->getOption('path'), '/');
139
+        $notifyHandler = $storage->notify($path);
140
+        $this->selfTest($storage, $notifyHandler, $verbose, $output);
141
+        $notifyHandler->listen(function (IChange $change) use ($mount, $verbose, $output) {
142
+            if ($verbose) {
143
+                $this->logUpdate($change, $output);
144
+            }
145
+            if ($change instanceof IRenameChange) {
146
+                $this->markParentAsOutdated($mount->getId(), $change->getTargetPath());
147
+            }
148
+            $this->markParentAsOutdated($mount->getId(), $change->getPath());
149
+        });
150
+    }
151
+
152
+    private function createStorage(StorageConfig $mount) {
153
+        $class = $mount->getBackend()->getStorageClass();
154
+        return new $class($mount->getBackendOptions());
155
+    }
156
+
157
+    private function markParentAsOutdated($mountId, $path) {
158
+        $parent = dirname($path);
159
+        if ($parent === '.') {
160
+            $parent = '';
161
+        }
162
+        $this->updateQuery->execute([$parent, $mountId]);
163
+    }
164
+
165
+    private function logUpdate(IChange $change, OutputInterface $output) {
166
+        switch ($change->getType()) {
167
+            case INotifyStorage::NOTIFY_ADDED:
168
+                $text = 'added';
169
+                break;
170
+            case INotifyStorage::NOTIFY_MODIFIED:
171
+                $text = 'modified';
172
+                break;
173
+            case INotifyStorage::NOTIFY_REMOVED:
174
+                $text = 'removed';
175
+                break;
176
+            case INotifyStorage::NOTIFY_RENAMED:
177
+                $text = 'renamed';
178
+                break;
179
+            default:
180
+                return;
181
+        }
182
+
183
+        $text .= ' ' . $change->getPath();
184
+        if ($change instanceof IRenameChange) {
185
+            $text .= ' to ' . $change->getTargetPath();
186
+        }
187
+
188
+        $output->writeln($text);
189
+    }
190
+
191
+    private function selfTest(IStorage $storage, INotifyHandler $notifyHandler, $verbose, OutputInterface $output) {
192
+        usleep(100 * 1000); //give time for the notify to start
193
+        $storage->file_put_contents('/.nc_test_file.txt', 'test content');
194
+        $storage->mkdir('/.nc_test_folder');
195
+        $storage->file_put_contents('/.nc_test_folder/subfile.txt', 'test content');
196
+
197
+        usleep(100 * 1000); //time for all changes to be processed
198
+        $changes = $notifyHandler->getChanges();
199
+
200
+        $storage->unlink('/.nc_test_file.txt');
201
+        $storage->unlink('/.nc_test_folder/subfile.txt');
202
+        $storage->rmdir('/.nc_test_folder');
203
+
204
+        usleep(100 * 1000); //time for all changes to be processed
205
+        $notifyHandler->getChanges(); // flush
206
+
207
+        $foundRootChange = false;
208
+        $foundSubfolderChange = false;
209
+
210
+        foreach ($changes as $change) {
211
+            if ($change->getPath() === '/.nc_test_file.txt' || $change->getPath() === '.nc_test_file.txt') {
212
+                $foundRootChange = true;
213
+            } else if ($change->getPath() === '/.nc_test_folder/subfile.txt' || $change->getPath() === '.nc_test_folder/subfile.txt') {
214
+                $foundSubfolderChange = true;
215
+            }
216
+        }
217
+
218
+        if ($foundRootChange && $foundSubfolderChange && $verbose) {
219
+            $output->writeln('<info>Self-test successful</info>');
220
+        } else if ($foundRootChange && !$foundSubfolderChange) {
221
+            $output->writeln('<error>Error while running self-test, change is subfolder not detected</error>');
222
+        } else if (!$foundRootChange) {
223
+            $output->writeln('<error>Error while running self-test, no changes detected</error>');
224
+        }
225
+    }
226 226
 }
Please login to merge, or discard this patch.