Skip to content
This repository has been archived by the owner on Mar 15, 2018. It is now read-only.

Commit

Permalink
Merge pull request #3089 from diox/websites-icons
Browse files Browse the repository at this point in the history
Add websites icon(s) to the model and expose them through the API (bug 1164053)
  • Loading branch information
diox committed May 19, 2015
2 parents ee74c91 + 41e41f2 commit d1a2d26
Show file tree
Hide file tree
Showing 47 changed files with 141 additions and 346 deletions.
2 changes: 1 addition & 1 deletion docs/api/topics/comm.rst
Expand Up @@ -113,7 +113,7 @@ Thread
"id": 5,
"name": "Test App (kinkajou3969)",
"review_url": "/reviewers/apps/review/test-app-kinkajou3969/",
"thumbnail_url": "/media/img/icons/no-preview.png",
"thumbnail_url": "/tmp/uploads/previews/thumbs/0/37.png?modified=1362762723",
"url": "/app/test-app-kinkajou3969/"
},
"created": "2013-06-14T11:54:24",
Expand Down
5 changes: 3 additions & 2 deletions lib/utils.py
Expand Up @@ -57,12 +57,13 @@ def static_url(url):
If the URL starts with https:// or http://, then no changes are made.
"""
prefix = {
'ADDON_ICONS_DEFAULT_URL': settings.MEDIA_URL,
'ICONS_DEFAULT_URL': settings.MEDIA_URL,
'ADDON_ICON_URL': settings.STATIC_URL,
'PREVIEW_THUMBNAIL_URL': settings.STATIC_URL,
'PREVIEW_FULL_URL': settings.STATIC_URL,
'PRODUCT_ICON_URL': settings.MEDIA_URL,
'WEBAPPS_RECEIPT_URL': settings.SITE_URL
'WEBAPPS_RECEIPT_URL': settings.SITE_URL,
'WEBSITE_ICON_URL': settings.STATIC_URL,
}

value = getattr(settings, url)
Expand Down
118 changes: 0 additions & 118 deletions media/css/devreg/landing.styl

This file was deleted.

Binary file removed media/img/hub/assetback.png
Binary file not shown.
Binary file added media/img/hub/default-128.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added media/img/hub/default-48.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed media/img/hub/headzilla.png
Binary file not shown.
Binary file removed media/img/hub/phase.png
Binary file not shown.
2 changes: 0 additions & 2 deletions media/js/devreg/devhub.js
Expand Up @@ -776,8 +776,6 @@ function initUploadIcon() {
$('#id_unsaved_icon_data').val(file.dataURL);

$('#icons_default input:checked').attr('checked', false);
$('input[name="icon_type"][value="'+file.type+'"]')
.attr('checked', true);
},

upload_start = function(e, file) {
Expand Down
3 changes: 0 additions & 3 deletions mkt/asset_bundles.py
Expand Up @@ -44,9 +44,6 @@
# Tables.
'css/devreg/data-grid.styl',

# Landing page
'css/devreg/landing.styl',

# "Manage ..." pages.
'css/devreg/manage.styl',
'css/devreg/prose.styl',
Expand Down
2 changes: 1 addition & 1 deletion mkt/constants/base.py
Expand Up @@ -163,7 +163,7 @@
MAX_CATEGORIES = 2

# Icon sizes we want to generate and expose in the API.
APP_ICON_SIZES = [32, 48, 64, 128]
CONTENT_ICON_SIZES = [32, 48, 64, 128]

# Preview upload sizes [thumb, full]
ADDON_PREVIEW_SIZES = [(200, 150), (700, 525)]
Expand Down
17 changes: 1 addition & 16 deletions mkt/developers/forms.py
Expand Up @@ -48,12 +48,10 @@
from mkt.translations.models import Translation
from mkt.translations.widgets import TranslationTextarea, TransTextarea
from mkt.versions.models import Version
from mkt.webapps.forms import clean_slug, icons
from mkt.webapps.models import (AddonUser, BlockedSlug, IARCInfo, Preview,
Webapp)
from mkt.webapps.tasks import (index_webapps, set_storefront_data,
update_manifests)
from mkt.webapps.widgets import IconWidgetRenderer

from . import tasks

Expand Down Expand Up @@ -509,9 +507,6 @@ class Meta:
models = Webapp
fields = ('name', 'slug')

def clean_slug(self):
return clean_slug(self.cleaned_data['slug'], self.instance)


class AppFormBasic(AddonFormBase):
"""Form to edit basic app info."""
Expand Down Expand Up @@ -676,9 +671,6 @@ def clean(self):


class AppFormMedia(AddonFormBase):
icon_type = forms.CharField(
required=False,
widget=forms.RadioSelect(renderer=IconWidgetRenderer, choices=[]))
icon_upload_hash = forms.CharField(required=False)
unsaved_icon_data = forms.CharField(required=False,
widget=forms.HiddenInput)
Expand All @@ -687,13 +679,6 @@ class Meta:
model = Webapp
fields = ('icon_upload_hash', 'icon_type')

def __init__(self, *args, **kwargs):
super(AppFormMedia, self).__init__(*args, **kwargs)

# Add icons here so we only read the directory when
# AppFormMedia is actually being used.
self.fields['icon_type'].widget.choices = icons()

def save(self, addon, commit=True):
if self.cleaned_data['icon_upload_hash']:
upload_hash = self.cleaned_data['icon_upload_hash']
Expand All @@ -704,7 +689,7 @@ def save(self, addon, commit=True):

remove_icons(destination)
tasks.resize_icon.delay(upload_path, destination,
mkt.APP_ICON_SIZES,
mkt.CONTENT_ICON_SIZES,
set_modified_on=[addon])

return super(AppFormMedia, self).save(commit)
Expand Down
24 changes: 14 additions & 10 deletions mkt/developers/tasks.py
Expand Up @@ -139,7 +139,7 @@ def _hash_file(fd):
@post_request_task
@set_modified_on
def resize_icon(src, dst, sizes, locally=False, **kw):
"""Resizes addon icons."""
"""Resizes addon/websites icons."""
log.info('[1@None] Resizing icon: %s' % dst)
try:
for s in sizes:
Expand All @@ -160,7 +160,7 @@ def resize_icon(src, dst, sizes, locally=False, **kw):
log.info('Icon resizing completed for: %s' % dst)
return {'icon_hash': icon_hash}
except Exception, e:
log.error("Error saving addon icon: %s; %s" % (e, dst))
log.error("Error resizing icon: %s; %s" % (e, dst))


@task
Expand Down Expand Up @@ -283,23 +283,27 @@ def get_content_and_check_size(response, max_size):
return content


def save_icon(webapp, content):
def save_icon(obj, icon_content):
"""
Saves the icon for `obj` to its final destination. `obj` can be an app or a
website.
"""
tmp_dst = os.path.join(settings.TMP_PATH, 'icon', uuid.uuid4().hex)
with storage.open(tmp_dst, 'wb') as fd:
fd.write(content)
fd.write(icon_content)

dirname = webapp.get_icon_dir()
destination = os.path.join(dirname, '%s' % webapp.id)
dirname = obj.get_icon_dir()
destination = os.path.join(dirname, '%s' % obj.pk)
remove_icons(destination)
resize_icon(tmp_dst, destination, mkt.APP_ICON_SIZES,
set_modified_on=[webapp])
resize_icon(tmp_dst, destination, mkt.CONTENT_ICON_SIZES,
set_modified_on=[obj])

# Need to set the icon type so .get_icon_url() works
# normally submit step 4 does it through AppFormMedia,
# but we want to beat them to the punch.
# resize_icon outputs pngs, so we know it's 'image/png'
webapp.icon_type = 'image/png'
webapp.save()
obj.icon_type = 'image/png'
obj.save()


@post_request_task
Expand Down
Expand Up @@ -84,7 +84,7 @@
<div id="icon_preview_readonly">
<img src="{{ addon.get_icon_url(128) }}">
<img src="{{ addon.get_icon_url(64) }}">
<img src="{{ addon.icon_url }}">
<img src="{{ addon.get_icon_url(32) }}">
</div>
{% endcall %}
{% endif %}
Expand Down
2 changes: 1 addition & 1 deletion mkt/developers/tests/test_tasks.py
Expand Up @@ -507,7 +507,7 @@ def check_icons(self, webapp, file_obj=None):
biggest = max([int(size) for size in manifest['icons']])

icon_dir = webapp.get_icon_dir()
for size in mkt.APP_ICON_SIZES:
for size in mkt.CONTENT_ICON_SIZES:
if not size <= biggest:
continue
icon_path = os.path.join(icon_dir, '%s-%s.png'
Expand Down
15 changes: 0 additions & 15 deletions mkt/developers/tests/test_views_edit.py
Expand Up @@ -638,21 +638,6 @@ def test_edit_defaulticon(self):
for k in data:
eq_(unicode(getattr(webapp, k)), data[k])

def test_edit_preuploadedicon(self):
data = dict(icon_type='icon/appearance')
data_formset = self.formset_media(prev_blank=self.new_preview_hash(),
**data)

r = self.client.post(self.edit_url, data_formset)
self.assertNoFormErrors(r)
webapp = self.get_webapp()

assert webapp.get_icon_url(64).endswith('appearance-64.png')
assert webapp.get_icon_url(128).endswith('appearance-128.png')

for k in data:
eq_(unicode(getattr(webapp, k)), data[k])

def test_edit_uploadedicon(self):
img = get_image_path('mozilla-sq.png')
src_image = open(img, 'rb')
Expand Down
2 changes: 1 addition & 1 deletion mkt/operators/templates/operators/preloads.html
Expand Up @@ -23,7 +23,7 @@ <h1>{{ _('Preload Candidates') }}</h1>
{% for preload in preloads %}
<tr>
<td>
<a href="{{ preload.addon.get_detail_url() }}"><img src="{{ preload.addon.icon_url }}"></a>
<a href="{{ preload.addon.get_detail_url() }}"><img src="{{ preload.addon.get_icon_url(32) }}"></a>
<h3><a href="{{ preload.addon.get_detail_url() }}">{{ preload.addon.name }}</a></h3>
<p>{{ preload.addon.description|truncate(length=150) }}</p>
</td>
Expand Down
2 changes: 1 addition & 1 deletion mkt/reviewers/templates/reviewers/review.html
Expand Up @@ -14,7 +14,7 @@

<header class="c">
<h1 class="addon"{{ product.name|locale_html }}>
<img src="{{ product.icon_url }}" class="icon">
<img src="{{ product.get_icon_url(32) }}" class="icon">
<span>{{ product.name }}</span>
</h1>
<p class="author">{{ _('by') }} {{ product.listed_authors|join(', ', attribute='email') }}</p>
Expand Down
2 changes: 2 additions & 0 deletions mkt/search/tests/test_views.py
Expand Up @@ -264,6 +264,8 @@ def test_dehydrate(self):
{'en-US': self.webapp.description.localized_string})
eq_(obj['icons']['128'], self.webapp.get_icon_url(128))
ok_(obj['icons']['128'].endswith('?modified=fakehash'))
eq_(sorted(int(k) for k in obj['icons'].keys()),
mkt.CONTENT_ICON_SIZES)
eq_(obj['id'], long(self.webapp.id))
eq_(obj['is_offline'], False)
eq_(obj['manifest_url'], self.webapp.get_manifest_url())
Expand Down
8 changes: 5 additions & 3 deletions mkt/settings.py
Expand Up @@ -320,14 +320,13 @@ def path(*args):

PREVIEWS_PATH = UPLOADS_PATH + '/previews'

ADDON_ICONS_DEFAULT_PATH = os.path.join(MEDIA_ROOT, 'img/hub')
ADDON_ICONS_PATH = UPLOADS_PATH + '/addon_icons'
WEBSITE_ICONS_PATH = UPLOADS_PATH + '/website_icons'

# File path for storing XPI/JAR files (or any files associated with an
# add-on). Example: /mnt/netapp_amo/addons.mozilla.org-remora/files
ADDONS_PATH = NETAPP_STORAGE + '/addons'
CA_CERT_BUNDLE_PATH = os.path.join(ROOT, 'mkt/site/certificates/roots.pem')
COLLECTIONS_ICON_PATH = UPLOADS_PATH + '/collection_icons'

# Where dumped apps will be written too.
DUMPED_APPS_PATH = NETAPP_STORAGE + '/dumped-apps'
Expand Down Expand Up @@ -371,8 +370,11 @@ def path(*args):
SITE_URL = 'http://%s' % DOMAIN
STATIC_URL = SITE_URL + '/'

ADDON_ICONS_DEFAULT_URL = 'img/hub'
ICONS_DEFAULT_URL = 'img/hub'

# Directory must match ADDON_ICONS_PATH and WEBSITE_ICONS_PATH, respectively.
ADDON_ICON_URL = 'img/uploads/addon_icons/%s/%s-%s.png?modified=%s'
WEBSITE_ICON_URL = 'img/uploads/website_icons/%s/%s-%s.png?modified=%s'

LOCAL_MIRROR_URL = 'https://marketplace.cdn.mozilla.net/_files'
PREVIEW_THUMBNAIL_URL = 'img/uploads/previews/thumbs/%s/%d.png?modified=%d'
Expand Down
2 changes: 1 addition & 1 deletion mkt/site/monitors.py
Expand Up @@ -132,7 +132,7 @@ def path():
settings.ADDONS_PATH,
settings.GUARDED_ADDONS_PATH,
settings.ADDON_ICONS_PATH,
settings.COLLECTIONS_ICON_PATH,
settings.WEBSITE_ICONS_PATH,
settings.PREVIEWS_PATH,
settings.REVIEWER_ATTACHMENTS_PATH,)
r = [os.path.join(settings.ROOT, 'locale')]
Expand Down

0 comments on commit d1a2d26

Please sign in to comment.