Migrating to staticfiles (bug 1013865)

This commit is contained in:
Yohan Boniface 2014-06-04 11:08:02 +02:00
Родитель d427491778
Коммит a35ab0834d
958 изменённых файлов: 424 добавлений и 789 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -42,3 +42,5 @@ media/commbadge
media/marketplace-stats
*.signed.zip
*.po~
site-static/*
storage/*

8
.gitmodules поставляемый
Просмотреть файл

@ -1,11 +1,11 @@
[submodule "templates/global"]
path = templates/global
url = https://github.com/mozilla/django-moz-header.git
[submodule "media/css/global"]
path = media/css/global
[submodule "static/css/global"]
path = static/css/global
url = https://github.com/mozilla/django-moz-header.git
[submodule "media/js/global"]
path = media/js/global
[submodule "static/js/global"]
path = static/js/global
url = https://github.com/mozilla/django-moz-header.git
[submodule "vendor"]
path = vendor

Просмотреть файл

@ -2,7 +2,7 @@
DJANGO = python manage.py
SETTINGS = settings_local
.PHONY: help docs test test_force_db tdd test_failed update_code update_deps update_db update_landfill full_update reindex
.PHONY: help docs test test_force_db tdd test_failed update_code update_deps update_db update_assets update_landfill full_update reindex
help:
@echo "Please use \`make <target>' where <target> is one of"
@ -47,7 +47,11 @@ update_deps:
update_db:
schematic migrations
full_update: update_code update_deps update_db
update_assets:
$(DJANGO) compress_assets
$(DJANGO) collectstatic --noinput
full_update: update_code update_deps update_db update_assets
update_landfill:
$(DJANGO) install_landfill --settings=$(SETTINGS) $(ARGS)

Просмотреть файл

@ -1,6 +1,5 @@
from datetime import datetime
import os
import re
from django import forms
from django.conf import settings

Просмотреть файл

@ -2,7 +2,6 @@ import os
import stat
from optparse import make_option
from django.conf import settings
from django.core.management.base import BaseCommand
from django.core.files.storage import default_storage as storage
@ -10,6 +9,7 @@ from addons.models import Addon
import amo
from amo.decorators import write
from amo.helpers import storage_path
from amo.storage_utils import walk_storage
from amo.utils import resize_image, chunked
@ -63,5 +63,5 @@ class Command(BaseCommand):
)
def handle(self, *args, **options):
start_dir = settings.ADDON_ICONS_PATH
start_dir = storage_path('addon_icons')
convert(start_dir, delete=options.get('delete'))

Просмотреть файл

@ -30,7 +30,7 @@ import amo.models
from access import acl
from amo.decorators import use_master, write
from amo.fields import DecimalCharField
from amo.helpers import absolutify, shared_url
from amo.helpers import absolutify, shared_url, storage_path, storage_url
from amo.utils import (attach_trans_dict, cache_ns_key, chunked, find_language,
JSONEncoder, send_mail, slugify, sorted_groupby, timer,
to_language, urlparams)
@ -889,7 +889,7 @@ class Addon(amo.models.OnChangeMixin, amo.models.ModelBase):
return self._backup_version
def get_icon_dir(self):
return os.path.join(settings.ADDON_ICONS_PATH,
return os.path.join(storage_path('addon_icons'),
'%s' % (self.id / 1000))
def get_icon_url(self, size, use_default=True):
@ -917,21 +917,30 @@ class Addon(amo.models.OnChangeMixin, amo.models.ModelBase):
if not self.icon_type:
if self.type == amo.ADDON_THEME:
icon = amo.ADDON_ICONS[amo.ADDON_THEME]
return settings.ADDON_ICON_BASE_URL + icon
return "%simg/icons/%s" % (settings.STATIC_URL, icon)
else:
if not use_default:
return None
return '%s/%s-%s.png' % (settings.ADDON_ICONS_DEFAULT_URL,
'default', size)
return '{0}img/addon-icons/{1}-{2}.png'.format(
settings.STATIC_URL,
'default',
size
)
elif icon_type_split[0] == 'icon':
return '%s/%s-%s.png' % (settings.ADDON_ICONS_DEFAULT_URL,
icon_type_split[1], size)
return '{0}img/addon-icons/{1}-{2}.png'.format(
settings.STATIC_URL,
icon_type_split[1],
size
)
else:
# [1] is the whole ID, [2] is the directory
split_id = re.match(r'((\d*?)\d{1,3})$', str(self.id))
return settings.ADDON_ICON_URL % (
split_id.group(2) or 0, self.id, size,
int(time.mktime(self.modified.timetuple())))
modified = int(time.mktime(self.modified.timetuple()))
path = '/'.join([
split_id.group(2) or '0',
'{0}-{1}.png?modified={2}'.format(self.id, size, modified),
])
return storage_url('addon_icons') + path
@write
def update_status(self):
@ -1117,7 +1126,7 @@ class Addon(amo.models.OnChangeMixin, amo.models.ModelBase):
preview = self.all_previews[0]
return preview.thumbnail_url
except IndexError:
return settings.MEDIA_URL + '/img/icons/no-preview.png'
return settings.STATIC_URL + '/img/icons/no-preview.png'
def can_request_review(self):
"""Return the statuses an add-on can request."""
@ -1662,11 +1671,11 @@ class Persona(caching.CachingMixin, models.Model):
return self.get_mirror_url(filename)
def _image_path(self, filename):
return os.path.join(settings.ADDONS_PATH, str(self.addon.id), filename)
return os.path.join(storage_path('addons'), str(self.addon.id), filename)
def get_mirror_url(self, filename):
host = (settings.PRIVATE_MIRROR_URL if self.addon.is_disabled
else settings.LOCAL_MIRROR_URL)
else storage_url('addons'))
image_url = posixpath.join(host, str(self.addon.id), filename or '')
# TODO: Bust the cache on the hash of the image contents or something.
if self.addon.modified is not None:
@ -2051,19 +2060,33 @@ class Preview(amo.models.ModelBase):
@property
def thumbnail_url(self):
return self._image_url(settings.PREVIEW_THUMBNAIL_URL)
template = storage_url('previews') + 'thumbs/%s/%d.png?modified=%s'
return self._image_url(template)
@property
def image_url(self):
return self._image_url(settings.PREVIEW_FULL_URL)
template = storage_url('previews') + 'full/%s/%d.%s?modified=%s'
return self._image_url(template)
@property
def thumbnail_path(self):
return self._image_path(settings.PREVIEW_THUMBNAIL_PATH)
template = os.path.join(
storage_path('previews'),
'thumbs',
'%s',
'%d.png'
)
return self._image_path(template)
@property
def image_path(self):
return self._image_path(settings.PREVIEW_FULL_PATH)
template = os.path.join(
storage_path('previews'),
'full',
'%s',
'%d.%s'
)
return self._image_path(template)
@property
def thumbnail_size(self):

Просмотреть файл

@ -13,6 +13,7 @@ from addons.models import Persona
from editors.models import RereviewQueueTheme
import amo
from amo.decorators import set_modified_on, write
from amo.helpers import storage_path
from amo.storage_utils import rm_stored_dir
from amo.utils import cache_ns_key, ImageCheck, LocalFileStorage
from lib.es.utils import index_objects
@ -119,7 +120,7 @@ def unindex_addons(ids, **kw):
@task
def delete_persona_image(dst, **kw):
log.info('[1@None] Deleting persona image: %s.' % dst)
if not dst.startswith(settings.ADDONS_PATH):
if not dst.startswith(storage_path('addons')):
log.error("Someone tried deleting something they shouldn't: %s" % dst)
return
try:
@ -291,7 +292,7 @@ def rereviewqueuetheme_checksum(rqt, **kw):
@write
def save_theme(header, footer, addon, **kw):
"""Save theme image and calculates checksum after theme save."""
dst_root = os.path.join(settings.ADDONS_PATH, str(addon.id))
dst_root = os.path.join(storage_path('addons'), str(addon.id))
header = os.path.join(settings.TMP_PATH, 'persona_header', header)
footer = os.path.join(settings.TMP_PATH, 'persona_footer', footer)
header_dst = os.path.join(dst_root, 'header.png')
@ -315,7 +316,7 @@ def save_theme(header, footer, addon, **kw):
def save_theme_reupload(header, footer, addon, **kw):
header_dst = None
footer_dst = None
dst_root = os.path.join(settings.ADDONS_PATH, str(addon.id))
dst_root = os.path.join(storage_path('addons'), str(addon.id))
try:
if header:

Просмотреть файл

@ -15,7 +15,7 @@
<h2>{{ _('What are Add-ons?') }}</h2>
<div class="column-wrapper">
<div class="first column">
<h3><img src="{{ media('img/illustrations/extras.gif') }}"
<h3><img src="{{ static('img/illustrations/extras.gif') }}"
alt="{{ _('Extras') }}">
</h3>
<p>
@ -26,7 +26,7 @@
</p>
</div>
<div class="column">
<h3><img src="{{ media('img/illustrations/themes.gif') }}"
<h3><img src="{{ static('img/illustrations/themes.gif') }}"
alt="{{ _('Themes') }}">
</h3>
<p>
@ -37,7 +37,7 @@
</p>
</div>
<div class="column">
<h3><img src="{{ media('img/illustrations/install.gif') }}"
<h3><img src="{{ static('img/illustrations/install.gif') }}"
alt="{{ _('Install') }}">
</h3>
<p>

Просмотреть файл

@ -7,7 +7,7 @@
<img src="{{ addon.icon_url }}" alt="">
{% else %}
<img data-defer-src="{{ addon.icon_url }}" alt=""
src="{{ media('img/addon-icons/default-32.png') }}">
src="{{ static('img/addon-icons/default-32.png') }}">
{% endif %}
</a>
</div>

Просмотреть файл

@ -14,7 +14,7 @@
<img src="{{ addon.thumbnail_url }}" alt="">
{% else %}
<img data-defer-src="{{ addon.thumbnail_url }}" alt=""
src="{{ media('img/icons/no-preview.png') }}">
src="{{ static('img/icons/no-preview.png') }}">
{% endif %}
</div>
</div>

Просмотреть файл

@ -13,7 +13,7 @@
{% set appicon = 'firefox' if request.APP in (amo.MOBILE, amo.ANDROID) else request.APP.short %}
<a href="{{ url('home') }}"
title="{{ _('Return to the {0} Add-ons homepage')|f(request.APP.pretty) }}">
<img src="{{ media('img/zamboni/app_icons/' + appicon + '.png') }}" alt="">
<img src="{{ static('img/zamboni/app_icons/' + appicon + '.png') }}" alt="">
{{ _('Add-ons') }}</a>
</h1>
<h2>{{ _('Easy ways to personalize.') }}</h2>

Просмотреть файл

@ -43,7 +43,7 @@
<span class="persona-install">
<button class="add">
<div>
<img src="{{ media('img/impala/add-small.png') }}" alt="{{ _('Add') }}">
<img src="{{ static('img/impala/add-small.png') }}" alt="{{ _('Add') }}">
<span class="disabled-icon">+</span>
<span>{{ _('Add') }}</span>
</div>
@ -54,7 +54,7 @@
{% if request and request.check_ownership(addon, require_owner=True, admin=False) %}
<span class="artist-tools">
<a href="{{ addon.get_dev_url() }}" title="{{ _('Edit') }}"><img src="{{ media('img/admin/icon_changelink.gif') }}" alt="{{ _('Edit') }}"></a>
<a href="{{ addon.get_dev_url() }}" title="{{ _('Edit') }}"><img src="{{ static('img/admin/icon_changelink.gif') }}" alt="{{ _('Edit') }}"></a>
</span>
{% endif %}

Просмотреть файл

@ -18,7 +18,7 @@ from nose.tools import assert_not_equal, eq_, ok_
import amo
import amo.tests
from amo import set_user
from amo.helpers import absolutify
from amo.helpers import absolutify, storage_url
from amo.signals import _connect, _disconnect
from addons.models import (Addon, AddonCategory, AddonDependency,
AddonDeviceType, AddonRecommendation, AddonType,
@ -526,8 +526,7 @@ class TestAddonModels(amo.tests.TestCase):
3. Test for default non-THEME icon.
"""
a = Addon.objects.get(pk=3615)
expected = (settings.ADDON_ICON_URL % (3, 3615, 32, 0)).rstrip('/0')
assert a.icon_url.startswith(expected)
assert "/3/3615-32.png" in a.icon_url
a = Addon.objects.get(pk=6704)
a.icon_type = None
assert a.icon_url.endswith('/icons/default-theme.png'), (
@ -1772,13 +1771,13 @@ class TestPersonaModel(amo.tests.TestCase):
eq_(data['description'], unicode(self.addon.description))
assert data['headerURL'].startswith(
'%s/%s/header.png?' % (settings.LOCAL_MIRROR_URL, id_))
'%s%s/header.png?' % (storage_url('addons'), id_))
assert data['footerURL'].startswith(
'%s/%s/footer.png?' % (settings.LOCAL_MIRROR_URL, id_))
'%s%s/footer.png?' % (storage_url('addons'), id_))
assert data['previewURL'].startswith(
'%s/%s/preview.jpg?' % (settings.LOCAL_MIRROR_URL, id_))
'%s%s/preview.jpg?' % (storage_url('addons'), id_))
assert data['iconURL'].startswith(
'%s/%s/preview_small.jpg?' % (settings.LOCAL_MIRROR_URL, id_))
'%s%s/preview_small.jpg?' % (storage_url('addons'), id_))
eq_(data['detailURL'],
'https://omgsh.it%s' % self.persona.addon.get_url_path())

Просмотреть файл

@ -1492,7 +1492,7 @@ class TestMobileDetails(TestPersonas, TestMobile):
# Get the url from a real page so it includes the build id.
client = test.Client()
doc = pq(client.get('/', follow=True).content)
js_url = absolutify(reverse('addons.buttons.js'))
js_url = reverse('addons.buttons.js')
url_with_build = doc('script[src^="%s"]' % js_url).attr('src')
response = client.get(url_with_build, follow=True)

Просмотреть файл

@ -3,6 +3,7 @@ from django.conf import settings
from django.utils.encoding import force_unicode
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe
from tower import ugettext as _
from addons.models import Category
@ -18,10 +19,10 @@ class IconWidgetRenderer(forms.RadioSelect.renderer):
value = w.choice_value
if value.split('/')[0] == 'icon' or value == '':
o = (("<li><a href='#' class='%s'>"
"<img src='%s/%s-32.png' alt=''>"
"<img src='%simg/addon-icons/%s-32.png' alt=''>"
"</a>%s</li>") %
('active' if self.value == w.choice_value else '',
settings.ADDON_ICONS_DEFAULT_URL, w.choice_label, w))
settings.STATIC_URL, w.choice_label, w))
else:
o = "<li class='hide'>%s</li>" % w
output.append(o)

Просмотреть файл

@ -11,6 +11,7 @@ import commonware.log
import amo
from amo.utils import chunked
from amo.helpers import storage_path
from bandwagon.models import Collection
from constants.base import VALID_STATUSES
from devhub.models import ActivityLog
@ -68,8 +69,8 @@ def gc(test_result=True):
log.debug('Cleaning up test results extraction cache.')
# lol at check for '/'
if settings.NETAPP_STORAGE and settings.NETAPP_STORAGE != '/':
cmd = ('find', settings.NETAPP_STORAGE, '-maxdepth', '1', '-name',
if settings.MEDIA_ROOT and settings.MEDIA_ROOT != '/':
cmd = ('find', settings.MEDIA_ROOT, '-maxdepth', '1', '-name',
'validate-*', '-mtime', '+7', '-type', 'd',
'-exec', 'rm', '-rf', "{}", ';')
@ -79,7 +80,7 @@ def gc(test_result=True):
log.debug(line)
else:
log.warning('NETAPP_STORAGE not defined.')
log.warning('MEDIA_ROOT not defined.')
if settings.PACKAGER_PATH:
log.debug('Cleaning up old packaged add-ons.')
@ -92,10 +93,10 @@ def gc(test_result=True):
for line in output.split("\n"):
log.debug(line)
if settings.COLLECTIONS_ICON_PATH:
if storage_path('collection_icons'):
log.debug('Cleaning up uncompressed icons.')
cmd = ('find', settings.COLLECTIONS_ICON_PATH,
cmd = ('find', storage_path('collection_icons'),
'-name', '*__unconverted', '-mtime', '+1', '-type', 'f',
'-exec', 'rm', '{}', ';')
output = Popen(cmd, stdout=PIPE).communicate()[0]
@ -103,10 +104,11 @@ def gc(test_result=True):
for line in output.split("\n"):
log.debug(line)
if settings.USERPICS_PATH:
USERPICS_PATH = storage_path('userpics')
if USERPICS_PATH:
log.debug('Cleaning up uncompressed userpics.')
cmd = ('find', settings.USERPICS_PATH,
cmd = ('find', USERPICS_PATH,
'-name', '*__unconverted', '-mtime', '+1', '-type', 'f',
'-exec', 'rm', '{}', ';')
output = Popen(cmd, stdout=PIPE).communicate()[0]

Просмотреть файл

@ -1,5 +1,6 @@
import collections
import json as jsonlib
import os
import random
import re
from operator import attrgetter
@ -28,7 +29,6 @@ from amo import utils, urlresolvers
from constants.licenses import PERSONA_LICENSES_IDS
from translations.query import order_by_translation
from translations.helpers import truncate
from versions.models import License
# Yanking filters from Django.
register.filter(defaultfilters.slugify)
@ -385,6 +385,7 @@ def shuffle(sequence):
def license_link(license):
"""Link to a code license, including icon where applicable."""
# If passed in an integer, try to look up the License.
from versions.models import License
if isinstance(license, (long, int)):
if license in PERSONA_LICENSES_IDS:
# Grab built-in license.
@ -469,8 +470,7 @@ def mobile_sort_by(base_url, options=None, selected=None, extra_sort_opts=None,
@register.function
@jinja2.contextfunction
def media(context, url, key='MEDIA_URL'):
"""Get a MEDIA_URL link with a cache buster querystring."""
def cache_buster(context, url):
if 'BUILD_ID' in context:
build = context['BUILD_ID']
else:
@ -480,14 +480,21 @@ def media(context, url, key='MEDIA_URL'):
build = context['BUILD_ID_CSS']
else:
build = context['BUILD_ID_IMG']
return urljoin(context[key], utils.urlparams(url, b=build))
return utils.urlparams(url, b=build)
@register.function
@jinja2.contextfunction
def media(context, url):
"""Get a MEDIA_URL link with a cache buster querystring."""
return urljoin(settings.MEDIA_URL, cache_buster(context, url))
@register.function
@jinja2.contextfunction
def static(context, url):
"""Get a STATIC_URL link with a cache buster querystring."""
return media(context, url, 'STATIC_URL')
return urljoin(settings.STATIC_URL, cache_buster(context, url))
@register.function
@ -606,13 +613,13 @@ def f(string, *args, **kwargs):
def _relative_to_absolute(url):
"""
Prepends relative URLs with MEDIA_URL to turn those inline-able.
Prepends relative URLs with STATIC_URL to turn those inline-able.
This method is intended to be used as a ``replace`` parameter of
``re.sub``.
"""
url = url.group(1).strip('"\'')
if not url.startswith(('data:', 'http:', 'https:', '//')):
url = url.replace('../../', settings.MEDIA_URL)
url = url.replace('../../', settings.STATIC_URL)
return 'url(%s)' % url
@ -625,7 +632,7 @@ def inline_css(bundle, media=False, debug=None):
Extracted from jingo-minify and re-registered, see:
https://github.com/jsocol/jingo-minify/pull/41
Added: turns relative links to absolute ones using MEDIA_URL.
Added: turns relative links to absolute ones using STATIC_URL.
"""
if debug is None:
debug = getattr(settings, 'TEMPLATE_DEBUG', False)
@ -653,3 +660,26 @@ def inline_css(bundle, media=False, debug=None):
return _build_html(contents, '<style type="text/css" media="%s">%%s'
'</style>' % media)
def storage_path(what):
"""Make it possible to override storage paths in settings.
By default, all storage paths are in the MEDIA_ROOT.
This is backwards compatible.
"""
default = os.path.join(settings.MEDIA_ROOT, what)
key = "{0}_PATH".format(what.upper())
return getattr(settings, key, default)
def storage_url(what):
"""
Generate default media url, and make possible to override it from
settings.
"""
default = '%s%s/' % (settings.MEDIA_URL, what)
key = "{0}_URL".format(what.upper().replace('-', '_'))
return getattr(settings, key, default)

Просмотреть файл

@ -1,6 +1,5 @@
import logging
from django.conf import settings
from django.core.management.base import BaseCommand
import path
@ -8,6 +7,7 @@ from celery.task.sets import TaskSet
import bandwagon.tasks
import users.tasks
from amo.helpers import storage_path
log = logging.getLogger('z.cmd')
@ -19,8 +19,8 @@ class Command(BaseCommand):
help = "Clean up __unconverted files"
def handle(self, *args, **kw):
z = ((settings.COLLECTIONS_ICON_PATH, bandwagon.tasks.resize_icon),
(settings.USERPICS_PATH, users.tasks.resize_photo))
z = ((storage_path('collection_icons'), bandwagon.tasks.resize_icon),
(storage_path('userpics'), users.tasks.resize_photo))
for base, task in z:
self.fix(base, task)

Просмотреть файл

@ -9,6 +9,7 @@ import commonware.log
from PIL import Image
import amo.search
from amo.helpers import storage_path
from applications.management.commands import dump_apps
monitor_log = commonware.log.getLogger('z.monitor')
@ -105,16 +106,17 @@ def elastic():
def path():
# Check file paths / permissions
rw = (settings.TMP_PATH,
settings.NETAPP_STORAGE,
settings.UPLOADS_PATH,
settings.ADDONS_PATH,
settings.MIRROR_STAGE_PATH,
settings.GUARDED_ADDONS_PATH,
settings.ADDON_ICONS_PATH,
settings.COLLECTIONS_ICON_PATH,
settings.MEDIA_ROOT,
storage_path('addons'),
storage_path('uploads'),
storage_path('guarded_addons'),
storage_path('mirror_stage'),
storage_path('addon_icons'),
storage_path('collection_icons'),
settings.PACKAGER_PATH,
settings.PREVIEWS_PATH,
settings.USERPICS_PATH,
storage_path('previews'),
storage_path('userpics'),
storage_path('reviewer_attachments'),
settings.REVIEWER_ATTACHMENTS_PATH,
dump_apps.Command.JSON_PATH,)
r = [os.path.join(settings.ROOT, 'locale'),

Просмотреть файл

@ -1,9 +1,9 @@
<style>
#{{ prefix }}-{{ key }} {
background: url({{ MEDIA_URL }}img/zamboni/arrow-right-blue.png) no-repeat left center;
background: url({{ STATIC_URL }}img/zamboni/arrow-right-blue.png) no-repeat left center;
}
.html-rtl #{{ prefix }}-{{ key }} {
background: url({{ MEDIA_URL }}img/zamboni/arrow-left-blue.png) no-repeat right center;
background: url({{ STATIC_URL }}img/zamboni/arrow-left-blue.png) no-repeat right center;
}
#{{ prefix }}-{{ key }} a {
color: inherit;

Просмотреть файл

@ -6,6 +6,7 @@ from urlparse import urljoin
from django.conf import settings
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test.utils import override_settings
from django.utils import encoding
import jingo
@ -475,4 +476,28 @@ def test_inline_css():
env = jingo.env
t = env.from_string("{{ inline_css('zamboni/mobile', debug=True) }}")
s = t.render()
ok_('background-image: url(/media/img/icons/stars.png);' in s)
ok_('background-image: url(/static/img/icons/stars.png);' in s)
class TestStoragePath(amo.tests.TestCase):
@override_settings(ADDONS_PATH=None, MEDIA_ROOT="/path/")
def test_without_settings(self):
del settings.ADDONS_PATH
path = helpers.storage_path('addons')
eq_(path, '/path/addons')
@override_settings(ADDONS_PATH="/another/path/")
def test_with_settings(self):
path = helpers.storage_path('addons')
eq_(path, '/another/path/')
class TestMediaUrl(amo.tests.TestCase):
@override_settings(USERPICS_URL=None)
def test_without_settings(self):
del settings.USERPICS_URL
settings.MEDIA_URL = '/mediapath/'
url = helpers.storage_url('userpics')
eq_(url, '/mediapath/userpics/')

Просмотреть файл

@ -270,7 +270,7 @@ class TestOtherStuff(amo.tests.TestCase):
# Get the url from a real page so it includes the build id.
client = test.Client()
doc = pq(client.get('/', follow=True).content)
js_url = absolutify(reverse('jsi18n'))
js_url = reverse('jsi18n')
url_with_build = doc('script[src^="%s"]' % js_url).attr('src')
response = client.get(url_with_build, follow=True)

Просмотреть файл

@ -290,7 +290,7 @@ class APITest(TestCase):
self.assertContains(response, "<summary>Delicious Bookmarks is the")
self.assertContains(response, "<description>This extension integrates")
icon_url = settings.ADDON_ICON_URL % (3, 3615, 32, '')
icon_url = "%s3/3615-32.png" % helpers.storage_url('addon_icons')
self.assertContains(response, '<icon size="32">' + icon_url)
self.assertContains(response, "<application>")
self.assertContains(response, "<name>Firefox</name>")
@ -326,7 +326,7 @@ class APITest(TestCase):
'(http://delicious.com), the leading social bookmarking '
'service on the Web.')
eq_(data['icon'],
settings.ADDON_ICON_URL % (3, 3615, 32, '') + '1275062517')
'%s3/3615-32.png?modified=1275062517' % helpers.storage_url('addon_icons'))
eq_(data['compatible_apps'],
[{'Firefox': {'max': '4.0', 'min': '2.0'}}])
eq_(data['eula'], unicode(addon.eula))
@ -430,11 +430,11 @@ class APITest(TestCase):
"<caption>"
"TwitterBar places an icon in the address bar.</caption>",
"""<full type="image/png">""",
urlparams(settings.PREVIEW_FULL_URL %
('20', 20397, 'png', 1209834208), src='api'),
urlparams('full/%s/%d.%s' %
('20', 20397, 'png'), src='api', modified=1209834208),
"""<thumbnail type="image/png">""",
urlparams(settings.PREVIEW_THUMBNAIL_URL %
('20', 20397, 1209834208), src='api'),
urlparams('thumbs/%s/%d.png' %
('20', 20397), src='api', modified=1209834208),
"<developer_comments>Embrace hug love hug meow meow"
"</developer_comments>",
'size="100352"',

Просмотреть файл

@ -16,7 +16,7 @@ log = commonware.log.getLogger('z.cron')
class Command(BaseCommand):
help = 'Dump a json file containing AMO apps and versions.'
JSON_PATH = os.path.join(settings.NETAPP_STORAGE, 'apps.json')
JSON_PATH = os.path.join(settings.MEDIA_ROOT, 'apps.json')
def handle(self, *args, **kw):
apps = {}

Просмотреть файл

@ -18,7 +18,7 @@ allowed for these applications.
{% for app in apps %}
<div class="appversion prose">
<h3>
<img src="{{ media('img/app-icons/small/' + app.short + '.png') }}" alt="">
<img src="{{ static('img/app-icons/small/' + app.short + '.png') }}" alt="">
{{ app.pretty }}
</h3>
<ul>

Просмотреть файл

@ -17,7 +17,7 @@ import amo.models
import sharing.utils as sharing
from access import acl
from addons.models import Addon, AddonRecommendation
from amo.helpers import absolutify
from amo.helpers import absolutify, storage_path, storage_url
from amo.urlresolvers import reverse
from amo.utils import sorted_groupby
from applications.models import Application
@ -201,7 +201,7 @@ class Collection(CollectionBase, amo.models.ModelBase):
return absolutify(self.get_url_path())
def get_img_dir(self):
return os.path.join(settings.COLLECTIONS_ICON_PATH,
return os.path.join(storage_path('collection_icons'),
str(self.id / 1000))
def upvote_url(self):
@ -259,12 +259,15 @@ class Collection(CollectionBase, amo.models.ModelBase):
if self.icontype:
# [1] is the whole ID, [2] is the directory
split_id = re.match(r'((\d*?)\d{1,3})$', str(self.id))
return settings.COLLECTION_ICON_URL % (
split_id.group(2) or 0, self.id, modified)
path = "/".join([
split_id.group(2) or '0',
"%s.png?m=%s" % (self.id, modified)
])
return storage_url('collection_icons') + path
elif self.type == amo.COLLECTION_FAVORITES:
return settings.MEDIA_URL + 'img/icons/heart.png'
return settings.STATIC_URL + 'img/icons/heart.png'
else:
return settings.MEDIA_URL + 'img/icons/collection.png'
return settings.STATIC_URL + 'img/icons/collection.png'
def set_addons(self, addon_ids, comments={}):
"""Replace the current add-ons with a new list of add-on ids."""

Просмотреть файл

@ -10,6 +10,7 @@ from celeryutils import task
import amo
from amo.decorators import set_modified_on
from amo.helpers import storage_path
from amo.utils import attach_trans_dict, resize_image
from tags.models import Tag
from lib.es.utils import index_objects
@ -56,7 +57,7 @@ def resize_icon(src, dst, locally=False, **kw):
def delete_icon(dst, **kw):
log.info('[1@None] Deleting icon: %s.' % dst)
if not dst.startswith(settings.COLLECTIONS_ICON_PATH):
if not dst.startswith(storage_path('collection_icons')):
log.error("Someone tried deleting something they shouldn't: %s" % dst)
return

Просмотреть файл

@ -12,7 +12,7 @@
<img src="{{ collection.icon_url }}" alt="">
{% else %}
<img data-defer-src="{{ collection.icon_url }}" alt=""
src="{{ media('img/addon-icons/default-32.png') }}">
src="{{ static('img/addon-icons/default-32.png') }}">
{% endif %}
</div>
<div class="summary">

Просмотреть файл

@ -1,5 +1,5 @@
{% extends "base.html" %}
{% block extrahead %}
<link rel="stylesheet" href="{{ MEDIA_URL }}css/zamboni/blocklist.css">
<link rel="stylesheet" href="{{ STATIC_URL }}css/zamboni/blocklist.css">
{% endblock %}

Просмотреть файл

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
import base64
import json
import logging
import os
@ -8,7 +7,6 @@ import sys
import tempfile
import traceback
import urllib2
import uuid
from django.conf import settings
from django.core.files.storage import default_storage as storage
@ -21,7 +19,7 @@ from tower import ugettext as _
import amo
from amo.decorators import write, set_modified_on
from amo.utils import remove_icons, resize_image, send_html_mail_jinja
from amo.utils import resize_image, send_html_mail_jinja
from addons.models import Addon
from applications.management.commands import dump_apps
from applications.models import Application, AppVersion

Просмотреть файл

@ -40,5 +40,5 @@
{% set hide_mobile_link=True %}
{% block footer_extras %}
<img class="footerlogo" src="{{ media('img/developers/hub-logo-footer.png') }}" alt="">
<img class="footerlogo" src="{{ static('img/developers/hub-logo-footer.png') }}" alt="">
{% endblock %}

Просмотреть файл

@ -36,5 +36,5 @@
{% set hide_mobile_link=True %}
{% block footer_extras %}
<img class="footerlogo" src="{{ media('img/developers/hub-logo-footer.png') }}" alt="">
<img class="footerlogo" src="{{ static('img/developers/hub-logo-footer.png') }}" alt="">
{% endblock %}

Просмотреть файл

@ -25,7 +25,7 @@
<div class='island'>
<div class='jetpack-sdk'>
<img src="{{ media('img/developers/jetpack_icon_command.png') }}" alt="">
<img src="{{ static('img/developers/jetpack_icon_command.png') }}" alt="">
<h2><a href='https://ftp.mozilla.org/pub/mozilla.org/labs/jetpack/jetpack-sdk-latest.zip'>
{{ _('Add-on SDK') }}</a></h2>
<p>

Просмотреть файл

@ -28,5 +28,5 @@
{% block js_extras %}
<!-- Google Custom Search Element -->
<script src="https://www.google.com/jsapi"></script>
<script src="{{ media('js/zamboni/devhub_search.js') }}"></script>
<script src="{{ static('js/zamboni/devhub_search.js') }}"></script>
{% endblock %}

Просмотреть файл

@ -52,9 +52,9 @@
corner</b> of the browser window.
{% endtrans %}
</p>
<p class="screenshot"><img src="{{ MEDIA_URL }}img/docs/themes/header-step.jpg" alt=""></p>
<p class="screenshot"><img src="{{ STATIC_URL }}img/docs/themes/header-step.jpg" alt=""></p>
<ul>
<li><a href="{{ MEDIA_URL }}img/docs/themes/header.jpg">{{ _('View a sample Theme Header here.') }}</a></li>
<li><a href="{{ STATIC_URL }}img/docs/themes/header.jpg">{{ _('View a sample Theme Header here.') }}</a></li>
</ul>
<h4>{{ _('Image Requirements') }}</h4>
<ul>
@ -123,9 +123,9 @@
to the bottom-left corner of the browser window.
{% endtrans %}
</p>
<p class="screenshot"><img src="{{ MEDIA_URL }}img/docs/themes/footer-step.jpg" alt=""></p>
<p class="screenshot"><img src="{{ STATIC_URL }}img/docs/themes/footer-step.jpg" alt=""></p>
<ul>
<li><a href="{{ MEDIA_URL }}img/docs/themes/footer.jpg">{{ _('View a sample Theme Footer here.') }}</a></li>
<li><a href="{{ STATIC_URL }}img/docs/themes/footer.jpg">{{ _('View a sample Theme Footer here.') }}</a></li>
</ul>
<h4>{{ _('Image Requirements') }}</h4>
<ul>
@ -249,7 +249,7 @@
</ul>
</li>
</ul>
<p class="screenshot"><img src="{{ MEDIA_URL }}img/docs/themes/submission-step.jpg" alt=""></p>
<p class="screenshot"><img src="{{ STATIC_URL }}img/docs/themes/submission-step.jpg" alt=""></p>
<p class="call-to-submit"><a href="{{ url('devhub.themes.submit') }}" class="button prominent">{{ _('Submit Your Theme Now') }}</a></p>
</div>

Просмотреть файл

@ -6,5 +6,5 @@
value="{{ search_form.q.data or '' }}"
placeholder="{{ _('Search Developer Docs') }}">
</span>
<button type="submit" class="search-button" src="{{ media('img/zamboni/global/btn-search.png') }}" title="{{ _('Search') }}"></button>
<button type="submit" class="search-button" src="{{ static('img/zamboni/global/btn-search.png') }}" title="{{ _('Search') }}"></button>
</form>

Просмотреть файл

@ -13,6 +13,7 @@ import amo
import amo.tests
from amo.tests.test_helpers import get_image_path
from amo.urlresolvers import reverse
from amo.helpers import storage_path
import paypal
from applications.models import AppVersion
from addons.forms import EditThemeForm, EditThemeOwnerForm, ThemeForm
@ -330,7 +331,7 @@ class TestThemeForm(amo.tests.TestCase):
eq_(v[0].version, '0')
# Test for header, footer, and preview images.
dst = os.path.join(settings.ADDONS_PATH, str(addon.id))
dst = os.path.join(storage_path('addons'), str(addon.id))
header_src = os.path.join(settings.TMP_PATH, 'persona_header',
u'b4ll1n')
@ -505,7 +506,7 @@ class TestEditThemeForm(amo.tests.TestCase):
eq_(self.form.is_valid(), True)
self.form.save()
dst = os.path.join(settings.ADDONS_PATH, str(self.instance.id))
dst = os.path.join(storage_path('addons'), str(self.instance.id))
header_src = os.path.join(settings.TMP_PATH, 'persona_header',
u'y0l0')
footer_src = os.path.join(settings.TMP_PATH, 'persona_footer',

Просмотреть файл

@ -13,6 +13,7 @@ from PIL import Image
import amo
import amo.tests
from addons.models import Addon
from amo.helpers import storage_path
from amo.tests.test_helpers import get_image_path
from devhub import tasks
from files.models import FileUpload
@ -68,8 +69,10 @@ def _uploader(resize_size, final_size):
eq_(src_image.size, original_size)
if isinstance(final_size, list):
uploadto = storage_path('addon_icons')
os.makedirs(uploadto)
for rsize, fsize in zip(resize_size, final_size):
dest_name = str(path.path(settings.ADDON_ICONS_PATH) / '1234')
dest_name = str(path.path(uploadto) / '1234')
tasks.resize_icon(src.name, dest_name, resize_size, locally=True)
dest_image = Image.open(open('%s-%s.png' % (dest_name, rsize)))

Просмотреть файл

@ -25,7 +25,7 @@ import files
import paypal
from addons.models import Addon, AddonCategory, Category, Charity
from amo.helpers import absolutify, url as url_reverse
from amo.helpers import absolutify, storage_path, url as url_reverse
from amo.tests import (addon_factory, assert_no_validation_errors, formset,
initial)
@ -1236,10 +1236,6 @@ class TestSubmitStep4(TestSubmitBase):
def setUp(self):
super(TestSubmitStep4, self).setUp()
self.old_addon_icon_url = settings.ADDON_ICON_URL
settings.ADDON_ICON_URL = (
settings.STATIC_URL +
'img/uploads/addon_icons/%s/%s-%s.png?modified=%s')
SubmitStep.objects.create(addon_id=3615, step=4)
self.url = reverse('devhub.submit.4', args=['a3615'])
self.next_step = reverse('devhub.submit.5', args=['a3615'])
@ -1248,9 +1244,6 @@ class TestSubmitStep4(TestSubmitBase):
self.preview_upload = reverse('devhub.addons.upload_preview',
args=['a3615'])
def tearDown(self):
settings.ADDON_ICON_URL = self.old_addon_icon_url
def test_get(self):
eq_(self.client.get(self.url).status_code, 200)
@ -1330,12 +1323,12 @@ class TestSubmitStep4(TestSubmitBase):
# Sad we're hardcoding /3/ here, but that's how the URLs work
_url = addon.get_icon_url(64).split('?')[0]
assert _url.endswith('img/uploads/addon_icons/3/%s-64.png' % addon.id)
assert _url.endswith('addon_icons/3/%s-64.png' % addon.id)
eq_(data['icon_type'], 'image/png')
# Check that it was actually uploaded
dirname = os.path.join(settings.ADDON_ICONS_PATH,
dirname = os.path.join(storage_path('addon_icons'),
'%s' % (addon.id / 1000))
dest = os.path.join(dirname, '%s-32.png' % addon.id)
@ -1344,7 +1337,7 @@ class TestSubmitStep4(TestSubmitBase):
eq_(Image.open(storage.open(dest)).size, (32, 12))
def test_edit_media_uploadedicon_noresize(self):
img = "%s/img/notifications/error.png" % settings.MEDIA_ROOT
img = "%s/img/notifications/error.png" % settings.STATIC_ROOT
src_image = open(img, 'rb')
data = dict(upload_image=src_image)
@ -1363,12 +1356,12 @@ class TestSubmitStep4(TestSubmitBase):
# Sad we're hardcoding /3/ here, but that's how the URLs work
_url = addon.get_icon_url(64).split('?')[0]
assert _url.endswith('img/uploads/addon_icons/3/%s-64.png' % addon.id)
assert _url.endswith('addon_icons/3/%s-64.png' % addon.id)
eq_(data['icon_type'], 'image/png')
# Check that it was actually uploaded
dirname = os.path.join(settings.ADDON_ICONS_PATH,
dirname = os.path.join(storage_path('addon_icons'),
'%s' % (addon.id / 1000))
dest = os.path.join(dirname, '%s-64.png' % addon.id)

Просмотреть файл

@ -6,6 +6,7 @@ from django.conf import settings
from django.core.cache import cache
from django.core.files.storage import default_storage as storage
from django.db.models import Q
from django.test.utils import override_settings
import mock
from nose import SkipTest
@ -15,6 +16,7 @@ from pyquery import PyQuery as pq
import amo
import amo.tests
from amo.helpers import storage_path
from amo.tests import addon_factory, formset, initial, req_factory_factory
from amo.tests.test_helpers import get_image_path
from amo.urlresolvers import reverse
@ -34,11 +36,14 @@ def get_section_url(addon, section, edit=False):
return reverse('devhub.addons.section', args=args)
@override_settings(MEDIA_ROOT=None) # Make it overridable.
class TestEdit(amo.tests.TestCase):
fixtures = ['base/apps', 'base/users', 'base/platforms', 'base/addon_3615',
'base/addon_5579', 'base/addon_3615_categories']
def setUp(self):
# Make new for each test.
settings.MEDIA_ROOT = tempfile.mkdtemp()
super(TestEdit, self).setUp()
addon = self.get_addon()
assert self.client.login(username='del@icio.us', password='password')
@ -47,7 +52,7 @@ class TestEdit(amo.tests.TestCase):
a.feature = False
a.save()
AddonCategory.objects.filter(addon=addon,
category__id__in=[23, 24]).delete()
category__id__in=[23, 24]).delete()
cache.clear()
self.url = addon.get_dev_url()
@ -496,15 +501,6 @@ class TestEditMedia(TestEdit):
args=[self.addon.slug])
self.preview_upload = reverse('devhub.addons.upload_preview',
args=[self.addon.slug])
self.old_settings = {'preview': settings.PREVIEW_THUMBNAIL_PATH,
'icons': settings.ADDON_ICONS_PATH}
settings.PREVIEW_THUMBNAIL_PATH = tempfile.mkstemp()[1] + '%s/%d.png'
settings.ADDON_ICONS_PATH = tempfile.mkdtemp()
def tearDown(self):
super(TestEditMedia, self).tearDown()
settings.PREVIEW_THUMBNAIL_PATH = self.old_settings['preview']
settings.ADDON_ICONS_PATH = self.old_settings['icons']
def formset_new_form(self, *args, **kw):
ctx = self.client.get(self.media_edit_url).context
@ -581,7 +577,7 @@ class TestEditMedia(TestEdit):
eq_(data['icon_type'], 'image/png')
# Check that it was actually uploaded
dirname = os.path.join(settings.ADDON_ICONS_PATH,
dirname = os.path.join(storage_path('addon_icons'),
'%s' % (addon.id / 1000))
dest = os.path.join(dirname, '%s-32.png' % addon.id)
@ -596,7 +592,7 @@ class TestEditMedia(TestEdit):
eq_(log[0].action, amo.LOG.CHANGE_ICON.id)
def test_edit_media_uploadedicon_noresize(self):
img = "%s/img/notifications/error.png" % settings.MEDIA_ROOT
img = "%s/img/notifications/error.png" % settings.STATIC_ROOT
src_image = open(img, 'rb')
data = dict(upload_image=src_image)
@ -622,7 +618,7 @@ class TestEditMedia(TestEdit):
eq_(data['icon_type'], 'image/png')
# Check that it was actually uploaded
dirname = os.path.join(settings.ADDON_ICONS_PATH,
dirname = os.path.join(storage_path('addon_icons'),
'%s' % (addon.id / 1000))
dest = os.path.join(dirname, '%s-64.png' % addon.id)
@ -631,7 +627,7 @@ class TestEditMedia(TestEdit):
eq_(Image.open(storage.open(dest)).size, (48, 48))
def check_image_type(self, url, msg):
img = '%s/js/zamboni/devhub.js' % settings.MEDIA_ROOT
img = '%s/js/zamboni/devhub.js' % settings.STATIC_ROOT
src_image = open(img, 'rb')
res = self.client.post(url, {'upload_image': src_image})

Просмотреть файл

@ -43,7 +43,7 @@ class TestSubmitPersona(amo.tests.TestCase):
'and %s pixels tall.' % (w, h)])
def test_img_wrongtype(self):
img = open('%s/js/impala/global.js' % settings.MEDIA_ROOT, 'rb')
img = open('%s/js/impala/global.js' % settings.STATIC_ROOT, 'rb')
for url in self.get_img_urls():
r_ajax = self.client.post(url, {'upload_image': img})
r_json = json.loads(r_ajax.content)

Просмотреть файл

@ -34,5 +34,5 @@
{% block js %}
{{ js('zamboni/discovery') }}
<script async defer src="{{ static(url('addons.buttons.js')) }}"></script>
<script async defer src="{{ cache_buster(url('addons.buttons.js')) }}"></script>
{% endblock %}

Просмотреть файл

@ -17,10 +17,11 @@
data-anonymous="{{ (not request.user.is_authenticated())|json }}"
data-readonly="{{ settings.READ_ONLY|json }}"
data-media-url="{{ MEDIA_URL }}"
data-static-url="{{ STATIC_URL }}"
data-show-recs="{{ waffle.flag('disco-pane-show-recs')|json }}"
{% block bodyattrs %}{% endblock %}>
{% block content %}{% endblock %}
<script src="{{ static(url('jsi18n')) }}"></script>
<script src="{{ cache_buster(url('jsi18n')) }}"></script>
{% block js %}{% endblock %}
</body>
</html>

Просмотреть файл

@ -19,7 +19,7 @@ data-upandcoming-url="{{ services_url('discovery.pane.more_addons', 'up-and-comi
<header{% if user.is_authenticated() %} class="auth"{% endif %}>
<section id="intro">
<h1>
<img src="{{ media('img/zamboni/discovery_pane/logo-addons.png') }}" width="87" height="82" alt="">
<img src="{{ static('img/zamboni/discovery_pane/logo-addons.png') }}" width="87" height="82" alt="">
<span class="translate" data-trans="title">
{{ _('What are Add-ons?') }}
</span>
@ -125,5 +125,5 @@ data-upandcoming-url="{{ services_url('discovery.pane.more_addons', 'up-and-comi
{% if request.LANG == 'en-US' %}
{{ js('zamboni/discovery-video', defer=True) }}
{% endif %}
<script async defer src="{{ static(url('addons.buttons.js')) }}"></script>
<script async defer src="{{ cache_buster(url('addons.buttons.js')) }}"></script>
{% endblock %}

Просмотреть файл

@ -2,6 +2,7 @@ import json
from django import test
from django.core.cache import cache
from django.test.utils import override_settings
from nose.tools import eq_
from pyquery import PyQuery as pq
@ -12,7 +13,7 @@ import amo.tests
from amo.tests import addon_factory
import addons.signals
from amo.urlresolvers import reverse
from addons.models import (Addon, AddonDependency, AddonUpsell, CompatOverride,
from addons.models import (Addon, AddonDependency, CompatOverride,
CompatOverrideRange, Preview)
from applications.models import Application, AppVersion
from bandwagon.models import MonthlyPick, SyncedCollection
@ -365,6 +366,7 @@ class TestPane(amo.tests.TestCase):
eq_(h2.text(), 'See all Featured Themes')
eq_(h2.find('a.all').attr('href'), reverse('browse.personas'))
@override_settings(MEDIA_URL='/media/', STATIC_URL='/static/')
def test_featured_personas(self):
addon = Addon.objects.get(id=15679)
r = self.client.get(self.url)
@ -374,8 +376,8 @@ class TestPane(amo.tests.TestCase):
eq_(featured.length, 1)
# Look for all images that are not icon uploads.
imgs = doc('img:not([src*="/uploads/"])')
imgs_ok = (pq(img).attr('src').startswith('/media/img/')
imgs = doc('img:not([src*="/media/"])')
imgs_ok = (pq(img).attr('src').startswith('/static/')
for img in imgs)
assert all(imgs_ok), 'Images must be prefixed with MEDIA_URL!'

Просмотреть файл

@ -35,7 +35,7 @@
{% endif %}
<a href="{{ url('editors.themes.queue' + url_suffix) }}">
{{ _('Interactive Theme Queue') }}
<img src="{{ media('img/impala/blue-arrow.png') }}" alt="">
<img src="{{ static('img/impala/blue-arrow.png') }}" alt="">
</a>
</h3>

Просмотреть файл

@ -13,6 +13,7 @@ import amo
import amo.tests
from addons.models import Addon
from amo.urlresolvers import reverse
from amo.helpers import storage_path
from devhub.models import ActivityLog
from editors import helpers
from editors.models import ReviewerScore
@ -173,9 +174,6 @@ class TestReviewHelper(amo.tests.TestCase):
self.helper = self.get_helper()
self.file = self.version.files.all()[0]
self.old_mirror = settings.MIRROR_STAGE_PATH
self.old_normal = settings.ADDONS_PATH
self.create_paths()
def _check_score(self, reviewed_type):

Просмотреть файл

@ -30,6 +30,7 @@ import amo.utils
from amo.decorators import use_master
from amo.storage_utils import copy_stored_file, move_stored_file
from amo.urlresolvers import reverse
from amo.helpers import storage_path
from applications.models import Application, AppVersion
import devhub.signals
from devhub.utils import limit_validation_results, escape_validation
@ -266,7 +267,7 @@ class File(amo.models.OnChangeMixin, amo.models.ModelBase):
@property
def file_path(self):
return os.path.join(settings.ADDONS_PATH, str(self.version.addon_id),
return os.path.join(storage_path('addons'), str(self.version.addon_id),
self.filename)
@property
@ -278,12 +279,12 @@ class File(amo.models.OnChangeMixin, amo.models.ModelBase):
@property
def mirror_file_path(self):
return os.path.join(settings.MIRROR_STAGE_PATH,
return os.path.join(storage_path('mirror_stage'),
str(self.version.addon_id), self.filename)
@property
def guarded_file_path(self):
return os.path.join(settings.GUARDED_ADDONS_PATH,
return os.path.join(storage_path('guarded_addons'),
str(self.version.addon_id), self.filename)
def _signed(self):
@ -575,7 +576,7 @@ class FileUpload(amo.models.ModelBase):
def add_file(self, chunks, filename, size):
filename = smart_str(filename)
loc = os.path.join(settings.ADDONS_PATH, 'temp', uuid.uuid4().hex)
loc = os.path.join(storage_path('addons'), 'temp', uuid.uuid4().hex)
base, ext = os.path.splitext(amo.utils.smart_path(filename))
if ext in EXTENSIONS:
loc += ext

Просмотреть файл

@ -155,24 +155,23 @@ class TestFile(amo.tests.TestCase, amo.tests.AMOPaths):
def test_unhide_disabled_file_mirroring(self):
tmp = tempfile.mkdtemp()
self.addCleanup(lambda: shutil.rmtree(tmp))
with mock.patch.object(settings, 'MIRROR_STAGE_PATH', tmp):
fo = File.objects.get(pk=67442)
with storage.open(fo.file_path, 'wb') as fp:
fp.write('<pretend this is an xpi>')
with storage.open(fo.mirror_file_path, 'wb') as fp:
fp.write('<pretend this is an xpi>')
fo.status = amo.STATUS_DISABLED
fo.save()
assert not storage.exists(fo.file_path), 'file not hidden'
assert not storage.exists(fo.mirror_file_path), (
'file not removed from mirror')
fo = File.objects.get(pk=67442)
with storage.open(fo.file_path, 'wb') as fp:
fp.write('<pretend this is an xpi>')
with storage.open(fo.mirror_file_path, 'wb') as fp:
fp.write('<pretend this is an xpi>')
fo.status = amo.STATUS_DISABLED
fo.save()
assert not storage.exists(fo.file_path), 'file not hidden'
assert not storage.exists(fo.mirror_file_path), (
'file not removed from mirror')
fo = File.objects.get(pk=67442)
fo.status = amo.STATUS_PUBLIC
fo.save()
assert storage.exists(fo.file_path), 'file not un-hidden'
assert storage.exists(fo.mirror_file_path), (
'file not copied back to mirror')
fo = File.objects.get(pk=67442)
fo.status = amo.STATUS_PUBLIC
fo.save()
assert storage.exists(fo.file_path), 'file not un-hidden'
assert storage.exists(fo.mirror_file_path), (
'file not copied back to mirror')
@mock.patch('files.models.File.copy_to_mirror')
def test_copy_to_mirror_on_status_change(self, copy_mock):

Просмотреть файл

@ -15,7 +15,7 @@ from nose.tools import eq_
import amo
import amo.tests
from amo.helpers import absolutify
from amo.helpers import absolutify, storage_path
from amo.urlresolvers import reverse
from addons.models import Addon
from applications.models import AppVersion
@ -239,7 +239,7 @@ class TestRepackageJetpack(amo.tests.TestCase):
def test_unreviewed_file_not_on_mirror(self):
# Make sure the mirror dir is clear.
mirrordir = settings.MIRROR_STAGE_PATH + '/3615'
mirrordir = storage_path('mirror_stage') + '/3615'
rmtree(mirrordir)
self.file.update(status=amo.STATUS_UNREVIEWED)
new_file = tasks.repackage_jetpack(self.builder_data())

Просмотреть файл

@ -8,7 +8,7 @@
{% block bodyclass %}inverse{% endblock %}
{% block extrahead %}
<link rel="stylesheet" href="{{ MEDIA_URL }}css/zamboni/perf.css">
<link rel="stylesheet" href="{{ STATIC_URL }}css/zamboni/perf.css">
{% endblock %}

Просмотреть файл

@ -9,7 +9,7 @@
{% block extrahead %}
{{ css('zamboni/stats') }}
<link rel="stylesheet"
href="{{ media('css/zamboni/jquery-ui/custom-1.7.2.css') }}">
href="{{ static('css/zamboni/jquery-ui/custom-1.7.2.css') }}">
{% endblock %}
{% block title %}
@ -199,7 +199,7 @@
{% block js %}
<!--[if IE]>
<script src="{{ media('js/lib/excanvas.compiled.js') }}"></script>
<script src="{{ static('js/lib/excanvas.compiled.js') }}"></script>
<![endif]-->
{{ js('zamboni/stats') }}
{% endblock %}

Просмотреть файл

@ -38,7 +38,6 @@ from translations.query import order_by_translation
log = commonware.log.getLogger('z.users')
class SHA512PasswordHasher(BasePasswordHasher):
"""
The SHA2 password hashing algorithm, 512 bits.
@ -128,9 +127,11 @@ class UserEmailField(forms.EmailField):
return {'class': 'email-autocomplete',
'data-src': lazy_reverse('users.ajax')}
class UserManager(BaseUserManager, amo.models.ManagerBase):
pass
AbstractBaseUser._meta.get_field('password').max_length = 255
class UserProfile(amo.models.OnChangeMixin, amo.models.ModelBase, AbstractBaseUser):
objects = UserManager()
@ -260,8 +261,9 @@ class UserProfile(amo.models.OnChangeMixin, amo.models.ModelBase, AbstractBaseUs
@property
def picture_dir(self):
from amo.helpers import storage_path
split_id = re.match(r'((\d*?)(\d{0,3}?))\d{1,3}$', str(self.id))
return os.path.join(settings.USERPICS_PATH, split_id.group(2) or '0',
return os.path.join(storage_path('userpics'), split_id.group(2) or '0',
split_id.group(1) or '0')
@property
@ -270,13 +272,18 @@ class UserProfile(amo.models.OnChangeMixin, amo.models.ModelBase, AbstractBaseUs
@property
def picture_url(self):
from amo.helpers import storage_url
if not self.picture_type:
return settings.MEDIA_URL + '/img/zamboni/anon_user.png'
return settings.STATIC_URL + '/img/zamboni/anon_user.png'
else:
split_id = re.match(r'((\d*?)(\d{0,3}?))\d{1,3}$', str(self.id))
return settings.USERPICS_URL % (
split_id.group(2) or 0, split_id.group(1) or 0, self.id,
int(time.mktime(self.modified.timetuple())))
modified = int(time.mktime(self.modified.timetuple()))
path = "/".join([
split_id.group(2) or '0',
split_id.group(1) or '0',
"%s.png?modified=%s" % (self.id, modified)
])
return storage_url('userpics') + path
@amo.cached_property
def is_developer(self):

Просмотреть файл

@ -1,4 +1,3 @@
from django.conf import settings
from django.core.files.storage import default_storage as storage
import commonware.log
@ -7,6 +6,7 @@ from lib.es.utils import index_objects
from amo.decorators import set_modified_on
from amo.utils import resize_image
from amo.helpers import storage_path
from .models import UserProfile
from . import search
@ -18,7 +18,7 @@ task_log = commonware.log.getLogger('z.task')
def delete_photo(dst, **kw):
task_log.debug('[1@None] Deleting photo: %s.' % dst)
if not dst.startswith(settings.USERPICS_PATH):
if not dst.startswith(storage_path('userpics')):
task_log.error("Someone tried deleting something they shouldn't: %s"
% dst)
return

Просмотреть файл

@ -2,7 +2,7 @@
{% from 'includes/forms.html' import required %}
{% block extrahead %}
{{ super() }}
<link rel="stylesheet" href="{{ media('css/zamboni/admin-django.css') }}">
<link rel="stylesheet" href="{{ static('css/zamboni/admin-django.css') }}">
{% endblock %}
{% block title %}{{ page_title('Add Blacklisted E-mail Domains') }}{% endblock %}

Просмотреть файл

@ -2,7 +2,7 @@
{% from 'includes/forms.html' import required %}
{% block extrahead %}
{{ super() }}
<link rel="stylesheet" href="{{ media('css/zamboni/admin-django.css') }}">
<link rel="stylesheet" href="{{ static('css/zamboni/admin-django.css') }}">
{% endblock %}
{% block title %}{{ page_title('Add Blacklisted Usernames') }}{% endblock %}

Просмотреть файл

@ -5,7 +5,7 @@
{% block title %}{{ page_title(_('Account Settings')) }}{% endblock %}
{% block extrahead %}
<link rel="stylesheet" href="{{ media('css/zamboni/translations/trans.css') }}">
<link rel="stylesheet" href="{{ static('css/zamboni/translations/trans.css') }}">
{% endblock %}
{% block bodyattrs %}

Просмотреть файл

@ -6,8 +6,8 @@ from urlparse import urlparse
from django import forms
from django.conf import settings
from django.contrib.auth.hashers import (is_password_usable,
check_password, make_password, identify_hasher)
from django.contrib.auth.hashers import (is_password_usable, check_password,
make_password, identify_hasher)
from django.core import mail
from django.utils import encoding, translation

Просмотреть файл

@ -9,6 +9,7 @@ import commonware.log
import happyforms
import amo
from amo.helpers import storage_path
from addons.models import Addon, AddonUser
from files.models import File
from files.utils import parse_addon
@ -76,7 +77,7 @@ class XPIForm(happyforms.Form):
size=xpi.size)
filename = f.generate_filename()
path = os.path.join(settings.ADDONS_PATH, str(version.addon.id))
path = os.path.join(storage_path('addons'), str(version.addon.id))
with storage.open(os.path.join(path, filename), 'wb') as destination:
for chunk in xpi.chunks():
hash.update(chunk)

Просмотреть файл

@ -18,6 +18,7 @@ import amo.models
import amo.utils
from amo.decorators import use_master
from amo.urlresolvers import reverse
from amo.helpers import storage_path
from applications.models import Application, AppVersion
from files import utils
from files.models import File, Platform, cleanup_file
@ -168,11 +169,11 @@ class Version(amo.models.ModelBase):
@property
def path_prefix(self):
return os.path.join(settings.ADDONS_PATH, str(self.addon_id))
return os.path.join(storage_path('addons'), str(self.addon_id))
@property
def mirror_path_prefix(self):
return os.path.join(settings.MIRROR_STAGE_PATH, str(self.addon_id))
return os.path.join(storage_path('mirror_stage'), str(self.addon_id))
def license_url(self, impala=False):
return reverse('addons.license', args=[self.addon.slug, self.version])

Просмотреть файл

@ -14,7 +14,7 @@ them. See zadmin.rendered_content for more details.
{% templatetag openblock %} block extrahead {% templatetag closeblock %}
{% templatetag openvariable %} super() {% templatetag closevariable %}
<link rel="stylesheet" href="{{ MEDIA_URL }}css/zamboni/admin-django.css?b={{ BUILD_ID_CSS }}">
<link rel="stylesheet" href="{{ STATIC_URL }}css/zamboni/admin-django.css?b={{ BUILD_ID_CSS }}">
{% block extrastyle %}{% endblock %}
{% block extrahead %}{% endblock %}
{% templatetag openblock %} endblock {% templatetag closeblock %}

Просмотреть файл

@ -9,12 +9,12 @@ data-featured-collection-url="{{ url('zadmin.featured_collection') }}"
{% endblock %}
{% block extrahead %}
<link rel="stylesheet" href="{{ media('css/zamboni/admin_features.css') }}">
<link rel="stylesheet" href="{{ static('css/zamboni/admin_features.css') }}">
{% endblock %}
{% block js %}
{{ super() }}
<script src="{{ media('js/zamboni/admin_features.js') }}"></script>
<script src="{{ static('js/zamboni/admin_features.js') }}"></script>
{% endblock %}
{% macro fc(form) %}

Просмотреть файл

@ -6,7 +6,7 @@
{% block extrahead %}
<link rel="stylesheet"
href="{{ media('css/zamboni/jquery-ui/custom-1.7.2.css') }}">
href="{{ static('css/zamboni/jquery-ui/custom-1.7.2.css') }}">
{% endblock %}
{% block content %}
@ -43,4 +43,4 @@
<tr><td colspan=0>No Records Found.
{% endfor %}
</table>
{% endblock %}
{% endblock %}

Просмотреть файл

@ -307,12 +307,11 @@ Persona
-------
We use `Persona <https://login.persona.org/>`_ to log in and create accounts.
In order for this to work you need to set ``SITE_URL`` and ``STATIC_URL`` in
In order for this to work you need to set ``SITE_URL`` in
your local settings file based on how you run your dev server. Here is an
example::
SITE_URL = 'http://localhost:8000'
STATIC_URL = SITE_URL + '/' # STATIC_URL must have a trailing slash.
Create an Admin User

Просмотреть файл

@ -1,6 +1,15 @@
Settings Changelog
==================
2014-07-09
----------
All the media related `XXX_PATH` and `XXX_URL` settings have now been
deprecated, in favor of helpers `storage_url` and `storage_path`, during
the switch to `django.contrib.staticfiles`. `JINGO_MINIFY_USE_STATIC` is
also now set to True.
2014-04-25
----------

Просмотреть файл

@ -12,16 +12,6 @@ couple of settings you should check.
Checking your image settings
____________________________
First look for the following image serving settings::
SERVE_TMP_PATH = True # maps /tmp to olympia/tmp
PREVIEW_THUMBNAIL_URL = '/tmp/uploads/previews/thumbs/%s/%d.png?modified=%d'
PREVIEW_FULL_URL = '/tmp/uploads/previews/full/%s/%d.png?modified=%d'
USERPICS_URL = '/tmp/uploads/userpics/%s/%s/%s.png?modified=%d'
ADDON_ICON_URL = '/tmp/uploads/addon_icons/%s/%s-%s.png?modified=%d'
PREVIEW_THUMBNAIL_URL = '/tmp/uploads/previews/thumbs/%s/%d.png?modified=%d'
NEW_PERSONAS_IMAGE_URL = '/tmp/uploads/personas/%(id)d/%(file)s'
Check that ``CELERY_ALWAYS_EAGER`` is set to ``True`` in your settings file. This
means it will process tasks without celeryd running::

5
fabfile.py поставляемый
Просмотреть файл

@ -59,6 +59,11 @@ def compress_assets(arg=''):
managecmd('compress_assets -t %s' % arg)
@task
def collectstatic():
managecmd('collectstatic --noinput')
@task
def schematic():
with lcd(OLYMPIA):

Просмотреть файл

@ -212,67 +212,36 @@ OAUTH_CALLBACK_VIEW = 'api.views.request_token_ready'
# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = path('media')
MEDIA_ROOT = path('storage')
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = '/media/'
MEDIA_URL = '/storage/'
# Absolute path to a temporary storage area
TMP_PATH = path('tmp')
# When True, create a URL root /tmp that serves files in your temp path.
# This is useful for development to view upload pics, etc.
# NOTE: This only works when DEBUG is also True.
SERVE_TMP_PATH = False
# Absolute path to a writable directory shared by all servers. No trailing
# slash. Example: /data/
NETAPP_STORAGE = TMP_PATH
# 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'
# Like ADDONS_PATH but protected by the app. Used for storing files that should
# not be publicly accessible (like disabled add-ons).
GUARDED_ADDONS_PATH = NETAPP_STORAGE + '/guarded-addons'
# Absolute path to a writable directory shared by all servers. No trailing
# slash.
# Example: /data/uploads
UPLOADS_PATH = NETAPP_STORAGE + '/uploads'
# File path for add-on files that get rsynced to mirrors.
# /mnt/netapp_amo/addons.mozilla.org-remora/public-staging
MIRROR_STAGE_PATH = NETAPP_STORAGE + '/public-staging'
# Where dumped apps will be written too.
DUMPED_APPS_PATH = NETAPP_STORAGE + '/dumped-apps'
# Tarballs in DUMPED_APPS_PATH deleted 30 days after they have been written.
DUMPED_APPS_DAYS_DELETE = 3600 * 24 * 30
# Where dumped apps will be written too.
DUMPED_USERS_PATH = NETAPP_STORAGE + '/dumped-users'
# Tarballs in DUMPED_USERS_PATH deleted 30 days after they have been written.
DUMPED_USERS_DAYS_DELETE = 3600 * 24 * 30
# paths that don't require an app prefix
SUPPORTED_NONAPPS = ('about', 'admin', 'apps', 'blocklist', 'credits',
'developer_agreement', 'developer_faq', 'developers',
'editors', 'faq', 'google1f3e37b7351799a5.html', 'img',
'jsi18n', 'localizers', 'media', 'review_guide',
'robots.txt', 'statistics', 'services', 'sunbird',
'__debug__')
SUPPORTED_NONAPPS = (
'about', 'admin', 'apps', 'blocklist', 'credits', 'developer_agreement',
'developer_faq', 'developers', 'editors', 'faq', 'jsi18n', 'localizers',
'review_guide', 'google1f3e37b7351799a5.html', 'robots.txt', 'statistics',
'services', 'sunbird', 'static', 'storage',
)
DEFAULT_APP = 'firefox'
# paths that don't require a locale prefix
SUPPORTED_NONLOCALES = ('google1f3e37b7351799a5.html', 'img', 'media',
'robots.txt', 'services', 'downloads', 'blocklist',
'__debug__')
SUPPORTED_NONLOCALES = (
'google1f3e37b7351799a5.html', 'robots.txt', 'services', 'downloads',
'blocklist', 'static', 'storage',
)
# Make this unique, and don't share it with anybody.
SECRET_KEY = 'r#%9w^o_80)7f%!_ir5zx$tu3mupw9u%&s!)-_q%gy7i+fhx#)'
@ -445,6 +414,7 @@ INSTALLED_APPS = (
'django.contrib.contenttypes',
'django.contrib.messages',
'django.contrib.sessions',
'django.contrib.staticfiles',
# Has to load after auth
'django_browserid',
@ -943,40 +913,12 @@ LOCAL_MIRROR_URL = 'https://static.addons.mozilla.net/_files'
PRIVATE_MIRROR_URL = '/_privatefiles'
# File paths
ADDON_ICONS_PATH = UPLOADS_PATH + '/addon_icons'
COLLECTIONS_ICON_PATH = UPLOADS_PATH + '/collection_icons'
PREVIEWS_PATH = UPLOADS_PATH + '/previews'
IMAGEASSETS_PATH = UPLOADS_PATH + '/imageassets'
REVIEWER_ATTACHMENTS_PATH = UPLOADS_PATH + '/reviewer_attachment'
USERPICS_PATH = UPLOADS_PATH + '/userpics'
PACKAGER_PATH = os.path.join(TMP_PATH, 'packager')
ADDON_ICONS_DEFAULT_PATH = os.path.join(MEDIA_ROOT, 'img/addon-icons')
ADDON_ICONS_DEFAULT_PATH = os.path.join(ROOT, 'static', 'img', 'addon-icons')
CA_CERT_BUNDLE_PATH = os.path.join(ROOT, 'apps/amo/certificates/roots.pem')
PREVIEW_THUMBNAIL_PATH = PREVIEWS_PATH + '/thumbs/%s/%d.png'
PREVIEW_FULL_PATH = PREVIEWS_PATH + '/full/%s/%d.%s'
# URL paths
# paths for images, e.g. mozcdn.com/amo or '/static'
STATIC_URL = SITE_URL + '/'
ADDON_ICONS_DEFAULT_URL = MEDIA_URL + '/img/addon-icons'
ADDON_ICON_BASE_URL = MEDIA_URL + 'img/icons/'
ADDON_ICON_URL = (STATIC_URL +
'img/uploads/addon_icons/%s/%s-%s.png?modified=%s')
PREVIEW_THUMBNAIL_URL = (STATIC_URL +
'img/uploads/previews/thumbs/%s/%d.png?modified=%d')
PREVIEW_FULL_URL = (STATIC_URL +
'img/uploads/previews/full/%s/%d.%s?modified=%d')
USERPICS_URL = STATIC_URL + 'img/uploads/userpics/%s/%s/%s.png?modified=%d'
# paths for uploaded extensions
COLLECTION_ICON_URL = (STATIC_URL +
'img/uploads/collection_icons/%s/%s.png?m=%s')
NEW_PERSONAS_IMAGE_URL = STATIC_URL + 'img/uploads/themes/%(id)d/%(file)s'
PERSONAS_IMAGE_URL = ('http://getpersonas.cdn.mozilla.net/static/'
'%(tens)d/%(units)d/%(id)d/%(file)s')
PERSONAS_IMAGE_URL_SSL = ('https://getpersonas.cdn.mozilla.net/static/'
'%(tens)d/%(units)d/%(id)d/%(file)s')
PERSONAS_UPDATE_URL = 'https://www.getpersonas.com/update_check/%d'
VAMO_URL = 'https://versioncheck.addons.mozilla.org'
NEW_PERSONAS_UPDATE_URL = VAMO_URL + '/%(locale)s/themes/update-check/%(id)d'
@ -1499,7 +1441,7 @@ LANGPACK_MAX_SIZE = 5 * 1024 * 1024 # 5MB should be more than enough
BASKET_URL = 'https://basket.mozilla.com'
# This saves us when we upgrade jingo-minify (jsocol/jingo-minify@916b054c).
JINGO_MINIFY_USE_STATIC = False
JINGO_MINIFY_USE_STATIC = True
# Monolith settings.
MONOLITH_SERVER = None
@ -1524,3 +1466,12 @@ HIVE_CONNECTION = {
'password': '',
'auth_mechanism': 'PLAIN',
}
# Static
STATIC_ROOT = path('site-static')
STATIC_URL = '/static/'
JINGO_MINIFY_ROOT = path('static')
STATICFILES_DIRS = (
path('static'),
JINGO_MINIFY_ROOT
)

Просмотреть файл

@ -1,9 +1,7 @@
import os
from django.conf import settings
from django.conf.urls import include, patterns, url
from django.contrib import admin
from django.shortcuts import redirect, render
from django.shortcuts import redirect
from django.views.i18n import javascript_catalog
from django.views.decorators.cache import cache_page
@ -191,24 +189,7 @@ if settings.TEMPLATE_DEBUG:
url(r'^__debug__/', include(debug_toolbar.urls)),
)
# We're not using the staticfiles app, like every good Django citizen
# should, so we have to cope with this weirdness.
ddt_folder = os.path.dirname(debug_toolbar.__file__)
ddt_static_path = os.path.join(ddt_folder, 'static')
urlpatterns += patterns('',
(r'^%s/(?P<path>debug_toolbar/.*)$' % media_url,
'django.views.static.serve',
{'document_root': ddt_static_path}),
)
urlpatterns += patterns('',
(r'^%s/(?P<path>.*)$' % media_url, 'django.views.static.serve',
{'document_root': settings.MEDIA_ROOT}),
)
if settings.SERVE_TMP_PATH and settings.DEBUG:
urlpatterns += patterns('',
(r'^tmp/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.TMP_PATH}),
)

Просмотреть файл

@ -1,345 +0,0 @@
/*
* packagedAppUploader()
* Extends fileUploader()
* Also, this can only be used once per page. Or you'll have lots of issues with closures and scope :)
*/
(function($) {
/* Normalize results */
function getErrors(results) {
var errors = [];
if (results.validation.messages) {
$.each(results.validation.messages, function(i, v) {
if (v.type == 'error') {
errors.push(v.message);
}
});
}
return errors;
}
$.fn.packagedAppUploader = function( options ) {
var settings = {'filetypes': ['zip'], 'getErrors': getErrors, 'cancel': $()};
if (options) {
$.extend( settings, options );
}
function parseErrorsFromJson(response) {
var json, errors = [];
try {
json = JSON.parse(response);
} catch (err) {
errors = [gettext('There was a problem contacting the server.')];
}
if (!errors.length) {
errors = settings['getErrors'](json);
}
return {
errors: errors,
json: json
}
}
return $(this).each(function() {
var $upload_field = $(this),
file = {};
/* Add some UI */
var ui_parent = $('<div>', {'class': 'invisible-upload prominent cta', 'id': 'upload-file-widget'}),
ui_link = $('<a>', {'class': 'button prominent', 'href': '#', 'text': gettext('Select a file...')}),
ui_details = $('<div>', {'class': 'upload-details', 'html': gettext('Your packaged app should end with <code>.zip</code>.')});
$upload_field.attr('disabled', false);
$upload_field.wrap(ui_parent);
$upload_field.before(ui_link);
$upload_field.parent().after(ui_details);
if (!z.capabilities.fileAPI) {
$('.invisible-upload').addClass('legacy');
}
/* Get things started */
var upload_box, upload_title, upload_progress_outside, upload_progress_inside,
upload_status, upload_results, upload_status_percent, upload_status_progress,
upload_status_cancel;
$upload_field.fileUploader(settings);
function textSize(bytes) {
// Based on code by Cary Dunn (http://bit.ly/d8qbWc).
var s = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
if (bytes === 0) {
return bytes + ' ' + s[1];
}
var e = Math.floor( Math.log(bytes) / Math.log(1024) );
return (bytes / Math.pow(1024, Math.floor(e))).toFixed(2)+' '+s[e];
}
function updateStatus(percentage, size) {
if (percentage) {
upload_status.show();
p = Math.round(percentage);
size = (p / 100) * size;
// L10n: {0} is the percent of the file that has been uploaded.
upload_status_percent.text(format(gettext('{0}% complete'), [p]));
// L10n: "{bytes uploaded} of {total filesize}".
upload_status_progress.text(format(gettext('{0} of {1}'),
[textSize(size), textSize(file.size)]));
}
}
/* Bind the events */
$upload_field.bind('upload_start', function(e, _file) {
file = _file;
/* Remove old upload box */
if (upload_box) {
upload_box.remove();
}
/* Remove old errors */
$upload_field.closest('form').find('.errorlist').remove();
/* Don't allow submitting */
$('.addon-upload-dependant').attr('disabled', true);
/* Create elements */
upload_title = $('<strong>', {'id': 'upload-status-text'});
upload_progress_outside = $('<div>', {'id': 'upload-status-bar'});
upload_progress_inside = $('<div>').css('width', 0);
upload_status = $('<div>', {'id': 'uploadstatus'}).hide();
upload_status_percent = $('<span>');
upload_status_progress = $('<span>');
upload_status_cancel_a = $('<a>', {'href': '#', 'text': gettext('Cancel')});
upload_status_cancel = $('<span> &middot; </span>');
upload_results = $('<div>', {'id': 'upload-status-results'});
upload_box = $('<div>', {'class': 'upload-status ajax-loading'}).hide();
/* Set up structure */
upload_box.append(upload_title);
upload_progress_outside.append(upload_progress_inside);
upload_box.append(upload_progress_outside);
upload_status.append(upload_status_percent);
upload_status.append(' <span> &middot; </span> ');
upload_status.append(upload_status_progress);
upload_status.append(upload_status_cancel);
upload_status_cancel.append(upload_status_cancel_a);
upload_box.append(upload_status);
upload_box.append(upload_results);
/* Add to the dom and clean up upload_field */
ui_details.after(upload_box);
/* It's showtime! */
upload_title.html(format(gettext('Uploading {0}'), [escape_(file.name)]));
upload_box.show();
upload_box.addClass('ajax-loading');
upload_status_cancel_a.click(_pd(function() {
$upload_field.trigger('upload_action_abort');
}));
});
$upload_field.bind('upload_progress', function(e, file, pct) {
upload_progress_inside.animate({'width': pct + '%'},
{duration: 300, step:function(i) { updateStatus(i, file.size); } });
});
$upload_field.bind('upload_errors', function(e, file, errors, results) {
var all_errors = $.extend([], errors); // be nice to other handlers
upload_progress_inside.stop().css({'width': '100%'});
$upload_field.val('').attr('disabled', false);
$upload_field.trigger('reenable_uploader');
upload_title.html(format(gettext('Error with {0}'), [escape_(file.name)]));
upload_progress_outside.attr('class', 'bar-fail');
upload_progress_inside.fadeOut();
var error_message = format(ngettext(
'Your app failed validation with {0} error.',
'Your app failed validation with {0} errors.',
all_errors.length), [all_errors.length]);
$('<strong>').text(error_message).appendTo(upload_results);
var errors_ul = $('<ul>', {'id': 'upload_errors'});
$.each(all_errors.splice(0, 5), function(i, error) {
errors_ul.append($('<li>', {'html': error }));
});
if (all_errors.length > 0) {
var message = format(ngettext('&hellip;and {0} more',
'&hellip;and {0} more',
all_errors.length), [all_errors.length]);
errors_ul.append($('<li>', {'html': message}));
}
upload_results.append(errors_ul).addClass('status-fail');
if (results && results.full_report_url) {
// There might not be a link to the full report
// if we get an early error like unsupported type.
upload_results.append($('<a>', {'href': results.full_report_url,
'class': 'view-more',
'target': '_blank',
'text': gettext('See full validation report')}));
}
});
$upload_field.bind('upload_finished', function(e, file, results) {
upload_box.removeClass('ajax-loading');
upload_status_cancel.remove();
});
$upload_field.bind('upload_success', function(e, file, results) {
upload_title.html(format(gettext('Validating {0}'), [escape_(file.name)]));
var animateArgs = {duration: 300, step:function(i) { updateStatus(i, file.size); }, complete: function() {
$upload_field.trigger('upload_success_results', [file, results]);
}};
$('#id_upload').val(results.upload);
$('#id_packaged').prop('checked', true);
upload_progress_inside.animate({'width': '100%'}, animateArgs);
});
$upload_field.bind('upload_onreadystatechange', function(e, file, xhr, aborted) {
var errors = [],
$form = $upload_field.closest('form'),
json = {},
errOb;
if (xhr.readyState == 4 && xhr.responseText &&
(xhr.status == 200 ||
xhr.status == 304 ||
xhr.status == 400)) {
errOb = parseErrorsFromJson(xhr.responseText);
errors = errOb.errors;
json = errOb.json;
if (errors.length > 0) {
$upload_field.trigger('upload_errors', [file, errors, json]);
} else {
$form.find('input#id_upload').val(json.upload);
$upload_field.trigger('upload_success', [file, json]);
$upload_field.trigger('upload_progress', [file, 100]);
}
$upload_field.trigger('upload_finished', [file]);
} else if (xhr.readyState == 4 && !aborted) {
// L10n: first argument is an HTTP status code
errors = [format(gettext('Received an empty response from the server; status: {0}'),
[xhr.status])];
$upload_field.trigger('upload_errors', [file, errors]);
}
});
$upload_field.bind('upload_success_results', function(e, file, results) {
if (results.error) {
// This shouldn't happen. But it might.
var error = gettext('Unexpected server error while validating.');
$upload_field.trigger('upload_errors', [file, [error]]);
return;
}
// Validation results? If not, fetch the json again.
if (! results.validation) {
upload_progress_outside.attr('class', 'progress-idle');
// Not loaded yet. Try again!
setTimeout(function() {
$.ajax({
url: results.url,
dataType: 'json',
success: function(r) {
$upload_field.trigger('upload_success_results', [file, r]);
},
error: function(xhr, textStatus, errorThrown) {
var errOb = parseErrorsFromJson(xhr.responseText);
$upload_field.trigger('upload_errors', [file, errOb.errors, errOb.json]);
$upload_field.trigger('upload_finished', [file]);
}
});
}, 1000);
} else {
var errors = getErrors(results),
v = results.validation,
$webapp_features = $('#upload-webapp-features');
if (errors.length > 0) {
$upload_field.trigger('upload_errors', [file, errors, results]);
return;
}
$upload_field.val('').attr('disabled', false);
/* Allow submitting */
$('.addon-upload-dependant').attr('disabled', false);
upload_title.html(format(gettext('Finished validating {0}'), [escape_(file.name)]));
var message = '';
var warnings = v.warnings + v.notices;
if (warnings > 0) {
message = format(ngettext(
'Your app passed validation with no errors and {0} warning.',
'Your app passed validation with no errors and {0} warnings.',
warnings), [warnings]);
} else {
message = gettext('Your app passed validation with no errors or warnings.');
}
upload_progress_outside.attr('class', 'bar-success');
upload_progress_inside.fadeOut();
$('.listing-footer').removeClass('hidden')
.siblings('#upload-webapp-features').removeClass('hidden');
$('button.upload-file-submit').removeAttr('disabled').focus();
$upload_field.trigger('reenable_uploader');
upload_results.addClass('status-pass');
$('<strong>').text(message).appendTo(upload_results);
if (results.full_report_url) {
// There might not be a link to the full report
// if we get an early error like unsupported type.
upload_results.append($('<a>', {'href': results.full_report_url,
'target': '_blank',
'text': gettext('See full validation report')}));
}
// Uncheck all existing features checkboxes since it's a new upload.
// We have to avoid has_qhd since it's not dependent on the feature
// profile returned by the validator.
$webapp_features.find('input:checked:not(#id_has_qhd)').prop('checked', false).trigger('change');
if (v.feature_profile && v.feature_profile.length) {
// Update the checkboxes with information from the validator's idea
// of the feature profile for the app.
v.feature_profile.forEach(function(feature) {
$('#id_has_' + feature.toLowerCase()).prop('checked', true).trigger('change');
});
}
}
});
});
};
})(jQuery);

