зеркало из https://github.com/mozilla/bedrock.git
Bug 1388150: Convert release notes to use git repo and JSON
Will allow us to simplify bedrock by not installing RNA. Remove: * django-mozilla-rna * django-restframework * django-synctool Do markdown conversion on load of release: Helps with cache and perf. Add tests for new release models
This commit is contained in:
Родитель
60d99689d4
Коммит
f9d55e9fc4
|
@ -33,6 +33,7 @@ test-results.xml
|
|||
tests/unit/coverage
|
||||
bedrock/externalfiles/files_cache
|
||||
mofo_security_advisories
|
||||
release_notes
|
||||
product_details_json
|
||||
supervisord.log
|
||||
.idea
|
||||
|
|
|
@ -14,6 +14,6 @@
|
|||
</div>
|
||||
<div class="description">
|
||||
<h2>{{ _('Version {version}, first offered to Firefox Developer Edition channel users on {date}')|f(channel=release.channel, date=release.release_date|l10n_format_date, version=release.version) }}</h2>
|
||||
<p>{{ release.text|markdown|safe }}</p>
|
||||
<p>{{ release.text|safe }}</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
</div>
|
||||
<div class="description">
|
||||
<h2>{{ _('Version {version}, first offered to {channel} channel users on {date}')|f(channel=release.channel, date=release.release_date|l10n_format_date, version=release.version) }}</h2>
|
||||
<p>{{ release.text|markdown|safe }}</p>
|
||||
<p>{{ release.text|safe }}</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
@ -133,8 +133,8 @@
|
|||
<section class="notes-section">
|
||||
<div class="features" id="new-features">
|
||||
<div class="container">
|
||||
{% if new_features %}
|
||||
{% for note in new_features if note.tag == "New" %}
|
||||
{% if release.notes %}
|
||||
{% for note in release.notes if note.tag == "New" %}
|
||||
{% if loop.first %}
|
||||
<div class="section-wrapper" id="{{ note.tag|lower() }}">
|
||||
<h4>{{ note.tag }}</h4>
|
||||
|
@ -147,7 +147,7 @@
|
|||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for note in new_features if note.tag == "Fixed" %}
|
||||
{% for note in release.notes if note.tag == "Fixed" %}
|
||||
{% if loop.first %}
|
||||
<div class="section-wrapper" id="{{ note.tag|lower() }}">
|
||||
<h4>{{ note.tag }}</h4>
|
||||
|
@ -160,7 +160,7 @@
|
|||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for note in new_features if note.tag == "Changed" %}
|
||||
{% for note in release.notes if note.tag == "Changed" %}
|
||||
{% if loop.first %}
|
||||
<div class="section-wrapper" id="{{ note.tag|lower() }}">
|
||||
<h4>{{ note.tag }}</h4>
|
||||
|
@ -173,7 +173,7 @@
|
|||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for note in new_features if note.tag == "Developer" %}
|
||||
{% for note in release.notes if note.tag == "Developer" %}
|
||||
{% if loop.first %}
|
||||
<div class="section-wrapper" id="{{ note.tag|lower() }}">
|
||||
<h4>{{ note.tag }}</h4>
|
||||
|
@ -182,12 +182,12 @@
|
|||
{{ note_entry(note) }}
|
||||
{% if loop.last %}
|
||||
</ul>
|
||||
<a class="mdn-icon more" rel="external" href="https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/{{ release.major_version() }}">{{ _('Developer Information') }}</a>
|
||||
<a class="mdn-icon more" rel="external" href="https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/{{ release.major_version }}">{{ _('Developer Information') }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for note in new_features if note.tag == "HTML5" %}
|
||||
{% for note in release.notes if note.tag == "HTML5" %}
|
||||
{% if loop.first %}
|
||||
<div class="section-wrapper" id="{{ note.tag|lower() }}">
|
||||
<h4>{{ note.tag }}</h4>
|
||||
|
@ -200,7 +200,7 @@
|
|||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for note in new_features if note.tag == "Resolved" %}
|
||||
{% for note in release.notes if note.tag == "Resolved" %}
|
||||
{% if loop.first %}
|
||||
<div class="section-wrapper" id="{{ note.tag|lower() }}">
|
||||
<h4>{{ note.tag }}</h4>
|
||||
|
@ -213,7 +213,7 @@
|
|||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for note in new_features if not note.tag %}
|
||||
{% for note in release.notes if not note.tag %}
|
||||
{% if loop.first %}
|
||||
<div class="section-wrapper" id="{{ note.tag|lower() }}">
|
||||
<h4>{{ note.tag }}</h4>
|
||||
|
@ -225,10 +225,8 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if known_issues %}
|
||||
{% for note in known_issues %}
|
||||
{% for note in release.notes if note.tag == "Known" %}
|
||||
{% if loop.first %}
|
||||
<div class="section-wrapper" id="known">
|
||||
<h4>{{ _('unresolved') }}</h4>
|
||||
|
@ -314,7 +312,7 @@
|
|||
<div class="col">
|
||||
<h2>{{ _('Other Resources') }}</h2>
|
||||
{% block extra_resources %}{% endblock %}
|
||||
<a rel="external" href="https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/{{ release.major_version() }}">{{ _('Developer Information') }}</a>
|
||||
<a rel="external" href="https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/{{ release.major_version }}">{{ _('Developer Information') }}</a>
|
||||
<a rel="external" href="{{ release.get_bug_search_url() }}">{{ _('Complete list of changes for this release') }}</a>
|
||||
<a rel="external" href="https://blog.mozilla.org/press/kits/">{{ _('Press Kit') }}</a>
|
||||
<a rel="external" href="https://blog.mozilla.org/press/">{{ _('Mozilla and Firefox News') }}</a>
|
||||
|
@ -335,7 +333,7 @@
|
|||
|
||||
{% macro note_entry(note) %}
|
||||
<li id="note-{{ note.id }}">
|
||||
{{ note.note|markdown|safe }}
|
||||
{{ note.note|safe }}
|
||||
{% if release.channel == 'Nightly' and note.bug -%}
|
||||
<span class="bug-id"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id={{ note.bug }}">{{ _('Bug %d')|format(note.bug) }}</a></span>
|
||||
{%- endif %}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
<div id="main-content">
|
||||
<article class="main-column">
|
||||
{{ release.system_requirements|markdown|safe }}
|
||||
{{ release.system_requirements|safe }}
|
||||
</article>
|
||||
</div>
|
||||
{% block sidebar %}{% endblock %}
|
||||
|
|
|
@ -12,11 +12,11 @@ from jinja2 import Markup
|
|||
from mock import patch
|
||||
from nose.tools import eq_, ok_
|
||||
from pyquery import PyQuery as pq
|
||||
from rna.models import Release
|
||||
|
||||
from bedrock.base.templatetags.helpers import static
|
||||
from bedrock.mozorg.templatetags import misc
|
||||
from bedrock.mozorg.tests import TestCase
|
||||
from bedrock.releasenotes.models import Release
|
||||
|
||||
|
||||
TEST_FILES_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
|
@ -505,8 +505,8 @@ class TestReleaseNotesURL(TestCase):
|
|||
"""
|
||||
Should return the results of reverse with the correct args
|
||||
"""
|
||||
release = Release(
|
||||
channel='Aurora', version='42.0a2', product='Firefox for Android')
|
||||
release = Release(dict(
|
||||
channel='Aurora', version='42.0a2', product='Firefox for Android'))
|
||||
eq_(misc.releasenotes_url(release), mock_reverse.return_value)
|
||||
mock_reverse.assert_called_with(
|
||||
'firefox.android.releasenotes', args=('42.0a2', 'aurora'))
|
||||
|
@ -516,7 +516,7 @@ class TestReleaseNotesURL(TestCase):
|
|||
"""
|
||||
Should return the results of reverse with the correct args
|
||||
"""
|
||||
release = Release(version='42.0', product='Firefox')
|
||||
release = Release(dict(version='42.0', product='Firefox'))
|
||||
eq_(misc.releasenotes_url(release), mock_reverse.return_value)
|
||||
mock_reverse.assert_called_with(
|
||||
'firefox.desktop.releasenotes', args=('42.0', 'release'))
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
from __future__ import print_function
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from bedrock.utils.git import GitRepo
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('-q', '--quiet', action='store_true', dest='quiet', default=False,
|
||||
help='If no error occurs, swallow all output.'),
|
||||
|
||||
def handle(self, *args, **options):
|
||||
repo = GitRepo(settings.RELEASE_NOTES_PATH, settings.RELEASE_NOTES_REPO,
|
||||
branch_name=settings.RELEASE_NOTES_BRANCH)
|
||||
repo.update()
|
||||
if not options['quiet']:
|
||||
print('Release Notes Successfully Updated')
|
|
@ -0,0 +1,229 @@
|
|||
import codecs
|
||||
import json
|
||||
import os
|
||||
from glob import glob
|
||||
from operator import attrgetter
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.cache import caches
|
||||
from django.http import Http404
|
||||
from django.utils.dateparse import parse_date, parse_datetime
|
||||
from django.utils.text import slugify
|
||||
|
||||
import markdown
|
||||
from product_details.version_compare import Version
|
||||
from raven.contrib.django.raven_compat.models import client as sentry_client
|
||||
|
||||
|
||||
cache = caches['release-notes']
|
||||
markdowner = markdown.Markdown(extensions=[
|
||||
'tables', 'codehilite', 'fenced_code', 'toc', 'nl2br'
|
||||
])
|
||||
|
||||
|
||||
def release_notes_path():
|
||||
return os.path.join(settings.RELEASE_NOTES_PATH, 'releases')
|
||||
|
||||
|
||||
def process_markdown(value):
|
||||
return markdowner.reset().convert(value)
|
||||
|
||||
|
||||
def process_notes(notes):
|
||||
notes = [Note(d) for d in notes]
|
||||
return [n for n in notes if n.is_public]
|
||||
|
||||
|
||||
def process_is_public(is_public):
|
||||
if settings.DEV:
|
||||
return True
|
||||
|
||||
return is_public
|
||||
|
||||
|
||||
FIELD_PROCESSORS = {
|
||||
'release_date': parse_date,
|
||||
'created': parse_datetime,
|
||||
'modified': parse_datetime,
|
||||
'notes': process_notes,
|
||||
'is_public': process_is_public,
|
||||
'note': process_markdown,
|
||||
'text': process_markdown,
|
||||
'system_requirements': process_markdown,
|
||||
}
|
||||
|
||||
|
||||
class ReleaseNotFound(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class RNModel(object):
|
||||
def __init__(self, data):
|
||||
for key, value in data.items():
|
||||
if not hasattr(self, key):
|
||||
continue
|
||||
if key in FIELD_PROCESSORS:
|
||||
value = FIELD_PROCESSORS[key](value)
|
||||
setattr(self, key, value)
|
||||
|
||||
|
||||
class Note(RNModel):
|
||||
id = None
|
||||
bug = None
|
||||
note = ''
|
||||
tag = None
|
||||
is_public = True
|
||||
fixed_in_release = None
|
||||
sort_num = None
|
||||
created = None
|
||||
modified = None
|
||||
|
||||
|
||||
class Release(RNModel):
|
||||
CHANNELS = ['release', 'esr', 'beta', 'aurora', 'nightly']
|
||||
product = None
|
||||
channel = None
|
||||
version = None
|
||||
slug = None
|
||||
title = None
|
||||
release_date = None
|
||||
text = ''
|
||||
is_public = True
|
||||
bug_list = None
|
||||
bug_search_url = None
|
||||
system_requirements = None
|
||||
created = None
|
||||
modified = None
|
||||
notes = None
|
||||
_version_obj = None
|
||||
|
||||
@property
|
||||
def major_version(self):
|
||||
return str(self.version_obj.major)
|
||||
|
||||
@property
|
||||
def version_obj(self):
|
||||
if self._version_obj is None:
|
||||
self._version_obj = Version(self.version)
|
||||
|
||||
return self._version_obj
|
||||
|
||||
def get_bug_search_url(self):
|
||||
if self.bug_search_url:
|
||||
return self.bug_search_url
|
||||
|
||||
if self.product == 'Thunderbird':
|
||||
return (
|
||||
'https://bugzilla.mozilla.org/buglist.cgi?'
|
||||
'classification=Client%20Software&query_format=advanced&'
|
||||
'bug_status=RESOLVED&bug_status=VERIFIED&bug_status=CLOSED&'
|
||||
'target_milestone=Thunderbird%20{version}.0&product=Thunderbird'
|
||||
'&resolution=FIXED'
|
||||
).format(version=self.major_version)
|
||||
|
||||
return (
|
||||
'https://bugzilla.mozilla.org/buglist.cgi?'
|
||||
'j_top=OR&f1=target_milestone&o3=equals&v3=Firefox%20{version}&'
|
||||
'o1=equals&resolution=FIXED&o2=anyexact&query_format=advanced&'
|
||||
'f3=target_milestone&f2=cf_status_firefox{version}&'
|
||||
'bug_status=RESOLVED&bug_status=VERIFIED&bug_status=CLOSED&'
|
||||
'v1=mozilla{version}&v2=fixed%2Cverified&limit=0'
|
||||
).format(version=self.major_version)
|
||||
|
||||
def equivalent_release_for_product(self, product):
|
||||
"""
|
||||
Returns the release for a specified product with the same
|
||||
channel and major version with the highest minor version,
|
||||
or None if no such releases exist
|
||||
"""
|
||||
major_version_file_id = get_file_id(product, self.channel, self.major_version + '.*')
|
||||
releases = glob(os.path.join(release_notes_path(), major_version_file_id + '.json'))
|
||||
if releases:
|
||||
releases = [get_release_from_file(fn) for fn in releases]
|
||||
releases = [r for r in releases if r.is_public]
|
||||
return sorted(releases, reverse=True, key=attrgetter('version_obj'))[0]
|
||||
|
||||
return None
|
||||
|
||||
def equivalent_android_release(self):
|
||||
if self.product == 'Firefox':
|
||||
return self.equivalent_release_for_product('Firefox for Android')
|
||||
|
||||
def equivalent_desktop_release(self):
|
||||
if self.product == 'Firefox for Android':
|
||||
return self.equivalent_release_for_product('Firefox')
|
||||
|
||||
|
||||
def get_release(product, version, channel=None):
|
||||
channels = [channel] if channel else Release.CHANNELS
|
||||
if product.lower() == 'firefox extended support release':
|
||||
product = 'firefox'
|
||||
channels = ['esr']
|
||||
for channel in channels:
|
||||
file_name = get_release_file_name(product, channel, version)
|
||||
if not file_name:
|
||||
continue
|
||||
|
||||
release = get_release_from_file(file_name)
|
||||
if release is not None:
|
||||
return release
|
||||
|
||||
raise ReleaseNotFound()
|
||||
|
||||
|
||||
def get_release_from_file(file_name):
|
||||
release = cache.get(file_name)
|
||||
if not release:
|
||||
release = get_release_from_file_system(file_name)
|
||||
if release:
|
||||
cache.set(file_name, release, 300) # 5 min
|
||||
|
||||
return release
|
||||
|
||||
|
||||
def get_release_from_file_system(file_name):
|
||||
try:
|
||||
with codecs.open(file_name, 'r', encoding='utf-8') as rel_fh:
|
||||
return Release(json.load(rel_fh))
|
||||
except Exception:
|
||||
sentry_client.captureException()
|
||||
return None
|
||||
|
||||
|
||||
def get_release_file_name(product, channel, version):
|
||||
file_id = get_file_id(product, channel, version)
|
||||
file_name = os.path.join(release_notes_path(), '{}.json'.format(file_id))
|
||||
if os.path.exists(file_name):
|
||||
return file_name
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_file_id(product, channel, version):
|
||||
product = slugify(product)
|
||||
channel = channel.lower()
|
||||
if product == 'firefox-extended-support-release':
|
||||
product = 'firefox'
|
||||
channel = 'esr'
|
||||
return '-'.join([product, version, channel])
|
||||
|
||||
|
||||
def get_release_or_404(version, product):
|
||||
try:
|
||||
release = get_release(product, version)
|
||||
except ReleaseNotFound:
|
||||
raise Http404
|
||||
|
||||
if not release.is_public:
|
||||
raise Http404
|
||||
|
||||
return release
|
||||
|
||||
|
||||
def get_releases_or_404(product, channel):
|
||||
file_prefix = get_file_id(product, channel, '*')
|
||||
releases = glob(os.path.join(release_notes_path(), file_prefix + '.*'))
|
||||
if releases:
|
||||
return [get_release_from_file(r) for r in releases]
|
||||
|
||||
raise Http404
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"bug_list": "",
|
||||
"bug_search_url": "https://bugzilla.mozilla.org/buglist.cgi?f1=cf_status_firefox_esr24&o1=anywordssubstr&o2=equals&query_format=advanced&f2=cf_tracking_firefox_esr24&v1=fixed%20verified&v2=29%2B",
|
||||
"channel": "ESR",
|
||||
"created": "2014-04-24T21:49:38+00:00",
|
||||
"is_public": true,
|
||||
"modified": "2014-06-10T08:59:37+00:00",
|
||||
"notes": [
|
||||
{
|
||||
"bug": null,
|
||||
"created": "2013-11-25T00:24:50+00:00",
|
||||
"id": 107,
|
||||
"is_public": true,
|
||||
"modified": "2015-05-12T16:59:10+00:00",
|
||||
"note": "Security fixes can be found <a href=\"https://www.mozilla.org/security/known-vulnerabilities/firefoxESR.html\">here</a>",
|
||||
"sort_num": 0,
|
||||
"tag": "Fixed"
|
||||
}
|
||||
],
|
||||
"product": "Firefox Extended Support Release",
|
||||
"release_date": "2014-04-29",
|
||||
"slug": "firefox-24.5.0-esr",
|
||||
"system_requirements": " ",
|
||||
"text": " ",
|
||||
"title": "Firefox Extended Support Release 24.5.0 ESR",
|
||||
"version": "24.5.0"
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"bug_list": "",
|
||||
"bug_search_url": "",
|
||||
"channel": "ESR",
|
||||
"created": "2016-03-08T15:21:24.120000+00:00",
|
||||
"is_public": true,
|
||||
"modified": "2016-08-22T09:09:17.746000+00:00",
|
||||
"notes": [
|
||||
{
|
||||
"bug": null,
|
||||
"created": "2016-03-08T15:23:04.674000+00:00",
|
||||
"id": 786524,
|
||||
"is_public": true,
|
||||
"modified": "2017-03-01T14:21:10.798000+00:00",
|
||||
"note": "[Complete 45.0 release notes][1]\r\n\r\n\r\n [1]: /en-US/firefox/45.0/releasenotes/",
|
||||
"sort_num": 0,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1232029,
|
||||
"created": "2016-03-08T15:24:17.674000+00:00",
|
||||
"id": 786525,
|
||||
"is_public": true,
|
||||
"modified": "2017-03-01T14:30:28.655000+00:00",
|
||||
"note": "[Service workers disabled][1]\r\n\r\n\r\n [1]: https://www.fxsitecompat.com/en-CA/docs/2016/service-workers-have-been-disabled-in-firefox-45-esr/",
|
||||
"sort_num": 0,
|
||||
"tag": "Changed"
|
||||
},
|
||||
{
|
||||
"bug": 1241501,
|
||||
"created": "2016-03-08T15:25:36.574000+00:00",
|
||||
"id": 786526,
|
||||
"is_public": true,
|
||||
"modified": "2017-03-01T14:30:36.099000+00:00",
|
||||
"note": "Firefox Hello disabled\r\n",
|
||||
"sort_num": 0,
|
||||
"tag": "Changed"
|
||||
}
|
||||
],
|
||||
"product": "Firefox Extended Support Release",
|
||||
"release_date": "2016-03-08",
|
||||
"slug": "firefox-45.0esr-esr",
|
||||
"system_requirements": "## Windows\r\n\r\n### Operating Systems (32-bit and 64-bit)\r\n - Windows XP SP2\r\n - Windows Server 2003 SP1\r\n - Windows Vista\r\n - Windows 7\r\n - Windows 8\r\n - Windows 10\r\n\r\n*Please note that 64-bit builds of Firefox are only supported on Windows 7 and higher.*\r\n\r\n*To install [Firefox on a Windows XP system][1], because of Windows restrictions, the user will have to download Firefox 43.0.1 and then update to the current release.*\r\n\r\n### Recommended Hardware\r\n- Pentium 4 or newer processor that supports SSE2\r\n- 512MB of RAM\r\n- 200MB of hard drive space\r\n\r\n---\r\n\r\n## Mac\r\n\r\n### Operating Systems\r\n- Mac OS X 10.6\r\n- Mac OS X 10.7\r\n- Mac OS X 10.8\r\n- Mac OS X 10.9\r\n- Mac OS X 10.10\r\n- Mac OS X 10.11\r\n\r\n### Recommended Hardware\r\n- Macintosh computer with an Intel x86 processor\r\n- 512 MB of RAM\r\n- 200 MB hard drive space\r\n\r\n---\r\n\r\n## GNU/Linux\r\n\r\n### Software Requirements\r\n\r\n*Please note that GNU/Linux distributors may provide packages for your distribution which have different requirements.*\r\n\r\n- Firefox will not run at all without the following libraries or packages:\r\n - GTK+ 3.4 or higher\r\n - GLib 2.22 or higher\r\n - Pango 1.14 or higher\r\n - X.Org 1.0 or higher (1.7 or higher is recommended)\r\n - libstdc++ 4.3 or higher\r\n- For optimal functionality, we recommend the following libraries or packages:\r\n - NetworkManager 0.7 or higher\r\n - DBus 1.0 or higher\r\n - HAL 0.5.8 or higher\r\n - GNOME 2.16 or higher\r\n\r\n [1]: https://support.mozilla.org/kb/get-latest-version-firefox-windows-xp-vista",
|
||||
"text": "",
|
||||
"title": "Firefox Extended Support Release 45.0esr ESR",
|
||||
"version": "45.0esr"
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
{
|
||||
"bug_list": "1335905",
|
||||
"bug_search_url": "",
|
||||
"channel": "Nightly",
|
||||
"created": "2017-03-21T13:19:13.668000+00:00",
|
||||
"is_public": true,
|
||||
"modified": "2017-05-30T18:51:00.765000+00:00",
|
||||
"notes": [
|
||||
{
|
||||
"bug": 1218482,
|
||||
"created": "2017-06-06T13:07:52.986000+00:00",
|
||||
"id": 787117,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-08T06:49:53.641000+00:00",
|
||||
"note": "Launched Windows support for [WebVR][1], bringing immersive experiences to the web. See examples and try working demos at [Mozilla VR][2].\r\n\r\n\r\n [1]: https://developer.mozilla.org/en-US/docs/Web/API/WebVR_API\r\n [2]: https://mozvr.com/",
|
||||
"sort_num": 10000,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1365998,
|
||||
"created": "2017-06-02T13:07:35.562000+00:00",
|
||||
"id": 787108,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-08T13:08:09.659000+00:00",
|
||||
"note": "Simplified installation process with a streamlined Windows stub installer\r\n\r\n - Firefox for Windows 64-bit is now installed by default on 64-bit systems with at least 2GB of RAM\r\n - [Full installers][1] with advanced installation options are still available \r\n\r\n[1]: https://www.mozilla.org/firefox/all/",
|
||||
"sort_num": 999,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1355331,
|
||||
"created": "2017-04-24T07:57:30.608000+00:00",
|
||||
"id": 787058,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-08T06:51:01.191000+00:00",
|
||||
"note": "Updated [Sidebar for bookmarks, history, and synced tabs][1] so it can appear at the right edge of the window as well as the left\r\n\r\n[1]: https://support.mozilla.org/kb/firefox-sidebar-access-bookmarks-history-social\r\n",
|
||||
"sort_num": 900,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1362526,
|
||||
"created": "2017-06-05T21:40:21.983000+00:00",
|
||||
"id": 787115,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-08T19:02:36.800000+00:00",
|
||||
"note": "Pages can be simplified before printing from within Print Preview",
|
||||
"sort_num": 400,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 429824,
|
||||
"created": "2017-06-05T21:31:14.641000+00:00",
|
||||
"id": 787114,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-08T06:51:49.291000+00:00",
|
||||
"note": "Updated Firefox for OSX and macOS to allow users to assign [custom keyboard shortcuts][1] to Firefox menu items via System Preferences \r\n\r\n\r\n [1]: https://support.mozilla.org/en-US/kb/keyboard-shortcuts-perform-firefox-tasks-quickly",
|
||||
"sort_num": 300,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1355082,
|
||||
"created": "2017-04-19T16:11:03.099000+00:00",
|
||||
"id": 787056,
|
||||
"is_public": true,
|
||||
"modified": "2017-06-05T14:46:22.654000+00:00",
|
||||
"note": "All locales are now available for Nightly",
|
||||
"sort_num": 3,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1345090,
|
||||
"created": "2017-05-17T14:47:50.171000+00:00",
|
||||
"id": 787091,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-01T13:51:16.107000+00:00",
|
||||
"note": "Browsing sessions with a high number of tabs are now restored in an instant",
|
||||
"sort_num": 2,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1346488,
|
||||
"created": "2017-05-24T13:14:31.757000+00:00",
|
||||
"id": 787105,
|
||||
"is_public": true,
|
||||
"modified": "2017-06-05T14:44:47.117000+00:00",
|
||||
"note": "The Photon project aiming at refreshing the user interface started being implemented in Nightly. These changes are only visible on the nightly channel and will not land in the beta and release channels before at least version 57.",
|
||||
"sort_num": 1,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1364070,
|
||||
"created": "2017-05-29T14:18:06.077000+00:00",
|
||||
"id": 787106,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-08T06:25:05.078000+00:00",
|
||||
"note": "[Fine-tune your browser performance][1] from the Preferences/Options page.\r\n\r\n[1]: https://support.mozilla.org/kb/performance-settings",
|
||||
"sort_num": 0,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1356243,
|
||||
"created": "2017-05-30T18:50:40.058000+00:00",
|
||||
"id": 787107,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-01T13:51:16.107000+00:00",
|
||||
"note": "Make [screenshots][1] of webpages, and save them locally or upload them to the cloud. This feature will undergo A/B testing and will not be visible for some users.\r\n\r\n[1]: https://screenshots.firefox.com/",
|
||||
"sort_num": 0,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1344928,
|
||||
"created": "2017-06-06T13:49:34.896000+00:00",
|
||||
"id": 787119,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-01T15:08:42.498000+00:00",
|
||||
"note": " Search suggestions are now enabled by default for users who haven't explicitly opted-out",
|
||||
"sort_num": 0,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 893505,
|
||||
"created": "2017-04-18T16:40:23.196000+00:00",
|
||||
"fixed_in_release": {
|
||||
"channel": "Nightly",
|
||||
"is_public": true,
|
||||
"product": "Firefox",
|
||||
"slug": "firefox-55.0a1-nightly",
|
||||
"title": "Firefox 55.0a1 Nightly",
|
||||
"version": "55.0a1"
|
||||
},
|
||||
"id": 787048,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-01T13:51:16.107000+00:00",
|
||||
"note": "Modernized application update UI to be less intrusive and more aligned with the rest of the browser. Only users who have not restarted their browser 8 days after downloading an update or users who opted out of automatic updates will see this change.",
|
||||
"sort_num": 0,
|
||||
"tag": "Changed"
|
||||
},
|
||||
{
|
||||
"bug": 548311,
|
||||
"created": "2017-04-19T13:12:28.496000+00:00",
|
||||
"id": 787051,
|
||||
"is_public": true,
|
||||
"modified": "2017-06-06T15:04:57.628000+00:00",
|
||||
"note": "The default font for Japanese text is now Meiryo",
|
||||
"sort_num": 0,
|
||||
"tag": "Changed"
|
||||
},
|
||||
{
|
||||
"bug": 977177,
|
||||
"created": "2017-04-19T13:16:55.825000+00:00",
|
||||
"id": 787052,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-08T06:40:10.406000+00:00",
|
||||
"note": "Firefox does not support downgrades, even though this may have worked in past versions. Users who install Firefox 55+ and later downgrade to an earlier version may experience issues with Firefox. \r\n",
|
||||
"sort_num": 0,
|
||||
"tag": "Changed"
|
||||
},
|
||||
{
|
||||
"bug": 1341897,
|
||||
"created": "2017-04-19T16:07:16.327000+00:00",
|
||||
"id": 787055,
|
||||
"is_public": true,
|
||||
"modified": "2017-06-05T14:47:28.870000+00:00",
|
||||
"note": "Firefox uses Mozilla Location Service for geolocation",
|
||||
"sort_num": 0,
|
||||
"tag": "Changed"
|
||||
},
|
||||
{
|
||||
"bug": 1335907,
|
||||
"created": "2017-04-19T16:17:08.859000+00:00",
|
||||
"id": 787057,
|
||||
"is_public": true,
|
||||
"modified": "2017-06-05T14:44:14.166000+00:00",
|
||||
"note": "about:preferences has been cleaned up and reorganized to make it easier for you to find what you need",
|
||||
"sort_num": 0,
|
||||
"tag": "Changed"
|
||||
},
|
||||
{
|
||||
"bug": 1317856,
|
||||
"created": "2017-06-06T13:26:48.862000+00:00",
|
||||
"id": 787118,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-08T06:39:42.278000+00:00",
|
||||
"note": "Made the Adobe Flash plugin click-to-activate by default and allowed only on http:// and https:// URL schemes. (This change will not be visible to all users immediately. For more information see the [Firefox plugin roadmap][1])\r\n\r\n\r\n[1]:https://developer.mozilla.org/docs/Plugins/Roadmap\r\n\r\n",
|
||||
"sort_num": 0,
|
||||
"tag": "Changed"
|
||||
},
|
||||
{
|
||||
"bug": 1072859,
|
||||
"created": "2017-04-19T13:19:25.800000+00:00",
|
||||
"id": 787053,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-08T06:48:39.244000+00:00",
|
||||
"note": "Sites that don\u2019t use SSL can no longer access Geolocation APIs to determine a user\u2019s physical location\r\n",
|
||||
"sort_num": 0,
|
||||
"tag": "Developer"
|
||||
}
|
||||
],
|
||||
"product": "Firefox",
|
||||
"release_date": "2017-03-06",
|
||||
"slug": "firefox-55.0a1-nightly",
|
||||
"system_requirements": "## Windows\r\n\r\n### Operating Systems (32-bit and 64-bit)\r\n - Windows 7\r\n - Windows 8\r\n - Windows 10\r\n\r\n### Recommended Hardware\r\n- Pentium 4 or newer processor that supports SSE2\r\n- 512MB of RAM\r\n- 200MB of hard drive space\r\n\r\n---\r\n\r\n## Mac\r\n\r\n### Operating Systems\r\n- Mac OS X 10.9\r\n- Mac OS X 10.10\r\n- Mac OS X 10.11\r\n- Mac OS X 10.12\r\n\r\n### Recommended Hardware\r\n- Macintosh computer with an Intel x86 processor\r\n- 512 MB of RAM\r\n- 200 MB hard drive space\r\n\r\n---\r\n\r\n## GNU/Linux\r\n\r\n### Software Requirements\r\n\r\n*Please note that GNU/Linux distributors may provide packages for your distribution which have different requirements.*\r\n\r\n- Firefox will not run at all without the following libraries or packages:\r\n - GTK+ 3.4 or higher\r\n - GLib 2.22 or higher\r\n - Pango 1.14 or higher\r\n - X.Org 1.0 or higher (1.7 or higher is recommended)\r\n - libstdc++ 4.6.1 or higher\r\n- For optimal functionality, we recommend the following libraries or packages:\r\n - NetworkManager 0.7 or higher\r\n - DBus 1.0 or higher\r\n - GNOME 2.16 or higher\r\n - PulseAudio\r\n\r\n [1]: https://support.mozilla.org/kb/get-latest-version-firefox-windows-xp-vista",
|
||||
"text": "Firefox Nightly gets a new version every day and as a consequence, the release notes for the Nightly channel are updated continuously to reflect features that have reached sufficient maturity to benefit from community feedback and bug reports. \r\n\r\nFeatures listed here may or may not make a final release of Firefox.",
|
||||
"title": "Firefox 55.0a1 Nightly",
|
||||
"version": "55.0a1"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"product": "Firefox",
|
||||
"channel": "Release",
|
||||
"version": "56.0",
|
||||
"is_public": true
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"bug_list": "",
|
||||
"bug_search_url": "",
|
||||
"channel": "Nightly",
|
||||
"created": "2017-06-12T13:42:25.322000+00:00",
|
||||
"is_public": true,
|
||||
"modified": "2017-08-17T08:24:32.975000+00:00",
|
||||
"notes": [
|
||||
{
|
||||
"bug": 1353954,
|
||||
"created": "2017-06-15T09:07:15.524000+00:00",
|
||||
"id": 787156,
|
||||
"is_public": true,
|
||||
"modified": "2017-06-15T09:11:36.233000+00:00",
|
||||
"note": "Search within the Options/Preferences panel to find relevant options across categories\r\n",
|
||||
"sort_num": 0,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1372309,
|
||||
"created": "2017-06-16T15:35:13.038000+00:00",
|
||||
"id": 787157,
|
||||
"is_public": true,
|
||||
"modified": "2017-06-16T15:58:42.656000+00:00",
|
||||
"note": "<!-- Nightly only -->\r\nThe application menu was [restructured][1] as part of the Photon redesign for Firefox 57. Nightly users are encouraged to [flle bugs][2] for any regression they may find.\r\n\r\n\r\n[1]: https://dolske.wordpress.com/2017/06/15/photon-engineering-newsletter-6/ \r\n[2]: https://bugzilla.mozilla.org/enter_bug.cgi?product=Firefox&component=Toolbars%20and%20Customization",
|
||||
"sort_num": 0,
|
||||
"tag": "Changed"
|
||||
}
|
||||
],
|
||||
"product": "Firefox",
|
||||
"release_date": "2017-06-12",
|
||||
"slug": "firefox-56.0a1-nightly",
|
||||
"system_requirements": "## Windows\r\n\r\n### Operating Systems (32-bit and 64-bit)\r\n - Windows 7\r\n - Windows 8\r\n - Windows 10\r\n\r\n### Recommended Hardware\r\n- Pentium 4 or newer processor that supports SSE2\r\n- 512MB of RAM\r\n- 200MB of hard drive space\r\n\r\n---\r\n\r\n## Mac\r\n\r\n### Operating Systems\r\n- Mac OS X 10.9\r\n- Mac OS X 10.10\r\n- Mac OS X 10.11\r\n- Mac OS X 10.12\r\n\r\n### Recommended Hardware\r\n- Macintosh computer with an Intel x86 processor\r\n- 512 MB of RAM\r\n- 200 MB hard drive space\r\n\r\n---\r\n\r\n## GNU/Linux\r\n\r\n### Software Requirements\r\n\r\n*Please note that GNU/Linux distributors may provide packages for your distribution which have different requirements.*\r\n\r\n- Firefox will not run at all without the following libraries or packages:\r\n - GTK+ 3.4 or higher\r\n - GLib 2.22 or higher\r\n - Pango 1.14 or higher\r\n - X.Org 1.0 or higher (1.7 or higher is recommended)\r\n - libstdc++ 4.6.1 or higher\r\n- For optimal functionality, we recommend the following libraries or packages:\r\n - NetworkManager 0.7 or higher\r\n - DBus 1.0 or higher\r\n - GNOME 2.16 or higher\r\n - PulseAudio\r\n\r\n [1]: https://support.mozilla.org/kb/get-latest-version-firefox-windows-xp-vista",
|
||||
"text": "Firefox Nightly gets a new version every day and as a consequence, the release notes for the Nightly channel are updated continuously to reflect features that have reached sufficient maturity to benefit from community feedback and bug reports. Features listed here may or may not make a final release of Firefox.",
|
||||
"title": "Firefox 56.0a1 Nightly",
|
||||
"version": "56.0a1"
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"bug_list": "",
|
||||
"bug_search_url": "",
|
||||
"channel": "Nightly",
|
||||
"created": "2017-08-02T14:20:49.003000+00:00",
|
||||
"is_public": true,
|
||||
"modified": "2017-09-13T08:55:02.648000+00:00",
|
||||
"notes": [
|
||||
{
|
||||
"bug": 1387254,
|
||||
"created": "2017-08-07T08:00:48.092000+00:00",
|
||||
"id": 787203,
|
||||
"is_public": true,
|
||||
"modified": "2017-08-07T08:00:48.092000+00:00",
|
||||
"note": "Firefox Nightly has a new logo",
|
||||
"sort_num": 0,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1373650,
|
||||
"created": "2017-08-17T08:23:04.304000+00:00",
|
||||
"id": 787237,
|
||||
"is_public": true,
|
||||
"modified": "2017-09-11T07:02:27.350000+00:00",
|
||||
"note": "Added an option to the Page Action menu to report a website issue in Firefox Nightly and Firefox Dev Edition",
|
||||
"sort_num": 0,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1349227,
|
||||
"created": "2017-08-31T07:52:29.636000+00:00",
|
||||
"id": 787243,
|
||||
"is_public": false,
|
||||
"modified": "2017-08-31T07:55:06.229000+00:00",
|
||||
"note": "Firefox Nightly now gets updated twice a day so as to help our communities in EMEA and Asia regions to catch regressions and report them during the Americas night.",
|
||||
"sort_num": 0,
|
||||
"tag": "New"
|
||||
},
|
||||
{
|
||||
"bug": 1388902,
|
||||
"created": "2017-09-04T11:13:42.634000+00:00",
|
||||
"id": 787244,
|
||||
"is_public": false,
|
||||
"modified": "2017-09-04T11:13:42.634000+00:00",
|
||||
"note": " The \"Share\" button was removed. If you relied on this feature, you can install the [Share Backported][1] extension instead.\r\n\r\n[1]: https://addons.mozilla.org/firefox/addon/share-backported/",
|
||||
"sort_num": 0,
|
||||
"tag": "Changed"
|
||||
},
|
||||
{
|
||||
"bug": 1346488,
|
||||
"created": "2017-09-07T13:00:41.753000+00:00",
|
||||
"id": 787245,
|
||||
"is_public": true,
|
||||
"modified": "2017-09-07T13:00:41.753000+00:00",
|
||||
"note": "Firefox is getting a major Visual Redesign ([Photon project][1]) activated on the Nightly channel and which will ship with Firefox 57 on the release channel.\r\n\r\n[1]: https://wiki.mozilla.org/Firefox/Photon/Updates",
|
||||
"sort_num": 0,
|
||||
"tag": "Changed"
|
||||
},
|
||||
{
|
||||
"bug": 1385463,
|
||||
"created": "2017-09-07T13:21:44.911000+00:00",
|
||||
"id": 787246,
|
||||
"is_public": true,
|
||||
"modified": "2017-09-07T13:21:44.911000+00:00",
|
||||
"note": "The browser's \"autoscrolling\" feature now uses asynchronous scrolling, similar to other input methods like mousewheel, providing a smoother scrolling experience.",
|
||||
"sort_num": 0,
|
||||
"tag": "Fixed"
|
||||
}
|
||||
],
|
||||
"product": "Firefox",
|
||||
"release_date": "2017-08-02",
|
||||
"slug": "firefox-57.0a1-nightly",
|
||||
"system_requirements": "## Windows\r\n\r\n### Operating Systems (32-bit and 64-bit)\r\n - Windows 7\r\n - Windows 8\r\n - Windows 10\r\n\r\n### Recommended Hardware\r\n- Pentium 4 or newer processor that supports SSE2\r\n- 512MB of RAM / 2GB of RAM for the 64-bit version\r\n- 200MB of hard drive space\r\n\r\n---\r\n\r\n## Mac\r\n\r\n### Operating Systems\r\n- macOS 10.9\r\n- macOS 10.10\r\n- macOS 10.11\r\n- macOS 10.12\r\n- macOS 10.13\r\n\r\n### Recommended Hardware\r\n- Macintosh computer with an Intel x86 processor\r\n- 512 MB of RAM\r\n- 200 MB hard drive space\r\n\r\n---\r\n\r\n## GNU/Linux\r\n\r\n### Software Requirements\r\n\r\n*Please note that GNU/Linux distributors may provide packages for your distribution which have different requirements.*\r\n\r\n- Firefox will not run at all without the following libraries or packages:\r\n - GTK+ 3.4 or higher\r\n - GLib 2.22 or higher\r\n - Pango 1.14 or higher\r\n - X.Org 1.0 or higher (1.7 or higher is recommended)\r\n - libstdc++ 4.6.1 or higher\r\n- For optimal functionality, we recommend the following libraries or packages:\r\n - NetworkManager 0.7 or higher\r\n - DBus 1.0 or higher\r\n - GNOME 2.16 or higher\r\n - PulseAudio\r\n\r\n [1]: https://support.mozilla.org/kb/get-latest-version-firefox-windows-xp-vista",
|
||||
"text": "Firefox Nightly gets a new version every day and as a consequence, the release notes for the Nightly channel are updated continuously to reflect features that have reached sufficient maturity to benefit from community feedback and bug reports. Features listed here may or may not make a final release of Firefox.\r\n\r\nIn addition to these release notes, you can follow ongoing development on our [@FirefoxNightly][1] Twitter account as well as read our [Nightly Blog][2].\r\n\r\n[1]: https://twitter.com/FirefoxNightly\r\n[2]: https://blog.nightly.mozilla.org",
|
||||
"title": "Firefox 57.0a1 Nightly",
|
||||
"version": "57.0a1"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"product": "Firefox for Android",
|
||||
"channel": "Release",
|
||||
"version": "56.0",
|
||||
"release_date": "2017-08-02",
|
||||
"is_public": true
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"product": "Firefox for Android",
|
||||
"channel": "Release",
|
||||
"version": "56.0.1",
|
||||
"release_date": "2017-08-03",
|
||||
"is_public": true
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"product": "Firefox for Android",
|
||||
"channel": "Release",
|
||||
"version": "56.0.2",
|
||||
"release_date": "2017-08-04",
|
||||
"is_public": true
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"product": "Firefox for Android",
|
||||
"channel": "Release",
|
||||
"version": "56.0.3",
|
||||
"release_date": "2017-08-05",
|
||||
"is_public": false
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
from dateutil.parser import parse as date_parse
|
||||
|
||||
from django.core.cache import caches
|
||||
from django.http import Http404
|
||||
|
@ -13,21 +12,26 @@ from mock import patch, Mock
|
|||
from nose.tools import eq_, ok_
|
||||
from pathlib2 import Path
|
||||
from pyquery import PyQuery as pq
|
||||
from rna.models import Release, Note
|
||||
|
||||
from bedrock.firefox.firefox_details import FirefoxDesktop
|
||||
from bedrock.mozorg.tests import TestCase
|
||||
from bedrock.releasenotes import views
|
||||
from bedrock.releasenotes.models import Release, ReleaseNotFound
|
||||
from bedrock.thunderbird.details import ThunderbirdDesktop
|
||||
|
||||
|
||||
DATA_PATH = str(Path(__file__).parent / 'data')
|
||||
TESTS_PATH = Path(__file__).parent
|
||||
DATA_PATH = str(TESTS_PATH.joinpath('data'))
|
||||
firefox_desktop = FirefoxDesktop(json_dir=DATA_PATH)
|
||||
thunderbird_desktop = ThunderbirdDesktop(json_dir=DATA_PATH)
|
||||
RELEASES_PATH = str(TESTS_PATH)
|
||||
|
||||
|
||||
class TestRNAViews(TestCase):
|
||||
@override_settings(RELEASE_NOTES_PATH=RELEASES_PATH)
|
||||
class TestReleaseViews(TestCase):
|
||||
def setUp(self):
|
||||
caches['release-notes'].clear()
|
||||
self.activate('en-US')
|
||||
self.factory = RequestFactory()
|
||||
self.request = self.factory.get('/')
|
||||
|
||||
|
@ -46,30 +50,24 @@ class TestRNAViews(TestCase):
|
|||
"""
|
||||
return self.mock_render.call_args[0][2]
|
||||
|
||||
@patch('bedrock.releasenotes.views.get_object_or_404')
|
||||
@patch('bedrock.releasenotes.views.Q')
|
||||
def test_get_release_or_404(self, Q, get_object_or_404):
|
||||
@patch('bedrock.releasenotes.models.get_release')
|
||||
def test_get_release_or_404(self, get_release):
|
||||
eq_(views.get_release_or_404('version', 'product'),
|
||||
get_object_or_404.return_value)
|
||||
get_object_or_404.assert_called_with(
|
||||
Release, Q.return_value, version='version')
|
||||
Q.assert_called_once_with(product='product')
|
||||
get_release.return_value)
|
||||
get_release.assert_called_with('product', 'version')
|
||||
get_release.side_effect = ReleaseNotFound
|
||||
with self.assertRaises(Http404):
|
||||
views.get_release_or_404('version', 'product')
|
||||
|
||||
@patch('bedrock.releasenotes.views.get_object_or_404')
|
||||
@patch('bedrock.releasenotes.views.Q')
|
||||
def test_get_release_or_404_esr(self, Q, get_object_or_404):
|
||||
eq_(views.get_release_or_404('24.5.0', 'Firefox'),
|
||||
get_object_or_404.return_value)
|
||||
Q.assert_any_call(product='Firefox')
|
||||
Q.assert_any_call(product='Firefox Extended Support Release')
|
||||
def test_get_release_or_404_esr(self):
|
||||
rel = views.get_release_or_404('24.5.0', 'Firefox')
|
||||
eq_(rel.version, '24.5.0')
|
||||
eq_(rel.channel, 'ESR')
|
||||
|
||||
@patch('bedrock.releasenotes.views.get_object_or_404')
|
||||
@patch('bedrock.releasenotes.views.Q')
|
||||
def test_get_release_or_404_endswith_esr(self, Q, get_object_or_404):
|
||||
eq_(views.get_release_or_404('45.0esr', 'Firefox'),
|
||||
get_object_or_404.return_value)
|
||||
Q.assert_any_call(product='Firefox')
|
||||
Q.assert_any_call(product='Firefox Extended Support Release')
|
||||
def test_get_release_or_404_endswith_esr(self):
|
||||
rel = views.get_release_or_404('45.0esr', 'Firefox')
|
||||
eq_(rel.version, '45.0esr')
|
||||
eq_(rel.channel, 'ESR')
|
||||
|
||||
@override_settings(DEV=False)
|
||||
@patch('bedrock.releasenotes.views.release_notes_template')
|
||||
|
@ -83,17 +81,14 @@ class TestRNAViews(TestCase):
|
|||
template to l10n_utils.render.
|
||||
"""
|
||||
mock_release = get_release_or_404.return_value
|
||||
mock_release.major_version.return_value = '34'
|
||||
mock_release.notes.return_value = ([Release(id=1), Release(id=2)],
|
||||
[Release(id=3), Release(id=4)])
|
||||
mock_release.major_version = '34'
|
||||
mock_release.notes.return_value = ([Release({}), Release({})],
|
||||
[Release({}), Release({})])
|
||||
|
||||
views.release_notes(self.request, '27.0')
|
||||
get_release_or_404.assert_called_with('27.0', 'Firefox')
|
||||
mock_release.notes.assert_called_with(public_only=True)
|
||||
eq_(self.last_ctx['version'], '27.0')
|
||||
eq_(self.last_ctx['release'], mock_release)
|
||||
eq_(self.last_ctx['new_features'], [Release(id=1), Release(id=2)])
|
||||
eq_(self.last_ctx['known_issues'], [Release(id=3), Release(id=4)])
|
||||
eq_(self.mock_render.call_args[0][1],
|
||||
mock_release_notes_template.return_value)
|
||||
mock_equiv_rel_url.assert_called_with(mock_release)
|
||||
|
@ -171,12 +166,12 @@ class TestRNAViews(TestCase):
|
|||
'firefox/releases/release-notes.html')
|
||||
|
||||
@override_settings(DEV=False)
|
||||
@patch('bedrock.releasenotes.views.get_object_or_404')
|
||||
def test_non_public_release(self, get_object_or_404):
|
||||
@patch('bedrock.releasenotes.models.get_release')
|
||||
def test_non_public_release(self, get_release):
|
||||
"""
|
||||
Should raise 404 if not release.is_public and not settings.DEV
|
||||
"""
|
||||
get_object_or_404.return_value = Release(is_public=False)
|
||||
get_release.return_value = Release({'is_public': False})
|
||||
with self.assertRaises(Http404):
|
||||
views.get_release_or_404('42', 'Firefox')
|
||||
|
||||
|
@ -254,47 +249,22 @@ class TestRNAViews(TestCase):
|
|||
eq_(views.check_url('Firefox', '42.0'),
|
||||
'/en-US/firefox/42.0/system-requirements/')
|
||||
|
||||
@patch('bedrock.releasenotes.views.get_list_or_404')
|
||||
def test_nightly_feed(self, get_list_or_404):
|
||||
@override_settings(DEV=False)
|
||||
def test_nightly_feed(self):
|
||||
"""Nightly Notes feed should be served with public changes"""
|
||||
release_1 = Mock()
|
||||
release_1.version = '55.0a1'
|
||||
release_1.is_public = True
|
||||
release_1.release_date = date_parse('2017-03-06T00:00:00')
|
||||
release_1.notes.return_value = ([
|
||||
Note(id=1, tag='New', note='New 1', is_public=True,
|
||||
modified=date_parse('2017-04-20T13:27:28')),
|
||||
Note(id=2, tag='New', note='New 2', is_public=True,
|
||||
modified=date_parse('2017-04-20T13:28:32')),
|
||||
Note(id=11, tag='Changed', note='Change 1', is_public=True,
|
||||
modified=date_parse('2017-04-20T13:27:50')),
|
||||
Note(id=12, tag='Changed', note='Change 2', is_public=True,
|
||||
modified=date_parse('2017-04-20T13:28:03')),
|
||||
Note(id=13, tag='Changed', note='Change 3', is_public=False,
|
||||
modified=date_parse('2017-04-20T13:28:16')),
|
||||
], [
|
||||
Note(id=21, tag='', note='Known issue 1', is_public=True,
|
||||
modified=date_parse('2017-04-20T13:30:12')),
|
||||
])
|
||||
|
||||
release_2 = Mock()
|
||||
release_2.version = '56.0a1'
|
||||
release_2.is_public = True
|
||||
release_2.release_date = date_parse('2017-05-08T00:00:00')
|
||||
release_2.notes.return_value = ([
|
||||
Note(id=31, tag='New', note='New 1', is_public=True,
|
||||
modified=date_parse('2017-05-08T13:27:28')),
|
||||
], [])
|
||||
|
||||
get_list_or_404.return_value = [release_1, release_2]
|
||||
views.nightly_feed(self.request)
|
||||
eq_(len(self.last_ctx['notes']), 24)
|
||||
eq_(self.last_ctx['notes'][0].id, 787237)
|
||||
eq_(self.last_ctx['notes'][1].id, 787246)
|
||||
eq_(self.last_ctx['notes'][2].id, 787245)
|
||||
eq_(self.last_ctx['notes'][3].id, 787115)
|
||||
eq_(self.last_ctx['notes'][4].id, 787108)
|
||||
|
||||
eq_(len(self.last_ctx['notes']), 5)
|
||||
eq_(self.last_ctx['notes'][0].id, 31)
|
||||
eq_(self.last_ctx['notes'][1].id, 2)
|
||||
eq_(self.last_ctx['notes'][2].id, 12)
|
||||
eq_(self.last_ctx['notes'][3].id, 11)
|
||||
eq_(self.last_ctx['notes'][4].id, 1)
|
||||
@override_settings(DEV=True)
|
||||
def test_nightly_feed_dev_mode(self):
|
||||
"""Nightly Notes feed should be served with all changes in DEV"""
|
||||
views.nightly_feed(self.request)
|
||||
eq_(len(self.last_ctx['notes']), 26)
|
||||
|
||||
|
||||
class TestReleaseNotesIndex(TestCase):
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import os
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.cache import caches
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from mock import call, patch
|
||||
from pathlib2 import Path
|
||||
|
||||
from bedrock.mozorg.tests import TestCase
|
||||
from bedrock.releasenotes import models
|
||||
|
||||
|
||||
RELEASES_PATH = str(Path(__file__).parent)
|
||||
release_cache = caches['release-notes']
|
||||
|
||||
|
||||
@override_settings(RELEASE_NOTES_PATH=RELEASES_PATH)
|
||||
class TestReleaseModel(TestCase):
|
||||
def setUp(self):
|
||||
release_cache.clear()
|
||||
|
||||
def test_release_major_version(self):
|
||||
rel = models.get_release('firefox', '57.0a1')
|
||||
assert rel.major_version == '57'
|
||||
|
||||
def test_get_bug_search_url(self):
|
||||
rel = models.get_release('firefox', '57.0a1')
|
||||
assert '=Firefox%2057&' in rel.get_bug_search_url()
|
||||
rel.product = 'Thunderbird'
|
||||
assert '=Thunderbird%2057.0&' in rel.get_bug_search_url()
|
||||
rel.bug_search_url = 'custom url'
|
||||
assert 'custom url' == rel.get_bug_search_url()
|
||||
|
||||
def test_equivalent_release_for_product(self):
|
||||
"""Based on the test files the equivalent release for 56 should be 56.0.2."""
|
||||
rel = models.get_release('firefox', '56.0', 'release')
|
||||
android = rel.equivalent_release_for_product('Firefox for Android')
|
||||
assert android.version == '56.0.2'
|
||||
assert android.product == 'Firefox for Android'
|
||||
|
||||
def test_equivalent_release_for_product_none_match(self):
|
||||
rel = models.get_release('firefox', '45.0esr', 'esr')
|
||||
android = rel.equivalent_release_for_product('Firefox for Android')
|
||||
assert android is None
|
||||
|
||||
def test_field_processors(self):
|
||||
rel = models.get_release('firefox', '57.0a1')
|
||||
# datetime conversion
|
||||
assert rel.created.year == 2017
|
||||
# datetime conversion
|
||||
assert rel.modified.year == 2017
|
||||
# date conversion
|
||||
assert rel.release_date.year == 2017
|
||||
# markdown
|
||||
assert rel.system_requirements.startswith('<h2 id="windows">Windows</h2>')
|
||||
# version
|
||||
assert rel.version_obj.major == 57
|
||||
|
||||
# notes
|
||||
note = rel.notes[0]
|
||||
# datetime conversion
|
||||
assert note.created.year == 2017
|
||||
# datetime conversion
|
||||
assert note.modified.year == 2017
|
||||
# markdown
|
||||
assert note.note.startswith('<p>Firefox Nightly')
|
||||
assert note.id == 787203
|
||||
|
||||
@override_settings(DEV=False)
|
||||
def test_is_public_field_processor(self):
|
||||
"""Should return the real value when DEV is false."""
|
||||
rel = models.get_release('firefox for android', '56.0.3')
|
||||
assert not rel.is_public
|
||||
rel = models.get_release('firefox', '57.0a1')
|
||||
assert len(rel.notes) == 4
|
||||
|
||||
@override_settings(DEV=True)
|
||||
def test_is_public_field_processor_dev_true(self):
|
||||
"""Should always be true when DEV is true."""
|
||||
rel = models.get_release('firefox for android', '56.0.3')
|
||||
assert rel.is_public
|
||||
rel = models.get_release('firefox', '57.0a1')
|
||||
assert len(rel.notes) == 6
|
||||
|
||||
|
||||
@patch.object(models, 'get_release_file_name')
|
||||
@patch.object(models, 'get_release_from_file')
|
||||
class TestGetRelease(TestCase):
|
||||
def test_get_release(self, grff_mock, grfn_mock):
|
||||
grfn_mock.return_value = 'dude'
|
||||
grff_mock.return_value = 'dude is released'
|
||||
ret = models.get_release('Firefox', '57.0')
|
||||
grfn_mock.assert_called_with('Firefox', models.Release.CHANNELS[0], '57.0')
|
||||
grff_mock.assert_called_with('dude')
|
||||
assert ret == 'dude is released'
|
||||
|
||||
def test_get_release_esr(self, grff_mock, grfn_mock):
|
||||
grfn_mock.return_value = 'dude'
|
||||
grff_mock.return_value = 'dude is released'
|
||||
ret = models.get_release('Firefox Extended Support Release', '51.0')
|
||||
grfn_mock.assert_called_with('firefox', 'esr', '51.0')
|
||||
grff_mock.assert_called_with('dude')
|
||||
assert ret == 'dude is released'
|
||||
|
||||
def test_get_release_none_match(self, grff_mock, grfn_mock):
|
||||
"""Make sure the proper exception is raised if no file matches the query"""
|
||||
grfn_mock.return_value = None
|
||||
with self.assertRaises(models.ReleaseNotFound):
|
||||
models.get_release('Firefox', '57.0')
|
||||
|
||||
expected_calls = [call('Firefox', ch, '57.0') for ch in models.Release.CHANNELS]
|
||||
grfn_mock.assert_has_calls(expected_calls)
|
||||
|
||||
def test_get_release_none_load(self, grff_mock, grfn_mock):
|
||||
"""Make sure the proper exception is raised if no file successfully loads"""
|
||||
grfn_mock.return_value = 'dude'
|
||||
grff_mock.return_value = None
|
||||
with self.assertRaises(models.ReleaseNotFound):
|
||||
models.get_release('Firefox', '57.0')
|
||||
|
||||
expected_calls = [call('Firefox', ch, '57.0') for ch in models.Release.CHANNELS]
|
||||
grfn_mock.assert_has_calls(expected_calls)
|
||||
|
||||
|
||||
@patch.object(models, 'cache')
|
||||
@patch.object(models, 'get_release_from_file_system')
|
||||
class TestGetReleaseFromFile(TestCase):
|
||||
def test_get_release_from_file(self, grffs_mock, cache_mock):
|
||||
cache_mock.get.return_value = 'dude'
|
||||
assert models.get_release_from_file('walter') == 'dude'
|
||||
cache_mock.get.assert_called_with('walter')
|
||||
grffs_mock.assert_not_called()
|
||||
|
||||
def test_get_release_from_file_no_cache(self, grffs_mock, cache_mock):
|
||||
cache_mock.get.return_value = None
|
||||
grffs_mock.return_value = 'donnie'
|
||||
assert models.get_release_from_file('walter') == 'donnie'
|
||||
cache_mock.get.assert_called_with('walter')
|
||||
grffs_mock.assert_called_with('walter')
|
||||
cache_mock.set.assert_called_with('walter', 'donnie', 300)
|
||||
|
||||
|
||||
@override_settings(RELEASE_NOTES_PATH=RELEASES_PATH)
|
||||
class TestGetReleaseFromFileSystem(TestCase):
|
||||
def test_get_release_from_file_system(self):
|
||||
filename = models.get_release_file_name('firefox', 'nightly', '57.0a1')
|
||||
rel = models.get_release_from_file_system(filename)
|
||||
assert rel.product == 'Firefox'
|
||||
assert rel.channel == 'Nightly'
|
||||
assert rel.version == '57.0a1'
|
||||
|
||||
@patch.object(models, 'codecs')
|
||||
def test_get_release_from_file_system_exception(self, codecs_mock):
|
||||
codecs_mock.open.side_effect = IOError()
|
||||
assert models.get_release_from_file_system('does-not-exist') is None
|
||||
|
||||
|
||||
@patch('os.path.exists')
|
||||
@patch.object(models, 'get_file_id')
|
||||
class TestGetReleaseFileName(TestCase):
|
||||
def test_get_release_file_name(self, gfi_mock, exists_mock):
|
||||
gfi_mock.return_value = 'dude'
|
||||
exists_mock.return_value = True
|
||||
file_name = os.path.join(settings.RELEASE_NOTES_PATH, 'releases', 'dude.json')
|
||||
assert models.get_release_file_name('firefox', 'nightly', '57.0a1') == file_name
|
||||
gfi_mock.assert_called_with('firefox', 'nightly', '57.0a1')
|
||||
exists_mock.assert_called_with(file_name)
|
||||
|
||||
def test_get_release_file_name_no_exists(self, gfi_mock, exists_mock):
|
||||
gfi_mock.return_value = 'dude'
|
||||
exists_mock.return_value = False
|
||||
file_name = os.path.join(settings.RELEASE_NOTES_PATH, 'releases', 'dude.json')
|
||||
assert models.get_release_file_name('firefox', 'nightly', '57.0a1') is None
|
||||
gfi_mock.assert_called_with('firefox', 'nightly', '57.0a1')
|
||||
exists_mock.assert_called_with(file_name)
|
||||
|
||||
|
||||
class TestGetFileID(TestCase):
|
||||
def test_get_file_id(self):
|
||||
assert models.get_file_id('Firefox', 'Nightly', '57.0a1') == 'firefox-57.0a1-nightly'
|
||||
assert models.get_file_id('Firefox', 'Release', '57.0') == 'firefox-57.0-release'
|
||||
assert models.get_file_id('Firefox Extended Support Release', 'ESR', '52.0') == 'firefox-52.0-esr'
|
||||
assert models.get_file_id('Firefox for Android', 'Beta', '57.0b2') == 'firefox-for-android-57.0b2-beta'
|
|
@ -4,21 +4,17 @@
|
|||
import re
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
from django.http import Http404, HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404, get_list_or_404
|
||||
|
||||
from bedrock.base.urlresolvers import reverse
|
||||
from lib import l10n_utils
|
||||
from rna.models import Release
|
||||
from product_details import product_details
|
||||
|
||||
from bedrock.base.urlresolvers import reverse
|
||||
from bedrock.firefox.firefox_details import firefox_desktop, firefox_android, firefox_ios
|
||||
from bedrock.thunderbird.details import thunderbird_desktop
|
||||
from bedrock.mozorg.decorators import cache_control_expires
|
||||
from bedrock.mozorg.templatetags.misc import releasenotes_url
|
||||
from bedrock.firefox.templatetags.helpers import android_builds, ios_builds
|
||||
|
||||
from bedrock.thunderbird.details import thunderbird_desktop
|
||||
from bedrock.mozorg.templatetags.misc import releasenotes_url
|
||||
from bedrock.releasenotes.models import get_release_or_404, get_releases_or_404
|
||||
|
||||
SUPPORT_URLS = {
|
||||
'Firefox for Android': 'https://support.mozilla.org/products/mobile',
|
||||
|
@ -29,8 +25,7 @@ SUPPORT_URLS = {
|
|||
|
||||
|
||||
def release_notes_template(channel, product, version=None):
|
||||
prefix = dict((c, c.lower()) for c in Release.CHANNELS)
|
||||
|
||||
channel = channel or 'release'
|
||||
if product == 'Firefox' and channel == 'Aurora' and version >= 35:
|
||||
return 'firefox/releases/dev-browser-notes.html'
|
||||
|
||||
|
@ -39,7 +34,7 @@ def release_notes_template(channel, product, version=None):
|
|||
dir = 'thunderbird'
|
||||
|
||||
return ('{dir}/releases/{channel}-notes.html'
|
||||
.format(dir=dir, channel=prefix.get(channel, 'release')))
|
||||
.format(dir=dir, channel=channel.lower()))
|
||||
|
||||
|
||||
def equivalent_release_url(release):
|
||||
|
@ -49,19 +44,6 @@ def equivalent_release_url(release):
|
|||
return releasenotes_url(equivalent_release)
|
||||
|
||||
|
||||
def get_release_or_404(version, product):
|
||||
if product == 'Firefox' and (version.endswith('esr') or
|
||||
len(version.split('.')) == 3):
|
||||
product_query = Q(product='Firefox') | Q(
|
||||
product='Firefox Extended Support Release')
|
||||
else:
|
||||
product_query = Q(product=product)
|
||||
release = get_object_or_404(Release, product_query, version=version)
|
||||
if not release.is_public and not settings.DEV:
|
||||
raise Http404
|
||||
return release
|
||||
|
||||
|
||||
def get_download_url(release):
|
||||
if release.product == 'Thunderbird':
|
||||
if release.channel == 'Beta':
|
||||
|
@ -113,22 +95,18 @@ def release_notes(request, version, product='Firefox'):
|
|||
release = get_release_or_404(version + 'beta', product)
|
||||
return HttpResponseRedirect(releasenotes_url(release))
|
||||
|
||||
new_features, known_issues = release.notes(public_only=not settings.DEV)
|
||||
|
||||
return l10n_utils.render(
|
||||
request, release_notes_template(release.channel, product,
|
||||
int(release.major_version())), {
|
||||
int(release.major_version)), {
|
||||
'version': version,
|
||||
'download_url': get_download_url(release),
|
||||
'support_url': SUPPORT_URLS.get(product, 'https://support.mozilla.org/'),
|
||||
'check_url': check_url(product, version),
|
||||
'release': release,
|
||||
'equivalent_release_url': equivalent_release_url(release),
|
||||
'new_features': new_features,
|
||||
'known_issues': known_issues})
|
||||
})
|
||||
|
||||
|
||||
@cache_control_expires(1)
|
||||
def system_requirements(request, version, product='Firefox'):
|
||||
release = get_release_or_404(version, product)
|
||||
dir = 'firefox'
|
||||
|
@ -239,9 +217,8 @@ def releases_index(request, product):
|
|||
|
||||
def nightly_feed(request):
|
||||
"""Serve an Atom feed with the latest changes in Firefox Nightly"""
|
||||
notes = []
|
||||
query = Q(product='Firefox', channel='Nightly')
|
||||
releases = sorted(get_list_or_404(Release, query),
|
||||
notes = {}
|
||||
releases = sorted(get_releases_or_404('firefox', 'nightly'),
|
||||
key=lambda x: x.release_date, reverse=True)[0:5]
|
||||
|
||||
for release in releases:
|
||||
|
@ -249,14 +226,17 @@ def nightly_feed(request):
|
|||
link = reverse('firefox.desktop.releasenotes',
|
||||
args=(release.version, 'release'))
|
||||
|
||||
for note in release.notes()[0]:
|
||||
for note in release.notes:
|
||||
if note.id in notes:
|
||||
continue
|
||||
|
||||
if note.is_public and note.tag:
|
||||
note.link = link + '#note-' + str(note.id)
|
||||
note.version = release.version
|
||||
notes.append(note)
|
||||
notes[note.id] = note
|
||||
|
||||
# Sort by date in descending order
|
||||
notes = sorted(notes, key=lambda x: x.modified, reverse=True)
|
||||
notes = sorted(notes.values(), key=lambda x: x.modified, reverse=True)
|
||||
|
||||
return l10n_utils.render(request, 'firefox/releases/nightly-feed.xml',
|
||||
{'notes': notes},
|
||||
|
|
|
@ -47,6 +47,16 @@ CACHES['product-details'] = {
|
|||
}
|
||||
}
|
||||
|
||||
# cache for release notes
|
||||
CACHES['release-notes'] = {
|
||||
'BACKEND': 'bedrock.base.cache.SimpleDictCache',
|
||||
'LOCATION': 'release-notes',
|
||||
'OPTIONS': {
|
||||
'MAX_ENTRIES': 300, # currently 564 json files but most are rarely accessed
|
||||
'CULL_FREQUENCY': 4, # 1/4 entries deleted if max reached
|
||||
}
|
||||
}
|
||||
|
||||
# cache for externalfiles
|
||||
CACHES['externalfiles'] = {
|
||||
'BACKEND': 'bedrock.base.cache.SimpleDictCache',
|
||||
|
|
|
@ -243,7 +243,6 @@ SUPPORTED_NONLOCALES = [
|
|||
'contribute.json',
|
||||
'credits',
|
||||
'gameon',
|
||||
'rna',
|
||||
'robots.txt',
|
||||
'telemetry',
|
||||
'webmaker',
|
||||
|
@ -280,7 +279,6 @@ NOINDEX_URLS = [
|
|||
r'^tabzilla/',
|
||||
r'/system-requirements/$',
|
||||
r'.*/(firstrun|thanks)/$',
|
||||
r'^rna/',
|
||||
r'^healthz/$',
|
||||
r'^country-code\.json$',
|
||||
# exclude redirects
|
||||
|
@ -445,7 +443,6 @@ INSTALLED_APPS = (
|
|||
'django_jinja_markdown',
|
||||
'django_statsd',
|
||||
'pagedown',
|
||||
'rest_framework',
|
||||
'pipeline',
|
||||
'localflavor',
|
||||
'django_jinja',
|
||||
|
@ -483,7 +480,6 @@ INSTALLED_APPS = (
|
|||
'django_extensions',
|
||||
'lib.l10n_utils',
|
||||
'captcha',
|
||||
'rna',
|
||||
)
|
||||
|
||||
# Must match the list at CloudFlare if the
|
||||
|
@ -1183,8 +1179,9 @@ SEND_TO_DEVICE_LOCALES = ['de', 'en-GB', 'en-US', 'en-ZA',
|
|||
DEV_GEO_COUNTRY_CODE = config('DEV_GEO_COUNTRY_CODE', default='US')
|
||||
SEND_TO_DEVICE_COUNTRIES = config('SEND_TO_DEVICE_COUNTRIES', default='US', cast=Csv())
|
||||
|
||||
RNA_SYNC_URL = config('RNA_SYNC_URL',
|
||||
default='https://nucleus.mozilla.org/rna/sync/')
|
||||
RELEASE_NOTES_PATH = config('RELEASE_NOTES_PATH', default=path('release_notes'))
|
||||
RELEASE_NOTES_REPO = config('RELEASE_NOTES_REPO', default='https://github.com/mozilla/release-notes.git')
|
||||
RELEASE_NOTES_BRANCH = config('RELEASE_NOTES_BRANCH', default='master')
|
||||
|
||||
MOFO_SECURITY_ADVISORIES_PATH = config('MOFO_SECURITY_ADVISORIES_PATH',
|
||||
default=path('mofo_security_advisories'))
|
||||
|
@ -1226,25 +1223,6 @@ LOGGING = {
|
|||
|
||||
PASSWORD_HASHERS = ['django.contrib.auth.hashers.PBKDF2PasswordHasher']
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
# Use hyperlinked styles by default.
|
||||
# Only used if the `serializer_class` attribute is not set on a view.
|
||||
'DEFAULT_MODEL_SERIALIZER_CLASS':
|
||||
'rna.serializers.HyperlinkedModelSerializerWithPkField',
|
||||
|
||||
# Use Django's standard `django.contrib.auth` permissions,
|
||||
# or allow read-only access for unauthenticated users.
|
||||
'DEFAULT_PERMISSION_CLASSES': (
|
||||
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',
|
||||
),
|
||||
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'rest_framework.authentication.SessionAuthentication',
|
||||
),
|
||||
|
||||
'DEFAULT_FILTER_BACKENDS': ('rna.filters.TimestampedFilterBackend',)
|
||||
}
|
||||
|
||||
TABLEAU_DB_URL = config('TABLEAU_DB_URL', default=None)
|
||||
|
||||
ADMINS = MANAGERS = config('ADMINS', cast=json.loads,
|
||||
|
|
|
@ -45,35 +45,38 @@
|
|||
{% else %}
|
||||
If interested, please see the <a href="{{ release.get_bug_search_url() }}">complete list of changes</a> in this release.
|
||||
{% endif %}
|
||||
{{ release.text|markdown|safe }}
|
||||
{{ release.text|safe }}
|
||||
</p>
|
||||
</header>
|
||||
{% endblock %}
|
||||
|
||||
<div class="main-column">
|
||||
{% if new_features %}
|
||||
{% for note in release.notes if note.tag != 'Known' %}
|
||||
{% if loop.first %}
|
||||
<section class="notes-section" id="new-features">
|
||||
<h3>{{ _('What’s New') }}</h3>
|
||||
<ul class="section-items tagged">
|
||||
{% for note in new_features %}
|
||||
{% endif %}
|
||||
<li {% if not note.tag %}class="untagged"{% endif %} id="note-{{ note.id }}">
|
||||
{% if note.tag %}
|
||||
<b class="tag tag-{{ note.tag.lower() }}">{{ note.tag }}</b>
|
||||
{% endif %}
|
||||
{{ note.note|markdown|safe }}
|
||||
{{ note.note|safe }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% if loop.last %}
|
||||
</ul>
|
||||
</section>
|
||||
{% endif %}
|
||||
{% if known_issues %}
|
||||
{% endfor %}
|
||||
{% for note in release.notes if note.tag == 'Known' %}
|
||||
{% if loop.first %}
|
||||
<section class="notes-section" id="known-issues">
|
||||
<h3>{{ _('Known Issues') }}</h3>
|
||||
<ul class="section-items tagged">
|
||||
{% for note in known_issues %}
|
||||
{% endif %}
|
||||
<li id="note-{{ note.id }}">
|
||||
<b class="tag tag-unresolved">{{ _('unresolved') }}</b>
|
||||
{{ note.note|markdown|safe }}
|
||||
{{ note.note|safe }}
|
||||
{% if note.fixed_in_release %}
|
||||
<p class="note">
|
||||
<a href="{{ releasenotes_url(note.fixed_in_release) }}">
|
||||
|
@ -82,10 +85,11 @@
|
|||
</p>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% if loop.last %}
|
||||
</ul>
|
||||
</section>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% block notes_sidebar %}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
<div id="main-content">
|
||||
<article class="main-column">
|
||||
{{ release.system_requirements|markdown|safe }}
|
||||
{{ release.system_requirements|safe }}
|
||||
</article>
|
||||
</div>
|
||||
{% block sidebar %}{% endblock %}
|
||||
|
|
|
@ -12,7 +12,6 @@ handler500 = 'bedrock.base.views.server_error_view'
|
|||
|
||||
|
||||
urlpatterns = (
|
||||
url(r'^rna/', include('rna.urls')),
|
||||
# Main pages
|
||||
url(r'^lightbeam/', include('bedrock.lightbeam.urls')),
|
||||
url(r'^foundation/', include('bedrock.foundation.urls')),
|
||||
|
|
|
@ -85,11 +85,6 @@ def schedule_database_jobs():
|
|||
def update_security_advisories():
|
||||
call_command('update_security_advisories')
|
||||
|
||||
@scheduled_job('interval', minutes=5)
|
||||
def rnasync():
|
||||
# running in a subprocess as rnasync was not designed for long-running process
|
||||
call_command('rnasync')
|
||||
|
||||
@scheduled_job('interval', hours=6)
|
||||
def update_tweets():
|
||||
call_command('cron update_tweets')
|
||||
|
@ -109,6 +104,10 @@ def schedul_l10n_jobs():
|
|||
def update_locales():
|
||||
call_command('l10n_update')
|
||||
|
||||
@scheduled_job('interval', minutes=5)
|
||||
def update_release_notes():
|
||||
call_command('update_release_notes --quiet')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = sys.argv[1:]
|
||||
|
|
|
@ -6,13 +6,13 @@ if [ ! -e ./manage.py ]; then
|
|||
cd $script_parent_dir
|
||||
fi
|
||||
./manage.py migrate --noinput --database bedrock
|
||||
./manage.py rnasync
|
||||
./manage.py cron update_ical_feeds
|
||||
./manage.py update_product_details_files --database bedrock
|
||||
./manage.py update_wordpress --database bedrock
|
||||
./manage.py update_externalfiles
|
||||
./manage.py update_security_advisories
|
||||
./manage.py l10n_update
|
||||
./manage.py update_release_notes
|
||||
./manage.py update_sitemaps
|
||||
#requires twitter api credentials not distributed publicly
|
||||
./manage.py cron update_tweets
|
||||
|
|
|
@ -88,6 +88,7 @@ if $PROD_MODE && ! imageExists "l10n"; then
|
|||
ENVFILE="master";
|
||||
fi
|
||||
dockerRun $ENVFILE code "python manage.py l10n_update"
|
||||
dockerRun $ENVFILE code "python manage.py update_release_notes"
|
||||
dockerRun $ENVFILE code "python manage.py update_sitemaps"
|
||||
docker/bin/docker_build.sh "l10n"
|
||||
fi
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
deis login $DEIS_CONTROLLER --username=$DEIS_USERNAME --password=$DEIS_PASSWORD
|
||||
deis run -a $DEIS_APPLICATION -- '\
|
||||
./manage.py rnasync; \
|
||||
./manage.py cron update_ical_feeds; \
|
||||
./manage.py update_product_details_files --database bedrock; \
|
||||
./manage.py update_externalfiles; \
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
FROM mozorg/bedrock_code:${GIT_COMMIT}
|
||||
|
||||
COPY ./locale ./locale
|
||||
COPY ./release_notes ./release_notes
|
||||
COPY ./root_files/sitemap.xml ./root_files/
|
||||
COPY ./root_files/default-urls.json ./root_files/
|
||||
COPY ./bedrock.db ./
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
FROM mozorg/bedrock_code:${GIT_COMMIT}
|
||||
|
||||
COPY ./locale ./locale
|
||||
COPY ./release_notes ./release_notes
|
||||
COPY ./root_files/sitemap.xml ./root_files/
|
||||
COPY ./root_files/default-urls.json ./root_files/
|
||||
|
||||
# Change User
|
||||
USER root
|
||||
RUN chown webdev.webdev -R locale
|
||||
RUN chown webdev.webdev -R release_notes
|
||||
RUN chown webdev.webdev -R root_files
|
||||
USER webdev
|
||||
|
|
|
@ -50,9 +50,6 @@ whitenoise==3.3.0 \
|
|||
django-localflavor==1.1 \
|
||||
--hash=sha256:3b5503b512248af661cf91e4f402327619ffc3bc5b3b0ea774a969ed3bf84594 \
|
||||
--hash=sha256:afd6627cd0fd396824e44a5e4f7bfe9c8d7a45d9bf09b4db2c0683d92681ba93
|
||||
djangorestframework==3.3.2 \
|
||||
--hash=sha256:5634b1ff56581bf0fe4075e86227fc9693c1ca031c7213c9ae942c445c24817b \
|
||||
--hash=sha256:4962418a57804f8323282728a4f9b9496e78caec1adda352170697752eff01bf
|
||||
django-filter==0.11.0 \
|
||||
--hash=sha256:7d17547b65216cc5c6fbc04aee55088ccd5917c0775304d96f7017c26c789cd7 \
|
||||
--hash=sha256:00cc47935afbbd83260fdd283b0aa790e658d2a71922049f6e467dca8a124537
|
||||
|
@ -100,11 +97,6 @@ puente==0.4.1 \
|
|||
babel==2.3.4 \
|
||||
--hash=sha256:3318ed2960240d61cbc6558858ee00c10eed77a6508c4d1ed8e6f7f48399c975 \
|
||||
--hash=sha256:c535c4403802f6eb38173cd4863e419e2274921a01a8aad8a5b497c131c62875
|
||||
https://github.com/pmclanahan/django-synctool/archive/5f7cf9bad741e60bd9df32aa90e71425d98e437c.tar.gz#egg=django-synctool==1.1.1 \
|
||||
--hash=sha256:2dd290c5339769e3c40d644b5248236bec7c558eaccb922badd7c39c5fd5e095
|
||||
django-mozilla-rna==2.0.2 \
|
||||
--hash=sha256:da0e199ef08b3ed7200232b2724cee82812d70edfcea63202c48408e3241eb4f \
|
||||
--hash=sha256:c75c905a0cfe744af143d7e7007ed5376ed0f27bf0db00b790dd9421eae027a0
|
||||
django-jinja==2.1.3 \
|
||||
--hash=sha256:64446ae1de3593136042147cb16ba9a3aa4449370d9c26c1ec9b7553b2d1c809
|
||||
django-jinja-markdown==1.0 \
|
||||
|
|
Загрузка…
Ссылка в новой задаче