{"action":"created","comment":{"url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls/comments/36455485","id":36455485,"diff_hunk":"@@ -0,0 +1,59 @@\n+from flask import current_app\n+import Image\n+from os import mkdir, remove\n+from os.path import exists, join\n+from project.bl.utils import BaseBL\n+from uuid import uuid4\n+from werkzeug import secure_filename\n+\n+\n+class UploadedImageBL(BaseBL):\n+\n+    def save_image(self, *, image, img_category, **kwargs):\n+        def mkdir_ifn_exists(dirpath):\n+            if not exists(dirpath):\n+                mkdir(dirpath, mode=0o751)\n+\n+        if image is None:\n+            return\n+        if 'title' not in kwargs:\n+            kwargs['title'] = secure_filename(image.filename)\n+        category_dir = join(\n+            current_app.config['UPLOAD_FOLDER'],\n+            img_category.name\n+        )\n+        mkdir_ifn_exists(category_dir)\n+\n+        thumbnail_dir = join(category_dir, 'thumb')\n+        fullsized_dir = join(category_dir, 'full')\n+        mkdir_ifn_exists(thumbnail_dir)\n+        mkdir_ifn_exists(fullsized_dir)\n+\n+        uid = uuid4().hex\n+        ext = image.filename.rsplit('.', 1)[1]\n+        uid += '.' + ext\n+        image.save(join(fullsized_dir, uid))\n+        thumb = Image.open(join(fullsized_dir, uid))\n+        thumb.thumbnail((75, 75), Image.NEAREST)","path":"project/bl/uploads.py","position":37,"original_position":37,"commit_id":"3e94fa953910819ca68c6e3e6bfe14071228858f","original_commit_id":"3e94fa953910819ca68c6e3e6bfe14071228858f","user":{"login":"Orhideous","id":2265184,"avatar_url":"https://avatars.githubusercontent.com/u/2265184?v=3","gravatar_id":"","url":"https://api.github.com/users/Orhideous","html_url":"https://github.com/Orhideous","followers_url":"https://api.github.com/users/Orhideous/followers","following_url":"https://api.github.com/users/Orhideous/following{/other_user}","gists_url":"https://api.github.com/users/Orhideous/gists{/gist_id}","starred_url":"https://api.github.com/users/Orhideous/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Orhideous/subscriptions","organizations_url":"https://api.github.com/users/Orhideous/orgs","repos_url":"https://api.github.com/users/Orhideous/repos","events_url":"https://api.github.com/users/Orhideous/events{/privacy}","received_events_url":"https://api.github.com/users/Orhideous/received_events","type":"User","site_admin":false},"body":"```\r\npython thumb.thumbnail((75, 75), Image.NEAREST```\r\nТак ведь оно ж страшное будет, как атомная война. Во-первых, используй `Image.LANCZOS`. Во-вторых, что в `PIL`, что в `Pillow` метод `thumbnail()` хронически поломан, и всем на него, как бы помягче… в общем, лучше брать `resize()`","created_at":"2015-08-06T19:31:29Z","updated_at":"2015-08-06T19:31:29Z","html_url":"https://github.com/uaprom-summer-2015/Meowth/pull/116#discussion_r36455485","pull_request_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls/116","_links":{"self":{"href":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls/comments/36455485"},"html":{"href":"https://github.com/uaprom-summer-2015/Meowth/pull/116#discussion_r36455485"},"pull_request":{"href":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls/116"}}},"pull_request":{"url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls/116","id":41784829,"html_url":"https://github.com/uaprom-summer-2015/Meowth/pull/116","diff_url":"https://github.com/uaprom-summer-2015/Meowth/pull/116.diff","patch_url":"https://github.com/uaprom-summer-2015/Meowth/pull/116.patch","issue_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/issues/116","number":116,"state":"open","locked":false,"title":"Uploads","user":{"login":"anxolerd","id":6533582,"avatar_url":"https://avatars.githubusercontent.com/u/6533582?v=3","gravatar_id":"","url":"https://api.github.com/users/anxolerd","html_url":"https://github.com/anxolerd","followers_url":"https://api.github.com/users/anxolerd/followers","following_url":"https://api.github.com/users/anxolerd/following{/other_user}","gists_url":"https://api.github.com/users/anxolerd/gists{/gist_id}","starred_url":"https://api.github.com/users/anxolerd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/anxolerd/subscriptions","organizations_url":"https://api.github.com/users/anxolerd/orgs","repos_url":"https://api.github.com/users/anxolerd/repos","events_url":"https://api.github.com/users/anxolerd/events{/privacy}","received_events_url":"https://api.github.com/users/anxolerd/received_events","type":"User","site_admin":false},"body":"# Uploads\r\nAdded basic ability to upload images It is available on `/admin/gallery/upload` endpoint ","created_at":"2015-08-06T13:01:36Z","updated_at":"2015-08-06T19:31:29Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d89b350cc4925fa169edaf98260d003d16b3eb98","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls/116/commits","review_comments_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls/116/comments","review_comment_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls/comments{/number}","comments_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/issues/116/comments","statuses_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/statuses/3e94fa953910819ca68c6e3e6bfe14071228858f","head":{"label":"uaprom-summer-2015:uploads","ref":"uploads","sha":"3e94fa953910819ca68c6e3e6bfe14071228858f","user":{"login":"uaprom-summer-2015","id":13165943,"avatar_url":"https://avatars.githubusercontent.com/u/13165943?v=3","gravatar_id":"","url":"https://api.github.com/users/uaprom-summer-2015","html_url":"https://github.com/uaprom-summer-2015","followers_url":"https://api.github.com/users/uaprom-summer-2015/followers","following_url":"https://api.github.com/users/uaprom-summer-2015/following{/other_user}","gists_url":"https://api.github.com/users/uaprom-summer-2015/gists{/gist_id}","starred_url":"https://api.github.com/users/uaprom-summer-2015/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uaprom-summer-2015/subscriptions","organizations_url":"https://api.github.com/users/uaprom-summer-2015/orgs","repos_url":"https://api.github.com/users/uaprom-summer-2015/repos","events_url":"https://api.github.com/users/uaprom-summer-2015/events{/privacy}","received_events_url":"https://api.github.com/users/uaprom-summer-2015/received_events","type":"Organization","site_admin":false},"repo":{"id":38690649,"name":"Meowth","full_name":"uaprom-summer-2015/Meowth","owner":{"login":"uaprom-summer-2015","id":13165943,"avatar_url":"https://avatars.githubusercontent.com/u/13165943?v=3","gravatar_id":"","url":"https://api.github.com/users/uaprom-summer-2015","html_url":"https://github.com/uaprom-summer-2015","followers_url":"https://api.github.com/users/uaprom-summer-2015/followers","following_url":"https://api.github.com/users/uaprom-summer-2015/following{/other_user}","gists_url":"https://api.github.com/users/uaprom-summer-2015/gists{/gist_id}","starred_url":"https://api.github.com/users/uaprom-summer-2015/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uaprom-summer-2015/subscriptions","organizations_url":"https://api.github.com/users/uaprom-summer-2015/orgs","repos_url":"https://api.github.com/users/uaprom-summer-2015/repos","events_url":"https://api.github.com/users/uaprom-summer-2015/events{/privacy}","received_events_url":"https://api.github.com/users/uaprom-summer-2015/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/uaprom-summer-2015/Meowth","description":"Yet another CMS for common use","fork":false,"url":"https://api.github.com/repos/uaprom-summer-2015/Meowth","forks_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/forks","keys_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/teams","hooks_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/hooks","issue_events_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/issues/events{/number}","events_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/events","assignees_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/assignees{/user}","branches_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/branches{/branch}","tags_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/tags","blobs_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/git/refs{/sha}","trees_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/statuses/{sha}","languages_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/languages","stargazers_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/stargazers","contributors_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/contributors","subscribers_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/subscribers","subscription_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/subscription","commits_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/commits{/sha}","git_commits_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/git/commits{/sha}","comments_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/comments{/number}","issue_comment_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/issues/comments{/number}","contents_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/contents/{+path}","compare_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/merges","archive_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/downloads","issues_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/issues{/number}","pulls_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls{/number}","milestones_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/milestones{/number}","notifications_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/labels{/name}","releases_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/releases{/id}","created_at":"2015-07-07T13:49:41Z","updated_at":"2015-07-31T13:20:32Z","pushed_at":"2015-08-06T15:23:33Z","git_url":"git://github.com/uaprom-summer-2015/Meowth.git","ssh_url":"git@github.com:uaprom-summer-2015/Meowth.git","clone_url":"https://github.com/uaprom-summer-2015/Meowth.git","svn_url":"https://github.com/uaprom-summer-2015/Meowth","homepage":"","size":7154,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":3,"forks":2,"open_issues":3,"watchers":0,"default_branch":"master"}},"base":{"label":"uaprom-summer-2015:master","ref":"master","sha":"7ed72db99dcac1b63289ffb5b1ce7d21630cca39","user":{"login":"uaprom-summer-2015","id":13165943,"avatar_url":"https://avatars.githubusercontent.com/u/13165943?v=3","gravatar_id":"","url":"https://api.github.com/users/uaprom-summer-2015","html_url":"https://github.com/uaprom-summer-2015","followers_url":"https://api.github.com/users/uaprom-summer-2015/followers","following_url":"https://api.github.com/users/uaprom-summer-2015/following{/other_user}","gists_url":"https://api.github.com/users/uaprom-summer-2015/gists{/gist_id}","starred_url":"https://api.github.com/users/uaprom-summer-2015/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uaprom-summer-2015/subscriptions","organizations_url":"https://api.github.com/users/uaprom-summer-2015/orgs","repos_url":"https://api.github.com/users/uaprom-summer-2015/repos","events_url":"https://api.github.com/users/uaprom-summer-2015/events{/privacy}","received_events_url":"https://api.github.com/users/uaprom-summer-2015/received_events","type":"Organization","site_admin":false},"repo":{"id":38690649,"name":"Meowth","full_name":"uaprom-summer-2015/Meowth","owner":{"login":"uaprom-summer-2015","id":13165943,"avatar_url":"https://avatars.githubusercontent.com/u/13165943?v=3","gravatar_id":"","url":"https://api.github.com/users/uaprom-summer-2015","html_url":"https://github.com/uaprom-summer-2015","followers_url":"https://api.github.com/users/uaprom-summer-2015/followers","following_url":"https://api.github.com/users/uaprom-summer-2015/following{/other_user}","gists_url":"https://api.github.com/users/uaprom-summer-2015/gists{/gist_id}","starred_url":"https://api.github.com/users/uaprom-summer-2015/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uaprom-summer-2015/subscriptions","organizations_url":"https://api.github.com/users/uaprom-summer-2015/orgs","repos_url":"https://api.github.com/users/uaprom-summer-2015/repos","events_url":"https://api.github.com/users/uaprom-summer-2015/events{/privacy}","received_events_url":"https://api.github.com/users/uaprom-summer-2015/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/uaprom-summer-2015/Meowth","description":"Yet another CMS for common use","fork":false,"url":"https://api.github.com/repos/uaprom-summer-2015/Meowth","forks_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/forks","keys_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/teams","hooks_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/hooks","issue_events_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/issues/events{/number}","events_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/events","assignees_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/assignees{/user}","branches_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/branches{/branch}","tags_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/tags","blobs_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/git/refs{/sha}","trees_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/statuses/{sha}","languages_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/languages","stargazers_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/stargazers","contributors_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/contributors","subscribers_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/subscribers","subscription_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/subscription","commits_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/commits{/sha}","git_commits_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/git/commits{/sha}","comments_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/comments{/number}","issue_comment_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/issues/comments{/number}","contents_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/contents/{+path}","compare_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/merges","archive_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/downloads","issues_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/issues{/number}","pulls_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls{/number}","milestones_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/milestones{/number}","notifications_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/labels{/name}","releases_url":"https://api.github.com/repos/uaprom-summer-2015/Meowth/releases{/id}","created_at":"2015-07-07T13:49:41Z","updated_at":"2015-07-31T13:20:32Z","pushed_at":"2015-08-06T15:23:33Z","git_url":"git://github.com/uaprom-summer-2015/Meowth.git","ssh_url":"git@github.com:uaprom-summer-2015/Meowth.git","clone_url":"https://github.com/uaprom-summer-2015/Meowth.git","svn_url":"https://github.com/uaprom-summer-2015/Meowth","homepage":"","size":7154,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":3,"forks":2,"open_issues":3,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls/116"},"html":{"href":"https://github.com/uaprom-summer-2015/Meowth/pull/116"},"issue":{"href":"https://api.github.com/repos/uaprom-summer-2015/Meowth/issues/116"},"comments":{"href":"https://api.github.com/repos/uaprom-summer-2015/Meowth/issues/116/comments"},"review_comments":{"href":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls/116/comments"},"review_comment":{"href":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/uaprom-summer-2015/Meowth/pulls/116/commits"},"statuses":{"href":"https://api.github.com/repos/uaprom-summer-2015/Meowth/statuses/3e94fa953910819ca68c6e3e6bfe14071228858f"}}}}