Просмотреть файл

@ -107,7 +107,7 @@ thrift==0.9.1
-e git+https://github.com/mozilla/happyforms.git@729612c2a824a7e8283d416d2084bf506c671e24#egg=happyforms
# Temporary fork.
-e git+https://github.com/jsocol/jingo-minify.git@b7405d3f93628190bf83cc43b0ff44e2fbb8b3c0#egg=jingo_minify
-e git+https://github.com/yohanboniface/jingo-minify.git@da0e4f4c0c29e7081d2aaf0bccfce8b101254724#egg=jingo_minify
-e git+https://github.com/washort/nuggets.git@02798dfce84030fca64775eaf56e92400f394e4f#egg=nuggets
-e git+https://github.com/washort/test-utils.git@4917197a64b6d0f2068c9ad1bfea0427c3e412e1#egg=test-utils
-e git+https://github.com/fwenzel/django-mozilla-product-details@f5a3c3c846fb75e12ad890b22ed5375d5b85ccb4#egg=django-mozilla-product-details

Просмотреть файл

@ -22,7 +22,7 @@ fi
SETTINGS=$1
# Delete old artifacts.
find . -name '*.pyc' -or -name '*.less.css' -or -name '*.styl.css' -or -name '*-min.css' -or -name '*-all.css' -or -name '*-min.js' -or -name '*-all.js' | grep -v media/js/lib/ | xargs rm
find . -name '*.pyc' -or -name '*.less.css' -or -name '*.styl.css' -or -name '*-min.css' -or -name '*-all.css' -or -name '*-min.js' -or -name '*-all.js' | grep -v static/js/lib/ | xargs rm
if [ ! -d "$VENV/bin" ]; then
echo "No virtualenv found. Making one..."

Просмотреть файл

@ -71,6 +71,12 @@ def compress_assets(ctx, arg=''):
arg))
@task
def collectstatic(ctx):
with ctx.lcd(settings.SRC_DIR):
ctx.local("%s manage.py collectstatic --noinput" % (settings.PYTHON, ))
@task
def schematic(ctx):
with ctx.lcd(settings.SRC_DIR):
@ -183,6 +189,7 @@ def update(ctx):
update_locales()
update_products()
compress_assets()
collectstatic()
schematic()
with ctx.lcd(settings.SRC_DIR):
ctx.local('%s manage.py dump_apps' % settings.PYTHON)

Просмотреть файл

@ -8,6 +8,7 @@ from wsgiref.handlers import format_date_time
from constants import base
from utils import log_configure, log_exception, mypool
# from amo.helpers import storage_path
from services.utils import settings
@ -169,7 +170,7 @@ class ThemeUpdate(object):
elif filename == 'icon.png':
filename = 'preview_small.jpg'
return os.path.join(settings.ADDONS_PATH, str(row['addon_id']),
return os.path.join(storage_path('addons'), str(row['addon_id']),
filename)
def image_url(self, filename):

Просмотреть файл

@ -30,18 +30,8 @@ def _polite_tmpdir():
# See settings.py for documentation:
IN_TEST_SUITE = True
NETAPP_STORAGE = _polite_tmpdir()
ADDONS_PATH = _polite_tmpdir()
GUARDED_ADDONS_PATH = _polite_tmpdir()
SIGNED_APPS_PATH = _polite_tmpdir()
SIGNED_APPS_REVIEWER_PATH = _polite_tmpdir()
UPLOADS_PATH = _polite_tmpdir()
MIRROR_STAGE_PATH = _polite_tmpdir()
MEDIA_ROOT = _polite_tmpdir()
TMP_PATH = _polite_tmpdir()
COLLECTIONS_ICON_PATH = _polite_tmpdir()
PACKAGER_PATH = _polite_tmpdir()
REVIEWER_ATTACHMENTS_PATH = _polite_tmpdir()
DUMPED_APPS_PATH = _polite_tmpdir()
# Don't call out to persona in tests.
AUTHENTICATION_BACKENDS = (
@ -62,19 +52,8 @@ PAYPAL_PERMISSIONS_URL = ''
ENABLE_API_ERROR_SERVICE = False
SITE_URL = 'http://testserver'
STATIC_URL = SITE_URL + '/'
LOCAL_MIRROR_URL = SITE_URL
MOBILE_SITE_URL = ''
MEDIA_URL = '/media/'
# Reset these URLs to the defaults so your settings_local doesn't clobber them:
ADDON_ICONS_DEFAULT_URL = MEDIA_URL + '/img/addon-icons'
ADDON_ICON_BASE_URL = MEDIA_URL + 'img/icons/'
ADDON_ICON_URL = (STATIC_URL +
'img/uploads/addon_icons/%s/%s-%s.png?modified=%s')
PREVIEW_THUMBNAIL_URL = (STATIC_URL +
'img/uploads/previews/thumbs/%s/%d.png?modified=%d')
PREVIEW_FULL_URL = (STATIC_URL +
'img/uploads/previews/full/%s/%d.%s?modified=%d')
USERPICS_URL = STATIC_URL + 'img/uploads/userpics/%s/%s/%s.png?modified=%d'
CACHES = {
'default': {

Просмотреть файл

@ -25,9 +25,6 @@ PREVIEW_FULL_URL = (STATIC_URL +
'img/uploads/previews/full/%s/%d.png?modified=%d')
NEW_PERSONAS_IMAGE_URL = STATIC_URL + 'img/uploads/themes/%(id)d/%(file)s'
# paths for uploaded extensions
FILES_URL = STATIC_URL + "%s/%s/downloads/file/%d/%s?src=%s"
SESSION_COOKIE_DOMAIN = ".%s" % DOMAIN
USERPICS_URL = STATIC_URL + 'img/uploads/userpics/%s/%s/%s.png?modified=%d'
@ -36,8 +33,6 @@ COLLECTION_ICON_URL = STATIC_URL + '/img/uploads/collection_icons/%s/%s.png?m=%s
NEW_PERSONAS_IMAGE_URL = STATIC_URL + 'img/uploads/themes/%(id)d/%(file)s'
MEDIA_URL = STATIC_URL + 'media/'
ADDON_ICONS_DEFAULT_URL = MEDIA_URL + 'img/addon-icons'
ADDON_ICON_BASE_URL = MEDIA_URL + 'img/icons/'
CACHE_PREFIX = 'altdev.%s' % CACHE_PREFIX

Просмотреть файл

@ -70,7 +70,7 @@ GUARDED_ADDONS_PATH = private.NETAPP_STORAGE_ROOT + '/guarded-addons'
UPLOADS_PATH = NETAPP_STORAGE + '/uploads'
USERPICS_PATH = UPLOADS_PATH + '/userpics'
ADDON_ICONS_PATH = UPLOADS_PATH + '/addon_icons'
COLLECTIONS_ICON_PATH = UPLOADS_PATH + '/collection_icons'
COLLECTION_ICONS_PATH = UPLOADS_PATH + '/collection_icons'
IMAGEASSETS_PATH = UPLOADS_PATH + '/imageassets'
REVIEWER_ATTACHMENTS_PATH = UPLOADS_PATH + '/reviewer_attachment'
PREVIEWS_PATH = UPLOADS_PATH + '/previews'

Просмотреть файл

@ -11,36 +11,17 @@ SERVER_EMAIL = 'zdev@addons.mozilla.org'
SITE_URL = getattr(private_addons, 'SITE_URL', 'https://' + DOMAIN)
SERVICES_URL = SITE_URL
STATIC_URL = getattr(private_addons, 'STATIC_URL', 'https://addons-dev-cdn.allizom.org/')
LOCAL_MIRROR_URL = '%s_files' % STATIC_URL
MIRROR_URL = STATIC_URL + 'storage/public-staging'
STATIC_URL = getattr(private_addons, 'STATIC_URL', 'https://addons-dev-cdn.allizom.org/static/')
MEDIA_URL = getattr(private_addons, 'MEDIA_URL', 'https://addons-dev-cdn.allizom.org/storage/')
LOCAL_MIRROR_URL = '%s_files' % MEDIA_URL
MIRROR_URL = MEDIA_URL + 'public-staging'
CSP_FRAME_SRC = CSP_FRAME_SRC + ("https://sandbox.paypal.com",)
CSP_SCRIPT_SRC = CSP_SCRIPT_SRC + (STATIC_URL[:-1],)
ADDON_ICON_URL = STATIC_URL + 'img/uploads/addon_icons/%s/%s-%s.png?modified=%s'
PREVIEW_THUMBNAIL_URL = (
STATIC_URL +
'img/uploads/previews/thumbs/%s/%d.png?modified=%d')
PREVIEW_FULL_URL = (
STATIC_URL +
'img/uploads/previews/full/%s/%d.png?modified=%d')
NEW_PERSONAS_IMAGE_URL = STATIC_URL + 'img/uploads/themes/%(id)d/%(file)s'
# paths for uploaded extensions
FILES_URL = STATIC_URL + "%s/%s/downloads/file/%d/%s?src=%s"
CSP_SCRIPT_SRC = CSP_SCRIPT_SRC + (MEDIA_URL[:-1],)
SESSION_COOKIE_DOMAIN = ".%s" % DOMAIN
USERPICS_URL = STATIC_URL + 'img/uploads/userpics/%s/%s/%s.png?modified=%d'
COLLECTION_ICON_URL = STATIC_URL + '/img/uploads/collection_icons/%s/%s.png?m=%s'
NEW_PERSONAS_IMAGE_URL = STATIC_URL + 'img/uploads/themes/%(id)d/%(file)s'
MEDIA_URL = STATIC_URL + 'media/'
ADDON_ICONS_DEFAULT_URL = MEDIA_URL + 'img/addon-icons'
ADDON_ICON_BASE_URL = MEDIA_URL + 'img/icons/'
CACHE_PREFIX = 'dev.olympia.%s' % CACHE_PREFIX
KEY_PREFIX = CACHE_PREFIX

Просмотреть файл

@ -68,17 +68,15 @@ CELERYD_PREFETCH_MULTIPLIER = 1
NETAPP_STORAGE = private.NETAPP_STORAGE_ROOT + '/shared_storage'
MIRROR_STAGE_PATH = private.NETAPP_STORAGE_ROOT + '/public-staging'
GUARDED_ADDONS_PATH = private.NETAPP_STORAGE_ROOT + '/guarded-addons'
UPLOADS_PATH = NETAPP_STORAGE + '/uploads'
USERPICS_PATH = UPLOADS_PATH + '/userpics'
ADDON_ICONS_PATH = UPLOADS_PATH + '/addon_icons'
COLLECTIONS_ICON_PATH = UPLOADS_PATH + '/collection_icons'
IMAGEASSETS_PATH = UPLOADS_PATH + '/imageassets'
REVIEWER_ATTACHMENTS_PATH = UPLOADS_PATH + '/reviewer_attachment'
PREVIEWS_PATH = UPLOADS_PATH + '/previews'
SIGNED_APPS_PATH = NETAPP_STORAGE + '/signed_apps'
SIGNED_APPS_REVIEWER_PATH = NETAPP_STORAGE + '/signed_apps_reviewer'
PREVIEW_THUMBNAIL_PATH = PREVIEWS_PATH + '/thumbs/%s/%d.png'
PREVIEW_FULL_PATH = PREVIEWS_PATH + '/full/%s/%d.%s'
MEDIA_ROOT = NETAPP_STORAGE + '/uploads'
STATIC_ROOT = NETAPP_STORAGE + '/static'
# Must be forced in settings because name => path can't be dyncamically
# computed: reviewer_attachmentS VS reviewer_attachment.
# TODO: rename folder on file system.
# (One can also just rename the setting, but this will not be consistent
# with the naming scheme.)
REVIEWER_ATTACHMENTS_PATH = MEDIA_ROOT + '/reviewer_attachment'
HERA = []
LOGGING['loggers'].update({

Просмотреть файл

@ -70,7 +70,7 @@ GUARDED_ADDONS_PATH = private.NETAPP_STORAGE_ROOT + '/guarded-addons'
UPLOADS_PATH = NETAPP_STORAGE + '/uploads'
USERPICS_PATH = UPLOADS_PATH + '/userpics'
ADDON_ICONS_PATH = UPLOADS_PATH + '/addon_icons'
COLLECTIONS_ICON_PATH = UPLOADS_PATH + '/collection_icons'
COLLECTION_ICONS_PATH = UPLOADS_PATH + '/collection_icons'
IMAGEASSETS_PATH = UPLOADS_PATH + '/imageassets'
REVIEWER_ATTACHMENTS_PATH = UPLOADS_PATH + '/reviewer_attachment'
PREVIEWS_PATH = UPLOADS_PATH + '/previews'

Просмотреть файл

@ -23,8 +23,6 @@ PREVIEW_THUMBNAIL_URL = (STATIC_URL +
'img/uploads/previews/thumbs/%s/%d.png?modified=%d')
PREVIEW_FULL_URL = (STATIC_URL +
'img/uploads/previews/full/%s/%d.png?modified=%d')
# paths for uploaded extensions
FILES_URL = STATIC_URL + "%s/%s/downloads/file/%d/%s?src=%s"
SESSION_COOKIE_DOMAIN = ".%s" % DOMAIN
@ -33,8 +31,6 @@ USERPICS_URL = STATIC_URL + 'img/uploads/userpics/%s/%s/%s.png?modified=%d'
COLLECTION_ICON_URL = STATIC_URL + '/img/uploads/collection_icons/%s/%s.png?m=%s'
MEDIA_URL = STATIC_URL + 'media/'
ADDON_ICONS_DEFAULT_URL = MEDIA_URL + 'img/addon-icons'
ADDON_ICON_BASE_URL = MEDIA_URL + 'img/icons/'
CACHE_PREFIX = 'landfill.%s' % CACHE_PREFIX

Просмотреть файл

@ -73,7 +73,7 @@ GUARDED_ADDONS_PATH = private.NETAPP_STORAGE_ROOT + '/guarded-addons'
UPLOADS_PATH = NETAPP_STORAGE + '/uploads'
USERPICS_PATH = UPLOADS_PATH + '/userpics'
ADDON_ICONS_PATH = UPLOADS_PATH + '/addon_icons'
COLLECTIONS_ICON_PATH = UPLOADS_PATH + '/collection_icons'
COLLECTION_ICONS_PATH = UPLOADS_PATH + '/collection_icons'
IMAGEASSETS_PATH = UPLOADS_PATH + '/imageassets'
REVIEWER_ATTACHMENTS_PATH = UPLOADS_PATH + '/reviewer_attachment'
PREVIEWS_PATH = UPLOADS_PATH + '/previews'

Просмотреть файл

@ -22,9 +22,7 @@ ADDON_ICON_URL = STATIC_URL + 'img/uploads/addon_icons/%s/%s-%s.png?modified=%s'
PREVIEW_THUMBNAIL_URL = (STATIC_URL +
'img/uploads/previews/thumbs/%s/%d.png?modified=%d')
PREVIEW_FULL_URL = STATIC_URL + 'img/uploads/previews/full/%s/%d.png?modified=%d'
# paths for uploaded extensions
FILES_URL = STATIC_URL + "%s/%s/downloads/file/%d/%s?src=%s"
PREVIEW_URL = MEDIA_URL = 'img/uploads/previews/'
SESSION_COOKIE_DOMAIN = ".%s" % DOMAIN
@ -34,8 +32,6 @@ COLLECTION_ICON_URL = STATIC_URL + 'img/uploads/collection_icons/%s/%s.png?m=%s'
NEW_PERSONAS_IMAGE_URL = STATIC_URL + 'img/uploads/themes/%(id)d/%(file)s'
MEDIA_URL = "%smedia/" % STATIC_URL
ADDON_ICONS_DEFAULT_URL = MEDIA_URL + '/img/addon-icons'
ADDON_ICON_BASE_URL = MEDIA_URL + 'img/icons/'
CACHE_PREFIX = 'prod.amo.%s' % CACHE_PREFIX
CACHE_MIDDLEWARE_KEY_PREFIX = CACHE_PREFIX

Просмотреть файл

@ -65,7 +65,7 @@ MIRROR_STAGE_PATH = NETAPP_STORAGE_ROOT + '/public-staging'
UPLOADS_PATH = NETAPP_STORAGE + '/uploads'
USERPICS_PATH = UPLOADS_PATH + '/userpics'
ADDON_ICONS_PATH = UPLOADS_PATH + '/addon_icons'
COLLECTIONS_ICON_PATH = UPLOADS_PATH + '/collection_icons'
COLLECTION_ICONS_PATH = UPLOADS_PATH + '/collection_icons'
IMAGEASSETS_PATH = UPLOADS_PATH + '/imageassets'
REVIEWER_ATTACHMENTS_PATH = UPLOADS_PATH + '/reviewer_attachment'
PREVIEWS_PATH = UPLOADS_PATH + '/previews'

Просмотреть файл

@ -23,8 +23,6 @@ PREVIEW_THUMBNAIL_URL = (STATIC_URL +
'img/uploads/previews/thumbs/%s/%d.png?modified=%d')
PREVIEW_FULL_URL = (STATIC_URL +
'img/uploads/previews/full/%s/%d.png?modified=%d')
# paths for uploaded extensions
FILES_URL = STATIC_URL + "%s/%s/downloads/file/%d/%s?src=%s"
SESSION_COOKIE_DOMAIN = ".%s" % DOMAIN
@ -32,9 +30,7 @@ SESSION_COOKIE_DOMAIN = ".%s" % DOMAIN
USERPICS_URL = STATIC_URL + 'img/uploads/userpics/%s/%s/%s.png?modified=%d'
COLLECTION_ICON_URL = STATIC_URL + '/img/uploads/collection_icons/%s/%s.png?m=%s'
MEDIA_URL = STATIC_URL + 'media/'
ADDON_ICONS_DEFAULT_URL = MEDIA_URL + 'img/addon-icons'
ADDON_ICON_BASE_URL = MEDIA_URL + 'img/icons/'
MEDIA_URL = '/media/'
CACHE_PREFIX = 'stage.%s' % CACHE_PREFIX

Просмотреть файл

@ -68,7 +68,7 @@ GUARDED_ADDONS_PATH = private.NETAPP_STORAGE_ROOT + '/guarded-addons'
UPLOADS_PATH = NETAPP_STORAGE + '/uploads'
USERPICS_PATH = UPLOADS_PATH + '/userpics'
ADDON_ICONS_PATH = UPLOADS_PATH + '/addon_icons'
COLLECTIONS_ICON_PATH = UPLOADS_PATH + '/collection_icons'
COLLECTION_ICONS_PATH = UPLOADS_PATH + '/collection_icons'
IMAGEASSETS_PATH = UPLOADS_PATH + '/imageassets'
REVIEWER_ATTACHMENTS_PATH = UPLOADS_PATH + '/reviewer_attachment'
PREVIEWS_PATH = UPLOADS_PATH + '/previews'

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше