Completed
Push — master ( 879e11...10930c )
by Lukas
20:02 queued 06:34
created

MoveAvatarsBackgroundJob::run()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright 2016 Roeland Jago Douma <[email protected]>
4
 *
5
 * @author Roeland Jago Douma <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
namespace OC\Repair\NC11;
24
25
use OC\BackgroundJob\QueuedJob;
26
use OCP\Files\File;
27
use OCP\Files\Folder;
28
use OCP\Files\IAppData;
29
use OCP\Files\IRootFolder;
30
use OCP\Files\NotFoundException;
31
use OCP\Files\SimpleFS\ISimpleFolder;
32
use OCP\ILogger;
33
use OCP\IUser;
34
use OCP\IUserManager;
35
36
class MoveAvatarsBackgroundJob extends QueuedJob {
37
38
	/** @var IUserManager */
39
	private $userManager;
40
41
	/** @var IRootFolder */
42
	private $rootFolder;
43
44
	/** @var IAppData */
45
	private $appData;
46
47
	/** @var ILogger */
48
	private $logger;
49
50
	/**
51
	 * MoveAvatars constructor.
52
	 */
53
	public function __construct() {
54
		$this->userManager = \OC::$server->getUserManager();
55
		$this->rootFolder = \OC::$server->getRootFolder();
56
		$this->logger = \OC::$server->getLogger();
57
		$this->appData = \OC::$server->getAppDataDir('avatar');
58
	}
59
60
	public function run($arguments) {
61
		$this->logger->info('Started migrating avatars to AppData folder');
62
		$this->moveAvatars();
63
		$this->logger->info('All avatars migrated to AppData folder');
64
	}
65
66
	private function moveAvatars() {
67
		try {
68
			$ownCloudAvatars = $this->rootFolder->get('avatars');
69
		} catch (NotFoundException $e) {
70
			$ownCloudAvatars = null;
71
		}
72
73
		$counter = 0;
74
		$this->userManager->callForSeenUsers(function (IUser $user) use ($counter, $ownCloudAvatars) {
75
			$uid = $user->getUID();
76
77
			\OC\Files\Filesystem::initMountPoints($uid);
78
			/** @var Folder $userFolder */
79
			$userFolder = $this->rootFolder->get($uid);
80
81
			try {
82
				$userData = $this->appData->getFolder($uid);
83
			} catch (NotFoundException $e) {
84
				$userData = $this->appData->newFolder($uid);
85
			}
86
87
			$foundAvatars = $this->copyAvatarsFromFolder($userFolder, $userData);
88
89
			// ownCloud migration?
90
			if ($foundAvatars === 0 && $ownCloudAvatars instanceof Folder) {
91
				$parts = $this->buildOwnCloudAvatarPath($uid);
92
				$userOwnCloudAvatar = $ownCloudAvatars;
93
				foreach ($parts as $part) {
94
					try {
95
						$userOwnCloudAvatar = $userOwnCloudAvatar->get($part);
96
					} catch (NotFoundException $e) {
97
						return;
98
					}
99
				}
100
101
				$this->copyAvatarsFromFolder($userOwnCloudAvatar, $userData);
102
			}
103
104
			$counter++;
105
			if ($counter % 100 === 0) {
106
				$this->logger->info('{amount} avatars migrated', ['amount' => $counter]);
107
			}
108
		});
109
	}
110
111
	/**
112
	 * @param Folder $source
113
	 * @param ISimpleFolder $target
114
	 * @return int
115
	 * @throws \OCP\Files\NotPermittedException
116
	 * @throws NotFoundException
117
	 */
118
	protected function copyAvatarsFromFolder(Folder $source, ISimpleFolder $target) {
119
		$foundAvatars = 0;
120
		$avatars = $source->getDirectoryListing();
121
		$regex = '/^avatar\.([0-9]+\.)?(jpg|png)$/';
122
123
		foreach ($avatars as $avatar) {
124
			/** @var File $avatar */
125
			if (preg_match($regex, $avatar->getName())) {
126
				/*
127
				 * This is not the most effective but it is the most abstract way
128
				 * to handle this. Avatars should be small anyways.
129
				 */
130
				$newAvatar = $target->newFile($avatar->getName());
131
				$newAvatar->putContent($avatar->getContent());
132
				$avatar->delete();
133
				$foundAvatars++;
134
			}
135
		}
136
137
		return $foundAvatars;
138
	}
139
140
	protected function buildOwnCloudAvatarPath($userId) {
141
		$avatar = substr_replace(substr_replace(md5($userId), '/', 4, 0), '/', 2, 0);
142
		return explode('/', $avatar);
143
	}
144
}
145