Mercurial > hg > agora-dellsystem
changeset 114:32a37a26534b
Merge back diff lexer
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Thu, 13 Sep 2012 13:59:45 -0400 |
parents | 892c7fbd3b35 (current diff) 4d5f23285bc2 (diff) |
children | 1abdcf1cf5cb |
files | |
diffstat | 25 files changed, 444 insertions(+), 132 deletions(-) [+] |
line wrap: on
line diff
--- a/apps/snippet/models.py +++ b/apps/snippet/models.py @@ -3,7 +3,6 @@ import random from django.db import models -from django.db.models import permalink from django.utils.translation import ugettext_lazy as _ from django.contrib.auth.models import User @@ -51,7 +50,7 @@ def get_title(self): return self.title or _('Snippet #%d' % self.id) - @permalink + @models.permalink def get_absolute_url(self): return ('snippet_details', (self.secret_id,))
--- a/static/css/agora.less +++ b/static/css/agora.less @@ -183,7 +183,7 @@ } p { - padding: 5px 0; + padding-bottom: 5px; } .snippetform { @@ -265,3 +265,75 @@ border-bottom: 1px solid @lightGrey; } } + +ul { + padding: 5px 0; + margin-left: 20px; +} + +#login-popup { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.3); + z-index: 200; +} + +#login-form { + @width: 600px; + @height: 300px; + @verticalPadding: 20px; + + .box-shadow(0 0 5px 1px rgba(0, 0, 0, 0.3)); + width: @width; + height: @height - (@verticalPadding * 2); + position: absolute; + top: 50%; + left: 50%; + margin-left: -@width / 2; + margin-top: -@height / 2; + background: @white; + .border-radius(5px); + padding: @verticalPadding 30px; +} + +.errors { + padding-top: 5px; + padding-left: 5px; + background: @lightOrange; + margin-bottom: 10px; + border: 1px solid @orange; + .border-radius(5px); +} + +form { + .form-line { + label { + float: left; + text-align: right; + } + } + + .form-input { + margin-left: 180px; + } + + .errors { + clear: both; + } +} + +dl { + dt { + float: left; + clear: left; + font-weight: bold; + padding-right: 5px; + } + + dd { + margin-left: 200px; + } +}
--- a/static/css/code.less +++ b/static/css/code.less @@ -1,27 +1,38 @@ -// For all syntax-highlighted code +.line-number { + width: 30px; + text-align: right; + font-weight: bold; + padding-right: 10px; + .disable-select; +} + .highlight { width: 650px; - padding: 10px; - .border-radius(7px); - overflow-x: auto; - border: 1px solid @lightGrey; + white-space: pre-wrap; + border-style: solid; + border-color: @lightGrey; + border-width: 0 1px; + padding: 0 10px; +} - &.wrap { - white-space: pre-wrap; - width: 688px; +.snippet tr { + &:first-child td { + border-top-width: 1px; + padding-top: 10px; + .border-radius(7px 7px 0 0); + } + + &:last-child td { + border-bottom-width: 1px; + padding-bottom: 10px; + .border-radius(0 0 7px 7px); } } -.numbers, .highlight { - line-height: 18px; +.snippet table { + font-family: monospace; + border-spacing: 0; + td { + vertical-align: top; + } } - -#line-numbers { - vertical-align: top; - padding-top: 11px; - width: 40px; -} - -.snippet table { - border-spacing: 0; -}
--- a/static/css/code/autumn.less +++ b/static/css/code/autumn.less @@ -1,4 +1,4 @@ -.highlight &.autumn { +.snippet &.autumn { .hll { background-color: #ffffcc } .c { color: #aaaaaa; font-style: italic } /* Comment */ .err { color: #F00000; background-color: #F0A0A0 } /* Error */
--- a/static/css/code/borland.less +++ b/static/css/code/borland.less @@ -1,4 +1,4 @@ -.highlight &.borland { +.snippet &.borland { .hll { background-color: #ffffcc } .c { color: #008800; font-style: italic } /* Comment */ .err { color: #a61717; background-color: #e3d2d2 } /* Error */
--- a/static/css/code/fruity.less +++ b/static/css/code/fruity.less @@ -1,5 +1,7 @@ -.highlight &.fruity { - background: @almostBlack; +.snippet &.fruity { + .highlight { + background: @almostBlack; + } .hll { background-color: #333333 } .c { color: #008800; font-style: italic; } /* Comment */
--- a/static/css/code/monokai.less +++ b/static/css/code/monokai.less @@ -1,6 +1,8 @@ -.highlight &.monokai { - background: #272822; - color: #F8F8F2; +.snippet &.monokai { + .highlight { + background: #272822; + color: #F8F8F2; + } .hll { background-color: #49483e } .c { color: #75715e } /* Comment */
--- a/static/css/code/native.less +++ b/static/css/code/native.less @@ -1,5 +1,7 @@ -.highlight &.native { - background: @almostBlack; +.snippet &.native { + .highlight { + background: @almostBlack; + } .hll { background-color: #404040 } .c { color: #999999; font-style: italic } /* Comment */
--- a/static/css/code/tango.less +++ b/static/css/code/tango.less @@ -1,4 +1,4 @@ -.highlight &.tango { +.snippet &.tango { .hll { background-color: #ffffcc } .c { color: #8f5902; font-style: italic } /* Comment */ .err { color: #a40000; border: 1px solid #ef2929 } /* Error */
--- a/static/css/code/vibrant.less +++ b/static/css/code/vibrant.less @@ -1,8 +1,9 @@ // Modified version of the vibrant pygments stylesheet -.highlight &.vibrant { - color: @white; - background: @almostBlack; - .box-shadow(inset 0 0 40px rgba(0, 0, 0, 0.7)); +.snippet &.vibrant { + .highlight { + color: @white; + background: @almostBlack; + } // Comments .c {
--- a/static/css/code/vs.less +++ b/static/css/code/vs.less @@ -1,4 +1,4 @@ -.highlight &.vs { +.snippet &.vs { .hll { background-color: #ffffcc } .c { color: #008000 } /* Comment */ .err { border: 1px solid #FF0000 } /* Error */
--- a/static/css/mixins.less +++ b/static/css/mixins.less @@ -71,7 +71,7 @@ } .pill { - .inline-block; + display: block; background: @lighterGrey; border: 1px solid lighten(@mediumGrey, 10%); .border-radius(3px); @@ -81,6 +81,8 @@ line-height: 1; text-shadow: 0 1px 0 @white; .box-shadow(inset 0 0 3px 0px @white); + margin-bottom: 10px; + .center-align; &:hover { color: @white; @@ -95,3 +97,12 @@ .hidden { display: none; } + +.disable-select { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +}
--- a/static/css/variables.less +++ b/static/css/variables.less @@ -9,8 +9,9 @@ @offWhite: #FBFBFB; @white: #FFF; +@darkOrange: #D45500; @orange: #FF7F2A; -@darkOrange: #D45500; +@lightOrange: lighten(@orange, 25%); @darkBlue: #1B749D; @mediumBlue: #22A2CA;
new file mode 100644 --- /dev/null +++ b/static/js/agora.js @@ -0,0 +1,25 @@ +(function ($) { + // Handle showing the login popup + var handleLoginLink = function () { + var loginLink = $('.login-link'); + + if (loginLink.length) { + loginLink.click(function () { + $('#login-popup').show(); + + return false; + }); + + $('#login-popup').click(function (event) { + // Only catch events in the outer, overlay div + if (event.target === this) { + $(this).hide(); + } + }); + } + }; + + $(document).ready(function () { + handleLoginLink(); + }); +})(jQuery);
--- a/templates/base.djhtml +++ b/templates/base.djhtml @@ -54,6 +54,7 @@ {% block navbar %} <div id="breadcrumbs"> <div class="right-float"> + {% block login_breadcrumbs %} {% if user.is_authenticated %} <a href="{% url auth_logout %}">Logout</a> :: @@ -61,10 +62,11 @@ :: <a href="{% url show_profile user %}">View your profile ({{ user }})</a> {% else %} - <a href="{% url auth_login %}?next={{ request.path }}">Login</a> - :: - <a href="{% url registration_register %}">Register</a> + <a href="{% url login %}?next={{ request.path }}" class="login-link"> + Login or register + </a> {% endif %} + {% endblock %} </div> <div> {% block breadcrumbs %} @@ -92,7 +94,15 @@ </p> </div> <!-- END #footer --> + {% block login_form %} + <div id="login-popup" class="hidden"> + <div id="login-form"> + {% include "login_form.djhtml" %} + </div> + </div> + {% endblock %} <script src="/static/js/jquery.min.js"></script> + <script src="/static/js/agora.js"></script> {% block script_footer %} {% endblock %} </body>
--- a/templates/code.djhtml +++ b/templates/code.djhtml @@ -4,42 +4,82 @@ <h1>Browse code submissions</h1> -<a class="pill" href="{% url snippet_new %}">Post a snippet</a> -{% if user.is_authenticated %} -<a class="pill" href="">Upload a single</a> -<a class="pill" href="">Upload a bundle</a> -{% else %} -<a class="pill" href="{% url auth_login %}">Login to upload singles/bundles</a> +{% if not user.is_authenticated %} +<p class="hint"> + Welcome to Agora. +</p> {% endif %} -<br /> -<br /> - <div class="row"> <div class="span3"> - <h2 class="center-align"><a href="{% url snippet_explore %}">Snippets</a></h2> + <h2 class="center-align">Snippets</h2> + <a class="pill" href="{% url snippet_new %}"> + Post a snippet + </a> + {% if snippets %} <ul> - <li>test</li> - <li>test</li> - <li>test</li> - <li>test</li> + {% for snippet in snippets %} + <li> + <a href="{{ snippet.get_absolute_url }}"> + <strong>{{ snippet.get_title }}</strong> + </a> + by + {% if snippet.author %} + <a href="{{ snippet.author.get_absolute_url }}"> + {{ snippet.author }} + </a> + {% else %} + anonymous + {% endif %} + <br /> + {{ snippet.published }} + </li> + {% endfor %} </ul> + <p class="right-float"> + <a href="{% url snippet_explore %}">View more »</a> + </p> + {% else %} + <p>No one has yet created a snippet. + <a href="{% url new_snippet %}">Be the first!</a> + </p> + {% endif %} </div><div class="span3"> <h2 class="center-align">Modules</h2> + {% if user.is_authenticated %} + <a class="pill" href="">Upload a modules</a> + {% else %} + <a class="pill login-link" href="{% url login %}"> + Login to upload modules + </a> + {% endif %} + {% if modules %} <ul> - <li>test</li> - <li>test</li> - <li>test</li> - <li>test</li> + {% for module in modules %} + <li>{{ module }}</li> + {% endfor %} </ul> + {% else %} + <p>This feature is not yet available.</p> + {% endif %} </div><div class="span3"> <h2 class="center-align">Forge</h2> + {% if user.is_authenticated %} + <a class="pill" href="">Add a module to the forge</a> + {% else %} + <a class="pill login-link" href="{% url login %}"> + Login to add a module to the forge + </a> + {% endif %} + {% if forge %} <ul> - <li>test</li> - <li>test</li> - <li>test</li> - <li>test</li> + {% for forge_module in forge %} + <li>{{ forge_module }}</li> + {% endfor %} </ul> + {% else %} + <p>This feature is not yet available.</p> + {% endif %} </div> </div>
--- a/templates/index.djhtml +++ b/templates/index.djhtml @@ -57,14 +57,16 @@ </div> </div> +{% if not user.is_authenticated %} <div class="center-align"> <p><a href="{% url code %}" class="button large">Explore</a> - <a href="{% url registration_register %}" class="button large"> - Register an account + <a href="{% url login %}" class="button large login-link"> + Login or register </a></p> <p> You can sign up, if you want, won't share your email, not required, etc </p> </div> +{% endif %} {% endblock %}
new file mode 100644 --- /dev/null +++ b/templates/login.djhtml @@ -0,0 +1,15 @@ +{% extends "base.djhtml" %} + +{% block content %} +{% include "login_form.djhtml" %} +{% endblock %} + +{% block login_form %} +{% endblock %} + +{% block login_breadcrumbs %} +{% endblock %} + +{% block breadcrumbs %} +<a href="{% url home %}">« Back to home</a> +{% endblock %}
new file mode 100644 --- /dev/null +++ b/templates/login_form.djhtml @@ -0,0 +1,85 @@ +<h1>Login or register</h1> + +{% if user.is_authenticated %} +<p> + You are already logged in. + <a href="{% url auth_logout %}">Logout »</a> +</p> +{% else %} +<form method="post" + action="{% url login %}?next={{ next_url|default:request.get_full_path }}"> + {% csrf_token %} + + <p>Already have an account? Enter your username and password below.</p> + + <div class="form-line"> + <label for="username">Username</label> + <div class="form-input"> + <input type="text" id="username" name="username" maxlength="30" /> + </div> + </div> + + {% if form.username.errors %} + <div class="errors"> + {{ form.username.errors }} + </div> + {% endif %} + + <div class="form-line"> + <label for="password1">Password</label> + <div class="form-input"> + <input type="password" id="password1" name="password1" /> + </div> + </div> + + {% if form.password1.errors %} + <div class="errors"> + {{ form.password1.errors }} + </div> + {% endif %} + + <br /> + + <p> + If you don't have an account yet, you can create one by filling out + the following fields as well: + </p> + + <div class="form-line"> + <label for="password2">Confirm password</label> + <div class="form-input"> + <input type="password" id="password2" name="password2" /> + </div> + </div> + + {% if form.password2.errors %} + <div class="errors"> + {{ form.password2.errors }} + </div> + {% endif %} + + <div class="form-line"> + <label for="email">Email address</label> + <div class="form-input"> + <input type="text" id="email" name="email" /> + </div> + </div> + + {% if form.email.errors %} + <div class="errors"> + {{ form.email.errors }} + </div> + {% endif %} + + <br /> + + <div class="center-align"> + <button type="submit" class="button large" name="action" value="login"> + Login + </button> + <button type="submit" class="button large" name="action" value="register"> + Register + </button> + </div> +</form> +{% endif %}
--- a/templates/profile/user.djhtml +++ b/templates/profile/user.djhtml @@ -1,44 +1,31 @@ {% extends "base.djhtml" %} -{% block boxtitle %} -{{profile.user.username}} <br/> -{% if profile.user = user %} -<small> - (<a href="{% url agora.apps.profile.views.editprofile %}"> - edit profile - </a>) -</small> -{% endif %} -{% endblock boxtitle%} +{% block breadcrumbs %} +Viewing profile: {{ profile.user }} +{% endblock %} + {% block content %} -<div id="userinfo"> - {% if profile.user.first_name or profile.user.last_name %} - <span class="userfield">Name</span> - <span class="userdata">{{name}}</span> - <br /> - {% endif %} - <span class="userfield">Preferred license</span> - <span class="userdata">{{profile.preferred_license}}</span> - <br /> - {% if profile.interests %} - <h4> - Interests - </h4> - <p class="userdata"> - {{profile.interests}} - </p> - {% endif %} + +<h1>{{ profile.user }}'s profile</h1> + +<dl> + {% if profile.user.first_name or profile.user.last_name %} + <dt>Name:</dt> + <dd>{{ name|default:"N/A" }}</dd> + {% endif %} - {% if profile.blurb %} - <h4> - About {{name}} - </h4> - <p class="userdata"> - {{profile.blurb}} - </p> -</div> -{% endif %} + <dt>Preferred license:</dt> + <dd>{{ profile.preferred_license }}</dd> +</dl> + +<h2>Interests</h2> + +<p>{{ profile.interests }}</p> + +<h2>About {{ name }}</h2> + +<p>{{ profile.blurb }}</p> {% endblock %} {% block content-related %}
--- a/templates/snippet/snippet_details.djhtml +++ b/templates/snippet/snippet_details.djhtml @@ -60,8 +60,6 @@ </a> — {% endif %} - <a id="toggle-wordwrap" href="#">{% trans "Toggle wordwrap" %}</a> - — Syntax highlighting style: <select id="change-highlighting" data-default="{{ default_style }}"> @@ -88,20 +86,18 @@ </div> </div> <br /> - <div class="snippet"> + <div class="snippet {{ default_style }}"> <table> + {% for line in snippet.content_splitted %} <tr> - <th id="line-numbers"> - {# this has to look like this due to the pre tags #} - <pre class="numbers">{% for l in lines %}<a href="#l{{ forloop.counter }}" id="l{{ forloop.counter }}">{{ forloop.counter }}</a> -{% endfor %}</pre> - </th> - <td> - {# this has to look like this due to the pre tags #} - <pre class="highlight {{ default_style }}">{% for line in snippet.content_splitted %}<span class="line" id="l{{ forloop.counter }}">{% if line %}{{ line|safe }}{% else %} {% endif %}</span> -{% endfor %}</pre> + <td class="line-number"> + <a name="l{{ forloop.counter }}" href="#l{{ forloop.counter }}"> + {{ forloop.counter }} + </a> </td> + <td class="highlight">{% if line %}{{ line|safe }}{% else %} {% endif %}</td> </tr> + {% endfor %} </table> </div>
--- a/templates/snippet/snippet_details.js +++ b/templates/snippet/snippet_details.js @@ -19,26 +19,13 @@ }); /** - * Word wrap - */ - $('#toggle-wordwrap').click(function () { - // Hide the line numbers (otherwise they could be wrong) - $('#line-numbers').toggle(); - - // Toggle the wrapping on the highlighted code - $('.highlight').toggleClass('wrap'); - - return false; - }); - - /** * Changing syntax highlighting colours */ var currentStyle = $('#change-highlighting').attr('data-default'); $('#change-highlighting').change(function () { var newStyle = $(this).find(':selected').attr('name'); - $('.highlight').removeClass(currentStyle).addClass(newStyle); + $('.snippet').removeClass(currentStyle).addClass(newStyle); currentStyle = newStyle; });
--- a/urls.py +++ b/urls.py @@ -1,4 +1,5 @@ from django.conf.urls.defaults import * +from django.views.generic import ListView # Uncomment the next two lines to enable the admin: from django.contrib import admin @@ -22,13 +23,16 @@ {'template': 'discuss.djhtml'}, name='discuss'), url(r'^code$', - 'django.views.generic.simple.direct_to_template', - {'template': 'code.djhtml'}, + 'views.code', name='code'), + url(r'^login', + 'views.login_register', + name='login'), url(r'^admin/doc/', include('django.contrib.admindocs.urls')), url(r'^admin/', include(admin.site.urls)), url(r'^accounts/logout/', 'django.contrib.auth.views.logout', - {'template_name' : 'index.djhtml', 'next_page' : '/'}), + {'template_name' : 'index.djhtml', 'next_page' : '/'} + ), url(r'^accounts/', include('registration.urls')), url(r'^licenses/', include('agora.apps.free_license.urls')), url(r'^users/', include('agora.apps.profile.urls')),
new file mode 100644 --- /dev/null +++ b/views.py @@ -0,0 +1,59 @@ +from django.contrib.auth import login, authenticate +from django.contrib.auth.forms import AuthenticationForm +from django.shortcuts import render, redirect +from django.core.urlresolvers import reverse +from registration.forms import RegistrationForm + +from agora.apps.snippet.models import Snippet + + +def code(request): + context = { + 'snippets': Snippet.objects.all()[:5], + 'modules': None, # temp + 'forge': None, # temp + } + + return render(request, 'code.djhtml', context) + + +def login_register(request): + form = None + next_url = None + + if request.method == 'POST': + action = request.POST.get('action') + next_url = request.GET.get('next') or reverse('login') + + if action == 'login': + username = request.POST.get('username', '') + password = request.POST.get('password1', '') + + if username and password: + user = authenticate(username=username, password=password) + login(request, user) + + return redirect(next_url) + else: + form = { + 'password1': { + 'errors': 'Please enter a username and password.', + }, + } + elif action == 'register': + form = RegistrationForm(request.POST) + + if form.is_valid(): + user = form.save() + login(request, user) + return redirect(next_url) + else: + # The action is not set. Malicious submission? + pass + + context = { + 'next_url': next_url, + 'form': form, + } + + return render(request, 'login.djhtml', context)