{"action":"created","comment":{"url":"https://api.github.com/repos/owncloud/core/pulls/comments/26199741","id":26199741,"diff_hunk":"@@ -0,0 +1,262 @@\n+<?php\n+/**\n+ * @author Roeland Jago Douma <roeland@famdouma.nl>\n+ *\n+ * @copyright Copyright (c) 2015, ownCloud, Inc.\n+ * @license AGPL-3.0\n+ *\n+ * This code is free software: you can redistribute it and/or modify\n+ * it under the terms of the GNU Affero General Public License, version 3,\n+ * as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n+ * GNU Affero General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU Affero General Public License, version 3,\n+ * along with this program.  If not, see <http://www.gnu.org/licenses/>\n+ *\n+ */\n+namespace OC\\Core\\Avatar;\n+\n+use OCP\\AppFramework\\Controller;\n+use OCP\\AppFramework\\Http;\n+use OCP\\AppFramework\\Http\\DataResponse;\n+use OCP\\AppFramework\\Http\\ImageResponse;\n+use OCP\\IAvatarManager;\n+use OCP\\ICache;\n+use OCP\\IL10N;\n+use OCP\\IRequest;\n+use OCP\\IUserManager;\n+use OCP\\IUserSession;\n+\n+/**\n+ * Class AvatarController\n+ *\n+ * @package OC\\Core\\Avatar\n+ */\n+class AvatarController extends Controller {\n+\n+\t/** @var IAvatarManager */\n+\tprotected $avatarManager;\n+\n+\t/** @var ICache */\n+\tprotected $cache;\n+\n+\t/** @var IL10N */\n+\tprotected $l;\n+\n+\t/** @var IUserManager */\n+\tprotected $userManager;\n+\n+\t/** @var IUserSession */\n+\tprotected $userSession;\n+\n+\t/**\n+\t * @param string $appName\n+\t * @param IRequest $request\n+\t * @param IAvatarManager $avatarManager\n+\t * @param ICache $cache\n+\t * @param IL10N $l10n\n+\t * @param IUserManager $userManager\n+\t * @param IUserSession $userSession\n+\t */\n+\tpublic function __construct($appName,\n+\t\t\t\t\t\t\t\tIRequest $request,\n+\t\t\t\t\t\t\t\tIAvatarManager $avatarManager,\n+\t\t\t\t\t\t\t\tICache $cache,\n+\t\t\t\t\t\t\t\tIL10N $l10n,\n+\t\t\t\t\t\t\t\tIUserManager $userManager,\n+\t\t\t\t\t\t\t\tIUserSession $userSession) {\n+\t\tparent::__construct($appName, $request);\n+\n+\t\t$this->avatarManager = $avatarManager;\n+\t\t$this->cache = $cache;\n+\t\t$this->l = $l10n;\n+\t\t$this->userManager = $userManager;\n+\t\t$this->userSession = $userSession;\n+\t}\n+\n+\t/**\n+\t * @NoAdminRequired\n+\t *\n+\t * @param string $userId\n+\t * @param int $size\n+\t * @return DataResponse|ImageResponse\n+\t */\n+\tpublic function getAvatar($userId, $size) {\n+\t\tif ($size > 2048) {\n+\t\t\t$size = 2048;\n+\t\t} elseif ($size <= 0) {\n+\t\t\t$size = 64;\n+\t\t}\n+\n+\t\t$avatar = $this->avatarManager->getAvatar($userId);\n+\t\t$image = $avatar->get($size);\n+\n+\t\tif ($image instanceof \\OC_Image) {\n+\t\t\t$resp = new ImageResponse($image->data(),\n+\t\t\t\tHttp::STATUS_OK,\n+\t\t\t\t['Content-Type' => $image->mimeType()]);\n+\t\t\t$resp->setETag(crc32($image->data()));\n+\t\t} else {\n+\t\t\t$resp = new DataResponse(\n+\t\t\t\t\t\t['data' => [\n+\t\t\t\t\t\t\t\t'displayname' => $this->userManager->get($userId)->getDisplayName()\n+\t\t\t\t\t\t\t]\n+\t\t\t\t\t\t]);\n+\t\t}\n+\n+\t\t$resp->addHeader('Pragma', 'public');\n+\t\t$resp->cacheFor(0);\n+\t\t$resp->setLastModified(new \\DateTime('now', new \\DateTimeZone('GMT')));\n+\n+\t\treturn $resp;\n+\t}\n+\n+\t/**\n+\t * @NoAdminRequired\n+\t *\n+\t * @param string $path\n+\t * @return DataResponse\n+\t */\n+\tpublic function postAvatar($path) {\n+\t\t$userId = $this->userSession->getUser()->getUID();\n+\t\t$files = $this->request->getUploadedFile('files');\n+\n+\t\tif (isset($path)) {\n+\t\t\t$path = stripslashes($path);\n+\t\t\t$view = new \\OC\\Files\\View('/'.$userId.'/files');\n+\t\t\t$fileName = $view->getLocalFile($path);\n+\t\t} elseif (!is_null($files)) {\n+\t\t\tif (\n+\t\t\t\t$files['error'][0] === 0 &&\n+\t\t\t\t is_uploaded_file($files['tmp_name'][0]) &&\n+\t\t\t\t!\\OC\\Files\\Filesystem::isFileBlacklisted($files['tmp_name'][0])","path":"core/avatar/avatarcontroller.php","position":136,"original_position":136,"commit_id":"a019dbb571cb2e26d74f61bf94c49ba0637cb4ce","original_commit_id":"a019dbb571cb2e26d74f61bf94c49ba0637cb4ce","user":{"login":"LukasReschke","id":878997,"avatar_url":"https://avatars.githubusercontent.com/u/878997?v=3","gravatar_id":"","url":"https://api.github.com/users/LukasReschke","html_url":"https://github.com/LukasReschke","followers_url":"https://api.github.com/users/LukasReschke/followers","following_url":"https://api.github.com/users/LukasReschke/following{/other_user}","gists_url":"https://api.github.com/users/LukasReschke/gists{/gist_id}","starred_url":"https://api.github.com/users/LukasReschke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LukasReschke/subscriptions","organizations_url":"https://api.github.com/users/LukasReschke/orgs","repos_url":"https://api.github.com/users/LukasReschke/repos","events_url":"https://api.github.com/users/LukasReschke/events{/privacy}","received_events_url":"https://api.github.com/users/LukasReschke/received_events","type":"User","site_admin":false},"body":"Not required if you use the Node / View API","created_at":"2015-03-11T09:56:54Z","updated_at":"2015-03-11T09:56:54Z","html_url":"https://github.com/owncloud/core/pull/14705#discussion_r26199741","pull_request_url":"https://api.github.com/repos/owncloud/core/pulls/14705","_links":{"self":{"href":"https://api.github.com/repos/owncloud/core/pulls/comments/26199741"},"html":{"href":"https://github.com/owncloud/core/pull/14705#discussion_r26199741"},"pull_request":{"href":"https://api.github.com/repos/owncloud/core/pulls/14705"}}},"pull_request":{"url":"https://api.github.com/repos/owncloud/core/pulls/14705","id":30551261,"html_url":"https://github.com/owncloud/core/pull/14705","diff_url":"https://github.com/owncloud/core/pull/14705.diff","patch_url":"https://github.com/owncloud/core/pull/14705.patch","issue_url":"https://api.github.com/repos/owncloud/core/issues/14705","number":14705,"state":"open","locked":false,"title":"Move AvatarController to AppFramework","user":{"login":"rullzer","id":45821,"avatar_url":"https://avatars.githubusercontent.com/u/45821?v=3","gravatar_id":"","url":"https://api.github.com/users/rullzer","html_url":"https://github.com/rullzer","followers_url":"https://api.github.com/users/rullzer/followers","following_url":"https://api.github.com/users/rullzer/following{/other_user}","gists_url":"https://api.github.com/users/rullzer/gists{/gist_id}","starred_url":"https://api.github.com/users/rullzer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rullzer/subscriptions","organizations_url":"https://api.github.com/users/rullzer/orgs","repos_url":"https://api.github.com/users/rullzer/repos","events_url":"https://api.github.com/users/rullzer/events{/privacy}","received_events_url":"https://api.github.com/users/rullzer/received_events","type":"User","site_admin":false},"body":"When trying to implement remote avatars I figured we'd better have decent unit tests to ensure nothing breaks. But before I could do that the Avatar controller has to be moved to the Appframework. This is a first step on this.\r\n\r\n- I added an ImageResponse: This is basically just a response that outputs the test you give it. So a better name would maybe be TextResponse or VerbatimResponse or whatever.\r\n- The avatar class is converted to use the appFramework\r\n  - There are still some calls to \\OC\\Files\\.... I could not yet find decent replacements for them (which are easily mockable as well).\r\n- Old routes are changed. I'm not sure if this breaks something elsewere. Is it possible to let the old routes point to the new routes?\r\n- I started with some unit tests.\r\n  - Getting an avatar\r\n  - Deleting an avatar\r\n  - The other functionality seems to work on my machine. But unit tests still have to be writen.\r\n\r\nFeedback is welcome. As well as tips on how to make this class fully (and properly) unit testable!","created_at":"2015-03-05T12:01:27Z","updated_at":"2015-03-11T09:56:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ce46df3772d86a7ab0f6acb363bce9748d5e4d7b","assignee":null,"milestone":{"url":"https://api.github.com/repos/owncloud/core/milestones/31","html_url":"https://github.com/owncloud/core/milestones/8.1-current","labels_url":"https://api.github.com/repos/owncloud/core/milestones/31/labels","id":912160,"number":31,"title":"8.1-current","description":"","creator":{"login":"MorrisJobke","id":245432,"avatar_url":"https://avatars.githubusercontent.com/u/245432?v=3","gravatar_id":"","url":"https://api.github.com/users/MorrisJobke","html_url":"https://github.com/MorrisJobke","followers_url":"https://api.github.com/users/MorrisJobke/followers","following_url":"https://api.github.com/users/MorrisJobke/following{/other_user}","gists_url":"https://api.github.com/users/MorrisJobke/gists{/gist_id}","starred_url":"https://api.github.com/users/MorrisJobke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MorrisJobke/subscriptions","organizations_url":"https://api.github.com/users/MorrisJobke/orgs","repos_url":"https://api.github.com/users/MorrisJobke/repos","events_url":"https://api.github.com/users/MorrisJobke/events{/privacy}","received_events_url":"https://api.github.com/users/MorrisJobke/received_events","type":"User","site_admin":false},"open_issues":263,"closed_issues":302,"state":"open","created_at":"2014-12-22T12:04:01Z","updated_at":"2015-03-11T09:47:54Z","due_on":"2015-04-02T22:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/owncloud/core/pulls/14705/commits","review_comments_url":"https://api.github.com/repos/owncloud/core/pulls/14705/comments","review_comment_url":"https://api.github.com/repos/owncloud/core/pulls/comments{/number}","comments_url":"https://api.github.com/repos/owncloud/core/issues/14705/comments","statuses_url":"https://api.github.com/repos/owncloud/core/statuses/a019dbb571cb2e26d74f61bf94c49ba0637cb4ce","head":{"label":"rullzer:avatarcontroller","ref":"avatarcontroller","sha":"a019dbb571cb2e26d74f61bf94c49ba0637cb4ce","user":{"login":"rullzer","id":45821,"avatar_url":"https://avatars.githubusercontent.com/u/45821?v=3","gravatar_id":"","url":"https://api.github.com/users/rullzer","html_url":"https://github.com/rullzer","followers_url":"https://api.github.com/users/rullzer/followers","following_url":"https://api.github.com/users/rullzer/following{/other_user}","gists_url":"https://api.github.com/users/rullzer/gists{/gist_id}","starred_url":"https://api.github.com/users/rullzer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rullzer/subscriptions","organizations_url":"https://api.github.com/users/rullzer/orgs","repos_url":"https://api.github.com/users/rullzer/repos","events_url":"https://api.github.com/users/rullzer/events{/privacy}","received_events_url":"https://api.github.com/users/rullzer/received_events","type":"User","site_admin":false},"repo":{"id":29611886,"name":"core","full_name":"rullzer/core","owner":{"login":"rullzer","id":45821,"avatar_url":"https://avatars.githubusercontent.com/u/45821?v=3","gravatar_id":"","url":"https://api.github.com/users/rullzer","html_url":"https://github.com/rullzer","followers_url":"https://api.github.com/users/rullzer/followers","following_url":"https://api.github.com/users/rullzer/following{/other_user}","gists_url":"https://api.github.com/users/rullzer/gists{/gist_id}","starred_url":"https://api.github.com/users/rullzer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rullzer/subscriptions","organizations_url":"https://api.github.com/users/rullzer/orgs","repos_url":"https://api.github.com/users/rullzer/repos","events_url":"https://api.github.com/users/rullzer/events{/privacy}","received_events_url":"https://api.github.com/users/rullzer/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/rullzer/core","description":"The ownCloud core","fork":true,"url":"https://api.github.com/repos/rullzer/core","forks_url":"https://api.github.com/repos/rullzer/core/forks","keys_url":"https://api.github.com/repos/rullzer/core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rullzer/core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rullzer/core/teams","hooks_url":"https://api.github.com/repos/rullzer/core/hooks","issue_events_url":"https://api.github.com/repos/rullzer/core/issues/events{/number}","events_url":"https://api.github.com/repos/rullzer/core/events","assignees_url":"https://api.github.com/repos/rullzer/core/assignees{/user}","branches_url":"https://api.github.com/repos/rullzer/core/branches{/branch}","tags_url":"https://api.github.com/repos/rullzer/core/tags","blobs_url":"https://api.github.com/repos/rullzer/core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rullzer/core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rullzer/core/git/refs{/sha}","trees_url":"https://api.github.com/repos/rullzer/core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rullzer/core/statuses/{sha}","languages_url":"https://api.github.com/repos/rullzer/core/languages","stargazers_url":"https://api.github.com/repos/rullzer/core/stargazers","contributors_url":"https://api.github.com/repos/rullzer/core/contributors","subscribers_url":"https://api.github.com/repos/rullzer/core/subscribers","subscription_url":"https://api.github.com/repos/rullzer/core/subscription","commits_url":"https://api.github.com/repos/rullzer/core/commits{/sha}","git_commits_url":"https://api.github.com/repos/rullzer/core/git/commits{/sha}","comments_url":"https://api.github.com/repos/rullzer/core/comments{/number}","issue_comment_url":"https://api.github.com/repos/rullzer/core/issues/comments{/number}","contents_url":"https://api.github.com/repos/rullzer/core/contents/{+path}","compare_url":"https://api.github.com/repos/rullzer/core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rullzer/core/merges","archive_url":"https://api.github.com/repos/rullzer/core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rullzer/core/downloads","issues_url":"https://api.github.com/repos/rullzer/core/issues{/number}","pulls_url":"https://api.github.com/repos/rullzer/core/pulls{/number}","milestones_url":"https://api.github.com/repos/rullzer/core/milestones{/number}","notifications_url":"https://api.github.com/repos/rullzer/core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rullzer/core/labels{/name}","releases_url":"https://api.github.com/repos/rullzer/core/releases{/id}","created_at":"2015-01-21T20:40:40Z","updated_at":"2015-03-11T09:49:54Z","pushed_at":"2015-03-11T09:49:53Z","git_url":"git://github.com/rullzer/core.git","ssh_url":"git@github.com:rullzer/core.git","clone_url":"https://github.com/rullzer/core.git","svn_url":"https://github.com/rullzer/core","homepage":null,"size":154536,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"owncloud:master","ref":"master","sha":"01ea056ac8ad46ea59c56ca8c9aa7e7c90564bc4","user":{"login":"owncloud","id":1645051,"avatar_url":"https://avatars.githubusercontent.com/u/1645051?v=3","gravatar_id":"","url":"https://api.github.com/users/owncloud","html_url":"https://github.com/owncloud","followers_url":"https://api.github.com/users/owncloud/followers","following_url":"https://api.github.com/users/owncloud/following{/other_user}","gists_url":"https://api.github.com/users/owncloud/gists{/gist_id}","starred_url":"https://api.github.com/users/owncloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/owncloud/subscriptions","organizations_url":"https://api.github.com/users/owncloud/orgs","repos_url":"https://api.github.com/users/owncloud/repos","events_url":"https://api.github.com/users/owncloud/events{/privacy}","received_events_url":"https://api.github.com/users/owncloud/received_events","type":"Organization","site_admin":false},"repo":{"id":5550552,"name":"core","full_name":"owncloud/core","owner":{"login":"owncloud","id":1645051,"avatar_url":"https://avatars.githubusercontent.com/u/1645051?v=3","gravatar_id":"","url":"https://api.github.com/users/owncloud","html_url":"https://github.com/owncloud","followers_url":"https://api.github.com/users/owncloud/followers","following_url":"https://api.github.com/users/owncloud/following{/other_user}","gists_url":"https://api.github.com/users/owncloud/gists{/gist_id}","starred_url":"https://api.github.com/users/owncloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/owncloud/subscriptions","organizations_url":"https://api.github.com/users/owncloud/orgs","repos_url":"https://api.github.com/users/owncloud/repos","events_url":"https://api.github.com/users/owncloud/events{/privacy}","received_events_url":"https://api.github.com/users/owncloud/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/owncloud/core","description":"The ownCloud core","fork":false,"url":"https://api.github.com/repos/owncloud/core","forks_url":"https://api.github.com/repos/owncloud/core/forks","keys_url":"https://api.github.com/repos/owncloud/core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/owncloud/core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/owncloud/core/teams","hooks_url":"https://api.github.com/repos/owncloud/core/hooks","issue_events_url":"https://api.github.com/repos/owncloud/core/issues/events{/number}","events_url":"https://api.github.com/repos/owncloud/core/events","assignees_url":"https://api.github.com/repos/owncloud/core/assignees{/user}","branches_url":"https://api.github.com/repos/owncloud/core/branches{/branch}","tags_url":"https://api.github.com/repos/owncloud/core/tags","blobs_url":"https://api.github.com/repos/owncloud/core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/owncloud/core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/owncloud/core/git/refs{/sha}","trees_url":"https://api.github.com/repos/owncloud/core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/owncloud/core/statuses/{sha}","languages_url":"https://api.github.com/repos/owncloud/core/languages","stargazers_url":"https://api.github.com/repos/owncloud/core/stargazers","contributors_url":"https://api.github.com/repos/owncloud/core/contributors","subscribers_url":"https://api.github.com/repos/owncloud/core/subscribers","subscription_url":"https://api.github.com/repos/owncloud/core/subscription","commits_url":"https://api.github.com/repos/owncloud/core/commits{/sha}","git_commits_url":"https://api.github.com/repos/owncloud/core/git/commits{/sha}","comments_url":"https://api.github.com/repos/owncloud/core/comments{/number}","issue_comment_url":"https://api.github.com/repos/owncloud/core/issues/comments{/number}","contents_url":"https://api.github.com/repos/owncloud/core/contents/{+path}","compare_url":"https://api.github.com/repos/owncloud/core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/owncloud/core/merges","archive_url":"https://api.github.com/repos/owncloud/core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/owncloud/core/downloads","issues_url":"https://api.github.com/repos/owncloud/core/issues{/number}","pulls_url":"https://api.github.com/repos/owncloud/core/pulls{/number}","milestones_url":"https://api.github.com/repos/owncloud/core/milestones{/number}","notifications_url":"https://api.github.com/repos/owncloud/core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/owncloud/core/labels{/name}","releases_url":"https://api.github.com/repos/owncloud/core/releases{/id}","created_at":"2012-08-25T10:32:48Z","updated_at":"2015-03-11T09:50:24Z","pushed_at":"2015-03-11T09:00:07Z","git_url":"git://github.com/owncloud/core.git","ssh_url":"git@github.com:owncloud/core.git","clone_url":"https://github.com/owncloud/core.git","svn_url":"https://github.com/owncloud/core","homepage":null,"size":923215,"stargazers_count":3117,"watchers_count":3117,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1002,"mirror_url":null,"open_issues_count":1823,"forks":1002,"open_issues":1823,"watchers":3117,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/owncloud/core/pulls/14705"},"html":{"href":"https://github.com/owncloud/core/pull/14705"},"issue":{"href":"https://api.github.com/repos/owncloud/core/issues/14705"},"comments":{"href":"https://api.github.com/repos/owncloud/core/issues/14705/comments"},"review_comments":{"href":"https://api.github.com/repos/owncloud/core/pulls/14705/comments"},"review_comment":{"href":"https://api.github.com/repos/owncloud/core/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/owncloud/core/pulls/14705/commits"},"statuses":{"href":"https://api.github.com/repos/owncloud/core/statuses/a019dbb571cb2e26d74f61bf94c49ba0637cb4ce"}}}}