delete unneeded files, de-webappify templates

This commit is contained in:
Allen Short 2014-02-21 23:01:52 -06:00
Родитель 582fedc55b
Коммит 8d520ef981
78 изменённых файлов: 591 добавлений и 2560 удалений

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

@ -48,10 +48,8 @@
{% endif %}
{% for link in links %}
{% set extra = "platform " + link.os.shortname if link.os else "" %}
<a class="button {{ b.button_class|join(' ') }} {{ extra }} {% if addon.is_webapp() %}disabled{% endif %}"
{% if not addon.is_premium() %}
data-hash="{{ link.file.hash }}"
{% endif %}
<a class="button {{ b.button_class|join(' ') }} {{ extra }}"
data-hash="{{ link.file.hash }}"
{% if b.show_warning %}
href="{{ b.addon.get_url_path() }}"
data-realurl="{{ link.url }}"

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

@ -56,11 +56,7 @@
{% if deps %}
<tr class="addon-dependencies">
<th>
{% if addon.is_webapp() %}
{{ _('Required Apps') }}
{% else %}
{{ _('Required Add-ons') }}
{% endif %}
{{ _('Required Add-ons') }}
</th>
<td>
<ul>

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

@ -23,8 +23,6 @@
{{ _('This add-on has been removed by its author.') }}
{% elif addon.status == amo.STATUS_DISABLED %}
{{ _('This add-on has been disabled by an administrator.') }}
{% elif addon.is_premium() %}
{{ _('This add-on is not ready for sale yet.') }}
{% endif %}
</div>
</div>

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

