new devhub for marketplace
This commit is contained in:
Родитель
964671f849
Коммит
d50aba8f11
|
@ -114,6 +114,8 @@ class UserProfile(amo.models.OnChangeMixin, amo.models.ModelBase):
|
|||
resetcode_expires = models.DateTimeField(default=datetime.now, null=True,
|
||||
blank=True)
|
||||
sandboxshown = models.BooleanField(default=False)
|
||||
read_dev_agreement = models.BooleanField(default=False)
|
||||
|
||||
last_login_ip = models.CharField(default='', max_length=45, editable=False)
|
||||
last_login_attempt = models.DateTimeField(null=True, editable=False)
|
||||
last_login_attempt_ip = models.CharField(default='', max_length=45,
|
||||
|
|
|
@ -0,0 +1,316 @@
|
|||
@import 'lib';
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: @link;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
border-top: 2px solid #fff;
|
||||
font: 13px/15px @sans-stack;
|
||||
position: relative;
|
||||
}
|
||||
#tabzilla-wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 10%;
|
||||
#tabzilla {
|
||||
background: url(//www.mozilla.org/tabzilla/media/img/tab.png) no-repeat;
|
||||
/* background: url(../../../media/img/hub/headzilla.png) no-repeat;*/
|
||||
display: block;
|
||||
height: 45px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
text-indent: -2000px;
|
||||
width: 150px;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
#site-nav ul {
|
||||
background: #f8f8f8;
|
||||
color: @dark-gray;
|
||||
font: 11px @open-stack;
|
||||
float: left;
|
||||
width: 100%;
|
||||
a {
|
||||
color: #484848;
|
||||
display: block;
|
||||
padding: .5em 1em;
|
||||
text-decoration: none;
|
||||
&:hover, &:focus, &:active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
li {
|
||||
border-right: 1px dotted #ccc;
|
||||
float: left;
|
||||
font-weight: bold;
|
||||
line-height: 1.1;
|
||||
text-transform: uppercase;
|
||||
&:first-child a {
|
||||
padding-left: 0;
|
||||
}
|
||||
+ li:last-child {
|
||||
border-right: 0;
|
||||
a {
|
||||
border-right: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#page {
|
||||
margin-top: 3em; /* hack */
|
||||
padding: 0 10%;
|
||||
}
|
||||
|
||||
#site-nav {
|
||||
background: #eee;
|
||||
padding: 2em 0;
|
||||
.site-title {
|
||||
font: bold 32px/1.2 @open-stack;
|
||||
text-transform: uppercase;
|
||||
margin: 0 10% .75em;
|
||||
small {
|
||||
color: @medium-gray;
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
padding: 2px;
|
||||
}
|
||||
a {
|
||||
color: @teal; /*@dark-gray*/
|
||||
&:hover {
|
||||
color: darken(@teal, 10%);
|
||||
text-decoration: none;
|
||||
small {
|
||||
color: @dark-gray;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ul {
|
||||
padding: 1em 0;
|
||||
li:first-child {
|
||||
margin-left: 10%;
|
||||
padding-left: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#page {
|
||||
h1 {
|
||||
color: @red;
|
||||
font: 32px @open-stack;
|
||||
}
|
||||
h2 {
|
||||
font: 16px @open-stack;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
p, ul, li {
|
||||
color: @dark-gray;
|
||||
line-height: 1.3;
|
||||
}
|
||||
p, ul {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
#content {
|
||||
margin: 1em 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* There are no buttons used yet. */
|
||||
.button, button, input[type=submit] {
|
||||
position: relative;
|
||||
font-family: @open-stack;
|
||||
font-weight: bold;
|
||||
line-height: 13px;
|
||||
padding: 6px 10px 7px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
background: #5784BF;
|
||||
.gradient-two-color(#669BE1, #5784BF);
|
||||
text-shadow: 0 1px 0 rgba(0,0,0,.5);
|
||||
.border-radius(6px);
|
||||
.box-shadow(0 1px rgba(0, 0, 0, 0.1), 0 -2px rgba(0, 0, 0, 0.1) inset);
|
||||
border: 0;
|
||||
&.prominent {
|
||||
font-size: 16px !important;
|
||||
padding: 8px 16px 12px;
|
||||
.box-shadow(0 3px rgba(0, 0, 0, 0.1), 0 -4px rgba(0, 0, 0, 0.1) inset);
|
||||
}
|
||||
}
|
||||
|
||||
button.good, .button.good, .button.add {
|
||||
.gradient-two-color(@button-green-light, @button-green-dark,
|
||||
@button-green-dark);
|
||||
}
|
||||
|
||||
#footer {
|
||||
border-top: #ccc 1px dotted;
|
||||
color: @note-gray;
|
||||
margin: 1em 10% 0;
|
||||
padding-top: 2em;
|
||||
#footzilla {
|
||||
background: url(../../../media/img/hub/footzilla.png) no-repeat;
|
||||
opacity: .5;
|
||||
float: left;
|
||||
margin-top: 5px;
|
||||
height: 50px;
|
||||
width: 100px;
|
||||
text-indent: -9999px;
|
||||
}
|
||||
p, ul {
|
||||
font-size: 12px;
|
||||
line-height: 1.3;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
ul {
|
||||
float: right;
|
||||
width: 20%;
|
||||
}
|
||||
ul, p {
|
||||
border-left: #eee 1px dotted;
|
||||
padding-left: 1em;
|
||||
}
|
||||
p {
|
||||
float: left;
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.menu-nav {
|
||||
font-size: 12px;
|
||||
margin-left: 64px;
|
||||
z-index: 50;
|
||||
a {
|
||||
color: @medium-gray;
|
||||
&:hover {
|
||||
color: @dark-gray;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
&.no-img {
|
||||
margin-left: 0;
|
||||
}
|
||||
> ul {
|
||||
font: 11px @open-stack;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
> li {
|
||||
+ li {
|
||||
border-left: 1px dotted @dark-gray;
|
||||
}
|
||||
border-width: 0 2px;
|
||||
float: left;
|
||||
position: relative;
|
||||
> a {
|
||||
border: 1px dotted transparent;
|
||||
display: block;
|
||||
padding: .5em 1em;
|
||||
&:after {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
top: 12px;
|
||||
left: 4px;
|
||||
margin: 0 0 0 4px;
|
||||
content: "\00a0";
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 4px solid transparent;
|
||||
border-style: solid;
|
||||
border-top-color: #666;
|
||||
}
|
||||
}
|
||||
&.nomenu a:after {
|
||||
display: none;
|
||||
}
|
||||
&:hover {
|
||||
> a {
|
||||
border-left-color: @light-gray;
|
||||
background: #fff;
|
||||
}
|
||||
> ul {
|
||||
display: block;
|
||||
}
|
||||
&:after {
|
||||
border-bottom: #000 10px solid;
|
||||
position: absolute;
|
||||
top: 17px;
|
||||
left: 1px;
|
||||
}
|
||||
&.nomenu {
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
> a {
|
||||
border-left-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
> ul {
|
||||
background: #fff;
|
||||
border: 1px dotted @light-gray;
|
||||
width: 190px;
|
||||
position: absolute;
|
||||
z-index: 59;
|
||||
padding: 8px;
|
||||
display: none;
|
||||
a {
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
padding: 6px 8px;
|
||||
word-wrap: break-word;
|
||||
&:hover {
|
||||
background: #fafafa;
|
||||
}
|
||||
}
|
||||
&.two-col {
|
||||
.columns(2, 8px);
|
||||
width: 340px;
|
||||
}
|
||||
}
|
||||
}
|
||||
em a:hover {
|
||||
background: #e1edfb;
|
||||
}
|
||||
}
|
||||
hr {
|
||||
border: 0;
|
||||
margin: 6px 8px;
|
||||
border-top: 1px dotted #ccc;
|
||||
}
|
||||
em {
|
||||
background: #F4F8FC;
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
#aux-nav {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -moz-calc(10%);
|
||||
margin-right: 150px;
|
||||
}
|
||||
|
||||
/* Toggle this for alternative aux nav at the top. */
|
||||
|
||||
/*
|
||||
#aux-nav {
|
||||
margin: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
#site-nav, #tabzilla-wrapper {
|
||||
margin-top: 28px;
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,8 @@
|
|||
@import 'lib';
|
||||
|
||||
.optional {
|
||||
color: @medium-gray;
|
||||
}
|
||||
.req {
|
||||
color: @error-red;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
@import '../impala/lib';
|
||||
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(//www.mozilla.org/img/fonts/OpenSans-Regular-webfont.eot?#iefix) format("embedded-opentype"),
|
||||
url(//www.mozilla.org/img/fonts/OpenSans-Regular-webfont.woff) format("woff"),
|
||||
url(//www.mozilla.org/img/fonts/OpenSans-Regular-webfont.ttf) format("truetype"),
|
||||
url(//www.mozilla.org/img/fonts/OpenSans-Regular-webfont.svg#OpenSansRegular) format("svg");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: url(//www.mozilla.org/img/fonts/OpenSans-Semibold-webfont.eot?#iefix) format("embedded-opentype"),
|
||||
url(//www.mozilla.org/img/fonts/OpenSans-Semibold-webfont.woff) format("woff"),
|
||||
url(//www.mozilla.org/img/fonts/OpenSans-Semibold-webfont.ttf) format("truetype"),
|
||||
url(//www.mozilla.org/img/fonts/OpenSans-Semibold-webfont.svg#OpenSansSemibold) format("svg");
|
||||
}
|
||||
@open-stack: "Open Sans", @sans-stack;
|
|
@ -0,0 +1 @@
|
|||
@import 'lib';
|
|
@ -0,0 +1,43 @@
|
|||
@import '../hub/lib';
|
||||
|
||||
#submission-progress {
|
||||
.border-box;
|
||||
border-bottom: #eee 1px dotted;
|
||||
display: table;
|
||||
margin-bottom: 1.5em;
|
||||
width: 100%;
|
||||
ol {
|
||||
display: table-row;
|
||||
counter-reset: item;
|
||||
}
|
||||
li {
|
||||
color: @light-gray;
|
||||
display: table-cell;
|
||||
counter-increment: item;
|
||||
font: 16px @open-stack;
|
||||
padding-bottom: 1.5em;
|
||||
text-align: center;
|
||||
width: 20%;
|
||||
&:before {
|
||||
.border-radius(30px);
|
||||
background: #eee;
|
||||
display: block;
|
||||
content: counter(item);
|
||||
font-size: 18px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
margin: 5px auto 0;
|
||||
text-align: center;
|
||||
width: 30px;
|
||||
}
|
||||
&.active {
|
||||
color: @dark-gray;
|
||||
font-weight: bold;
|
||||
&:before {
|
||||
background: transparent;
|
||||
border: 1px solid #000;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
@import '../hub/lib';
|
||||
|
||||
#terms {
|
||||
#agreement-container {
|
||||
border: 1px solid @light-gray;
|
||||
margin-bottom: .5em;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
padding: 1em;
|
||||
#dev-agreement {
|
||||
ul, ol {
|
||||
list-style: decimal outside;
|
||||
margin-left: 4ex;
|
||||
.loud-noises {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
li {
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
ul {
|
||||
list-style: circle outside;
|
||||
margin: 1em 2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#agreement-extra-links {
|
||||
float: right;
|
||||
font-size: 11px;
|
||||
}
|
||||
#agreement-form {
|
||||
margin: 2.5em 0 1em;
|
||||
label {
|
||||
cursor: pointer;
|
||||
}
|
||||
p {
|
||||
margin: 0 0 .25em;
|
||||
}
|
||||
button {
|
||||
color: darken(#ccc, 5%);
|
||||
float: right;
|
||||
b {
|
||||
color: darken(#def, 5%);
|
||||
}
|
||||
&:hover {
|
||||
color: #ccc;
|
||||
b {
|
||||
color: #def;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.5 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 2.8 KiB |
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE `users` ADD COLUMN `read_dev_agreement` tinyint(1) unsigned
|
||||
NOT NULL DEFAULT '0';
|
|
@ -0,0 +1,94 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ LANG }}" dir="{{ DIR }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
{% if not settings.ENGAGE_ROBOTS %}
|
||||
<meta name="robots" content="noindex">
|
||||
{% endif %}
|
||||
{% block extrameta %}{% endblock %}
|
||||
<title>
|
||||
{% block title %}Developer Hub | {{ _('Mozilla Marketplace') }}{% endblock %}
|
||||
</title>
|
||||
{% block site_css %}{{ css('hub') }}{% endblock %}
|
||||
{% if settings.DEBUG %}
|
||||
{% if settings.LESS_LIVE_REFRESH %}
|
||||
<meta id="live_refresh" name="live_refresh" value="1">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if request.user.is_authenticated() %}
|
||||
<meta name="csrf" content="{{ csrf_token }}">
|
||||
{% endif %}
|
||||
</head>
|
||||
<body class="html-{{ DIR }} {% block bodyclass %}{% endblock %}"
|
||||
data-anonymous="{{ (not request.user.is_authenticated())|json }}"
|
||||
data-readonly="{{ settings.READ_ONLY|json }}"
|
||||
data-media-url="{{ MEDIA_URL }}"
|
||||
data-collect-timings="{{ url('amo.timing.record') }}:{{ collect_timings_percent }}"
|
||||
{% block bodyattrs %}{% endblock %}>
|
||||
<div id="tabzilla-wrapper">
|
||||
<a id="tabzilla" href="http://mozilla.org/">mozilla</a>
|
||||
</div>
|
||||
<nav id="aux-nav" role="navigation" class="menu-nav c">
|
||||
<ul>
|
||||
{% if not settings.READ_ONLY %}
|
||||
{% include 'impala/user_login.html' %}
|
||||
{% endif %}
|
||||
{% block aux_nav %}{% endblock aux_nav %}
|
||||
</ul>
|
||||
</nav>
|
||||
<nav id="site-nav">
|
||||
<h1 class="site-title">
|
||||
<a href="{{ url('hub.index') }}">
|
||||
<small>Marketplace</small> Developer Hub
|
||||
</a>
|
||||
</h1>
|
||||
<ul>
|
||||
<li><a href="{{ url('hub.index') }}">My Submissions</a></li>
|
||||
<li><a href="">Documentation</a></li>
|
||||
<li><a href="{{ url('submit.apps.1') }}">Upload an App</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div id="page">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
<footer class="c" id="footer">
|
||||
<h1 id="footzilla">mozilla</h1>
|
||||
<p>
|
||||
{% trans %}
|
||||
Except where otherwise
|
||||
<a href="http://mozilla.com/about/legal.html#site">noted</a>,
|
||||
content on this site is licensed under the <br />
|
||||
<a href="http://creativecommons.org/licenses/by-sa/3.0/">
|
||||
Creative Commons Attribution Share-Alike License v3.0
|
||||
</a> or any later version.
|
||||
{% endtrans %}
|
||||
</p>
|
||||
<ul>
|
||||
<li><a href="http://mozilla.com/privacy-policy.html">
|
||||
{{ _('Privacy Policy') }}</a></li>
|
||||
<li><a href="http://mozilla.com/about/legal.html">
|
||||
{{ _('Legal Notices') }}</a></li>
|
||||
<li><a href="http://mozilla.com/legal/fraud-report/index.html">
|
||||
{{ _('Report Trademark Abuse') }}</a></li>
|
||||
</ul>
|
||||
</footer>
|
||||
{# js #}
|
||||
{% block site_js %}
|
||||
<script src="{{ static(url('jsi18n')) }}"></script>
|
||||
{% if waffle.switch('browserid-login') %}
|
||||
<script async defer src="https://browserid.org/include.js"></script>
|
||||
{% endif %}
|
||||
{{ js('hub') }}
|
||||
<script async defer src="{{ settings.PAYPAL_JS_URL }}"></script>
|
||||
{% endblock %}
|
||||
{% block js %}{% endblock %}
|
||||
{# Webtrends Stats Tracking #}
|
||||
<script defer src="{{ media('js/webtrends/webtrends-v0.1.js') }}"></script>
|
||||
{% block js_extras %}{% endblock %}
|
||||
<noscript>
|
||||
<img class="hidden" id="DCSIMG" width="1" height="1"
|
||||
src="https://statse.webtrendslive.com/dcso6de4r0000082npfcmh4rf_4b1e/njs.gif?dcsuri=/nojavascript&WT.js=No&WT.tv=8.6.2" />
|
||||
</noscript>
|
||||
{# End Webtrends #}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
{% extends 'hub/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Developer Launchpad</h1>
|
||||
<p>TODO(greg): Get copy</p>
|
||||
{% endblock %}
|
|
@ -0,0 +1,15 @@
|
|||
from django.conf.urls.defaults import patterns, url, include
|
||||
|
||||
from lib.misc.urlconf_decorator import decorate
|
||||
|
||||
from amo.decorators import write
|
||||
from . import views
|
||||
|
||||
|
||||
# Decorate all the views as @write so as to bypass cache.
|
||||
urlpatterns = decorate(write, patterns('',
|
||||
# Submission.
|
||||
('', include('mkt.submit.urls')),
|
||||
# Launchpad.
|
||||
url('^$', views.index, name='hub.index'),
|
||||
))
|
|
@ -0,0 +1,5 @@
|
|||
import jingo
|
||||
|
||||
|
||||
def index(request):
|
||||
return jingo.render(request, 'hub/index.html')
|
|
@ -2,9 +2,32 @@ from lib.settings_base import *
|
|||
|
||||
APP_PREVIEW = True
|
||||
ROOT_URLCONF = 'mkt.urls'
|
||||
TEMPLATE_DIRS = (path('mkt/templates'),) + TEMPLATE_DIRS
|
||||
POTCH_MARKETPLACE_EXPERIMENTS = False
|
||||
INSTALLED_APPS += ('mkt.experiments', 'mkt.site')
|
||||
TEMPLATE_DIRS += (path('mkt/templates'),)
|
||||
INSTALLED_APPS += (
|
||||
'mkt.site',
|
||||
'mkt.hub',
|
||||
'mkt.submit',
|
||||
'mkt.experiments',
|
||||
)
|
||||
SUPPORTED_NONAPPS += (
|
||||
'hub',
|
||||
'submit',
|
||||
)
|
||||
|
||||
TEMPLATE_CONTEXT_PROCESSORS = (
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.core.context_processors.debug',
|
||||
'django.core.context_processors.media',
|
||||
'django.core.context_processors.request',
|
||||
'session_csrf.context_processor',
|
||||
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
|
||||
'mkt.site.context_processors.i18n',
|
||||
'mkt.site.context_processors.global_settings',
|
||||
'mkt.site.context_processors.static_url',
|
||||
'jingo_minify.helpers.build_ids',
|
||||
)
|
||||
|
||||
TEMPLATE_CONTEXT_PROCESSORS += ('mkt.experiments.context_processors.fragment',)
|
||||
|
||||
|
@ -48,8 +71,15 @@ NO_LOGIN_REQUIRED_MODULES = (
|
|||
'django.contrib.auth.views.password_reset_done'
|
||||
)
|
||||
|
||||
|
||||
# Extend the bundles.
|
||||
MINIFY_BUNDLES['css'].update({
|
||||
'hub': (
|
||||
'css/impala/base.css',
|
||||
'css/hub/base.less',
|
||||
'css/hub/forms.less',
|
||||
'css/submit/progress.less',
|
||||
'css/submit/terms.less',
|
||||
),
|
||||
'marketplace-experiments': (
|
||||
'marketplace-experiments/css/reset.less',
|
||||
'marketplace-experiments/css/site.less',
|
||||
|
@ -60,9 +90,13 @@ MINIFY_BUNDLES['css'].update({
|
|||
),
|
||||
})
|
||||
MINIFY_BUNDLES['js'].update({
|
||||
'hub': (
|
||||
),
|
||||
'marketplace-experiments': (
|
||||
'js/marketplace-experiments/jquery-1.7.1.min.js',
|
||||
'js/marketplace-experiments/slider.js',
|
||||
),
|
||||
})
|
||||
|
||||
# Feature flags.
|
||||
POTCH_MARKETPLACE_EXPERIMENTS = False
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
from django.conf import settings
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.utils import translation
|
||||
from django.utils.http import urlquote
|
||||
|
||||
from tower import ugettext as _
|
||||
import waffle
|
||||
|
||||
import amo
|
||||
from amo.urlresolvers import reverse
|
||||
from amo.utils import memoize
|
||||
from cake.urlresolvers import remora_url
|
||||
from zadmin.models import get_config
|
||||
|
||||
|
||||
def static_url(request):
|
||||
return {'STATIC_URL': settings.STATIC_URL}
|
||||
|
||||
|
||||
def i18n(request):
|
||||
return {'LANGUAGES': settings.LANGUAGES,
|
||||
'LANG': settings.LANGUAGE_URL_MAP.get(translation.get_language())
|
||||
or translation.get_language(),
|
||||
'DIR': 'rtl' if translation.get_language_bidi() else 'ltr'}
|
||||
|
||||
|
||||
@memoize('collect-timings')
|
||||
def get_collect_timings():
|
||||
# The flag has to be enabled for everyone and then we'll use that
|
||||
# percentage in the pages.
|
||||
percent = 0
|
||||
try:
|
||||
flag = waffle.models.Flag.objects.get(name='collect-timings')
|
||||
if flag.everyone and flag.percent:
|
||||
percent = float(flag.percent) / 100.0
|
||||
except waffle.models.Flag.DoesNotExist:
|
||||
pass
|
||||
return percent
|
||||
|
||||
|
||||
def global_settings(request):
|
||||
"""
|
||||
Storing global Marketplace-wide info. used in global headers
|
||||
(e.g., account links and settings).
|
||||
"""
|
||||
account_links = []
|
||||
context = {}
|
||||
if request.user.is_authenticated() and hasattr(request, 'amo_user'):
|
||||
amo_user = request.amo_user
|
||||
account_links += [
|
||||
{'text': _('My Profile'),
|
||||
'href': request.user.get_profile().get_url_path()},
|
||||
{'text': _('Account Settings'), 'href': reverse('users.edit')},
|
||||
{'text': _('Log Out'),
|
||||
'href': remora_url('/users/logout?to=' + urlquote(request.path))},
|
||||
]
|
||||
context['amo_user'] = request.amo_user
|
||||
else:
|
||||
context['amo_user'] = AnonymousUser()
|
||||
context.update(account_links=account_links,
|
||||
settings=settings,
|
||||
amo=amo,
|
||||
ADMIN_MESSAGE=get_config('site_notice'),
|
||||
collect_timings_percent=get_collect_timings())
|
||||
return context
|
|
@ -0,0 +1,9 @@
|
|||
from jingo import register, env
|
||||
import jinja2
|
||||
|
||||
|
||||
@register.function
|
||||
def form_field(field, label=None, tag=None, req=None, **attrs):
|
||||
c = dict(field=field, label=label, tag=tag, req=req, attrs=attrs)
|
||||
t = env.get_template('site/helpers/simple_field.html').render(**c)
|
||||
return jinja2.Markup(t)
|
|
@ -0,0 +1,22 @@
|
|||
{% from 'includes/forms.html' import required, optional, tip %}
|
||||
{% if tag %}
|
||||
<{{ tag }} class="{{ class }}{{ ' error' if field.errors }}">
|
||||
{% endif %}
|
||||
{% set choice = field|is_choice_field %}
|
||||
<label class="{{ class }}{{ ' choice' if choice }}" for="{{ field.auto_id }}">
|
||||
{% if choice %}{{ field.as_widget() }}{% endif %}
|
||||
{{ label or field.label }}
|
||||
|
||||
{% if field.field.required and req != False %}{{ required() -}}{% endif %}
|
||||
{% if opt %}{{ optional() -}}{% endif %}
|
||||
|
||||
{% if not tooltip %}{% set tooltip = field.help_text %}{% endif %}
|
||||
{% if tooltip %}{{ tip(None, tooltip) }}{% endif %}
|
||||
</label>
|
||||
{% if not choice %}
|
||||
{{ field.as_widget(attrs=attrs) }}
|
||||
{% endif %}
|
||||
{{ field.errors }}
|
||||
{% if tag %}
|
||||
</{{ tag }}>
|
||||
{% endif %}
|
|
@ -0,0 +1,17 @@
|
|||
from django import forms
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
import happyforms
|
||||
from tower import ugettext_lazy as _lazy
|
||||
|
||||
from users.models import UserProfile
|
||||
|
||||
|
||||
class DevAgreementForm(happyforms.ModelForm):
|
||||
yes = forms.BooleanField(
|
||||
label=mark_safe(_lazy('<b>Agree</b> and Continue')),
|
||||
widget=forms.HiddenInput)
|
||||
|
||||
class Meta:
|
||||
model = UserProfile
|
||||
exclude = ('read_dev_agreement',)
|
|
@ -0,0 +1,98 @@
|
|||
{% extends 'hub/base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<!-- TODO: Put in a helpers function. -->
|
||||
<ol id="submission-progress" class="c">
|
||||
<li class="active">Developer Account</li>
|
||||
<li>App Manifest</li>
|
||||
<li>App Details</li>
|
||||
<li>Payments</li>
|
||||
<li>Finished!</li>
|
||||
</ol>
|
||||
<h1>Submit an App</h1>
|
||||
<section id="content" class="primary addon-submission-process">
|
||||
<div id="terms">
|
||||
<h2>Marketplace Developer Program</h2>
|
||||
<p>
|
||||
We're excited you've built an app using web technologies, and
|
||||
submitting it to the Mozilla Marketplace is the best way for users
|
||||
to discover and enjoy it across their devices. First, you'll need to
|
||||
join the Marketplace Developer Program below.
|
||||
</p>
|
||||
<p>
|
||||
To begin, please read and accept our <strong>Developer
|
||||
Agreement</strong>:
|
||||
</p>
|
||||
<div id="agreement-container">
|
||||
<div id="dev-agreement">
|
||||
<p>
|
||||
<strong>App Developer Preview Terms</strong>
|
||||
<br>
|
||||
Last Update: <strong>December 7, 2011</strong>
|
||||
</p>
|
||||
<ol start="0">
|
||||
<li>
|
||||
<strong>The following terms</strong> (the
|
||||
“<strong>Terms</strong>”) <strong>apply to your use of
|
||||
this developer preview of the Mozilla application marketplace
|
||||
</strong> (the “<strong>App Developer Preview</strong>”).
|
||||
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 Personas
|
||||
or other content (“Developer Content”) 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'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 “as is”.
|
||||
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>
|
||||
</div>
|
||||
<div class="c" id="agreement-extra-links">
|
||||
<a href="/en-US/developers/docs/policies/agreement">
|
||||
Printable Version</a>
|
||||
</div>
|
||||
<form action="" class="c" id="agreement-form" method="post">
|
||||
{# TODO: Add newsletter field. #}
|
||||
{{ csrf() }}
|
||||
{{ agreement_form.yes }}
|
||||
<button class="prominent">{{ agreement_form.yes.label }}</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
|
@ -0,0 +1,31 @@
|
|||
from django.conf.urls.defaults import patterns, url, include
|
||||
from django.shortcuts import redirect
|
||||
|
||||
from lib.misc.urlconf_decorator import decorate
|
||||
|
||||
from amo.decorators import write
|
||||
from devhub.decorators import use_apps
|
||||
import devhub.views
|
||||
from webapps.urls import APP_SLUG
|
||||
from . import views
|
||||
|
||||
# TODO: Rename `hub` app to `submit`.
|
||||
|
||||
|
||||
# These will all start with /submit/app/<app_slug>
|
||||
submit_apps_patterns = patterns('',
|
||||
url('^3$', use_apps(views.describe), name='submit.apps.3'),
|
||||
url('^4$', use_apps(views.media), name='submit.apps.4'),
|
||||
url('^5$', use_apps(views.done), name='submit.apps.5'),
|
||||
)
|
||||
|
||||
|
||||
# Decorate all the views as @write so as to bypass cache.
|
||||
urlpatterns = decorate(write, patterns('',
|
||||
# App submission.
|
||||
url('^app/submit/$', lambda r: redirect('submit.apps.1')),
|
||||
url('^app/submit/1$', views.terms, name='submit.apps.1'),
|
||||
# url('^app/submit/2$', use_apps(devhub.views.submit_addon),
|
||||
# name='hub.submit_apps.2'),
|
||||
# url('^app/%s/submit/' % APP_SLUG, include(submit_apps_patterns)),
|
||||
))
|
|
@ -0,0 +1,36 @@
|
|||
from django.conf import settings
|
||||
|
||||
import jingo
|
||||
|
||||
import amo
|
||||
from . import forms
|
||||
|
||||
|
||||
def submit(request):
|
||||
#if settings.APP_PREVIEW:
|
||||
# # This can be a permanent redirect when we finalize devhub for apps.
|
||||
# return redirect('devhub.submit_apps.1')
|
||||
return jingo.render(request, 'hub/submit.html')
|
||||
|
||||
|
||||
def terms(request):
|
||||
agreement_form = forms.DevAgreementForm(request.POST or None,
|
||||
instance=request.amo_user)
|
||||
if agreement_form.is_valid():
|
||||
agreement_form.save()
|
||||
return redirect('hub.index')
|
||||
return jingo.render(request, 'submit/terms.html', {
|
||||
'agreement_form': agreement_form,
|
||||
})
|
||||
|
||||
|
||||
def describe(request):
|
||||
return jingo.render(request, 'hub/describe.html')
|
||||
|
||||
|
||||
def media(request):
|
||||
return jingo.render(request, 'hub/media.html')
|
||||
|
||||
|
||||
def done(request):
|
||||
return jingo.render(request, 'hub/done.html')
|
|
@ -1,9 +1,13 @@
|
|||
from lib.urls_base import *
|
||||
|
||||
|
||||
urlpatterns += patterns('',
|
||||
('^hub/', include('mkt.hub.urls')),
|
||||
)
|
||||
|
||||
|
||||
# Marketplace UI Experiments
|
||||
if settings.POTCH_MARKETPLACE_EXPERIMENTS:
|
||||
urlpatterns += patterns('',
|
||||
('^marketplace-experiments/', include('mkt.experiments.urls'))
|
||||
)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче