{"action":"created","comment":{"url":"https://api.github.com/repos/edx/ecommerce/pulls/comments/59446954","id":59446954,"diff_hunk":"@@ -0,0 +1,96 @@\n+\"\"\"\n+Static file finders for Django.\n+https://docs.djangoproject.com/en/1.8/ref/settings/#std:setting-STATICFILES_FINDERS\n+Yes, this interface is private and undocumented, but we need to access it anyway.\n+\n+In order to deploy Open edX in production, it's important to be able to collect\n+and process static assets: images, CSS, JS, fonts, etc. Django's collectstatic\n+system is the accepted way to do that in Django-based projects, but that system\n+doesn't handle every kind of collection and processing that web developers need.\n+Other open source projects like `Django-Pipeline`_ and `Django-Require`_ hook\n+into Django's collectstatic system to provide features like minification,\n+compression, Sass pre-processing, and require.js optimization for assets before\n+they are pushed to production. To make sure that themed assets are collected\n+and served by the system (in addition to core assets), we need to extend this\n+interface, as well.\n+\n+.. _Django-Pipeline: http://django-pipeline.readthedocs.org/\n+.. _Django-Require: https://github.com/etianen/django-require\n+\"\"\"\n+import os\n+from collections import OrderedDict\n+\n+from django.contrib.staticfiles import utils\n+from django.contrib.staticfiles.finders import BaseFinder\n+from django.utils import six\n+\n+from ecommerce.theming.helpers import get_themes\n+from ecommerce.theming.storage import ThemeStorage\n+\n+\n+class ThemeFilesFinder(BaseFinder):\n+    \"\"\"\n+    A static files finder that looks in the directory of each theme as\n+    specified in the source_dir attribute.\n+    \"\"\"\n+    storage_class = ThemeStorage\n+    source_dir = 'static'\n+\n+    def __init__(self, *args, **kwargs):\n+        # The list of themes that are handled\n+        self.themes = []\n+        # Mapping of theme names to storage instances\n+        self.storages = OrderedDict()\n+\n+        themes = get_themes()\n+        for theme in themes:\n+            theme_storage = self.storage_class(\n+                os.path.join(theme.path, self.source_dir),\n+                prefix=theme.theme_dir,\n+            )\n+\n+            self.storages[theme.theme_dir] = theme_storage\n+            if theme.theme_dir not in self.themes:\n+                self.themes.append(theme.theme_dir)\n+\n+        super(ThemeFilesFinder, self).__init__(*args, **kwargs)\n+\n+    def list(self, ignore_patterns):\n+        \"\"\"\n+        List all files in all theme storages.\n+        \"\"\"\n+        for storage in six.itervalues(self.storages):\n+            if storage.exists(''):  # check if storage location exists\n+                for path in utils.get_files(storage, ignore_patterns):\n+                    yield path, storage\n+\n+    def find(self, path, all=False):  # pylint: disable=redefined-builtin\n+        \"\"\"\n+        Looks for files in the theme directories.\n+        \"\"\"\n+        matches = []\n+        theme_dir = path.split(\"/\", 1)[0]","path":"ecommerce/theming/finders.py","position":72,"original_position":72,"commit_id":"6538bd3b31e83ce1474df26724b49b32c98ca6aa","original_commit_id":"6538bd3b31e83ce1474df26724b49b32c98ca6aa","user":{"login":"jimabramson","id":1349368,"avatar_url":"https://avatars.githubusercontent.com/u/1349368?v=3","gravatar_id":"","url":"https://api.github.com/users/jimabramson","html_url":"https://github.com/jimabramson","followers_url":"https://api.github.com/users/jimabramson/followers","following_url":"https://api.github.com/users/jimabramson/following{/other_user}","gists_url":"https://api.github.com/users/jimabramson/gists{/gist_id}","starred_url":"https://api.github.com/users/jimabramson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jimabramson/subscriptions","organizations_url":"https://api.github.com/users/jimabramson/orgs","repos_url":"https://api.github.com/users/jimabramson/repos","events_url":"https://api.github.com/users/jimabramson/events{/privacy}","received_events_url":"https://api.github.com/users/jimabramson/received_events","type":"User","site_admin":false},"body":"perhaps an edge case, but if i have a subdirectory that has the same name as one of the known themes, this function will get confused, right?   If so, might be worth adding a warning to the docs. ","created_at":"2016-04-12T20:24:58Z","updated_at":"2016-04-12T20:24:58Z","html_url":"https://github.com/edx/ecommerce/pull/649#discussion_r59446954","pull_request_url":"https://api.github.com/repos/edx/ecommerce/pulls/649","_links":{"self":{"href":"https://api.github.com/repos/edx/ecommerce/pulls/comments/59446954"},"html":{"href":"https://github.com/edx/ecommerce/pull/649#discussion_r59446954"},"pull_request":{"href":"https://api.github.com/repos/edx/ecommerce/pulls/649"}}},"pull_request":{"url":"https://api.github.com/repos/edx/ecommerce/pulls/649","id":64941282,"html_url":"https://github.com/edx/ecommerce/pull/649","diff_url":"https://github.com/edx/ecommerce/pull/649.diff","patch_url":"https://github.com/edx/ecommerce/pull/649.patch","issue_url":"https://api.github.com/repos/edx/ecommerce/issues/649","number":649,"state":"open","locked":false,"title":"WL-330: Multi-Site Branding in Otto","user":{"login":"saleem-latif","id":7114956,"avatar_url":"https://avatars.githubusercontent.com/u/7114956?v=3","gravatar_id":"","url":"https://api.github.com/users/saleem-latif","html_url":"https://github.com/saleem-latif","followers_url":"https://api.github.com/users/saleem-latif/followers","following_url":"https://api.github.com/users/saleem-latif/following{/other_user}","gists_url":"https://api.github.com/users/saleem-latif/gists{/gist_id}","starred_url":"https://api.github.com/users/saleem-latif/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/saleem-latif/subscriptions","organizations_url":"https://api.github.com/users/saleem-latif/orgs","repos_url":"https://api.github.com/users/saleem-latif/repos","events_url":"https://api.github.com/users/saleem-latif/events{/privacy}","received_events_url":"https://api.github.com/users/saleem-latif/received_events","type":"User","site_admin":false},"body":"Hi @mattdrayer \r\n\r\nI have completed changes related to WL-330, Kindly review these changes and share your thoughts on this.\r\n\r\n__Description of WL-330:__\r\nChanges included customization of\r\n* Static Files Finders and Static Storage\r\n* Sass compilation workflow\r\n* Template Loaders\r\n\r\nand helper functions for enabling comprehensive theming for Otto.\r\n","created_at":"2016-04-01T13:04:27Z","updated_at":"2016-04-12T20:24:58Z","closed_at":null,"merged_at":null,"merge_commit_sha":"df8d120ba86b205ca59492cb28ac426f1e9499bd","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/edx/ecommerce/pulls/649/commits","review_comments_url":"https://api.github.com/repos/edx/ecommerce/pulls/649/comments","review_comment_url":"https://api.github.com/repos/edx/ecommerce/pulls/comments{/number}","comments_url":"https://api.github.com/repos/edx/ecommerce/issues/649/comments","statuses_url":"https://api.github.com/repos/edx/ecommerce/statuses/6538bd3b31e83ce1474df26724b49b32c98ca6aa","head":{"label":"edx:saleem-latif/WL-330","ref":"saleem-latif/WL-330","sha":"6538bd3b31e83ce1474df26724b49b32c98ca6aa","user":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"repo":{"id":30175039,"name":"ecommerce","full_name":"edx/ecommerce","owner":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/edx/ecommerce","description":"Django application used to manage edX's product catalog and handle orders for those products.","fork":false,"url":"https://api.github.com/repos/edx/ecommerce","forks_url":"https://api.github.com/repos/edx/ecommerce/forks","keys_url":"https://api.github.com/repos/edx/ecommerce/keys{/key_id}","collaborators_url":"https://api.github.com/repos/edx/ecommerce/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/edx/ecommerce/teams","hooks_url":"https://api.github.com/repos/edx/ecommerce/hooks","issue_events_url":"https://api.github.com/repos/edx/ecommerce/issues/events{/number}","events_url":"https://api.github.com/repos/edx/ecommerce/events","assignees_url":"https://api.github.com/repos/edx/ecommerce/assignees{/user}","branches_url":"https://api.github.com/repos/edx/ecommerce/branches{/branch}","tags_url":"https://api.github.com/repos/edx/ecommerce/tags","blobs_url":"https://api.github.com/repos/edx/ecommerce/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/edx/ecommerce/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/edx/ecommerce/git/refs{/sha}","trees_url":"https://api.github.com/repos/edx/ecommerce/git/trees{/sha}","statuses_url":"https://api.github.com/repos/edx/ecommerce/statuses/{sha}","languages_url":"https://api.github.com/repos/edx/ecommerce/languages","stargazers_url":"https://api.github.com/repos/edx/ecommerce/stargazers","contributors_url":"https://api.github.com/repos/edx/ecommerce/contributors","subscribers_url":"https://api.github.com/repos/edx/ecommerce/subscribers","subscription_url":"https://api.github.com/repos/edx/ecommerce/subscription","commits_url":"https://api.github.com/repos/edx/ecommerce/commits{/sha}","git_commits_url":"https://api.github.com/repos/edx/ecommerce/git/commits{/sha}","comments_url":"https://api.github.com/repos/edx/ecommerce/comments{/number}","issue_comment_url":"https://api.github.com/repos/edx/ecommerce/issues/comments{/number}","contents_url":"https://api.github.com/repos/edx/ecommerce/contents/{+path}","compare_url":"https://api.github.com/repos/edx/ecommerce/compare/{base}...{head}","merges_url":"https://api.github.com/repos/edx/ecommerce/merges","archive_url":"https://api.github.com/repos/edx/ecommerce/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/edx/ecommerce/downloads","issues_url":"https://api.github.com/repos/edx/ecommerce/issues{/number}","pulls_url":"https://api.github.com/repos/edx/ecommerce/pulls{/number}","milestones_url":"https://api.github.com/repos/edx/ecommerce/milestones{/number}","notifications_url":"https://api.github.com/repos/edx/ecommerce/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/edx/ecommerce/labels{/name}","releases_url":"https://api.github.com/repos/edx/ecommerce/releases{/id}","deployments_url":"https://api.github.com/repos/edx/ecommerce/deployments","created_at":"2015-02-02T06:55:15Z","updated_at":"2016-04-08T10:19:34Z","pushed_at":"2016-04-12T18:50:23Z","git_url":"git://github.com/edx/ecommerce.git","ssh_url":"git@github.com:edx/ecommerce.git","clone_url":"https://github.com/edx/ecommerce.git","svn_url":"https://github.com/edx/ecommerce","homepage":"","size":10044,"stargazers_count":30,"watchers_count":30,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":31,"mirror_url":null,"open_issues_count":11,"forks":31,"open_issues":11,"watchers":30,"default_branch":"master"}},"base":{"label":"edx:master","ref":"master","sha":"c17a6ea8a1acaf1e9aa92adf81193f142d649cb7","user":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"repo":{"id":30175039,"name":"ecommerce","full_name":"edx/ecommerce","owner":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/edx/ecommerce","description":"Django application used to manage edX's product catalog and handle orders for those products.","fork":false,"url":"https://api.github.com/repos/edx/ecommerce","forks_url":"https://api.github.com/repos/edx/ecommerce/forks","keys_url":"https://api.github.com/repos/edx/ecommerce/keys{/key_id}","collaborators_url":"https://api.github.com/repos/edx/ecommerce/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/edx/ecommerce/teams","hooks_url":"https://api.github.com/repos/edx/ecommerce/hooks","issue_events_url":"https://api.github.com/repos/edx/ecommerce/issues/events{/number}","events_url":"https://api.github.com/repos/edx/ecommerce/events","assignees_url":"https://api.github.com/repos/edx/ecommerce/assignees{/user}","branches_url":"https://api.github.com/repos/edx/ecommerce/branches{/branch}","tags_url":"https://api.github.com/repos/edx/ecommerce/tags","blobs_url":"https://api.github.com/repos/edx/ecommerce/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/edx/ecommerce/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/edx/ecommerce/git/refs{/sha}","trees_url":"https://api.github.com/repos/edx/ecommerce/git/trees{/sha}","statuses_url":"https://api.github.com/repos/edx/ecommerce/statuses/{sha}","languages_url":"https://api.github.com/repos/edx/ecommerce/languages","stargazers_url":"https://api.github.com/repos/edx/ecommerce/stargazers","contributors_url":"https://api.github.com/repos/edx/ecommerce/contributors","subscribers_url":"https://api.github.com/repos/edx/ecommerce/subscribers","subscription_url":"https://api.github.com/repos/edx/ecommerce/subscription","commits_url":"https://api.github.com/repos/edx/ecommerce/commits{/sha}","git_commits_url":"https://api.github.com/repos/edx/ecommerce/git/commits{/sha}","comments_url":"https://api.github.com/repos/edx/ecommerce/comments{/number}","issue_comment_url":"https://api.github.com/repos/edx/ecommerce/issues/comments{/number}","contents_url":"https://api.github.com/repos/edx/ecommerce/contents/{+path}","compare_url":"https://api.github.com/repos/edx/ecommerce/compare/{base}...{head}","merges_url":"https://api.github.com/repos/edx/ecommerce/merges","archive_url":"https://api.github.com/repos/edx/ecommerce/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/edx/ecommerce/downloads","issues_url":"https://api.github.com/repos/edx/ecommerce/issues{/number}","pulls_url":"https://api.github.com/repos/edx/ecommerce/pulls{/number}","milestones_url":"https://api.github.com/repos/edx/ecommerce/milestones{/number}","notifications_url":"https://api.github.com/repos/edx/ecommerce/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/edx/ecommerce/labels{/name}","releases_url":"https://api.github.com/repos/edx/ecommerce/releases{/id}","deployments_url":"https://api.github.com/repos/edx/ecommerce/deployments","created_at":"2015-02-02T06:55:15Z","updated_at":"2016-04-08T10:19:34Z","pushed_at":"2016-04-12T18:50:23Z","git_url":"git://github.com/edx/ecommerce.git","ssh_url":"git@github.com:edx/ecommerce.git","clone_url":"https://github.com/edx/ecommerce.git","svn_url":"https://github.com/edx/ecommerce","homepage":"","size":10044,"stargazers_count":30,"watchers_count":30,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":31,"mirror_url":null,"open_issues_count":11,"forks":31,"open_issues":11,"watchers":30,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/edx/ecommerce/pulls/649"},"html":{"href":"https://github.com/edx/ecommerce/pull/649"},"issue":{"href":"https://api.github.com/repos/edx/ecommerce/issues/649"},"comments":{"href":"https://api.github.com/repos/edx/ecommerce/issues/649/comments"},"review_comments":{"href":"https://api.github.com/repos/edx/ecommerce/pulls/649/comments"},"review_comment":{"href":"https://api.github.com/repos/edx/ecommerce/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/edx/ecommerce/pulls/649/commits"},"statuses":{"href":"https://api.github.com/repos/edx/ecommerce/statuses/6538bd3b31e83ce1474df26724b49b32c98ca6aa"}}}}