@ -51,17 +51,10 @@
{% if addon.is_unreviewed() %}
<p class="warning">
{% if addon.is_webapp() %}
{% trans url=url('pages.faq') + "#unreviewed" %}
This app has not been reviewed by Mozilla.
<a href="{{ url }}">Learn more</a>
{% endtrans %}
{% else %}
{% trans url=url('pages.faq') + "#unreviewed" %}
This add-on has not been reviewed by Mozilla.
<a href="{{ url }}">Learn more</a>
{% endtrans %}
{% endif %}
{% trans url=url('pages.faq') + "#unreviewed" %}
This add-on has not been reviewed by Mozilla.
<a href="{{ url }}">Learn more</a>
{% endtrans %}
</p>
{% elif b.lite %}
<p class="warning">{% trans url=url('pages.faq') + "#preliminary" %}
@ -84,7 +77,3 @@
{% endif %}
</div> {# install-shell #}
{% if addon.is_webapp() %}
{% include 'addons/includes/apps_error_msg.html' %}
{% endif %}

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

@ -35,50 +35,25 @@
{% endif %}
</div>{# /aux #}
{% if addon.is_webapp() %}
<h3>{{ _('Enjoy this app?') }}</h3>
{% else %}
<h3>{{ _('Enjoy this add-on?') }}</h3>
{% endif %}
<h3>{{ _('Enjoy this add-on?') }}</h3>
<p class="{% if show_install %}show-install{% endif %}">
{% if text %}
{{ text }}
{% elif not addon.charity %}
{% if addon.is_webapp() %}
{% trans %}
The <a href="{{ meet_url }}">developer of this app</a> asks that you help support its
continued development by making a small contribution.
{% endtrans %}
{% else %}
{% trans %}
The <a href="{{ meet_url }}">developer of this add-on</a> asks that you help support its
continued development by making a small contribution.
{% endtrans %}
{% endif %}
{% trans %}
The <a href="{{ meet_url }}">developer of this add-on</a> asks that you help support its
continued development by making a small contribution.
{% endtrans %}
{% elif addon.charity_id == amo.FOUNDATION_ORG %}
{% if addon.is_webapp() %}
{% trans %}
The <a href="{{ meet_url }}">developer of this app</a> asks that you show your support
by making a donation to the <a href="{{ charity_url }}">{{ charity_name }}</a>.
{% endtrans %}
{% else %}
{% trans %}
The <a href="{{ meet_url }}">developer of this add-on</a> asks that you show your support
by making a donation to the <a href="{{ charity_url }}">{{ charity_name }}</a>.
{% endtrans %}
{% endif %}
{% trans %}
The <a href="{{ meet_url }}">developer of this add-on</a> asks that you show your support
by making a donation to the <a href="{{ charity_url }}">{{ charity_name }}</a>.
{% endtrans %}
{% else %}
{% if addon.is_webapp() %}
{% trans %}
The <a href="{{ meet_url }}">developer of this app</a> asks that you show your support
by making a small contribution to <a href="{{ charity_url }}">{{ charity_name }}</a>.
{% endtrans %}
{% else %}
{% trans %}
The <a href="{{ meet_url }}">developer of this add-on</a> asks that you show your support
by making a small contribution to <a href="{{ charity_url }}">{{ charity_name }}</a>.
{% endtrans %}
{% endif %}
{% trans %}
The <a href="{{ meet_url }}">developer of this add-on</a> asks that you show your support
by making a small contribution to <a href="{{ charity_url }}">{{ charity_name }}</a>.
{% endtrans %}
{% endif %}
</p>

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

@ -1,11 +1,7 @@
{% set deps = addon.all_dependencies %}
{% if deps %}
<div class="notice dependencies">
{% if addon.is_webapp() %}
<h3>{{ _('This app requires the following apps to work properly:') }}</h3>
{% else %}
<h3>{{ _('This add-on requires the following add-ons to work properly:') }}</h3>
{% endif %}
<h3>{{ _('This add-on requires the following add-ons to work properly:') }}</h3>
{% if module_context == 'discovery' %}
<ul>
{% for dep in deps %}

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

@ -32,8 +32,7 @@
and it all depends on the addon in some way. #}
{% cache addon %}
<aside id="related" class="secondary metadata c">
{% with categories = addon.all_categories if addon.is_webapp()
else addon.categories.filter(application=APP.id) %}
{% with categories = addon.categories.filter(application=APP.id) %}
{% if categories %}
<h3>{{ _('Related Categories') }}</h3>
<ul>
@ -70,19 +69,11 @@
<h2>
{% with count=addon.listed_authors|length,
author=users_list(addon.listed_authors) %}
{% if addon.is_webapp() %}
{% trans count=count %}
Other apps by {{ author }}
{% pluralize %}
Other apps by these authors
{% endtrans %}
{% else %}
{% trans count=count %}
Other add-ons by {{ author }}
{% pluralize %}
Other add-ons by these authors
{% endtrans %}
{% endif %}
{% trans count=count %}
Other add-ons by {{ author }}
{% pluralize %}
Other add-ons by these authors
{% endtrans %}
{% endwith %}
</h2>
{{ author_addons|addon_grid(cols=3, src='dp-hc-othersby',

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

@ -125,8 +125,6 @@
{{ dependencies_note(addon) }}
{{ upsell_note(addon) }}
{% if addon.takes_contributions %}
{{ impala_contribution(addon=addon, src='dp-btn-primary') }}
{% elif addon.has_profile() and addon.listed_authors %}

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

@ -4,10 +4,8 @@
{% block bodyclass %}gutter{% endblock %}
{% block content %}
{% if not addon.is_webapp() %}
{{ impala_breadcrumbs([(addon.type_url(), amo.ADDON_TYPES[addon.type]),
{{ impala_breadcrumbs([(addon.type_url(), amo.ADDON_TYPES[addon.type]),
(None, addon.name)]) }}
{% endif %}
<aside class="secondary">
{{ addon|sidebar_listing }}
@ -15,18 +13,10 @@
<div class="primary">
<div class="notification-box error {{ 'removed' if addon.disabled_by_user else 'disabled' }}">
{% if addon.is_webapp() %}
{% if addon.disabled_by_user %}
{{ _('This app has been removed by its author.') }}
{% elif addon.status == amo.STATUS_DISABLED %}
{{ _('This app has been disabled by an administrator.') }}
{% endif %}
{% else %}
{% if addon.disabled_by_user %}
{{ _('This add-on has been removed by its author.') }}
{% elif addon.status == amo.STATUS_DISABLED %}
{{ _('This add-on has been disabled by an administrator.') }}
{% endif %}
{% if addon.disabled_by_user %}
{{ _('This add-on has been removed by its author.') }}
{% elif addon.status == amo.STATUS_DISABLED %}
{{ _('This add-on has been disabled by an administrator.') }}
{% endif %}
</div>
</div>

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

@ -23,37 +23,23 @@
<div>
<p>
{% if webapp %}
{{ loc('Please do not post bug reports in reviews. We do not make
your email address available to app developers and they may
need to contact you to help resolve your issue.') }}
{% else %}
{% trans %}
Please do not post bug reports in reviews. We do not make your email
address available to add-on developers and they may need to contact
you to help resolve your issue.
{% endtrans %}
{% endif %}
{% trans %}
Please do not post bug reports in reviews. We do not make your email
address available to add-on developers and they may need to contact
you to help resolve your issue.
{% endtrans %}
</p>
{% if addon.support_url or addon.support_email %}
<p>
{% with support=request.path + '#support' %}
{% if webapp %}
{{ loc('See the <a href="{support}">support section</a> to
find out where to get assistance for this app.')|f(
support=support)|safe }}
{% else %}
{% trans %}
See the <a href="{{ support }}">support section</a> to find out
where to get assistance for this add-on.
{% endtrans %}
{% endif %}
{% trans %}
See the <a href="{{ support }}">support section</a> to find out
where to get assistance for this add-on.
{% endtrans %}
{% endwith %}
</p>
{% endif %}
{% if not webapp %}
<p><a href="{{ remora_url('/pages/review_guide') }}" target="_blank">{{ _('Review Guidelines') }}</a></p>
{% endif %}
<p><a href="{{ remora_url('/pages/review_guide') }}" target="_blank">{{ _('Review Guidelines') }}</a></p>
<p>
<a href="{{ shared_url('reviews.add', addon) }}"
id="detail-review-link">{{ _('Detailed Review') }}</a>

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

@ -44,11 +44,7 @@
{% else %}
<div class="review no-reviews">
<h3>
{% if addon.is_webapp() %}
{{ _('This app has not yet been reviewed.') }}
{% else %}
{{ _('This add-on has not yet been reviewed.') }}
{% endif %}
{{ _('This add-on has not yet been reviewed.') }}
{% if addon.can_review(amo_user) %}
<a id="add-first-review" href="{{ shared_url('reviews.add', addon) }}">
{{ _('Be the first!') }}

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

@ -1,16 +0,0 @@
{% set upsell = addon.upsell %}
{% if upsell %}
<div class="notice upsell">
<h3>{{ _('Premium version available') }}</h3>
<div class="premium">
{% with prm = upsell.premium %}
{% if module_context == 'discovery' %}
<a href="{{ services_url('discovery.addons.detail', prm.slug, src='discovery-upsell') }}">
<img src="{{ prm.icon }}">{{ prm.name }}</a>
{% else %}
{{ prm|addon_hovercard(src='dp-hc-upsell', dl_src='dp-dl-upsell') }}
{% endif %}
{% endwith %}
</div>
</div>
{% endif %}

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

@ -1,23 +1,13 @@
<a class="button {% if request.MOBILE %}add{% endif %} {{ b.button_class|join(' ') }} {{ extra }}"
{% if not addon.is_premium() and not addon.is_webapp() %}
data-hash="{{ link.file.hash }}"
{% endif %}
{% if b.show_warning and not addon.is_webapp() %}
data-hash="{{ link.file.hash }}"
{% if b.show_warning %}
href="{{ b.addon.get_url_path() }}"
data-realurl="{{ link.url }}"
{% else %}
href="{{ link.url }}"
{% endif %}>
{% if request.MOBILE %}
{% if addon.is_webapp() %}
{% if (addon.is_premium() and addon.has_purchased(amo_user)) or (not addon.is_premium()) %}
{{ _('Install') }}
{% else %}
{{ _('Purchase for {0}')|f(addon.premium.get_price_locale()) }}
{% endif %}
{% else %}
{{ _('Add to Firefox') }}
{% endif %}
{{ _('Add to Firefox') }}
{% else %}
<b></b>
<span>

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

@ -75,13 +75,11 @@
</td>
</tr>
{% endif %}
{% if not addon.is_webapp() %}
{% if addon.compatible_apps[APP] %}
<tr>
<th>{{ _('Works with') }}</th>
<td>{{ addon.compatible_apps[APP] }}</td>
</tr>
{% endif %}
{% if addon.compatible_apps[APP] %}
<tr>
<th>{{ _('Works with') }}</th>
<td>{{ addon.compatible_apps[APP] }}</td>
</tr>
{% endif %}
{% if addon.show_adu() and addon.average_daily_users %}
<tr class="adu">
@ -95,7 +93,7 @@
<td>{{ addon.weekly_downloads|numberfmt }}</td>
</tr>
{% endif %}
{% set version = addon.current_version if not addon.is_webapp() else None %}
{% set version = addon.current_version %}
{% if version %}
<tr>
<th>{{ _('Version') }}</th>

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

@ -5,11 +5,9 @@
{% block header %}
<header id="home-header">
{% include "mobile/header.html" %}
{% if not (settings.APP_PREVIEW or WEBAPP) %}
<div class="get-fx-message">
{{ _('You need Firefox to install add-ons. <a href="http://mozilla.com/mobile">Learn More&nbsp;&raquo;</a>') }}
</div>
{% endif %}
<div class="get-fx-message">
{{ _('You need Firefox to install add-ons. <a href="http://mozilla.com/mobile">Learn More&nbsp;&raquo;</a>') }}
</div>
<hgroup>
<h1 class="site-title">
{% set appicon = 'firefox' if request.APP in (amo.MOBILE, amo.ANDROID) else request.APP.short %}

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

@ -1,28 +0,0 @@
{% extends "base_modal.html" if is_ajax else "impala/base_shared.html" %}
{% block classes %}paypal-modal{% endblock %}
{% block content %}
<section class="paypal-parent paypal-thank-you" id="addon_info" data-addon="{{ addon.id }}">
{% if addon.is_webapp() %}
<h2>{{ loc('Purchase App') }}</h2>
{% else %}
<h2>{{ loc('Purchase Add-on') }}</h2>
{% endif %}
<h5 class="error">{{ loc('Error with your purchase') }}</h5>
{# TODO(apps): Finalize copy. #}
{% with addon_name=addon.name, support_link="mailto:%s" % settings.MARKETPLACE_EMAIL %}
<p>
Unfortunately, your purchase of <strong class='addon-title'>{{ addon_name }}</strong> could <strong>not</strong> be completed.
</p>
<p>You can try again, or <a href="{{ support_link }}">try contacting us</a>.</p>
{% endwith %}
</section>
<section class="paypal-parent">
{# TODO(marketplace-docs)
&middot;
<a href="{{ url('devhub.docs', doc_name='marketplace') }}">{{ loc('Marketplace Support') }}</a>
#}
</section>
{% endblock %}

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

@ -22,24 +22,11 @@
{% if status == 'error' %}
<a href="{{ shared_url('addons.purchase.error', addon)|urlparams(realurl=realurl) }}"
id="paypal-error">Error</a>
{% elif status != 'cancel' %}
{% if addon.is_premium() %}
<a href="{{ shared_url('addons.purchase.thanks', addon)|urlparams(realurl=realurl) }}"
id="paypal-thanks">
{% if webapp %}
{{ loc('Thank you for purchasing the app') -}}
{% else %}
{{ _('Thank you for purchasing the add-on') -}}
{% endif %}</a>
{% endif %}
{% endif %}
<p>
<a id="paypal-result" target="_top" href="{{ addon.get_url_path() }}">
{% if webapp %}
{{ _('Return to the app.') -}}
{% else %}
{{ _('Return to the addon.') -}}
{% endif %}</a>
</a>
</p>
</section>
{% endblock %}

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

@ -1,80 +0,0 @@
{% extends "base_modal.html" if is_ajax else "impala/base_shared.html" %}
{% block classes %}paypal-modal{% endblock %}
{% block content %}
{% if user.is_authenticated() and addon.has_purchased(user.get_profile()) %}
<section class="paypal-parent ajax-submit" id="addon_info" data-addon="{{ addon.id }}">
{% if addon.is_webapp() %}
<h2>{{ _('Purchased App') }}</h2>
{{ _("You've already bought this app!") }}
{% else %}
<h2>{{ _('Purchased Add-on') }}</h2>
{{ _("You've already bought this add-on!") }}
{% endif %}
{% trans manifest_url=addon.manifest_url if addon.is_webapp() else '',
class='trigger_app_install' if addon.is_webapp() else 'trigger_download',
receipt='receipt',
href='#' if addon.is_webapp() else download %}
<p>If installation does not automatically begin, please <a class="{{ class }}" data-manifest-url="{{ manifest_url }}" href="{{ href }}"
data-receipt="{{ receipt }}">click here</a>.</p>
{% endtrans %}
</p>
</section>
{% else: %}
<div class="ajax-submit">
{% if addon.is_webapp() %}
<h2>{{ _('Purchase App') }}</h2>
{% else %}
<h2>{{ _('Purchase Add-on') }}</h2>
{% endif %}
<div class="paypal-content">
<div class="price-wrapper">
<span class="price">{{ addon.premium.get_price_locale() }}</span>
{% if currencies|length > 1 %}
<br />
<a href="#">change currency</a>
<select name="currency" class="js-hidden">
{% for pk, currency in currencies %}
<option value="{{ pk }}" data-display="{{ currency.get_price_locale() }}">{{ amo.PAYPAL_CURRENCIES[currency.currency] }}</option>
{% endfor %}
</select>
</span>
{% endif %}
</div>
<h5>{{ addon.name }}</h5>
<div class="paypal-links">
{# TODO(apps): Add a link to purchase info.
<a>{{ _('Learn about purchases') }}</a>
#}
</div>
<div class="paypal-parent">
{% if user.is_authenticated() %}
<div class="paypal-user">
{% trans user_email=user.email %}
You are logged in as <strong>{{ user_email }}</strong>!
{% endtrans %}
</div>
<form method="post" action="{{ shared_url('addons.purchase', addon) }}?">
{{ csrf() }}
<button class="button prominent paypal"
data-realurl="{{ download }}"
data-thanksurl="{{ shared_url('addons.purchase.thanks', addon) }}">
{# The <small> makes it smaller, <em> makes it darker. Don't localize "PayPal". #}
{{ loc('Pay <small>with</small> Pay<em>Pal</em>')|xssafe }}
</button>
</form>
<p>{{ loc('Complete your purchase with PayPal. No PayPal account is necessary.') }}</p>
{% else %}
<div class="paypal-user login">
<a href="#" class="browserid-login button prominent"
data-url="{{ url('users.browserid_login') }}" data-event="login-complete">
{{ loc('Log in / Register') }}
</a>
</div>
<p>{{ loc('You need to be logged in to download and install apps to your browser.') }}</p>
{% endif %}
</div>
</div>
{% endif %}
{% endblock %}

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

@ -1,46 +0,0 @@
{% extends "base_modal.html" if is_ajax else "impala/base_shared.html" %}
{% block classes %}paypal-modal{% endblock %}
{% block content %}
<section class="paypal-parent paypal-thank-you" id="addon_info" data-addon="{{ addon.id }}">
{% if addon.is_webapp() %}
<h2>{{ loc('Purchase App') }}</h2>
{% else %}
<h2>{{ loc('Purchase Add-on') }}</h2>
{% endif %}
<h5>{{ loc('Thank you!') }}</h5>
{# TODO(apps): Finalize copy. #}
{% with addon_name=addon.name, manifest_url=addon.manifest_url if addon.is_webapp() else '',
receipt=receipt, href='#' if addon.is_webapp() else download,
class='trigger_app_install' if addon.is_webapp() else 'trigger_download' %}
Your purchase of <strong class='addon-title'>{{ addon_name }}</strong> is complete.
<p>If installation does not automatically begin, please <a class="{{ class }}"
data-receipt="{{ receipt }}" data-manifest-url="{{ manifest_url }}" href="{{ href }}">click here</a>.</p>
{% endwith %}
<p class="mozilla-mission">
{% with learn_more='http://www.mozilla.org/causes' %}
Your purchase helps support Mozilla's mission.
<a href="{{ learn_more }}" target="_blank">Learn more</a>
{% endwith %}
</p>
</section>
{% if waffle.flag('allow-pre-auth') and not amo_user.has_preapproval_key() %}
<section class="paypal-parent">
<form form id="preapproval" method="post">
{{ csrf() }}
<p>{{ loc('Want to do this faster next time?') }}</p>
<p>{{ loc('Setting up PayPal pre-approval allows you to buy apps quickly on this site. They also allow you to use in-app purchases that go through this site.') }}</p>
<p><button>{{ loc('Set up pre-approval') }}</button></p>
</form>
</section>
{% endif %}
<section class="paypal-parent">
{# TODO(marketplace-docs)
&middot;
<a href="{{ url('devhub.docs', doc_name='marketplace') }}">{{ loc('Marketplace Support') }}</a>
#}
</section>
{% endblock %}

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

@ -7,20 +7,10 @@
{% endif %}
<ol {% if hide %}style="display: none"{% endif %}>
<li>
{% if addon.is_webapp() %}
<p>
{# TODO(apps): Add link back to apps policies when bug 685602 is done. #}
{{ loc('If you suspect this app violates our policies or has
security or privacy issues, please use the form below to
describe your concerns. Please do not use this form for
any other reason.') }}
</p>
{% else %}
<p>{% trans url=remora_url('developers/docs/policies') %}
If you suspect this add-on violates <a href="{{ url }}">our policies</a> or
has security or privacy issues, please use the form below to describe your
concerns. Please do not use this form for any other reason.{% endtrans %}</p>
{% endif %}
<p>{% trans url=remora_url('developers/docs/policies') %}
If you suspect this add-on violates <a href="{{ url }}">our policies</a> or
has security or privacy issues, please use the form below to describe your
concerns. Please do not use this form for any other reason.{% endtrans %}</p>
</li>
<li>
{{ abuse_form.text }}

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

@ -1,25 +0,0 @@
{% set addon_type = amo.ADDON_WEBAPP %}
{% extends 'base_modal.html' if request.is_ajax() else 'impala/base_side_categories.html' %}
{% block title %}{{ _('Oops') }}{% endblock %}
{# TODO(apps): Finalize copy. #}
{% block primary %}
{% block content %}
<section class="primary">
<header>
<h1>Oops! Not allowed.</h1>
</header>
<div class="island hero prose">
<p>You tried to do something that you weren't allowed to.</p>
{% if csrf %}
{% trans %}
<p>Try going back to the previous page, refreshing
and then trying again.</p>
{% endtrans %}
{% endif %}
</div>
</section>
{% endblock %}
{% endblock %}

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

@ -1,59 +0,0 @@
<!-- Not in a trans block on purpose; we don't want to get into
any legal ambiguities between the english version and a translation. -->
<!-- When updating, don't forget to change the Last Updated date -->
<div id="dev-agreement" class="rounded webapp">
<strong>App Developer Preview Terms</strong>
<p>Last Update: <strong>December 7, 2011</strong></p>
<ol start="0">
<li>
<strong>The following terms</strong> (the &#8220;<strong>Terms</strong>&#8221;)
<strong>apply to your use of this developer preview of the Mozilla application
marketplace</strong> (the &#8220;<strong>App Developer Preview</strong>&#8221;).
By indicating your acceptance below or otherwise using the App Developer Preview,
you represent that you are at least 18 years of age, and have full power, capacity,
and authority to accept these Terms on behalf of yourself, or if applicable, your
employer or such other entity that you represent. If you do not agree to these Terms
or cannot make the foregoing representations, then you cannot use the App Developer
Preview. We reserve the right to change these Terms and the Firefox Market in our
sole discretion.
</li>
<li>
You may upload or otherwise make applications, add-ons or themes or other content
(&#8220;Developer Content&#8221;) available on the App Developer Preview in conjunction
with your testing of our service. In connection with the Developer Content you upload,
during the term of these Terms, you hereby grant us a nonexclusive, worldwide, royalty-free
license under all rights necessary to make such Developer Content available through the
functionality of the App Developer Preview.
</li>
<li>If any third party brings a claim against Mozilla related to your actions or your Developer
Content, you will defend and hold Mozilla harmless from and against all damages, losses, and
expenses of any kind (including reasonable legal fees and costs) related to such claim.</li>
<li>Mozilla reserves the right to manage the App Developer Preview in a manner designed to
facilitate its integrity and functionality, including the right to remove or disable Developer
Content or a developer&#39;s account.</li>
<li>Mozilla may terminate this Agreement or the App Developer Preview at any time. You may
terminate this Agreement by removing your Developer Content and ceasing use of the App Developer
Preview. Sections 2, and 4-7 will survive any termination or expiration of these Terms.</li>
<li class="loud-noises"><strong>The APP DEVELOPER PREVIEW IS provided &#8220;as is&#8221;.
Mozilla, its contributors, licensors and distributors disclaim all warranties,</strong>
whether express or implied, including without limitation, implied warranties of merchantability,
fitness for a particular purpose and non-infringement. Some jurisdictions do not allow the exclusion
or limitation of implied warranties, so this disclaimer may not apply to you.</li>
<li class="loud-noises">YOU EXPRESSLY UNDERSTAND AND AGREE THAT, EXCEPT AS REQUIRED BY LAW, MOZILLA,
ITS CONTRIBUTORS, LICENSORS, SUBSIDIARIES, AFFILIATES AND DISTRIBUTORS WILL NOT BE LIABLE TO YOU UNDER
ANY THEORY OF LIABILITY FOR ANY INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
THAT MAY BE INCURRED BY YOU, INCLUDING ANY LOSS OF DATA, WHETHER OR NOT MOZILLA OR ITS REPRESENTATIVES HAVE
BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING. IN NO EVENT SHALL
MOZILLA AGGREGATE LIABILITY TO YOU FOR ALL DAMAGES ARISING FROM OR RELATED TO THIS AGREEMENT BE IN EXCESS
OF $100.</li>
<li>This Agreement, and your relationship with Mozilla under this Agreement, shall be governed by the
laws of the State of California without regard to its conflict of laws provisions. You and Mozilla
agree to submit to the exclusive jurisdiction of the courts located within the county of Santa Clara,
California to resolve any legal matter arising from this Agreement.</li>
</ol>
</div>

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

@ -5,13 +5,6 @@
('created', _('Newest')),
('featured', _('Featured')),
) %}
{% elif addon_type == amo.ADDON_WEBAPP %}
{% set extras = (
('downloads', _('Most Popular')),
('free', loc('Top Free')),
('paid', loc('Top Paid')),
('rating', _('Highest Rated')),
) %}
{% else %}
{% set extras = (
('featured', _('Featured')),

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

@ -1,10 +1,7 @@
{% extends "devhub/base_impala.html" %}
{% if webapp %}
{% set title = loc('Manage My Apps') %}
{% else %}
{% set title = _('Manage My Submissions') %}
{% endif %}
{% set title = _('Manage My Submissions') %}
{% block title %}{{ dev_page_title(title) }}{% endblock %}
@ -16,115 +13,76 @@
{% if addon_tab %}
{% set cnt = addons.paginator.count %}
{% if webapp %}
{# L10n: {0} is an integer. #}
<h2>{{ ngettext('<b>{0}</b> app', '<b>{0}</b> apps', cnt)|f(cnt|numberfmt)|safe }}</h2>
{% else %}
{# L10n: {0} is an integer. #}
<h2 class="submission-count">{{ ngettext('<b>{0}</b> add-on', '<b>{0}</b> add-ons', cnt)|f(cnt|numberfmt)|safe }}</h2>
{% endif %}
{# L10n: {0} is an integer. #}
<h2 class="submission-count">{{ ngettext('<b>{0}</b> add-on', '<b>{0}</b> add-ons', cnt)|f(cnt|numberfmt)|safe }}</h2>
{% endif %}
</header>
</section>
{% if webapp %}
<div class="island action-needed">
<h2>{{ _('Welcome to the Developer Dashboard') }}</h2>
{% if webapp %}
<p>
{{ loc("You don't currently have any apps hosted on Firefox Marketplace. To
learn how the process works and submit your first app, click Get
Started below.") }}
</p>
{% else %}
<p>
{% trans %}
You don't currently have any add-ons hosted on Mozilla Add-ons. To learn
how the process works and submit your first add-on, click Get Started
below.
{% endtrans %}
</p>
<section class="secondary devhub-sidebar">
<p id="submit-addon" class="submit-cta">
<a href="{{ url('devhub.submit.1') }}"
class="button prominent">{{ _('Submit a New Add-on') }}</a>
</p>
<p class="submit-theme submit-cta">
<a href="{{ url('devhub.themes.submit') }}"
class="button prominent">{{ _('Submit a New Theme') }}</a>
</p>
<div class="item recent-activity">
<h3>
{{ _('Recent Activity') }}
<a href="{{ rss }}" class="subscribe-feed" title="{{ _('Subscribe to this feed') }}">
{{ _('Subscribe to this feed') }}</a>
</h3>
{% if addon_items %}
<ul>
{% for item in addon_items %}
<li class="item">
{{ item }}
<span class="activity-timestamp">
{% trans user=item.user|user_link, ago=item.created|timesince %}
{{ ago }} by {{ user }}
{% endtrans %}
</span>
</li>
{% endfor %}
</ul>
{% endif %}
{% set submit_view = 'devhub.submit_apps.1' if webapp else 'devhub.submit.1' %}
<p class="button-wrapper">
<a href="{{ url(submit_view) }}" class="button prominent">
{{ _('Get Started') }}</a>
</p>
<p class="older-activity"><a href="{{ url('devhub.feed_all') }}">
{{ _('Older activity for My Add-ons') }} &#9658;</a></p>
</div>
{% else %}
<section class="secondary devhub-sidebar">
<p id="submit-addon" class="submit-cta">
<a href="{{ url('devhub.submit.1') }}"
class="button prominent">{{ _('Submit a New Add-on') }}</a>
</p>
<p class="submit-theme submit-cta">
<a href="{{ url('devhub.themes.submit') }}"
class="button prominent">{{ _('Submit a New Theme') }}</a>
</p>
<div class="item recent-activity">
<h3>
{{ _('Recent Activity') }}
<a href="{{ rss }}" class="subscribe-feed" title="{{ _('Subscribe to this feed') }}">
{{ _('Subscribe to this feed') }}</a>
</h3>
{% if addon_items %}
<ul>
{% for item in addon_items %}
<li class="item">
{{ item }}
<span class="activity-timestamp">
{% trans user=item.user|user_link, ago=item.created|timesince %}
{{ ago }} by {{ user }}
{% endtrans %}
</span>
</li>
{% endfor %}
</ul>
{% endif %}
{% if webapp %}
{#<p class="older-activity"><a href="{{ url('devhub.feed_all') }}">
{{ loc('Older activity for My Apps') }} &#9658;</a></p>#}
{% else %}
<p class="older-activity"><a href="{{ url('devhub.feed_all') }}">
{{ _('Older activity for My Add-ons') }} &#9658;</a></p>
{% endif %}
{% include "devhub/includes/blog_posts.html" %}
</section>
{% if addon_tab %}
{% include "addons/includes/dashboard_tabs.html" %}
<section class="dashboard primary" role="main">
<div class="listing island hero c">
{{ impala_addon_listing_header(request.get_full_path(), search_filter=filter) }}
<div class="items">
{{ dev_addon_listing_items(addons.object_list) }}
</div>
{{ addons|impala_paginator }}
</div>
{% if not webapp %}
{% include "devhub/includes/blog_posts.html" %}
{% endif %}
</section>
{% endif %}
{% if addon_tab %}
{% if theme %}
{# L10n: {0} is an integer. #}
<section class="dashboard primary theme-dashboard">
{% set cnt = themes.paginator.count %}
<h2 class="submission-count">
{{ ngettext('<b>{0}</b> theme', '<b>{0}</b> themes', cnt)|f(cnt|numberfmt)|safe }}
</h2>
{% include "addons/includes/dashboard_tabs.html" %}
<section class="dashboard primary" role="main">
<div class="listing island hero c">
{{ impala_addon_listing_header(request.get_full_path(), search_filter=filter) }}
<div class="items">
{{ dev_addon_listing_items(addons.object_list) }}
</div>
{{ addons|impala_paginator }}
<div class="listing island hero c">
{{ impala_addon_listing_header(request.get_full_path(), search_filter=filter) }}
<div class="items">
{{ dev_addon_listing_items(themes.object_list) }}
</div>
</section>
{% endif %}
{% if theme %}
{# L10n: {0} is an integer. #}
<section class="dashboard primary theme-dashboard">
{% set cnt = themes.paginator.count %}
<h2 class="submission-count">
{{ ngettext('<b>{0}</b> theme', '<b>{0}</b> themes', cnt)|f(cnt|numberfmt)|safe }}
</h2>
{% include "addons/includes/dashboard_tabs.html" %}
<div class="listing island hero c">
{{ impala_addon_listing_header(request.get_full_path(), search_filter=filter) }}
<div class="items">
{{ dev_addon_listing_items(themes.object_list) }}
</div>
{{ themes|impala_paginator }}
</div>
</section>
{% endif %}
{{ themes|impala_paginator }}
</div>
</section>
{% endif %}
{% endblock %}

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

@ -21,13 +21,8 @@
<th>
<label data-for="trusted">
Trusted?
{% if webapp %}
{{ tip(None,
'Trusted apps can become public without editor review.') }}
{% else %}
{{ tip(None,
'Trusted add-ons can become public without editor review.') }}
{% endif %}
{{ tip(None,
'Trusted add-ons can become public without editor review.') }}
</label>
</th>
<td>
@ -41,11 +36,7 @@
<tr>
<th>
<label data-for="type">
{% if webapp %}
App Type
{% else %}
Add-on Type
{% endif %}
Add-on Type
</label>
</th>
<td>
@ -59,11 +50,7 @@
<tr>
<th>
<label data-for="guid">
{% if webapp %}
App GUID
{% else %}
Add-on GUID
{% endif %}
Add-on GUID
{{ tip(None,
"Only change if you understand all of the consequences.") }}
</label>

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

@ -29,14 +29,8 @@
</tr>
<tr>
<th>
{% if webapp %}
{# TODO(apps): Finalize copy. #}
{{ tip('App URL',
'Choose a short, unique URL slug for your app.') }}
{% else %}
{{ tip(_("Add-on URL"),
_("Choose a short, unique URL slug for your add-on.")) }}
{% endif %}
{{ tip(_("Add-on URL"),
_("Choose a short, unique URL slug for your add-on.")) }}
</th>
<td id="slug_edit">
{% if editable %}
@ -45,7 +39,7 @@
</div>
{{ form.slug.errors }}
{% else %}
{{ settings.SITE_URL }}/&hellip;/{{ addon.app_slug if webapp else addon.slug }}
{{ settings.SITE_URL }}/&hellip;/{{ addon.slug }}
<a href="{{ addon.get_url_path() }}">{{ _('View Listing') }}</a>
{% endif %}
</td>
@ -54,20 +48,11 @@
<th>
<label data-for="summary">
{{ _("Summary") }}
{% if webapp %}
{# TODO(apps): Finalize copy. #}
{{ tip(None,
"A short explanation of your app's basic
{{ tip(None,
_("A short explanation of your add-on's basic
functionality that is displayed in search and browse
listings, as well as at the top of your app's
details page.") }}
{% else %}
{{ tip(None,
_("A short explanation of your add-on's basic
functionality that is displayed in search and browse
listings, as well as at the top of your add-on's
details page.")) }}
{% endif %}
listings, as well as at the top of your add-on's
details page.")) }}
</label>
</th>
<td>
@ -84,18 +69,10 @@
</tr>
<tr>
<th>
{% if webapp %}
{# TODO(apps): Finalize copy. #}
{{ tip('Categories',
"Categories are the primary way users browse through apps.
Choose any that fit your app's functionality for the
most exposure.") }}
{% else %}
{{ tip(_("Categories"),
_("Categories are the primary way users browse through add-ons.
Choose any that fit your add-on's functionality for the most
exposure.")) }}
{% endif %}
{{ tip(_("Categories"),
_("Categories are the primary way users browse through add-ons.
Choose any that fit your add-on's functionality for the most
exposure.")) }}
</th>
<td id="addon-categories-edit"
data-max-categories="{{ amo.MAX_CATEGORIES }}">
@ -110,25 +87,15 @@
{{ cats|join(' &middot; ')|safe }}
</p>
<p>
{% if webapp %}
{# TODO(apps): Finalize copy. #}
{% with email='amo-editors@mozilla.org' %}
Categories cannot be changed while your app is
featured. Please email
<a href="mailto:{{ email }}">{{ email }}</a> if there
is a reason you need to modify your categories.
{% endwith %}
{% else %}
{% trans email='amo-editors@mozilla.org' %}
Categories cannot be changed while your add-on is
featured for this application. Please email
<a href="mailto:{{ email }}">{{ email }}</a> if there is
a reason you need to modify your categories.
{% endtrans %}
{% endif %}
{% trans email='amo-editors@mozilla.org' %}
Categories cannot be changed while your add-on is
featured for this application. Please email
<a href="mailto:{{ email }}">{{ email }}</a> if there is
a reason you need to modify your categories.
{% endtrans %}
</p>
{% else %}
{{ select_cats(amo.MAX_CATEGORIES, form, webapp) }}
{{ select_cats(amo.MAX_CATEGORIES, form) }}
{% endif %}
{% endfor %}
{% else %}
@ -137,9 +104,7 @@
<ul class="addon-app-cats-inline">
{% for app, cats in categories %}
<li>
{% if not webapp %}
<b>{{ app.pretty }}:</b>
{% endif %}
<b>{{ app.pretty }}:</b>
{{ cats|join(' &middot; ')|safe }}
</li>
{% endfor %}
@ -150,18 +115,10 @@
</tr>
<tr>
<th>
{% if webapp %}
{# TODO(apps): Finalize copy. #}
{{ tip('Tags',
"Tags help users find your app and should be short
descriptors such as tabs, toolbar, or twitter. You
may have a maximum of {0} tags.".format(amo.MAX_TAGS)) }}
{% else %}
{{ tip(_("Tags"),
_("Tags help users find your add-on and should be short
descriptors such as tabs, toolbar, or twitter. You
may have a maximum of {0} tags.").format(amo.MAX_TAGS)) }}
{% endif %}
{{ tip(_("Tags"),
_("Tags help users find your add-on and should be short
descriptors such as tabs, toolbar, or twitter. You
may have a maximum of {0} tags.").format(amo.MAX_TAGS)) }}
</th>
<td id="addon_tags_edit">
{% if editable %}

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

@ -2,12 +2,7 @@
<form method="post" action="{{ url('devhub.addons.section', addon.slug, 'details', 'edit') }}">
<h3>
{% if webapp %}
{# TODO(apps): Finalize copy. #}
App Details
{% else %}
{{ _('Add-on Details') }}
{% endif %}
{{ _('Add-on Details') }}
{% if not editable %}
<a href="#" data-editurl="{{ url('devhub.addons.section', addon.slug, 'details', 'edit') }}" class="button">
{{ _('Edit') }}</a>
@ -17,27 +12,17 @@
<div class="item_wrapper">
{% if editable %}{{ form.non_field_errors() }}{% endif %}
<table>
{% if not webapp %}
<caption>{{ _('Add-on Details for {0}')|f(addon.name) }}</caption>
{% endif %}
<caption>{{ _('Add-on Details for {0}')|f(addon.name) }}</caption>
<tbody>
<tr>
<th>
<label data-for="description">
{{ _('Description') }}
{% if webapp %}
{# TODO(apps): Finalize copy. #}
{{ tip(None,
"A longer explanation of features, functionality, and
other relevant information. This field is displayed
only on the app's details page.") }}
{% else %}
{{ tip(None,
_("A longer explanation of features,
functionality, and other relevant information. This
field is only displayed on the add-on's details
page.")) }}
{% endif %}
{{ tip(None,
_("A longer explanation of features,
functionality, and other relevant information. This
field is only displayed on the add-on's details
page.")) }}
</label>
</th>
<td>
@ -56,16 +41,9 @@
</tr>
<tr>
<th>
{% if webapp %}
{# TODO(apps): Finalize copy. #}
{{ tip(_("Default Locale"),
"Information about your app is displayed in this locale
unless you override it with a locale-specific translation.") }}
{% else %}
{{ tip(_("Default Locale"),
_("Information about your add-on is displayed in this locale
unless you override it with a locale-specific translation.")) }}
{% endif %}
{{ tip(_("Default Locale"),
_("Information about your add-on is displayed in this locale
unless you override it with a locale-specific translation.")) }}
</th>
<td class="addon_edit_locale">
{% if editable %}
@ -80,20 +58,11 @@
<th>
<label data-for="homepage">
{{ _("Homepage") }}
{% if webapp %}
{# TODO(apps): Finalize copy. #}
{{ tip(None,
"If your app has another homepage, enter its
{{ tip(None,
_("If your add-on has another homepage, enter its
address here. If your website is localized into other
languages multiple translations of this field can be
added.") }}
{% else %}
{{ tip(None,
_("If your add-on has another homepage, enter its
address here. If your website is localized into other
languages multiple translations of this field can be
added.")) }}
{% endif %}
added.")) }}
</label>
</th>
<td>

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

@ -40,20 +40,11 @@
<th>
<label data-for="support_url">
{{ _("Website") }}
{% if webapp %}
{# TODO(apps): Finalize copy. #}
{{ tip(None,
"If your app has a support website or forum, enter
{{ tip(None,
_("If your add-on has a support website or forum, enter
its address here. If your website is localized into
other languages, multiple translations of this field can
be added.") }}
{% else %}
{{ tip(None,
_("If your add-on has a support website or forum, enter
its address here. If your website is localized into
other languages, multiple translations of this field can
be added.")) }}
{% endif %}
be added.")) }}
</label>
</th>
<td>

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

@ -19,21 +19,12 @@
<th>
<label data-for="developer_comments">
{{ _("Developer Comments") }}
{% if webapp %}
{{ tip(None,
_("Any information end users may want to know that isn't
necessarily applicable to the app summary or description.
Common uses include listing known major bugs, information on
how to report bugs, anticipated release date of a new version,
etc.")) }}
{% else %}
{{ tip(None,
_("Any information end users may want to know that isn't
necessarily applicable to the add-on summary or description.
Common uses include listing known major bugs, information on
how to report bugs, anticipated release date of a new version,
etc.")) }}
{% endif %}
{{ tip(None,
_("Any information end users may want to know that isn't
necessarily applicable to the add-on summary or description.
Common uses include listing known major bugs, information on
how to report bugs, anticipated release date of a new version,
etc.")) }}
</label>
</th>
<td>

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

@ -7,38 +7,23 @@
<div class="item">
<div class="item_wrapper">
<table>
{% if not webapp %}
<caption>{{ _('Add-on Media for {0}')|f(addon.name) }}</caption>
{% endif %}
<caption>{{ _('Add-on Media for {0}')|f(addon.name) }}</caption>
<tbody>
<tr>
{% if context == 'edit' %}
<th>
{% if webapp %}
{# TODO(apps): Finalize copy. #}
{{ tip('App icon',
"Upload an icon for your app or choose from one of ours. The
icon is displayed nearly everywhere your app is. Uploaded images
must be one of the following image types: .png, .jpg") }}
{% else %}
{{ tip(_("Add-on icon"),
_("Upload an icon for your add-on or choose from one of ours. The
icon is displayed nearly everywhere your add-on is. Uploaded images
must be one of the following image types: .png, .jpg")) }}
{% endif %}
{{ tip(_("Add-on icon"),
_("Upload an icon for your add-on or choose from one of ours. The
icon is displayed nearly everywhere your add-on is. Uploaded images
must be one of the following image types: .png, .jpg")) }}
</th>
{% endif %}
<td>
{% if context == 'submit' %}
<label>
{% if webapp %}
{# TODO(apps): Finalize copy. #}
Select an icon for your app:
{% else %}
{% trans %}
Select an icon for your add-on:
{% endtrans %}
{% endif %}
{% trans %}
Select an icon for your add-on:
{% endtrans %}
</label>
{% endif %}
{% if editable %}
@ -49,16 +34,9 @@
<div class="edit-media-details">
{# L10n: The size of the icon #}
{{ _('32x32px') }}
{% if webapp %}
{# TODO(apps): Finalize copy. #}
{{ tip(None,
'Used in listings of apps, like search results
and featured apps.') }}
{% else %}
{{ tip(None,
_("Used in listings of add-ons, like search results
and featured add-ons.")) }}
{% endif %}
{{ tip(None,
_("Used in listings of add-ons, like search results
and featured add-ons.")) }}
</div>
<div class="icon_preview" id="icon_preview_64">
@ -67,12 +45,7 @@
<div class="edit-media-details">
{# L10n: The size of the icon #}
{{ _('64x64px') }}
{% if webapp %}
{# TODO(apps): Finalize copy. #}
{{ tip(None, 'Used in app detail pages.') }}
{% else %}
{{ tip(None, _("Used in add-on detail pages.")) }}
{% endif %}
{{ tip(None, _("Used in add-on detail pages.")) }}
</div>
</div>
<ul id="icons_default">
@ -112,14 +85,9 @@
<td class="edit-previews-readonly">
{% if context == 'submit' %}
<label>
{% if webapp %}
{# TODO(apps): Finalize copy. #}
Please provide at least one screen shot of your app:
{% else %}
{% trans %}
Please provide at least one screen shot of your add-on:
{% endtrans %}
{% endif %}
{% trans %}
Please provide at least one screen shot of your add-on:
{% endtrans %}
</label>
{% endif %}

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

@ -7,9 +7,7 @@
</h3>
{% if addon.highest_status or addon.status %}
<p class="warning">
{% if webapp %}
{{ loc('Deleting your app will permanently remove it from the site.') }}
{% elif addon.is_persona() %}
{% if addon.is_persona() %}
{{ _('Deleting your theme will permanently remove it from the site.') }}
{% else %}
{% trans %}

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

@ -38,11 +38,6 @@
{% set manage_urls = [
(addon.get_dev_url('versions'), _('Manage Status')),
] %}
{% if addon.is_premium() and waffle.switch('allow-refund') %}
{% do manage_urls.insert(1,
(addon.get_dev_url('refunds'), loc('Manage Refunds'))
) %}
{% endif %}
{% do manage_urls.insert(0,
(addon.get_dev_url('in_app_config'), _('Manage In-App Payments'))
) %}

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

@ -17,22 +17,20 @@
{{ dev_item_info(addon, amo) }}
</div>
<ul class="item-details">
{% if not webapp %}
{% if addon.current_version %}
{% set link = url('devhub.versions.edit', addon.slug, addon.current_version.id) %}
{# L10n: {1} is a version number. #}
<li>{{ _('<strong>Latest version:</strong> <a href="{0}">{1}</a>')|
f(link, addon.current_version) }}</li>
{% endif %}
{% if sorting == 'created' %}
{# L10n: {0} is a date. #}
<li class="date-created">{{ _('<strong>Created:</strong> {0}'|
f(addon.created|datetime)) }}</li>
{% else %}
{# L10n: {0} is a date. #}
<li class="date-updated">{{ _('<strong>Last updated:</strong> {0}'|
f(addon.last_updated|datetime)) }}</li>
{% endif %}
{% if addon.current_version %}
{% set link = url('devhub.versions.edit', addon.slug, addon.current_version.id) %}
{# L10n: {1} is a version number. #}
<li>{{ _('<strong>Latest version:</strong> <a href="{0}">{1}</a>')|
f(link, addon.current_version) }}</li>
{% endif %}
{% if sorting == 'created' %}
{# L10n: {0} is a date. #}
<li class="date-created">{{ _('<strong>Created:</strong> {0}'|
f(addon.created|datetime)) }}</li>
{% else %}
{# L10n: {0} is a date. #}
<li class="date-updated">{{ _('<strong>Last updated:</strong> {0}'|
f(addon.last_updated|datetime)) }}</li>
{% endif %}
<li id="version-status-item">
<strong>{{ _('Status:') }}</strong>
@ -57,14 +55,10 @@
</ul>
{% endif %}
<div class="item-actions">
{% if webapp %}
{% include "devhub/addons/listing/item_actions_app.html" %}
{% if addon.is_persona() %}
{% include "devhub/addons/listing/item_actions_theme.html" %}
{% else %}
{% if addon.is_persona() %}
{% include "devhub/addons/listing/item_actions_theme.html" %}
{% else %}
{% include "devhub/addons/listing/item_actions.html" %}
{% endif %}
{% include "devhub/addons/listing/item_actions.html" %}
{% endif %}
</div>
</div>

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

@ -17,14 +17,12 @@
num)|f(num|numberfmt)|safe }}
{% endwith %}
</p>
{% if not addon.is_webapp() %}
<p class="users">
{% with num=addon.average_daily_users %}
{# L10n: {0} is the number of active users. #}
{{ ngettext("<strong>{0}</strong> active user",
"<strong>{0}</strong> active users",
num)|f(num|numberfmt)|safe }}
{% endwith %}
</p>
{% endif %}
<p class="users">
{% with num=addon.average_daily_users %}
{# L10n: {0} is the number of active users. #}
{{ ngettext("<strong>{0}</strong> active user",
"<strong>{0}</strong> active users",
num)|f(num|numberfmt)|safe }}
{% endwith %}
</p>
{% endmacro %}

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

@ -1,11 +1,7 @@
{% extends "devhub/base.html" %}
{% if webapp %}
{# TODO(apps): Finalize copy. #}
{% set title = 'Manage Authors' %}
{% else %}
{% set title = _('Manage Authors & License') %}
{% endif %}
{% set title = _('Manage Authors & License') %}
{% block title %}
{{ dev_page_title(title, addon) }}
@ -19,9 +15,7 @@
{% block content %}
<header>
{{ dev_breadcrumbs(addon, items=[(None, title)]) }}
{% if not webapp %}
{{ l10n_menu(addon.default_locale) }}
{% endif %}
{{ l10n_menu(addon.default_locale) }}
<h2>{{ title }}</h2>
</header>
<section id="edit-addon" class="primary devhub-form" role="main">
@ -81,24 +75,14 @@
{% include "devhub/includes/addons_edit_nav.html" %}
<div id="author-roles-help" class="popup">
{% if webapp %}
{# TODO(apps): Finalize copy. #}
<p>Apps can have any number of authors with 3 possible roles:</p>
<ul>
<li><b>Owner:</b> Can manage all aspects of the app's listing, including adding and removing other authors</li>
<li><b>Developer:</b> Can manage all aspects of the app's listing, except for adding and removing other authors and managing payments</li>
<li><b>Viewer:</b> Can view the app's settings, but cannot make any changes</li>
</ul>
{% else %}
{% trans %}
<p>Add-ons can have any number of authors with 3 possible roles:</p>
<ul>
<li><b>Owner:</b> Can manage all aspects of the add-on's listing, including adding and removing other authors</li>
<li><b>Developer:</b> Can manage all aspects of the add-on's listing, except for adding and removing other authors and managing payments</li>
<li><b>Viewer:</b> Can view the add-on's settings and statistics, but cannot make any changes</li>
</ul>
{% endtrans %}
{% endif %}
{% trans %}
<p>Add-ons can have any number of authors with 3 possible roles:</p>
<ul>
<li><b>Owner:</b> Can manage all aspects of the add-on's listing, including adding and removing other authors</li>
<li><b>Developer:</b> Can manage all aspects of the add-on's listing, except for adding and removing other authors and managing payments</li>
<li><b>Viewer:</b> Can view the add-on's settings and statistics, but cannot make any changes</li>
</ul>
{% endtrans %}
<p><a href="#" class="cancel close">{{ _('Close') }}</a></p>
</div>
{% endblock %}

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

@ -1,20 +1,17 @@
{% extends "devhub/base.html" %}
{% if webapp %}
{% set title = _('Submit a New App') %}
{% else %}
{% set title = _('Submit a New Add-on') %}
{% endif %}
{% set title = _('Submit a New Add-on') %}
{% block title %}
{{ dev_page_title(title) }}
{% endblock %}
{% block content %}
{% set page_title = _('Submit App') if webapp else _('Submit Add-on') %}
{% set page_title = _('Submit Add-on') %}
<header>
{{ dev_breadcrumbs(items=[(None, page_title)]) }}
<h2 class="{{ 'is_webapp' if webapp else 'is_addon' }}">{{ title }}</h2>
<h2 class="is_addon">{{ title }}</h2>
</header>
<section class="secondary" role="complementary">
{% include "devhub/addons/submit/sidebar.html" %}

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

@ -4,11 +4,7 @@
<h3>Let's talk about {{ addon.name }}</h3>
<p>Right now it's
{% if step %}
{% if addon.is_webapp() %}
on <b><a href="{{ url('devhub.submit_apps.{0}'.format(step.step), addon.slug) }}">step {{ step.step }}</a></b>.
{% else %}
on <b><a href="{{ url('devhub.submit.{0}'.format(step.step), addon.slug) }}">step {{ step.step }}</a></b>.
{% endif %}
on <b><a href="{{ url('devhub.submit.{0}'.format(step.step), addon.slug) }}">step {{ step.step }}</a></b>.
{% else %}
not in the submission process.
{% endif %}

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

@ -6,26 +6,24 @@
{% block primary %}
<h3>{{ _("You're done!") }}</h3>
{% if not webapp %}
<p>
{% if addon.status == amo.STATUS_UNREVIEWED %}
{% trans %}
Your add-on has been submitted to the Preliminary Review queue.
{% endtrans %}
{% elif addon.status == amo.STATUS_NOMINATED %}
{% trans %}
Your add-on has been submitted to the Full Review queue.
{% endtrans %}
{% endif %}
</p>
<p>
<p>
{% if addon.status == amo.STATUS_UNREVIEWED %}
{% trans %}
You'll receive an email once it has been reviewed by an editor. In
the meantime, you and your friends can install it directly from its
details page:
Your add-on has been submitted to the Preliminary Review queue.
{% endtrans %}
{% elif addon.status == amo.STATUS_NOMINATED %}
{% trans %}
Your add-on has been submitted to the Full Review queue.
{% endtrans %}
</p>
{% endif %}
</p>
<p>
{% trans %}
You'll receive an email once it has been reviewed by an editor. In
the meantime, you and your friends can install it directly from its
details page:
{% endtrans %}
</p>
<p>
<a id="submitted-addon-url" href="{{ addon.get_url_path() }}">
{{ addon.get_url_path()|absolutify|display_url }}</a>
@ -43,24 +41,18 @@
{% set profile_url = addon.get_dev_url('profile') %}
<li>{{ _('Tell your users why you created this in your <a href="{0}">Developer Profile</a>.')|f(profile_url) }}</li>
{% set feed_url = url('devhub.feed', addon.slug) %}
{% if webapp %}
<li>{{ _('View and subscribe to your app\'s <a href="{0}">activity feed</a> to stay updated on reviews, collections, and more.')|f(feed_url) }}</li>
{% else %}
<li>{{ _('View and subscribe to your add-on\'s <a href="{0}">activity feed</a> to stay updated on reviews, collections, and more.')|f(feed_url) }}</li>
<li>{{ _('View approximate review queue <a href="{0}">wait times</a>.')|f('https://forums.addons.mozilla.org/viewforum.php?f=21') }}</li>
{% endif %}
<li>{{ _('View and subscribe to your add-on\'s <a href="{0}">activity feed</a> to stay updated on reviews, collections, and more.')|f(feed_url) }}</li>
<li>{{ _('View approximate review queue <a href="{0}">wait times</a>.')|f('https://forums.addons.mozilla.org/viewforum.php?f=21') }}</li>
</ul>
</div>
{% if not webapp %}
<div id="editor-pitch" class="action-needed">
<h3>{{ _('Get Ahead in the Review Queue!') }}</h3>
<p>
{{ _('Become an AMO Reviewer today and get your add-ons reviewed faster.') }}
<a class="button learn-more" href="https://wiki.mozilla.org/AMO:Editors">
{{ _('Learn More') }}</a>
</p>
</div>
{% endif %}
<div id="editor-pitch" class="action-needed">
<h3>{{ _('Get Ahead in the Review Queue!') }}</h3>
<p>
{{ _('Become an AMO Reviewer today and get your add-ons reviewed faster.') }}
<a class="button learn-more" href="https://wiki.mozilla.org/AMO:Editors">
{{ _('Learn More') }}</a>
</p>
</div>
{% endblock %}

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

@ -1,25 +1,15 @@
{# Steps below HAS_ADDON don't have an addon associated. Once we have an
addon we can't go back below that line. #}
{% set HAS_ADDON = 3 %}
{% if webapp %}
{% set NAV = (_('Getting Started'),
_('Link your app'),
_('Describe your app'),
_('Add images'),
_("You're done!")) %}
{% set MAX = 5 %}
{% set BASE = 'devhub.submit_apps.%s' %}
{% else %}
{% set NAV = (_('Getting Started'),
_('Upload your add-on'),
_('Describe your add-on'),
_('Add images'),
_('Select a license'),
_('Select a review process'),
_("You're done!")) %}
{% set MAX = 7 %}
{% set BASE = 'devhub.submit.%s' %}
{% endif %}
{% set NAV = (_('Getting Started'),
_('Upload your add-on'),
_('Describe your add-on'),
_('Add images'),
_('Select a license'),
_('Select a review process'),
_("You're done!")) %}
{% set MAX = 7 %}
{% set BASE = 'devhub.submit.%s' %}
<div class="highlight">
<hgroup>
<h3>{{ _('Submission Process') }}</h3>

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

@ -4,29 +4,21 @@
{% block primary %}
<h3>{{ _('Step 1. Getting Started') }}</h3>
{% if webapp %}
<p>
{% with url="https://developer.mozilla.org/en-US/docs/Apps/Manifest" %}
{{ loc('To list your app, we need to know where to find it. Give us the URL
to your <a href="{url}">manifest</a> below.</a>')|f(url=url)|safe }}
{% endwith %}
{% trans %}
Hosting your add-on in our gallery is the best way to expose your work
to millions of Firefox users. We'll provide everything you need to
distribute and update your add-on for free.
{% endtrans %}
</p>
<p>
{% trans %}
To complete this submission process you'll need your add-on
package (.xpi, .jar, or .xml) and at least one screenshot of
your add-on in action.
{% endtrans %}
</p>
{% else %}
<p>
{% trans %}
Hosting your add-on in our gallery is the best way to expose your work
to millions of Firefox users. We'll provide everything you need to
distribute and update your add-on for free.
{% endtrans %}
</p>
<p>
{% trans %}
To complete this submission process you'll need your add-on
package (.xpi, .jar, or .xml) and at least one screenshot of
your add-on in action.
{% endtrans %}
</p>
{% endif %}
<p>
{% trans %}
@ -35,21 +27,14 @@
{% endtrans %}
</p>
<div id="agreement-container">
{% if webapp %}
{% include 'amo/developer_webapp_agreement.html' %}
{% else %}
{% include 'amo/developer_agreement.html' %}
{% endif %}
{% include 'amo/developer_agreement.html' %}
</div>
<div id="agreement-extra-links">
<a href="{{ url('devhub.docs', 'policies', 'agreement') }}">
{{ _('Printable Version') }}</a>
{# TODO: Add link to "App Policies" once fligtar authors it (bug 699882). #}
{% if not webapp %}
<span>&bull;</span>
<a href="{{ url('devhub.docs', 'policies') }}">
{{ _('Additional Add-on Policies') }}</a>
{% endif %}
<span>&bull;</span>
<a href="{{ url('devhub.docs', 'policies') }}">
{{ _('Additional Add-on Policies') }}</a>
</div>
<div class="submit-buttons">
<form method="post" action="">

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

@ -1,45 +0,0 @@
{% extends "devhub/addons/submit/base.html" %}
{% block title %}{{ dev_page_title(_('Step 2'), addon) }}{% endblock %}
{% block primary %}
{# TODO(apps): Finalize copy. #}
<h3>{{ _('Step 2. Link to Your App') }}</h3>
<p>
{% with url="https://developer.mozilla.org/en-US/docs/Apps/Manifest" %}
{{ loc('You\'re about to submit your app for all the world to see. All
you need to complete this process is a working
<a href="{url}">manifest</a> for your app.')|f(url=url)|safe }}
{% endwith %}
</p>
<section id="upload-file">
<div class="upload-status">
<label>{{ loc('Submit your app manifest by URL:') }}
<form id="validate-field">
<div class="vf-text">
<input id="upload-webapp-url" name="manifest" class="large"
placeholder="http://" data-upload-url="{{ url('devhub.upload_manifest') }}">
</div>
<div class="vf-button">
<button type="submit" id="validate_app">{{ _('Validate') }}</button>
</div>
</form>
</label>
<div class="upload-details">
<div id="validate-error-protocol" class="pretty-tooltip tl">
<strong>Don't forget a protocol!</strong> Try adding either <a href="#">http://</a> or <a href="#">https://</a>.
</div>
<div>
{{ loc('App URLs must start with a protocol (for example, http:// or https://) and end with either .webapp or .json.') }}
</div>
</div>
</div>
<form method="post" id="upload-webapp" action="">
{{ csrf() }}
<div class="hidden">
{{ new_addon_form.upload }}
</div>
<button class="upload-file-submit" type="submit">{{ _('Continue') }}</button>
</form>
</section>
{% endblock primary %}

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

@ -1,13 +1,9 @@
{% if webapp or WEBAPPS %}
{% set webapp, WEBAPPS = True, True %}
{% endif %}
{% extends "base.html" %}
{% if addon %}
{% set editable = "no-edit" if not check_addon_ownership(request, addon, dev=True) %}
{% endif %}
{% block bodyclass %}developer-hub{{ ' apps' if webapp }} {{ editable }}{% endblock %}
{% block bodyclass %}developer-hub {{ editable }}{% endblock %}
{# Don't show the amo header on devhub pages #}
{% set hide_header = True %}
@ -29,9 +25,7 @@
{% endblock %}
{% block site_header_title %}
{% with webapp=webapp %}
{% include "devhub/nav.html" %}
{% endwith %}
{% include "devhub/nav.html" %}
{% endblock %}
{% block search_form %}
@ -45,16 +39,6 @@
{% endblock %}
{% set hide_mobile_link=True %}
{% block footer %}
{% if webapp %}
{% with hide_mobile_link=True %}
{% include "amo_footer_small.html" %}
{% endwith %}
{% else %}
{{ super() }}
{% endif %}
{% endblock %}
{% block footer_extras %}
<img class="footerlogo" src="{{ media('img/developers/hub-logo-footer.png') }}" alt="">
{% endblock %}

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

@ -1,13 +1,9 @@
{% if webapp or WEBAPPS %}
{% set webapp, WEBAPPS = True, True %}
{% endif %}
{% extends "impala/base.html" %}
{% if addon %}
{% set editable = "no-edit" if not check_addon_ownership(request, addon, dev=True) %}
{% endif %}
{% block bodyclass %}developer-hub{{ ' apps' if webapp }} gutter {{ editable }}{% endblock %}
{% block bodyclass %}developer-hub gutter {{ editable }}{% endblock %}
{% block bodyattrs %}
{% if addon %}data-default-locale="{{ addon.default_locale|lower }}"{% endif %}
@ -26,9 +22,7 @@
{% endblock %}
{% block site_header_title %}
{% with webapp=webapp %}
{% include "devhub/nav.html" %}
{% endwith %}
{% include "devhub/nav.html" %}
{% endblock %}
{% block search_form %}
@ -40,15 +34,6 @@
{% endblock %}
{% set hide_mobile_link=True %}
{% block footer %}
{% if webapp %}
{% with hide_mobile_link=True %}
{% include "amo_footer_small.html" %}
{% endwith %}
{% else %}
{{ super() }}
{% endif %}
{% endblock %}
{% block footer_extras %}
<img class="footerlogo" src="{{ media('img/developers/hub-logo-footer.png') }}" alt="">

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

@ -6,11 +6,7 @@
{% if addon.takes_contributions %}
{{ required() }}
<span class="req">
{% if webapp %}
{{ loc('(required since this app accepts contributions)') }}
{% else %}
{{ _('(required since this add-on accepts contributions)') }}
{% endif %}
{{ _('(required since this add-on accepts contributions)') }}
</span>
{% else %}
{{ optional() }}
@ -25,18 +21,12 @@
{% endif %}
<p>
{% if webapp %}
{{ _("Your developer profile will tell users about you, why you made this
app, and what's next for the app. This profile can be useful for
any developer interested in connecting with users.") }}
{% else %}
{% trans %}
Your developer profile will tell users about you, why you made this
add-on, and what's next for the add-on. This profile is required for
add-ons requesting contributions, but can be useful for any developer
interested in connecting with users.
{% endtrans %}
{% endif %}
{% trans %}
Your developer profile will tell users about you, why you made this
add-on, and what's next for the add-on. This profile is required for
add-ons requesting contributions, but can be useful for any developer
interested in connecting with users.
{% endtrans %}
</p>
<h4>{{ _('Make sure your user profile is up to date.') }}</h4>

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

@ -1,20 +1,10 @@
{% set urls = [
(addon.get_dev_url(), _('Edit Listing')),
(addon.get_dev_url('owner'), _('Manage Authors') if webapp
else _('Manage Authors & License')),
(addon.get_dev_url('owner'), _('Manage Authors & License')),
(addon.get_dev_url('profile'), _('Manage Developer Profile')),
(addon.get_dev_url('payments'), _('Manage Payments')),
(addon.get_dev_url('versions'), _('Manage App Status') if webapp
else _('Manage Status & Versions')),
(addon.get_dev_url('versions'), _('Manage Status & Versions')),
] %}
{% if addon.is_premium() and waffle.switch('allow-refund') %}
{% do urls.insert(4, (addon.get_dev_url('refunds'), loc('Manage Refunds'))) %}
{% endif %}
{% if addon.is_webapp() %}
{% do urls.insert(4,
(addon.get_dev_url('in_app_config'), _('Manage In-App Payments'))
) %}
{% endif %}
<section class="secondary" role="complementary">
<div class="highlight" id="edit-addon-nav">

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

@ -62,18 +62,14 @@
</tr>
{% endmacro %}
{% macro select_cats(max, form, webapp=False) %}
{% macro select_cats(max, form) %}
<div class="addon-app-cats">
<label>
{% if webapp %}
{{ loc('Select <b>up to {0}</b> categories for this app:')|f(max)|safe }}
{% else %}
{# L10n: {0} is the maximum number of add-on categories allowed.
{1} is the application name. #}
{{ ngettext('Select <b>up to {0}</b> {1} category for this add-on:',
'Select <b>up to {0}</b> {1} categories for this add-on:',
max)|f(max, form.app.pretty if form.app else '')|safe }}
{% endif %}
</label>
{{ form.application }}
{{ form.categories }}

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

@ -1,103 +1,71 @@
<h1 class="site-title prominent">
<a href="{{ url('devhub.index') }}" title="{{ _('Return to the DevHub homepage') }}">
{% if webapp %}
Apps Developer Preview
{% else %}
{# L10n: Text in small tag is smaller and on its own line. #}
{% trans %}
<small>Add-on</small> Developer Hub
{% endtrans %}
{% endif %}
{# L10n: Text in small tag is smaller and on its own line. #}
{% trans %}
<small>Add-on</small> Developer Hub
{% endtrans %}
</a>
</h1>
<nav id="site-nav" class="menu-nav{{ ' app-nav' if webapp }} no-img c">
<nav id="site-nav" class="menu-nav no-img c">
<ul>
{% if request.user.is_authenticated() and request.amo_user.is_developer %}
{% if webapp %}
<li class="top">
<a href="{{ url('devhub.apps') }}" class="controller">
{{ _('My Apps') }}</a>
<ul>
{% set my_apps = request.amo_user.my_apps() %}
{% for addon in my_apps %}
{% if loop.index == 8 %}
<li><a href="{{ url('devhub.apps') }}">
{{ _('more apps...') }}</a></li>
{% else %}
<li><a href="{{ addon.get_dev_url() }}">
{{ addon.name }}</a></li>
{% endif %}
{% endfor %}
<li><em><a href="{{ url('devhub.submit_apps.1') }}">
{{ _('Submit a New App') }}</a></em></li>
</ul>
</li>
{% else %}
<li class="top">
<a href="{{ url('devhub.addons') }}" class="controller">
{{ _('My Add-ons') }}</a>
<ul>
{% set my_addons = request.amo_user.my_addons() %}
{% for addon in my_addons %}
{% if loop.index == 8 %}
<li><a href="{{ url('devhub.addons') }}">
{{ _('more add-ons...') }}</a></li>
{% else %}
<li><a href="{{ addon.get_dev_url() }}">
{{ addon.name }}</a></li>
{% endif %}
{% endfor %}
<li><em><a href="{{ url('devhub.submit.1') }}">
{{ _('Submit a New Add-on') }}</a></em></li>
</ul>
</li>
{% endif %}
{% endif %}
{% if webapp %}
<li class="slim">
<a href="http://developer.mozilla.org/en-US/apps" class="controller">
{{ _('Documentation') }}</a>
</li>
{% else %}
<li>
<a href="#" class="controller">{{ _('Documentation') }}</a>
<li class="top">
<a href="{{ url('devhub.addons') }}" class="controller">
{{ _('My Add-ons') }}</a>
<ul>
<li><a href="{{ url('devhub.docs', 'getting-started') }}">
{{ _('Getting Started') }}</a></li>
<li><a href="{{ url('devhub.docs', 'policies') }}">
{{ _('Add-on Policies') }}</a></li>
<li><a href="{{ url('devhub.docs', 'case-studies') }}">
{{ _('Case Studies') }}</a></li>
<li><a href="{{ url('devhub.docs', 'how-to') }}">
{{ _('How-to Library') }}</a></li>
<li><a href="{{ url('devhub.docs', 'reference') }}">
{{ _('API &amp; Language Reference') }}</a></li>
<li><a href="{{ url('devhub.docs', 'themes') }}">
{{ _('Themes') }}</a></li>
</ul>
</li>
<li>
<a href="#" class="controller">{{ _('Tools') }}</a>
<ul>
<li><a href="{{ url('devhub.package_addon') }}">
{{ _('Add-on Packager') }}</a></li>
<li><a href="{{ url('devhub.validate_addon') }}">
{{ _('Add-on Validator') }}</a></li>
<li><a href="{{ url('devhub.check_addon_compatibility') }}">
{{ _('Add-on Compatibility Checker') }}</a></li>
<li><a href="{{ remora_url('/collection/devel-tools') }}">
{{ _('Development Add-ons') }}</a></li>
</ul>
</li>
<li>
<a href="#" class="controller">{{ _('Community') }}</a>
<ul>
<li><a href="http://blog.mozilla.com/addons/">
{{ _('Add-ons Blog') }}</a></li>
<li><a href="https://forums.addons.mozilla.org">
{{ _('Add-ons Forum') }}</a></li>
{% set my_addons = request.amo_user.my_addons() %}
{% for addon in my_addons %}
{% if loop.index == 8 %}
<li><a href="{{ url('devhub.addons') }}">
{{ _('more add-ons...') }}</a></li>
{% else %}
<li><a href="{{ addon.get_dev_url() }}">
{{ addon.name }}</a></li>
{% endif %}
{% endfor %}
<li><em><a href="{{ url('devhub.submit.1') }}">
{{ _('Submit a New Add-on') }}</a></em></li>
</ul>
</li>
{% endif %}
<li>
<a href="#" class="controller">{{ _('Documentation') }}</a>
<ul>
<li><a href="{{ url('devhub.docs', 'getting-started') }}">
{{ _('Getting Started') }}</a></li>
<li><a href="{{ url('devhub.docs', 'policies') }}">
{{ _('Add-on Policies') }}</a></li>
<li><a href="{{ url('devhub.docs', 'case-studies') }}">
{{ _('Case Studies') }}</a></li>
<li><a href="{{ url('devhub.docs', 'how-to') }}">
{{ _('How-to Library') }}</a></li>
<li><a href="{{ url('devhub.docs', 'reference') }}">
{{ _('API &amp; Language Reference') }}</a></li>
<li><a href="{{ url('devhub.docs', 'themes') }}">
{{ _('Themes') }}</a></li>
</ul>
</li>
<li>
<a href="#" class="controller">{{ _('Tools') }}</a>
<ul>
<li><a href="{{ url('devhub.package_addon') }}">
{{ _('Add-on Packager') }}</a></li>
<li><a href="{{ url('devhub.validate_addon') }}">
{{ _('Add-on Validator') }}</a></li>
<li><a href="{{ url('devhub.check_addon_compatibility') }}">
{{ _('Add-on Compatibility Checker') }}</a></li>
<li><a href="{{ remora_url('/collection/devel-tools') }}">
{{ _('Development Add-ons') }}</a></li>
</ul>
</li>
<li>
<a href="#" class="controller">{{ _('Community') }}</a>
<ul>
<li><a href="http://blog.mozilla.com/addons/">
{{ _('Add-ons Blog') }}</a></li>
<li><a href="https://forums.addons.mozilla.org">
{{ _('Add-ons Forum') }}</a></li>
</ul>
</li>
</ul>
</nav>

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

@ -1,54 +0,0 @@
{% extends "devhub/base.html" %}
{% set title = _('Manage In-App Payments') %}
{% block title %}{{ dev_page_title(title, addon) }}{% endblock %}
{% set can_edit = check_addon_ownership(request, addon) %}
{% block bodyclass %}
{{ super() }}{% if not can_edit %} no-edit{% endif %}
{% endblock %}
{% block content %}
<header>
{{ dev_breadcrumbs(addon, items=[(None, title)]) }}
<h2>{{ title }}</h2>
</header>
<section id="in-app-config" class="primary devhub-form" role="main">
<form class="item in-app-config" method="post" action="{{ request.path }}">
{{ csrf() }}
<div class="item_wrapper">
<table>
<tr>
<th>{{ _('Application Domain') }}</th>
<td>https://{{ addon.app_domain }}</td>
</tr>
{{ inapp_form.as_table() }}
<tr id="in-app-public-key">
<th>{{ _('Application Key') }}</th>
{% if inapp_config %}
<td><input type="text" value="{{ inapp_config.public_key }}" readonly></td>
{% else %}
<td class="not-generated">({{ _('Not yet generated.') }})</td>
{% endif %}
</tr>
<tr id="in-app-private-key">
<th>{{ _('Application Secret') }}</th>
{% if inapp_config %}
<td>
<button data-url="{{ addon.get_dev_url('in_app_secret') }}"
class="generator">{{ _('Show secret') }}</button>
<input class="secret" type="text" value="" readonly>
</td>
{% else %}
<td class="not-generated">({{ _('Not yet generated.') }})</td>
{% endif %}
</tr>
</table>
</div>
<div class="listing-footer">
<button type="submit">{{ _('Save Changes') }}</button>
</div>
</form>
</section>
{% include "devhub/includes/addons_edit_nav.html" %}
{% endblock %}

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

@ -1,19 +0,0 @@
<div id="org-dev" class="brform paypal">
<label for="id_paypal_id">{{ loc('What is your PayPal email address?') }}</label>
{{ form.paypal_id.errors }}
<div>
{{ form.paypal_id }}<div id="paypal-id-verify" data-url="{{ url('devhub.check_paypal') }}"></div>
<div id="paypal-id-error"></div>
</div>
</div>
<div class="brform">
<label for="id_support_email">{{ form.support_email.label }}</label>
<div class="extra">
<p>
{% trans %}The email address used by end users to contact you
with support issues and refund requests.{% endtrans %}
</p>
</div>
{{ form.support_email.errors }}
<div>{{ form.support_email }}</div>
</div>

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

@ -1,13 +0,0 @@
<div class="brform">
<label for="id_price">{{ form.price.label }}</label>
<div class="extra">
<p>
{% trans doc_url='https://developer.mozilla.org/en-US/docs/Apps/Marketplace_Payments#Price_tiers' %}
Select a price tier below. Price tiers are based on US Dollars and are fixed for all supported countries.
For more information <a href="{{ doc_url }}">view our pricing matrix</a>.
{% endtrans %}
</p>
</div>
{{ form.price.errors }}
<div>{{ form.price }}</div>
</div>

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

@ -1,26 +0,0 @@
{% from 'devhub/includes/macros.html' import some_html_tip %}
<div class="brform">
{% if form.fields['free'].queryset.count() %}
{{ form.do_upsell.errors }}
{{ form.do_upsell }}
<div class="indent">
{{ form.free.errors }}
<p>{{ form.free }}</p>
</div>
{% else %}
<label>{{ loc('App upsell') if webapp else _('Add-on upsell') }}</label>
<div class="extra">
{% if webapp %}
{% trans %}
If you have a free app, you can pitch your premium app
on that free app. Currently you have no free apps.
{% endtrans %}
{% else %}
{% trans %}
If you have a free add-on, you can pitch your premium add-on
on that free add-on. Currently you have no free add-ons.
{% endtrans %}
{% endif %}
</div>
{% endif %}
</div>

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

@ -1,49 +0,0 @@
{% extends 'devhub/base_impala.html' %}
{% set title = _('Issue Refund') %}
{% block title %}{{ dev_page_title(title) }}{% endblock %}
{# TODO(apps): Finalize copy. #}
{% block content %}
<header>
{{ dev_breadcrumbs(addon) }}
<h1>{{ title }}</h1>
</header>
<form method="post" action="" id="issue-refund" class="primary island full c">
{% if transaction_id and enabled %}
{{ csrf() }}
<p>
{% with user=contribution.user.display_name,
user_url=contribution.user.get_url_path(),
addon_url=addon.get_url_path(),
addon_name=addon.name %}
A refund was requested by
<a href="{{ user_url }}" target="_blank">{{ user }}</a> for
<a href="{{ addon_url }}" target="_blank">{{ addon_name }}</a>.
{% endwith %}
</p>
<p>
{% with price=contribution.get_amount_locale() %}
<b>Price:</b> {{ price }}
{% endwith %}
</p>
<p>
{% with purchase_date=contribution.created|datetime %}
<b>Purchase date:</b> {{ purchase_date }}
{% endwith %}
</p>
<p>
<button type="submit" class="good" name="issue">
{{ _('Issue Refund') }}
</button>
<button type="submit" class="bad" name="decline">
{{ _('Decline Refund') }}
</button>
<input type="hidden" name="transaction_id" value="{{ transaction_id }}">
</p>
{% else %}
<p>{{ loc('No refundable transaction found.') }}</p>
{% endif %}
</form>
{% endblock %}

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

@ -1,24 +0,0 @@
{% extends "devhub/base.html" %}
{% from 'devhub/includes/macros.html' import some_html_tip %}
{% set title = _('Manage Payments') %}
{% block title %}{{ dev_page_title(title, addon) }}{% endblock %}
{% block content %}
<header>
{{ dev_breadcrumbs(addon, items=[(None, title)]) }}
<h2>{{ title }}</h2>
</header>
<section class="primary payments devhub-form" role="main">
<h3>{{ _('Step 1. Merchant Account') }}</h3>
<form method="post">
{{ csrf() }}
{% include "devhub/payments/includes/paypal.html" %}
<button type="submit">{{ _('Continue') }}</button>
{% trans cancel=addon.get_dev_url('payments') %}
or <a href="{{ cancel }}">Cancel</a>
{% endtrans %}
</form>
</section>
{% include "devhub/includes/addons_edit_nav.html" %}
{% endblock %}

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

@ -1,44 +0,0 @@
{% extends "devhub/base.html" %}
{% from 'devhub/includes/macros.html' import some_html_tip %}
{% set title = _('Manage Payments') %}
{% block title %}{{ dev_page_title(title, addon) }}{% endblock %}
{% block content %}
<header>
{{ dev_breadcrumbs(addon, items=[(None, title)]) }}
{# l10n_menu(addon.default_locale) #}
<h2>{{ title }}</h2>
</header>
<section class="primary payments devhub-form" role="main">
<h3>{{ _('Step 4. Confirm') }}</h3>
{% if webapp %}
<p>
{{ loc('Please review your Marketplace enrollment details below.
Once you enroll in Marketplace, your app must be reviewed for
compliance with Marketplace policies before it will be
available for sale.') }}
</p>
{% else %}
<p>{% trans %}Please review your Marketplace enrollment details below.
Once you enroll in Marketplace, your add-on must be reviewed for
compliance with Marketplace policies before it will be available for sale.
{% endtrans %}</p>
{% endif %}
<form method="post">
{{ csrf() }}
<h3>{{ addon.name }}</h3>
<ul>
<li>{% trans price=premium.price %}Price {{ price }}{% endtrans %}</li>
{% if upsell %}
<li>{% trans name=upsell.free.name %}Premium upgrade to {{ name }}{% endtrans %}</li>
{% endif %}
</ul>
<button type="submit">{{ _('Enroll in Marketplace') }}</button>
{% trans cancel=addon.get_dev_url('payments') %}
or <a href="{{ cancel }}">Cancel</a>
{% endtrans %}
</form>
</section>
{% include "devhub/includes/addons_edit_nav.html" %}
{% endblock %}

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

@ -1,26 +0,0 @@
{% extends "devhub/base.html" %}
{% set title = _('Manage Payments') %}
{% block title %}{{ dev_page_title(title, addon) }}{% endblock %}
{% block content %}
<header>
{{ dev_breadcrumbs(addon, items=[(None, title)]) }}
{% if not settings.APP_PREVIEW %}
{{ l10n_menu(addon.default_locale) }}
{% endif %}
<h2>{{ title }}</h2>
</header>
<section class="primary payments devhub-form" role="main">
<h3>{{ _('Step 3. Upsell Settings') }}</h3>
<form method="post">
{{ csrf() }}
{% include "devhub/payments/includes/upsell.html" %}
<button type="submit">{{ _('Continue') }}</button>
{% trans cancel=addon.get_dev_url('payments') %}
or <a href="{{ cancel }}">Cancel</a>
{% endtrans %}
</form>
</section>
{% include "devhub/includes/addons_edit_nav.html" %}
{% endblock %}

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

@ -1,10 +1,6 @@
{% extends "devhub/base.html" %}
{% if webapp %}
{% set title = loc('Manage App Status') %}
{% else %}
{% set title = _('Status & Versions') %}
{% endif %}
{% set title = _('Status & Versions') %}
{% block title %}{{ dev_page_title(title, addon) }}{% endblock %}
{% macro status(msg) %}
@ -21,26 +17,12 @@
<div class="item" id="version-status">
<div>
{% if addon.disabled_by_user and addon.status != amo.STATUS_DISABLED %}
{% if webapp %}
{{ status(loc('You have <b>disabled</b> this app.')|safe) }}
{{ loc("Your app's listing is disabled and is not showing anywhere in
our gallery. You may re-enable it at any time below.") }}
{% else %}
{{ status(_('You have <b>disabled</b> this add-on.')) }}
{{ _("Your add-on's listing is disabled and is not showing anywhere in our gallery or update service. You may re-enable it at any time below.") }}
{% endif %}
{{ status(_('You have <b>disabled</b> this add-on.')) }}
{{ _("Your add-on's listing is disabled and is not showing anywhere in our gallery or update service. You may re-enable it at any time below.") }}
{% elif addon.status == amo.STATUS_NULL %}
{% if webapp %}
{{ status(loc('This app is <b>incomplete</b>.')|safe) }}
{% else %}
{{ status(_('This add-on is <b>incomplete</b>.')) }}
{% endif %}
{{ status(_('This add-on is <b>incomplete</b>.')) }}
<a href="{{ url('devhub.submit.resume', addon.slug) }}">
{% if webapp %}
{{ _('Please complete your app.') -}}
{% else %}
{{ _('Please complete your add-on.') -}}
{% endif %}</a>
{{ _('Please complete your add-on.') -}}
{% elif addon.status == amo.STATUS_PENDING %}
{{ status(loc('This app is <b>awaiting review</b>.')|safe) }}
{{ loc('You will receive an email when the review is complete.') }}
@ -58,39 +40,18 @@
{{ status(_('This add-on is <b>awaiting full review</b>.')) }}
{{ _("You will receive an email when the review is complete. Until then, your add-on is not listed in our gallery but can be accessed directly from its details page. ") }}
{% elif addon.status == amo.STATUS_PUBLIC %}
{% if webapp %}
{{ status(loc('This app is <b>public</b>.')|safe) }}
{{ loc('Your app is displayed in our gallery.') }}
{% else %}
{{ status(_('This add-on has been <b>fully reviewed</b>.')) }}
{{ _("Your add-on is displayed in our gallery and users are receiving automatic updates.") }}
{% endif %}
{{ status(_('This add-on has been <b>fully reviewed</b>.')) }}
{{ _("Your add-on is displayed in our gallery and users are receiving automatic updates.") }}
{% elif addon.status == amo.STATUS_DISABLED %}
{% if webapp %}
{{ status(loc('This app has been <b>disabled by Mozilla</b>.')|safe) }}
{{ loc("Your app was disabled by a site administrator and is no
longer shown in our gallery. If you have any questions,
please email marketplace-staff@mozilla.org.") }}
{% else %}
{{ status(_('This add-on has been <b>disabled by Mozilla</b>.')) }}
{{ _("Your add-on was disabled by a site administrator and is no longer shown in our gallery. If you have any questions, please email marketplace-staff@mozilla.org.") }}
{% endif %}
{{ status(_('This add-on has been <b>disabled by Mozilla</b>.')) }}
{{ _("Your add-on was disabled by a site administrator and is no longer shown in our gallery. If you have any questions, please email marketplace-staff@mozilla.org.") }}
{% endif %}
{% if not webapp %}
{% if addon.status == amo.STATUS_LITE %}
{{ status(_('This add-on has been <b>preliminarily reviewed</b>.')) }}
{{ _("Your add-on is displayed in our gallery as experimental and users are receiving automatic updates. Some features are unavailable to your add-on.") }}
{% elif addon.status == amo.STATUS_LITE_AND_NOMINATED %}
{% if webapp %}
{{ status(loc('This app has been <b>preliminarily reviewed</b> and is <i>awaiting full review</i>.')|safe) }}
{{ loc("You will receive an email when the full review is complete.
Until then, your app is displayed in our gallery as
experimental and users are receiving automatic updates. Some
features are unavailable to your app.") }}
{% else %}
{{ status(_('This add-on has been <b>preliminarily reviewed</b> and is <i>awaiting full review</i>.')) }}
{{ _("You will receive an email when the full review is complete. Until then, your add-on is displayed in our gallery as experimental and users are receiving automatic updates. Some features are unavailable to your add-on.") }}
{% endif %}
{{ status(_('This add-on has been <b>preliminarily reviewed</b> and is <i>awaiting full review</i>.')) }}
{{ _("You will receive an email when the full review is complete. Until then, your add-on is displayed in our gallery as experimental and users are receiving automatic updates. Some features are unavailable to your add-on.") }}
{% elif addon.status == amo.STATUS_PURGATORY %}
{{ status(_('Please select a review option.')) }}
{{ _("All add-ons hosted in our gallery must now be reviewed by an editor. If you wish to continue hosting your add-on, please select a review process from the choices below.") }}
@ -99,147 +60,142 @@
<a href="{{ remora_url('developers/docs/policies/reviews#selection') }}">
{{ _('Learn more') }}</a>
{% endif %}
{% endif %}
<div class="version-status-actions item-actions">
{% if not webapp %}
{% if position %}
<span class="dark" title="{{ _('Queues are not reviewed strictly in order.') }}">
{% trans pos=position['pos'], total=position['total'] %}
Queue Position: {{ pos }} of {{ total }}
{% endtrans %}
&middot;
</span>
{% if position %}
<span class="dark" title="{{ _('Queues are not reviewed strictly in order.') }}">
{% trans pos=position['pos'], total=position['total'] %}
Queue Position: {{ pos }} of {{ total }}
{% endtrans %}
&middot;
</span>
{% endif %}
{% if check_addon_ownership(request, addon, dev=True) %}
{% set req = {amo.STATUS_PUBLIC: _('Request Full Review'),
amo.STATUS_LITE: _('Request Preliminary Review')} %}
{% for status in addon.can_request_review() %}
<form method="post"
action="{{ url('devhub.request-review', addon.slug, status) }}">
{{ csrf() }}
<button class="link" type="submit">{{ req[status] }}</button> &middot;
</form>
{% endfor %}
{% set days = addon.days_until_full_nomination() %}
{% if days != 0 %}
<span class="warning">{{ ngettext('Full nomination will be available in {0} day',
'Full nomination will be available in {0} days',
days)|f(days) }}</span>
{% endif %}
{% if check_addon_ownership(request, addon, dev=True) %}
{% set req = {amo.STATUS_PUBLIC: _('Request Full Review'),
amo.STATUS_LITE: _('Request Preliminary Review')} %}
{% for status in addon.can_request_review() %}
<form method="post"
action="{{ url('devhub.request-review', addon.slug, status) }}">
{{ csrf() }}
<button class="link" type="submit">{{ req[status] }}</button> &middot;
</form>
{% endfor %}
{% set days = addon.days_until_full_nomination() %}
{% if days != 0 %}
<span class="warning">{{ ngettext('Full nomination will be available in {0} day',
'Full nomination will be available in {0} days',
days)|f(days) }}</span>
{% endif %}
{% if not addon.is_disabled and addon.is_under_review %}
<a href="#" id="cancel-review">{{ _('Cancel Review Request') }}</a> &middot;
{% endif %}
{% if not addon.is_disabled and addon.is_under_review %}
<a href="#" id="cancel-review">{{ _('Cancel Review Request') }}</a> &middot;
{% endif %}
{% endif %}
{% if check_addon_ownership(request, addon, dev=True) %}
{% if addon.disabled_by_user and addon.status != amo.STATUS_DISABLED %}
<a href="{{ addon.get_dev_url('enable') }}" id="enable-addon">
{{ loc('Enable App') if webapp else _('Enable Add-on') }}</a>
{{ _('Enable Add-on') }}</a>
{% elif not addon.is_disabled %}
<a href="#" id="disable-addon">
{{ loc('Disable App') if webapp else _('Disable Add-on') }}</a>
{{ _('Disable Add-on') }}</a>
{% endif %}
{% endif %}
{% if check_addon_ownership(request, addon) and addon.can_be_deleted() %}
&middot; <a href="#" id="delete-addon">
{{ loc('Delete App') if webapp else _('Delete Add-on') }}</a>
{{ _('Delete Add-on') }}</a>
{% endif %}
{% if not webapp %}
{% set current = addon.current_version %}
{% if current %}
<span class="version-changed">
{{ _('Displayed version: {0}')|f(current.version) }}
</span>
{% endif %}
{% set current = addon.current_version %}
{% if current %}
<span class="version-changed">
{{ _('Displayed version: {0}')|f(current.version) }}
</span>
{% endif %}
</div>
</div>
</div>
{% if not webapp %}
<h3>{{ _('Version History') }}</h3>
<div class="item" id="version-list"
data-stats="{{ url('devhub.versions.stats', addon.slug) }}">
<div class="item_wrapper">
<table>
<tr>
<th>{{ _('Version') }}</th>
<th>{{ _('Submitted') }}</th>
<th>{{ _('Status') }}</th>
<th>{{ _('Validation') }}</th>
{% if waffle.flag('perf-tests') %}
<th>{{ _('Performance') }}</th>
{% endif %}
<th class="version-delete">{{ _('Delete') }}</th>
</tr>
<tr>
<td colspan="0">
<a href="#" class="button version-upload">{{ _('Upload a New Version') }}</a>
</td>
</tr>
{% for version in versions.object_list %}
<tr>
<td>
<strong>
<a href="{{ url('devhub.versions.edit', addon.slug, version.id) }}"
title="{{ _('Edit this version') }}">
{{ _('Version {0}', 'addon_display_header_version')|f(version.version) }}</a>
</strong>
</td>
<td>
<span title="{{ version.created|isotime }}">
{{ version.created|datetime }}
</span>
</td>
<td class="file-status">
{% for count, status in dev_files_status(version.all_files, addon) %}
<div>
{# L10n: {0} is the number of files, {1} is the status #}
{{ ngettext('{0} file is {1}', '{0} files are {1}', count)|f(count, status) }}
</div>
{% else %}
{{ _('0 files') }}
{% endfor %}
</td>
<td class="file-validation">
<ul>
{% for file in version.all_files %}
<li>{{ file.platform }}
<ul>
{% if file.has_been_validated %}
<li><a href="{{ url('devhub.file_validation', addon.slug, file.id) }}">
{{ summarize_validation(file.validation) }}</a></li>
{% else %}
<li>{{ _('Not validated.') }}
<a href="{{ url('devhub.file_validation', addon.slug, file.id) }}">
{{ _('Validate now.') }}</a>
</li>
{% endif %}
</ul>
<h3>{{ _('Version History') }}</h3>
<div class="item" id="version-list"
data-stats="{{ url('devhub.versions.stats', addon.slug) }}">
<div class="item_wrapper">
<table>
<tr>
<th>{{ _('Version') }}</th>
<th>{{ _('Submitted') }}</th>
<th>{{ _('Status') }}</th>
<th>{{ _('Validation') }}</th>
{% if waffle.flag('perf-tests') %}
<th>{{ _('Performance') }}</th>
{% endif %}
<th class="version-delete">{{ _('Delete') }}</th>
</tr>
<tr>
<td colspan="0">
<a href="#" class="button version-upload">{{ _('Upload a New Version') }}</a>
</td>
</tr>
{% for version in versions.object_list %}
<tr>
<td>
<strong>
<a href="{{ url('devhub.versions.edit', addon.slug, version.id) }}"
title="{{ _('Edit this version') }}">
{{ _('Version {0}', 'addon_display_header_version')|f(version.version) }}</a>
</strong>
</td>
<td>
<span title="{{ version.created|isotime }}">
{{ version.created|datetime }}
</span>
</td>
<td class="file-status">
{% for count, status in dev_files_status(version.all_files, addon) %}
<div>
{# L10n: {0} is the number of files, {1} is the status #}
{{ ngettext('{0} file is {1}', '{0} files are {1}', count)|f(count, status) }}
</div>
{% else %}
{{ _('0 files') }}
{% endfor %}
</td>
<td class="file-validation">
<ul>
{% for file in version.all_files %}
<li>{{ file.platform }}
<ul>
{% if file.has_been_validated %}
<li><a href="{{ url('devhub.file_validation', addon.slug, file.id) }}">
{{ summarize_validation(file.validation) }}</a></li>
{% else %}
<li>{{ _('Not validated.') }}
<a href="{{ url('devhub.file_validation', addon.slug, file.id) }}">
{{ _('Validate now.') }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
</ul>
</li>
{% endfor %}
</ul>
</td>
{% if waffle.flag('perf-tests') %}
<td class="perf-tests">
{% include "devhub/addons/listing/perf_file_listing.html" %}
</td>
{% if waffle.flag('perf-tests') %}
<td class="perf-tests">
{% include "devhub/addons/listing/perf_file_listing.html" %}
</td>
{% endif %}
<td class="version-delete">
<a href="#" class="remove" data-version="{{ version.id }}">x</a>
</td>
</tr>
{% endfor %}
</table>
</div>
{% if versions.paginator.num_pages > 1 %}
<div class="listing-footer">
{{ versions|paginator }}
</div>
{% endif %}
{% endif %}
<td class="version-delete">
<a href="#" class="remove" data-version="{{ version.id }}">x</a>
</td>
</tr>
{% endfor %}
</table>
</div>
{% if versions.paginator.num_pages > 1 %}
<div class="listing-footer">
{{ versions|paginator }}
</div>
{% endif %}
</div>
</section>
@ -251,75 +207,64 @@
</div>
{% endif %}
{% if not webapp %}
<div id="modal-delete-version" class="modal modal-delete">
<form method="post" action="{{ url('devhub.versions.delete', addon.slug) }}">
<h3 data-tmpl="{{ _('Delete Version {version}') }}"></h3>
<p>{{ _('Deleting this version will permanently delete:') }}</p>
<ul>
<li id="del-files"></li>
<li id="del-reviews"></li>
</ul>
<p>
{% trans %}
<strong>Important:</strong>
Once a version has been deleted, you may not upload a new
version with the same version number.
{% endtrans %}
<p>{{ _('Deleting a version which has already been reviewed
may also cause a significant delay in the review of
your next update.') }}</p>
<p>{{ _('Are you sure you wish to delete this version?') }}</p>
{{ csrf() }}
<div class="modal-actions">
<input type="hidden" name="version_id" class="version_id">
<input type="hidden" name="addon_id" class="addon_id" value="{{ addon.id }}">
<button type="submit" class="delete-button">{{ _('Delete Version') }}</button>
<button type="submit" class="disable-button" name="disable_version">
{{ _('Disable Version') }}
</button>
{{ _('or') }} <a href="#" class="close">{{ _('Cancel') }}</a>
</div>
</form>
</div>
<div id="modal-delete-version" class="modal modal-delete">
<form method="post" action="{{ url('devhub.versions.delete', addon.slug) }}">
<h3 data-tmpl="{{ _('Delete Version {version}') }}"></h3>
<p>{{ _('Deleting this version will permanently delete:') }}</p>
<ul>
<li id="del-files"></li>
<li id="del-reviews"></li>
</ul>
<p>
{% trans %}
<strong>Important:</strong>
Once a version has been deleted, you may not upload a new
version with the same version number.
{% endtrans %}
<p>{{ _('Deleting a version which has already been reviewed
may also cause a significant delay in the review of
your next update.') }}</p>
<p>{{ _('Are you sure you wish to delete this version?') }}</p>
{{ csrf() }}
<div class="modal-actions">
<input type="hidden" name="version_id" class="version_id">
<input type="hidden" name="addon_id" class="addon_id" value="{{ addon.id }}">
<button type="submit" class="delete-button">{{ _('Delete Version') }}</button>
<button type="submit" class="disable-button" name="disable_version">
{{ _('Disable Version') }}
</button>
{{ _('or') }} <a href="#" class="close">{{ _('Cancel') }}</a>
</div>
</form>
</div>
{{ add_version_modal(_("Add a new Version"),
url('devhub.versions.add', addon.slug),
url('devhub.upload_for_addon', addon.slug), _("Add Version") )}}
{% endif %}
{{ add_version_modal(_("Add a new Version"),
url('devhub.versions.add', addon.slug),
url('devhub.upload_for_addon', addon.slug), _("Add Version") )}}
{% if not addon.disabled_by_user and not addon.is_disabled %}
<div id="modal-disable" class="modal">
<form method="post" action="{{ addon.get_dev_url('disable') }}">
<h3>
{{ loc('Disable App') if webapp else _('Disable Add-on') }}
{{ _('Disable Add-on') }}
</h3>
<p>
{% if webapp %}
{{ loc('Disabling your app will prevent it from appearing anywhere
in our gallery.') }}
{% else %}
{% trans %}
Disabling your add-on will prevent it from appearing anywhere in our
gallery and will stop users from receiving automatic updates.
{% endtrans %}
{% endif %}
{% trans %}
Disabling your add-on will prevent it from appearing anywhere in our
gallery and will stop users from receiving automatic updates.
{% endtrans %}
</p>
<p>
{% if webapp %}
{{ loc('Are you sure you wish to disable your app?') }}
{% else %}
{% trans %}
Are you sure you wish to disable your add-on?
{% endtrans %}
{% endif %}
{% trans %}
Are you sure you wish to disable your add-on?
{% endtrans %}
</p>
{{ csrf() }}
<input type="hidden" name="version_id" class="version_id">
<input type="hidden" name="addon_id" class="addon_id" value="{{ addon.id }}">
<p>
<button type="submit">
{{ loc('Disable App') if webapp else _('Disable Add-on') }}
{{ _('Disable Add-on') }}
</button>
{{ _('or') }} <a href="#" class="close">{{ _('Cancel') }}</a>
</p>
@ -327,7 +272,7 @@
</div>
{% endif %}
{% if not webapp and not addon.is_disabled and addon.is_under_review %}
{% if not addon.is_disabled and addon.is_under_review %}
<div id="modal-cancel" class="modal">
<form method="post" action="{{ url('devhub.addons.cancel', addon.slug) }}">
<h3>{{ _('Cancel Review Request') }}</h3>

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

@ -41,8 +41,6 @@
{{ dependencies_note(addon, 'discovery') }}
{{ upsell_note(addon, 'discovery') }}
{% if addon.type != amo.ADDON_PERSONA %}
{% if addon.all_previews|length > 0 %}
<div id="images">

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

@ -29,5 +29,4 @@
{% if settings.PERF_THRESHOLD and addon.ts_slowness >= settings.PERF_THRESHOLD %}
{{ performance_note(amount=addon.ts_slowness) }}
{% endif %}
{{ upsell_note(addon, 'discovery') }}
{% endblock %}

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

@ -1,110 +0,0 @@
import hashlib
import logging
import uuid
from tower import ugettext as _
import paypal
log = logging.getLogger('z.paypal')
class Check(object):
"""
Run a series of tests on PayPal for either an addon or a paypal_id.
The add-on is not required, but we'll do another check or two if the
add-on is there.
"""
def __init__(self, addon=None, paypal_id=None):
# If this state flips to False, it means they need to
# go to Paypal and re-set up permissions. We'll assume the best.
self.state = {'permissions': True}
self.tests = ['id', 'refund']
for test in self.tests:
# Three states for pass:
# None: haven't tried
# False: tried but failed
# True: tried and passed
self.state[test] = {'pass': None, 'errors': []}
self.addon = addon
self.paypal_id = paypal_id
if not self.paypal_id and self.addon:
self.paypal_id = self.addon.paypal_id
def all(self):
self.check_id()
self.check_refund()
def failure(self, test, msg):
self.state[test]['errors'].append(msg)
self.state[test]['pass'] = False
def pass_(self, test):
self.state[test]['pass'] = True
def check_id(self):
"""Check that the paypal id is good."""
test_id = 'id'
if not self.paypal_id:
self.failure(test_id, _('No PayPal ID provided.'))
return
valid, msg = paypal.check_paypal_id(self.paypal_id)
if not valid:
self.failure(test_id, _('Please enter a valid email.'))
else:
self.pass_(test_id)
def check_refund(self):
"""Check that we have the refund permission."""
test_id = 'refund'
msg = _('You have not setup permissions for us to check this '
'PayPal account.')
if not self.addon:
# If there's no addon there's not even any point checking.
return
premium = self.addon.premium
if not premium:
self.state['permissions'] = False
self.failure(test_id, msg)
return
def test_paykey(self, data):
"""
Wraps get_paykey filling none optional data with test data. This
should never ever be used for real purchases.
The only things that you can set on this are:
email: who the money is going to (required)
amount: the amount of money (required)
currency: valid paypal currency, defaults to USD (optional)
"""
data.update({
'pattern': '',
'ip': '127.0.0.1',
'slug': 'foo',
'uuid': hashlib.md5(str(uuid.uuid4())).hexdigest()
})
return paypal.get_paykey(data)
@property
def passed(self):
"""Returns a boolean to check that all the attempted tests passed."""
values = [self.state[k] for k in self.tests]
passes = [s['pass'] for s in values if s['pass'] is not None]
if passes:
return all(passes)
return False
@property
def errors(self):
errs = []
for k in self.tests:
if self.state[k]['pass'] is False:
for err in self.state[k]['errors']:
errs.append(err)
return errs

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

@ -1,20 +0,0 @@
from django.shortcuts import render
import paypal
def handle_paypal_error(fn):
"""Wraps the view so that if a paypal error occurs, you show
a more menaningful error message. May or may not make sense for
all views, so providing as a decorator."""
def wrapper(request, *args, **kw):
try:
return fn(request, *args, **kw)
except paypal.PaypalError:
# This is specific handling for the submission step.
dest = request.GET.get('dest')
return render(request, 'site/500_paypal.html',
{'submission': dest == 'submission',
'addon': kw.get('addon', None)},
status=500)
return wrapper

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

@ -1,48 +0,0 @@
from decimal import Decimal
from mock import Mock, patch
from nose.tools import eq_
import amo
import amo.tests
from paypal.check import Check
from paypal import PaypalError
class TestCheck(amo.tests.TestCase):
def setUp(self):
self.addon = Mock()
self.addon.paypal_id = 'foo@bar.com'
self.addon.premium.paypal_permission_token = 'foo'
self.addon.premium.price.price = Decimal('1.00')
self.addon.premium.price._currencies = {}
self.usd = Mock()
self.usd.price = Decimal('1.0')
self.currency = Mock()
self.currency.currency = 'EUR'
self.currency.price = Decimal('0.5')
self.check = Check(addon=self.addon)
def test_uses_addon(self):
self.check = Check(addon=self.addon)
eq_(self.check.paypal_id, self.addon.paypal_id)
self.check = Check(addon=self.addon, paypal_id='goo@bar.com')
eq_(self.check.paypal_id, 'goo@bar.com')
@patch('paypal.check_paypal_id')
def test_check_id_pass(self, check_paypal_id):
check_paypal_id.return_value = True, ''
self.check.check_id()
assert self.check.passed, self.check.state
@patch('paypal.check_paypal_id')
def test_check_id_fail(self, check_paypal_id):
check_paypal_id.return_value = False, ''
self.check.check_id()
assert not self.check.passed, self.check.state
def test_check_id_none(self):
self.check.paypal_id = None
self.check.check_id()
assert not self.check.passed, self.check.state

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

@ -22,59 +22,31 @@
<div id="reviews" class="primary island hero prettyform c">
<fieldset class="prose">
{% if addon.is_webapp() %}
{# TODO(apps): Finalize copy. #}
{% with support=addon.get_url_path() + "#support",
guide=remora_url('pages/review_guide') %}
<h2>Keep these tips in mind:</h2>
<ul>
<li>
Write like you're telling a friend about your experience with the app.
Give specifics and helpful details, such as what features you liked and/or
disliked, how easy to use it is, and any disadvantages it has. Avoid generic
language such as calling it "Great" or "Bad" unless you can give reasons why
you believe this is so.
</li>
<li>
Please do not post bug reports in reviews. We do not make your email
address available to app developers and they may need to contact you to help
resolve your issue. See the <a href="{{ support }}">support section</a> to find out
where to get assistance for this app.
</li>
<li>Please keep reviews clean, avoid the use of improper language and do not
post any personal information.
</li>
</ul>
{#<p>Please read the <a href="{{ guide }}" target="_blank">Review Guidelines</a> for more detail
about user app reviews.</p>#}
{% endwith %}
{% else %}
{# Text for add-ons: #}
{% trans support=addon.get_url_path() + "#support",
guide=remora_url('pages/review_guide') %}
<h2>Keep these tips in mind:</h2>
<ul>
<li>
Write like you're telling a friend about your experience with the add-on.
Give specifics and helpful details, such as what features you liked and/or
disliked, how easy to use it is, and any disadvantages it has. Avoid generic
language such as calling it "Great" or "Bad" unless you can give reasons why
you believe this is so.
</li>
<li>
Please do not post bug reports in reviews. We do not make your email
address available to add-on developers and they may need to contact you to help
resolve your issue. See the <a href="{{ support }}">support section</a> to find out
where to get assistance for this add-on.
</li>
<li>Please keep reviews clean, avoid the use of improper language and do not
post any personal information.
</li>
</ul>
<p>Please read the <a href="{{ guide }}" target="_blank">Review Guidelines</a> for more detail
about user add-on reviews.</p>
{% endtrans %}
{% endif %}
{# Text for add-ons: #}
{% trans support=addon.get_url_path() + "#support",
guide=remora_url('pages/review_guide') %}
<h2>Keep these tips in mind:</h2>
<ul>
<li>
Write like you're telling a friend about your experience with the add-on.
Give specifics and helpful details, such as what features you liked and/or
disliked, how easy to use it is, and any disadvantages it has. Avoid generic
language such as calling it "Great" or "Bad" unless you can give reasons why
you believe this is so.
</li>
<li>
Please do not post bug reports in reviews. We do not make your email
address available to add-on developers and they may need to contact you to help
resolve your issue. See the <a href="{{ support }}">support section</a> to find out
where to get assistance for this add-on.
</li>
<li>Please keep reviews clean, avoid the use of improper language and do not
post any personal information.
</li>
</ul>
<p>Please read the <a href="{{ guide }}" target="_blank">Review Guidelines</a> for more detail
about user add-on reviews.</p>
{% endtrans %}
</fieldset>
<form method="post" class="review-form" id="review-form"
action="{{ shared_url('reviews.add', addon) }}">

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

@ -23,17 +23,10 @@
{% if page == 'list' %}
<h1>{{ _('Reviews for {0}')|f(addon.name) }}</h1>
{% with num = reviews.paginator.count %}
{% if addon.is_webapp() %}
{# L10n: {0} is a number. #}
<h3>{{ ngettext('<b>{0}</b> review for this app',
'<b>{0}</b> reviews for this app',
num)|f(num|numberfmt)|safe }}</h3>
{% else %}
{# L10n: {0} is a number. #}
<h3>{{ ngettext('<b>{0}</b> review for this add-on',
'<b>{0}</b> reviews for this add-on',
num)|f(num|numberfmt)|safe }}</h3>
{% endif %}
{# L10n: {0} is a number. #}
<h3>{{ ngettext('<b>{0}</b> review for this add-on',
'<b>{0}</b> reviews for this add-on',
num)|f(num|numberfmt)|safe }}</h3>
{% endwith %}
{% elif reply %}
{# L10n: {0} is a developer's name. #}

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

@ -9,10 +9,8 @@
{% if search_form.cat.value() %}
{{ search_form.cat }}
{% endif %}
{% if not WEBAPPS %}
{{ search_form.appver }}
{{ search_form.platform }}
{% endif %}
{{ search_form.appver }}
{{ search_form.platform }}
<button type="submit" value="">
<svg width="22" height="23" xmlns="http://www.w3.org/2000/svg" version="1.1"><polygon fill="#ffffff" points="22,12 11,23 8,20 14,14 0,14 0,10 14,10 8,4 11,1"/></svg>
</button>

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

@ -1,7 +1,4 @@
{% if obj.is_webapp and obj.is_webapp() %}
{% set sharemsg = _('Share this App') %}
{% set listed = True %}
{% elif obj.__class__.__name__ == 'Addon' %}
{% if obj.__class__.__name__ == 'Addon' %}
{% set sharemsg = _('Share this Add-on') %}
{% set listed = True %}
{% elif obj.__class__.__name__ == 'Collection' %}

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

@ -1,5 +0,0 @@
{% trans %}
A reversal has occurred for your payment for {{ name }} from PayPal. Your account has been refunded {{ amount }}.
Thank you for shopping in the Firefox Marketplace.
{% endtrans %}

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

@ -1,4 +1,4 @@
{{ 'App' if addon.is_webapp() else 'Add-on' }}, {{ addon.name }}, has received a new support request:
Add-on, {{ addon.name }}, has received a new support request:
User: {{ user.display_name or user.username }}
Email: {{ user.email }}
Purchased on {{ contribution.date|datetime }}

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

@ -1,40 +0,0 @@
"""
A Marketplace only command that finds apps missing from the search index and
adds them.
"""
import sys
from pyelasticsearch.exceptions import ElasticHttpNotFoundError
from django.core.management.base import BaseCommand
from addons.models import Webapp # To avoid circular import.
from mkt.webapps.models import WebappIndexer
from mkt.webapps.tasks import index_webapps
class Command(BaseCommand):
help = 'Fix up Marketplace index.'
def handle(self, *args, **kwargs):
index = WebappIndexer.get_index()
doctype = WebappIndexer.get_mapping_type_name()
es = WebappIndexer.get_es()
apps = Webapp.objects.values_list('id', flat=True)
missing_ids = []
for app in apps:
try:
res = es.get(index, doctype, app, fields='id')
except ElasticHttpNotFoundError:
# App doesn't exist in our index, add it to `missing_ids`.
missing_ids.append(app)
if missing_ids:
sys.stdout.write('Adding %s doc(s) to the index.'
% len(missing_ids))
index_webapps.delay(missing_ids)
else:
sys.stdout.write('No docs missing from index.')

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

@ -1,39 +0,0 @@
"""
A Marketplace only command to re-index a specific app or apps.
Call like:
./manage.py reindex_app --apps=1234
Or call with a comma separated list of ids:
./manage.py reindex_app --apps=1234,2345,3456
"""
import logging
from optparse import make_option
from django.core.management.base import BaseCommand, CommandError
from mkt.webapps.tasks import index_webapps
log = logging.getLogger('z.elasticsearch')
class Command(BaseCommand):
option_list = BaseCommand.option_list + (
make_option('--apps',
help='Webapp ids to process. Use commas to separate '
'multiple ids.'),
)
help = __doc__
def handle(self, *args, **kw):
apps = kw.get('apps')
if not apps:
raise CommandError('The --apps option is required.')
ids = [int(a.strip()) for a in apps.split(',')]
index_webapps.delay(ids)

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

@ -1,269 +0,0 @@
"""
A Marketplace only reindexing that indexes only apps.
This avoids a lot of complexity for now. We might want an all encompassing
reindex command that has args for AMO and MKT.
"""
import logging
import os
import sys
import time
from optparse import make_option
import pyelasticsearch
from celery import task
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from amo.utils import chunked, timestamp_index
from addons.models import Webapp # To avoid circular import.
from lib.es.utils import (flag_reindexing_mkt, is_reindexing_mkt,
unflag_reindexing_mkt)
from mkt.webapps.models import WebappIndexer
logger = logging.getLogger('z.elasticsearch')
# Enable these to get full debugging information.
# logging.getLogger('pyelasticsearch').setLevel(logging.DEBUG)
# logging.getLogger('requests').setLevel(logging.DEBUG)
# The subset of settings.ES_INDEXES we are concerned with.
ALIAS = settings.ES_INDEXES['webapp']
if hasattr(settings, 'ES_URLS'):
ES_URL = settings.ES_URLS[0]
else:
ES_URL = 'http://127.0.0.1:9200'
ES = pyelasticsearch.ElasticSearch(ES_URL)
job = 'lib.es.management.commands.reindex_mkt.run_indexing'
time_limits = settings.CELERY_TIME_LIMITS[job]
@task
def delete_index(old_index):
"""Removes the index."""
sys.stdout.write('Removing index %r' % old_index)
ES.delete_index(old_index)
@task
def create_index(new_index, alias, settings):
"""Creates a mapping for the new index.
- new_index: new index name
- alias: alias name
- settings: a dictionary of settings
"""
sys.stdout.write(
'Create the mapping for index %r, alias: %r' % (new_index, alias))
# Update settings with mapping.
settings = {
'settings': settings,
'mappings': WebappIndexer.get_mapping(),
}
# Create index and mapping.
try:
ES.create_index(new_index, settings)
except pyelasticsearch.exceptions.IndexAlreadyExistsError:
raise CommandError('New index [%s] already exists' % new_index)
# Don't return until the health is green. By default waits for 30s.
ES.health(new_index, wait_for_status='green', wait_for_relocating_shards=0)
def index_webapp(ids, **kw):
index = kw.pop('index', None) or ALIAS
sys.stdout.write('Indexing %s apps' % len(ids))
qs = Webapp.indexing_transformer(Webapp.with_deleted.no_cache()
.filter(id__in=ids))
docs = []
for obj in qs:
try:
docs.append(WebappIndexer.extract_document(obj.id, obj=obj))
except Exception as e:
sys.stdout.write('Failed to index obj: {0}. {1}'.format(obj.id, e))
WebappIndexer.bulk_index(docs, es=ES, index=index)
@task(time_limit=time_limits['hard'], soft_time_limit=time_limits['soft'])
def run_indexing(index):
"""Index the objects.
- index: name of the index
Note: Our ES doc sizes are about 5k in size. Chunking by 100 sends ~500kb
of data to ES at a time.
TODO: Use celery chords here to parallelize these indexing chunks. This
requires celery 3 (bug 825938).
"""
sys.stdout.write('Indexing apps into index: %s' % index)
qs = WebappIndexer.get_indexable()
for chunk in chunked(list(qs), 100):
index_webapp(chunk, index=index)
@task
def flag_database(new_index, old_index, alias):
"""Flags the database to indicate that the reindexing has started."""
sys.stdout.write('Flagging the database to start the reindexation')
flag_reindexing_mkt(new_index=new_index, old_index=old_index, alias=alias)
time.sleep(5) # Give celeryd some time to flag the DB.
@task
def unflag_database():
"""Unflag the database to indicate that the reindexing is over."""
sys.stdout.write('Unflagging the database')
unflag_reindexing_mkt()
@task
def update_alias(new_index, old_index, alias, settings):
"""
Update the alias now that indexing is over.
We do 3 things:
1. Optimize (which also does a refresh and a flush by default).
2. Update settings to reset number of replicas.
3. Point the alias to this new index.
"""
sys.stdout.write('Optimizing, updating settings and aliases.')
# Optimize.
ES.optimize(new_index)
# Update the replicas.
ES.update_settings(new_index, settings)
# Add and remove aliases.
actions = [
{'add': {'index': new_index, 'alias': alias}}
]
if old_index:
actions.append(
{'remove': {'index': old_index, 'alias': alias}}
)
ES.update_aliases(dict(actions=actions))
@task
def output_summary():
aliases = ES.aliases(ALIAS)
sys.stdout.write(
'Reindexation done. Current Aliases configuration: %s\n' % aliases)
class Command(BaseCommand):
help = 'Reindex all ES indexes'
option_list = BaseCommand.option_list + (
make_option('--prefix', action='store',
help='Indexes prefixes, like test_',
default=''),
make_option('--force', action='store_true',
help=('Bypass the database flag that says '
'another indexation is ongoing'),
default=False),
)
def handle(self, *args, **kwargs):
"""Set up reindexing tasks.
Creates a Tasktree that creates a new indexes and indexes all objects,
then points the alias to this new index when finished.
"""
if not settings.MARKETPLACE:
raise CommandError('This command affects only marketplace and '
'should be run under Marketplace settings.')
force = kwargs.get('force', False)
prefix = kwargs.get('prefix', '')
if is_reindexing_mkt() and not force:
raise CommandError('Indexation already occuring - use --force to '
'bypass')
elif force:
unflag_database()
# The list of indexes that is currently aliased by `ALIAS`.
try:
aliases = ES.aliases(ALIAS).keys()
except pyelasticsearch.exceptions.ElasticHttpNotFoundError:
aliases = []
old_index = aliases[0] if aliases else None
# Create a new index, using the index name with a timestamp.
new_index = timestamp_index(prefix + ALIAS)
# See how the index is currently configured.
if old_index:
try:
s = (ES.get_settings(old_index).get(old_index, {})
.get('settings', {}))
except pyelasticsearch.exceptions.ElasticHttpNotFoundError:
s = {}
else:
s = {}
num_replicas = s.get('number_of_replicas',
settings.ES_DEFAULT_NUM_REPLICAS)
num_shards = s.get('number_of_shards', settings.ES_DEFAULT_NUM_SHARDS)
# Flag the database.
chain = flag_database.si(new_index, old_index, ALIAS)
# Create the index and mapping.
#
# Note: We set num_replicas=0 here to decrease load while re-indexing.
# In a later step we increase it which results in a more efficient bulk
# copy in Elasticsearch.
# For ES < 0.90 we manually enable compression.
chain |= create_index.si(new_index, ALIAS, {
'analysis': WebappIndexer.get_analysis(),
'number_of_replicas': 0, 'number_of_shards': num_shards,
'store.compress.tv': True, 'store.compress.stored': True,
'refresh_interval': '-1'})
# Index all the things!
chain |= run_indexing.si(new_index)
# After indexing we optimize the index, adjust settings, and point the
# alias to the new index.
chain |= update_alias.si(new_index, old_index, ALIAS, {
'number_of_replicas': num_replicas, 'refresh_interval': '5s'})
# Unflag the database.
chain |= unflag_database.si()
# Delete the old index, if any.
if old_index:
chain |= delete_index.si(old_index)
chain |= output_summary.si()
self.stdout.write('\nNew index and indexing tasks all queued up.\n')
os.environ['FORCE_INDEXING'] = '1'
try:
chain.apply_async()
finally:
del os.environ['FORCE_INDEXING']

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

@ -1,46 +0,0 @@
import amo
from addons.models import AddonCategory, Category, Webapp
def run():
"""
Usage::
python -B manage.py runscript scripts.generate-mkt-cats
"""
cats = {
'books-reference': 'Books & Reference',
'business': 'Business',
'education': 'Education',
'entertainment-sports': 'Entertainment & Sports',
'games': 'Games',
'health-fitness': 'Health & Fitness',
'lifestyle': 'Lifestyle',
'music': 'Music',
'news-weather': 'News & Weather',
'photos-media': 'Photos & Media',
'productivity': 'Productivity',
'shopping': 'Shopping',
'social': 'Social',
'travel': 'Travel',
'utilities': 'Utilities'
}
for slug, name in cats.iteritems():
cat, created = Category.objects.get_or_create(type=amo.ADDON_WEBAPP,
slug=slug)
if created:
cat.name = name
cat.save()
print 'Created "%s" category' % name
try:
w = Webapp.objects.visible()[0]
except IndexError:
pass
else:
ac, created = AddonCategory.objects.get_or_create(category=cat,
addon=w)
if created:
print 'Added "%s" to "%s" category' % (w.name, name)
w.save()

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

@ -1,188 +0,0 @@
#!/usr/bin/env python
"""
Script to serve packaged app mini-manifest and zip files to ease development.
Change directory to the root of your packaged app directory and execute this
script. For example:
$ cd ~/myapp
$ python ~/serve_packaged_apps.py
"""
import json
import logging
import optparse
import os
import re
import socket
from StringIO import StringIO
from sys import exc_info
from traceback import format_tb
from wsgiref import simple_server
from zipfile import ZipFile, ZIP_DEFLATED
DEFAULT_ADDR = '0.0.0.0'
DEFAULT_PORT = '8888'
ROOT = os.getcwd()
NAME = os.path.basename(ROOT)
log = logging.getLogger(__name__)
def _absolutify(path):
return '%s%s/%s' % (os.environ['BASE_URL'], NAME, path.rsplit('/', 1)[0])
def _get_local_ip():
"""A hack way to find the local IP without using any Python libraries."""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('google.com', 80))
ip = s.getsockname()[0]
s.close()
return ip
def index(environ, start_response):
template = '''
<!DOCTYPE html>
<html>
<head>
<title>{name} - Packaged App Server</title>
<style>
button {{
font-size: 18px;
padding: 5px;
width: 100%;
}}
</style>
</head>
<body>
<p><a href="{manifest}">{manifest}</a>: The mini-manifest is what
is provided to the <code>installPackage</code> API and provides
information about your app to Firefox OS.</p>
<p><a href="{package}">{package}</a>: The zipped-on-the-fly path to
your packaged app. The mini-manifest points to this URL inside the
mini-manifest.</p>
<button onclick="{install}('{manifest}');">Install</button>
</body>
</html>
'''
context = {
'name': NAME,
'install': 'navigator.mozApps.installPackage',
'manifest': _absolutify('manifest.webapp'),
'package': _absolutify('package.zip'),
}
start_response('200 OK', [('Content-Type', 'text/html')])
return [template.format(**context)]
def manifest(environ, start_response):
data = {
'name': u'My app',
'version': 1,
'size': 1000, # TODO
'package_path': _absolutify('package.zip'),
}
start_response('200 OK', [('Content-Type', 'application/json')])
return [json.dumps(data)]
def zip_file(environ, start_response):
def _add_file(f, name, path):
with open(path, 'r') as p:
f.writestr(name, p.read())
# Walk path, add all files to zip archive.
sio = StringIO()
with ZipFile(file=sio, mode='w', compression=ZIP_DEFLATED) as outfile:
for path, dirs, files in os.walk(ROOT):
for f in files:
full_path = os.path.join(path, f)
zip_path = full_path[len(ROOT) + 1:] # +1 for the slash.
_add_file(outfile, zip_path, full_path)
sio.seek(0)
start_response('200 OK', [('Content-Type', 'application/zip')])
return sio.getvalue()
# Routing URLs.
URLS = [
(r'^$', index), # Index points to these other URLs.
(r'manifest.webapp$', manifest), # The mini-manifest.
(r'package.zip$', zip_file), # The zipped package.
]
def application(environ, start_response):
path = environ.get('PATH_INFO', '').lstrip('/')
for regex, callback in URLS:
match = re.search(regex, path)
if match is not None:
environ['myapp.url_args'] = match.groups()
return callback(environ, start_response)
# If no URLs match, 404.
start_response('404 NOT FOUND', [('Content-Type', 'text/plain')])
return ['Not Found']
class ExceptionMiddleware(object):
"""Exception middleware to catch errors and show a useful traceback."""
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
appiter = None
# Call the application sending the output back unchanged. Catch any
# exceptions that occur.
try:
appiter = self.app(environ, start_response)
for item in appiter:
yield item
# If an exception occours we get the exception information and prepare
# a traceback we can render.
except:
e_type, e_value, tb = exc_info()
traceback = ['Traceback (most recent call last):']
traceback += format_tb(tb)
traceback.append('%s: %s' % (e_type.__name__, e_value))
# We may or may have not started a response.
try:
start_response('500 INTERNAL SERVER ERROR', [('Content-Type',
'text/plain')])
except:
pass
yield '\n'.join(traceback)
if hasattr(appiter, 'close'):
appiter.close()
if __name__ == '__main__':
p = optparse.OptionParser(usage='%prog\n\n' + __doc__)
p.add_option('--addr',
default=DEFAULT_ADDR,
help='Address to serve at. Default: %s' % DEFAULT_ADDR)
p.add_option('--port',
default=DEFAULT_PORT,
help='Port to run server on. Default: %s' % DEFAULT_PORT,
type=int)
(options, args) = p.parse_args()
logging.basicConfig(level=logging.DEBUG,
format='[%(asctime)s] %(message)s')
ip = _get_local_ip() if options.addr == DEFAULT_ADDR else options.addr
base_url = 'http://%s:%s/' % (ip, options.port)
log.info('Serving at %s' % base_url)
os.environ['BASE_URL'] = base_url
application = ExceptionMiddleware(application)
server = simple_server.make_server(options.addr, options.port, application)
server.serve_forever()

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

@ -1,61 +0,0 @@
#!/usr/bin/env python
"""Serves .webapp/.json manifest files from the working directory."""
import logging
import optparse
import os
from wsgiref import simple_server
log = logging.getLogger(__name__)
document_root = os.getcwd()
def fileapp(environ, start_response):
path_info = environ['PATH_INFO']
if path_info.startswith('/'):
path_info = path_info[1:] # make relative
full_path = os.path.join(document_root, path_info)
content_type = 'text/html'
if full_path == '':
full_path = '.' # must be working dir
if path_info == "" or path_info.endswith('/') or os.path.isdir(full_path):
# directory listing:
out = ['<html><head></head><body><ul>']
for filename in os.listdir(full_path):
if filename.startswith('.'):
continue
if os.path.isdir(os.path.join(full_path, filename)):
filename = filename + '/'
out.append('<li><a href="%s">%s</a></li>' % (filename, filename))
out.append("</ul></body></html>")
body = "".join(out)
else:
f = open(full_path, 'r')
if full_path.endswith('.webapp') or full_path.endswith('.json'):
content_type = 'application/x-web-app-manifest+json'
body = f.read() # optimized for small files :)
start_response('200 OK', [('Content-Type', content_type),
('Content-Length', str(len(body)))])
return [body]
def main():
p = optparse.OptionParser(usage="%prog\n\n" + __doc__)
p.add_option("--addr", help="Address to serve at. Default: localhost",
default='')
p.add_option("--port", help="Port to run server on. Default: %default",
default=8090, type=int)
(options, args) = p.parse_args()
logging.basicConfig(level=logging.DEBUG,
format='[%(asctime)s] %(message)s')
log.info("starting webserver at http://%s:%s/"
% (options.addr or 'localhost', options.port))
httpd = simple_server.WSGIServer((options.addr, options.port),
simple_server.WSGIRequestHandler)
httpd.set_app(fileapp)
httpd.serve_forever()
if __name__ == '__main__':
main()

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

@ -86,7 +86,7 @@
<div class="header-search" role="search">
{% block search_form %}
{# Get this in scope. #}
{% with WEBAPPS=WEBAPPS, query_term=query_term %}
{% with query_term=query_term %}
{% include 'impala/search.html' %}
{% endwith %}
{% endblock %}
@ -111,61 +111,45 @@
</div>
{% endif %}
{% block amo_balloons %}
{% if WEBAPPS %}
<div class="site-tip" id="appruntime-pitch">
{% if APP == amo.FIREFOX %}
<div class="site-balloon" id="site-nonfx">
<p>
{% with url='https://addons.mozilla.org/en-US/firefox/addon/app-runtime/?src=apps-preview' %}
To easily install and manage Apps in Firefox with a
tightly integrated experience, check out the experimental
<a href="{{ url }}">App Runtime extension</a>.
{% endwith %}
</p>
<a href="#" class="close">{{ _('Close') }}</a>
</div>
<div class="site-balloon" id="site-nojs-apps">
<p>{{ loc('To use Apps, you must enable JavaScript.') }}</p>
</div>
{% else %}
{% if APP == amo.FIREFOX %}
<div class="site-balloon" id="site-nonfx">
<p>
{% trans url='http://mozilla.org/firefox/?src=amo' %}
To try the thousands of add-ons available here, download
<a href="{{ url }}">Mozilla Firefox</a>,
a fast, free way to surf the Web!
{% endtrans %}
</p>
<a href="#" class="close">{{ _('Close') }}</a>
</div>
{% endif %}
<div class="site-balloon" id="site-welcome">
{# L10n: {0} is an application, such as Firefox. #}
<h3>{{ _('Welcome to {0} Add-ons.')|f(APP.pretty) }}</h3>
<p>
{% if APP == amo.FIREFOX %}
{% trans %}
Choose from thousands of extra features and styles to make
Firefox your own.
{% endtrans %}
{% else %}
{% trans app=APP.pretty %}
Add extra features and styles to make {{ app }} your own.
{% endtrans %}
{% endif %}
</p>
<a href="#" class="close">{{ _('Close') }}</a>
</div>
<div class="site-balloon" id="mobile-banner">
<h3>{{ _('On the go?') }}</h3>
<p>
{% trans %}
Check out our
<a class="mobile-link" href="#">Mobile Add-ons site</a>.
{% trans url='http://mozilla.org/firefox/?src=amo' %}
To try the thousands of add-ons available here, download
<a href="{{ url }}">Mozilla Firefox</a>,
a fast, free way to surf the Web!
{% endtrans %}
</p>
<a href="#" class="close">{{ _('Close') }}</a>
</div>
{% endif %}
<div class="site-balloon" id="site-welcome">
{# L10n: {0} is an application, such as Firefox. #}
<h3>{{ _('Welcome to {0} Add-ons.')|f(APP.pretty) }}</h3>
<p>
{% if APP == amo.FIREFOX %}
{% trans %}
Choose from thousands of extra features and styles to make
Firefox your own.
{% endtrans %}
{% else %}
{% trans app=APP.pretty %}
Add extra features and styles to make {{ app }} your own.
{% endtrans %}
{% endif %}
</p>
<a href="#" class="close">{{ _('Close') }}</a>
</div>
<div class="site-balloon" id="mobile-banner">
<h3>{{ _('On the go?') }}</h3>
<p>
{% trans %}
Check out our
<a class="mobile-link" href="#">Mobile Add-ons site</a>.
{% endtrans %}
</p>
<a href="#" class="close">{{ _('Close') }}</a>
</div>
{% endblock %}
</div>
{% endblock site_header %}

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

@ -1,4 +1 @@
{% if webapp or WEBAPPS %}
{% set webapp, WEBAPPS = True, True %}
{% endif %}
{% extends 'impala/base.html' %}

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

@ -11,7 +11,7 @@
{% if search_form.cat.value() %}
{{ search_form.cat }}
{% endif %}
{% if not (WEBAPPS or search_cat in ('themes', 'collections')) %}
{% if not search_cat in ('themes', 'collections') %}
{{ search_form.appver }}
{{ search_form.platform }}
{% endif %}

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

@ -1,4 +1,2 @@
{% if webapp %}
{% set WEBAPPS = True %}
{% endif %}
{% extends "mobile/base_apps.html" if WEBAPPS else "mobile/base_addons.html" %}
{% extends "mobile/base_addons.html" %}

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

@ -49,11 +49,9 @@
</a>
</h1>
</hgroup>
{% if not (settings.APP_PREVIEW or WEBAPP) %}
<div class="get-fx-message">
{{ _('You need Firefox to install add-ons. <a href="http://mozilla.com/mobile">Learn More&nbsp;&raquo;</a>') }}
</div>
{% endif %}
<div class="get-fx-message">
{{ _('You need Firefox to install add-ons. <a href="http://mozilla.com/mobile">Learn More&nbsp;&raquo;</a>') }}
</div>
<nav>
<ul>
{% block back_link %}