├── .gitignore ├── README.md ├── Vagrantfile ├── bootstrap.sh ├── community ├── __init__.py ├── admin.py ├── models.py ├── templates │ ├── _tags_filtering_form.html │ ├── base.html │ ├── base_site.html │ ├── community │ │ └── index.html │ ├── confirm_delete.html │ ├── footer.html │ └── header.html ├── templatetags │ ├── __init__.py │ └── devtags.py ├── tests.py ├── urls.py └── views.py ├── events ├── __init__.py ├── admin.py ├── forms.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto_20141211_1638.py │ ├── 0003_auto_20150308_2006.py │ ├── 0004_auto_20150310_2120.py │ └── __init__.py ├── mixins.py ├── models.py ├── templatetags │ ├── __init__.py │ └── event_tags.py ├── tests.py ├── urls.py └── views.py ├── fabfile.py ├── faq ├── __init__.py ├── admin.py ├── models.py ├── tests.py ├── urls.py └── views.py ├── fixtures └── planeta_pyar.json ├── jobs ├── __init__.py ├── admin.py ├── forms.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto_20150308_2348.py │ ├── 0003_job_slug.py │ ├── 0004_auto_20150316_2322.py │ ├── 0005_auto_20150316_2326.py │ └── __init__.py ├── models.py ├── tests.py ├── urls.py └── views.py ├── manage.py ├── newbie ├── __init__.py ├── admin.py ├── forms.py ├── models.py ├── tests.py ├── urls.py └── views.py ├── news ├── __init__.py ├── admin.py ├── forms.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto__add_field_newsarticle_introduction__chg_field_newsarticle_create.py │ └── __init__.py ├── models.py ├── tests.py ├── urls.py └── views.py ├── planet ├── __init__.py ├── admin.py ├── context_processors.py ├── feeds.py ├── forms.py ├── management │ ├── __init__.py │ └── commands │ │ ├── __init__.py │ │ ├── planet_add_feed.py │ │ ├── planet_update_all_feeds.py │ │ └── planet_update_feed.py ├── managers.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto__chg_field_post_guid.py │ ├── 0003_auto__chg_field_post_url.py │ ├── 0004_auto__chg_field_post_date_created.py │ ├── 0005_auto__add_category__add_field_feed_category.py │ ├── 0006_auto__chg_field_generator_version.py │ ├── 0007_migrate_guids.py │ ├── 0008_auto__chg_field_feed_guid.py │ ├── 0009_auto__chg_field_post_guid.py │ ├── 0009_drop_feed_guid_index.py │ └── __init__.py ├── models.py ├── settings.py ├── signals.py ├── sitemaps.py ├── tasks.py ├── templatetags │ ├── __init__.py │ └── planet_tags.py ├── tests │ ├── __init__.py │ ├── factories.py │ ├── managers.py │ └── views.py ├── urls.py └── views.py ├── projects ├── __init__.py ├── admin.py ├── apis.py ├── forms.py ├── models.py ├── tests.py ├── urls.py └── views.py ├── pyarweb ├── __init__.py ├── celery.py ├── formats │ ├── __init__.py │ └── es_AR │ │ ├── __init__.py │ │ └── formats.py ├── settings.py ├── urls.py ├── views.py └── wsgi.py ├── pycompanies ├── __init__.py ├── admin.py ├── forms.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto_20141211_1638.py │ └── __init__.py ├── models.py ├── tests.py ├── urls.py └── views.py ├── requirements.txt ├── static ├── bootstrap │ └── 3.1.1 │ │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ └── bootstrap.min.css │ │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ │ └── js │ │ ├── bootstrap-growl.min.js │ │ ├── bootstrap.js │ │ └── bootstrap.min.js ├── css │ ├── animate.css │ ├── event_map.css │ ├── search.css │ └── styles.css ├── img │ ├── banner.png │ ├── icons │ │ ├── icons.png │ │ ├── icons_active.png │ │ └── pyar.ico │ ├── logo-header.png │ ├── moin-www.png │ ├── pyar-footer.png │ ├── python-banner.png │ ├── python-footer.png │ ├── ribbon.png │ └── usla-footer.png ├── jquery-autosuggest │ ├── css │ │ ├── autoSuggest-grappelli.css │ │ └── autoSuggest.css │ └── js │ │ └── jquery.autoSuggest.minified.js ├── jquery │ └── 1.11.0 │ │ └── jquery.min.js └── js │ └── web.js └── templates ├── account ├── base.html ├── login.html ├── logout.html ├── password_reset.html ├── password_reset_done.html ├── password_reset_from_key.html ├── password_reset_from_key_done.html ├── signup.html └── signup_closed.html ├── buscador.html ├── companies ├── company_confirm_delete.html ├── company_detail.html ├── company_form.html └── company_list.html ├── events ├── event_confirm_delete.html ├── event_detail.html ├── event_detail_body.html ├── event_form.html ├── event_list.html └── next_events.html ├── faq └── all.html ├── irc └── irc.html ├── jobs ├── _jobs_tags.html ├── job_confirm_delete.html ├── job_detail.html ├── job_detail_feed.html ├── job_form.html ├── job_list.html ├── job_overview.html └── jobs_by_user.html ├── newbie ├── add-jedi.html ├── add-padawan.html ├── jedi-receive-response.html ├── jedi-request-successfully.html ├── list-jedi.html ├── list-padawan.html └── register.html ├── news ├── newsarticle_confirm_delete.html ├── newsarticle_detail.html ├── newsarticle_form.html └── newsarticle_list.html ├── planet ├── authors │ ├── blocks │ │ ├── list.html │ │ ├── list_for_feed.html │ │ └── list_for_tag.html │ ├── detail.html │ ├── list.html │ └── list_for_tag.html ├── base.html ├── blogs │ ├── confirm_delete.html │ ├── detail.html │ ├── list.html │ └── list_by_user.html ├── dummy.html ├── feeds │ ├── blocks │ │ ├── list_for_author.html │ │ ├── list_for_tag.html │ │ └── syndication_block.html │ ├── detail.html │ ├── form.html │ ├── list.html │ └── list_for_tag.html ├── list.html ├── microformats │ ├── foaf.xml │ └── opml.xml ├── posts │ ├── confirm_delete.html │ ├── detail.html │ ├── details.html │ ├── full_details.html │ ├── list.html │ └── short.html └── tags │ ├── blocks │ ├── authors_cloud.html │ ├── blogs_cloud.html │ ├── cloud.html │ ├── feeds_cloud.html │ └── related_list.html │ ├── cloud.html │ ├── detail.html │ └── list.html ├── projects ├── add.html ├── all.html ├── update.html └── view.html ├── registration ├── activate.html ├── activation_complete.html ├── activation_email.txt ├── activation_email_subject.txt ├── login.html ├── logout.html ├── registration_complete.html └── registration_form.html ├── special_page.html └── waliki └── detail.html /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.swp 3 | *.swo 4 | .venv 5 | db.sqlite3 6 | waliki_data 7 | waliki_attachments 8 | media 9 | .vagrant 10 | src 11 | pyarweb 12 | celerybeat-schedule 13 | local_settings.py 14 | Dockerfile 15 | docker-compose.yml 16 | run-docker.sh 17 | -------------------------------------------------------------------------------- /bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | yes | aptitude install git-core redis-server python3-dev python3-pip gettext libxml2-dev libxslt1-dev zlib1g-dev 4 | 5 | pip3 install -r /vagrant/requirements.txt 6 | -------------------------------------------------------------------------------- /community/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/community/__init__.py -------------------------------------------------------------------------------- /community/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /community/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /community/templates/_tags_filtering_form.html: -------------------------------------------------------------------------------- 1 | {% load i18n staticfiles %} 2 | 3 |
4 |
5 |

{% trans 'Filtrar por etiqueta' %}

6 |
7 |
8 |
9 |
10 | {% csrf_token %} 11 | {% for tag in tags %} 12 | 17 | 20 | {% endfor %} 21 |
22 |
23 |
24 | 25 | 26 |
27 |
28 |
29 |
30 |
31 |
32 | 33 | -------------------------------------------------------------------------------- /community/templates/base.html: -------------------------------------------------------------------------------- 1 | {% load staticfiles %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | {% block title_wrapper %}{% block title %}{% endblock title %} - {% endblock title_wrapper %} PyAr - Python Argentina 11 | 12 | 13 | 14 | 15 | 16 | 17 | {% block stylesheets %} {% endblock %} 18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {% block extra_head %}{% endblock %} 31 | 32 | 33 | 34 | 35 | 36 | {% include "header.html" %} 37 | 38 | {% block container_wrapper %} 39 | {% block content %}{% endblock %} 40 | {% block extra_content %}{% endblock extra_content %} 41 | {% endblock %} 42 | 43 | {% include "footer.html" %} 44 | 45 | {% block javascripts %}{% endblock %} 46 | 47 | {% block extra_script %}{% endblock %} 48 | 49 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /community/templates/base_site.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load i18n devtags %} 3 | {% load event_tags %} 4 | 5 | {% block content %} 6 | 7 |
8 | {% block beforemain %}{% endblock %} 9 | 10 |
11 | 12 | {% block container %} 13 | 14 |
15 | 16 |
17 | {% block left-column %}{% endblock %} 18 |
19 | 20 |
21 | 22 | {% block right-column %} 23 | 24 | 25 | 26 |
27 | 28 | 29 | 32 | 33 |
34 | 35 |
36 |
37 |

{% trans "Suscribite a la lista" %}

38 |
39 |
40 |
41 |
42 | 43 |
44 | 45 |
46 |
47 |
48 | 49 | 50 |
51 |
52 |

{% trans "Próximos Eventos" %}
53 | 54 | RSS 55 |

56 | 57 | 58 | 59 |
60 | 61 | {% next_events %} 62 | 63 |
64 | 65 | {% endblock %} 66 | 67 | 68 |
69 |
70 | 71 | {% endblock %} 72 |
73 | {% endblock %} 74 |
75 | -------------------------------------------------------------------------------- /community/templates/confirm_delete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load i18n %} 3 | 4 | {% load devtags %} 5 | 6 | {% block content %} 7 |
8 |
9 | 12 |
{% csrf_token %} 13 |

{% blocktrans %}¿Está seguro de que desear eliminar "{{ object }}"?{% endblocktrans %}

14 | 15 | {% trans 'Cancelar' %} 16 |
17 |
18 |
19 | {% endblock %} 20 | -------------------------------------------------------------------------------- /community/templates/footer.html: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /community/templates/header.html: -------------------------------------------------------------------------------- 1 | {% load staticfiles i18n %} 2 | 3 | 60 | -------------------------------------------------------------------------------- /community/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/community/templatetags/__init__.py -------------------------------------------------------------------------------- /community/templatetags/devtags.py: -------------------------------------------------------------------------------- 1 | from django.template import Library 2 | from lxml import etree 3 | 4 | register = Library() 5 | 6 | 7 | @register.filter 8 | def get_range(value): 9 | """ 10 | Filter - returns a list containing range made from given value 11 | Usage (in template): 12 | 13 | 16 | 17 | Results with the HTML: 18 | 23 | 24 | Instead of 3 one may use the variable set in the views 25 | """ 26 | return range(value) 27 | 28 | 29 | @register.filter 30 | def html2text(html): 31 | if html: 32 | return etree.tostring( 33 | etree.HTML(html), 34 | encoding='utf8', method='text' 35 | ) 36 | return '' -------------------------------------------------------------------------------- /community/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /community/urls.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.conf.urls import patterns, url 4 | 5 | 6 | urlpatterns = patterns('', 7 | url(r'^', 'community.views.homepage', name='homepage'), 8 | ) 9 | -------------------------------------------------------------------------------- /community/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | """Handle the Views of the Homepage and others.""" 5 | 6 | 7 | from django.http import Http404 8 | from django.shortcuts import render 9 | from django.views.generic.detail import SingleObjectMixin 10 | from django.views.generic.list import MultipleObjectMixin 11 | from django.utils.translation import ugettext_lazy as _ 12 | from jobs.models import Job 13 | from news.models import NewsArticle 14 | 15 | 16 | def homepage(request): 17 | news = NewsArticle.objects.order_by('-created')[:3] 18 | jobs = Job.objects.order_by('-created')[:3] 19 | return render(request, 'community/index.html', 20 | {'news': news, 'jobs': jobs}) 21 | 22 | 23 | def learning(request): 24 | title = _('Aprendiendo Python') 25 | return render(request, 'special_page.html', {'title': title, 'slug': 'AprendiendoPython'}) 26 | 27 | 28 | def about_pyar(request): 29 | title = _('Acerca de PyAr') 30 | return render(request, 'special_page.html', {'title': title, 'slug': 'QuienesSomos'}) 31 | 32 | 33 | def members(request): 34 | title = _('¿Dónde viven los miembros de PyAr?') 35 | return render(request, 'special_page.html', {'title': title, 'slug': 'MiembrosDePyAr'}) 36 | 37 | 38 | def mailing_list(request): 39 | title = _('Lista de Correo') 40 | return render(request, 'special_page.html', {'title': title, 'slug': 'ListaDeCorreo'}) 41 | 42 | 43 | class OwnedObject(SingleObjectMixin): 44 | 45 | """An object that needs to verify current user ownership 46 | before allowing manipulation. """ 47 | 48 | def get_object(self, *args, **kwargs): 49 | obj = super(OwnedObject, self).get_object(*args, **kwargs) 50 | try: 51 | if not obj.owner == self.request.user: 52 | raise Http404() 53 | except AttributeError: 54 | pass 55 | return obj 56 | 57 | 58 | class FilterableList(MultipleObjectMixin): 59 | 60 | """A list of objects whose queryset depends on excluded 61 | and included tags in the request. """ 62 | 63 | def dispatch(self, request, *args, **kwargs): 64 | self.included_tags = [] 65 | self.excluded_tags = [] 66 | for k, v in request.GET.items(): 67 | if k.startswith('tag_'): 68 | if v == '1': 69 | self.included_tags.append(k[4:]) 70 | elif v == '2': 71 | self.excluded_tags.append(k[4:]) 72 | return super(FilterableList, self).dispatch(request, *args, **kwargs) 73 | 74 | def get_queryset(self): 75 | object_list = self.model.objects.order_by('-created') 76 | included = self.included_tags 77 | excluded = self.excluded_tags 78 | if included: 79 | object_list = object_list.filter( 80 | tags__name__in=included).distinct() 81 | if excluded: 82 | object_list = object_list.exclude( 83 | tags__name__in=excluded).distinct() 84 | return object_list 85 | 86 | def get_context_data(self, **kwargs): 87 | context = super(FilterableList, self).get_context_data(**kwargs) 88 | context['tags'] = self.model.tags.all() 89 | context['included'] = self.included_tags 90 | context['excluded'] = self.excluded_tags 91 | return context 92 | -------------------------------------------------------------------------------- /events/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/events/__init__.py -------------------------------------------------------------------------------- /events/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import Event 4 | 5 | admin.site.register(Event) 6 | -------------------------------------------------------------------------------- /events/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django_summernote.widgets import SummernoteInplaceWidget 3 | from django.utils.translation import ugettext_lazy as _ 4 | 5 | from bootstrap3_datetime.widgets import DateTimePicker 6 | from crispy_forms.layout import Submit, Reset, Layout, Div, Field 7 | from crispy_forms.helper import FormHelper 8 | 9 | from .models import Event 10 | 11 | 12 | class EventForm(forms.ModelForm): 13 | 14 | description = forms.CharField(widget=SummernoteInplaceWidget()) 15 | 16 | start_at = forms.DateField( 17 | required=True, 18 | label=_('Comienza'), 19 | widget=DateTimePicker( 20 | options={ 21 | "format": "DD/MM/YYYY" 22 | } 23 | ) 24 | ) 25 | 26 | end_at = forms.DateField( 27 | required=True, 28 | label=_('Finaliza'), 29 | widget=DateTimePicker( 30 | options={ 31 | "format": "DD/MM/YYYY" 32 | } 33 | ) 34 | ) 35 | 36 | class Meta: 37 | model = Event 38 | fields = ( 39 | 'name', 40 | 'description', 41 | 'place', 42 | 'address', 43 | 'url', 44 | 'start_at', 45 | 'end_at' 46 | ) 47 | 48 | def __init__(self, *args, **kwargs): 49 | super(EventForm, self).__init__(*args, **kwargs) 50 | self.helper = FormHelper() 51 | self.form_method = "post" 52 | self.helper.add_input(Submit('job_submit', _('Guardar'))) 53 | self.helper.add_input(Reset('job_reset', _('Limpiar'), css_class='btn-default')) 54 | self.helper.layout = Layout( 55 | Div( 56 | 'name', 57 | 'description', 58 | 'place', 59 | 'address', 60 | 'url', 61 | 'start_at', 62 | 'end_at', 63 | ) 64 | ) 65 | 66 | def clean(self): 67 | cleaned_data = super(EventForm, self).clean() 68 | start_at = cleaned_data.get('start_at') 69 | end_at = cleaned_data.get('end_at') 70 | if start_at is not None and end_at is not None: 71 | if start_at > end_at: 72 | msg = 'La fecha de inicio es menor a la fecha de finalizacion' 73 | self._errors['start_at'] = [_(msg)] 74 | self._errors['end_at'] = [_(msg)] 75 | return cleaned_data 76 | 77 | def save(self, *args, **kwargs): 78 | super(EventForm, self).save(*args, **kwargs) 79 | self.instance.save() 80 | -------------------------------------------------------------------------------- /events/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | from django.conf import settings 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='Event', 17 | fields=[ 18 | ('id', models.AutoField(primary_key=True, serialize=False, verbose_name='ID', auto_created=True)), 19 | ('name', models.CharField(verbose_name='Título', max_length=100)), 20 | ('description', models.TextField(verbose_name='Descripcion')), 21 | ('place', models.CharField(verbose_name='Lugar', max_length=100)), 22 | ('lat', models.CharField(max_length=20)), 23 | ('lng', models.CharField(max_length=20)), 24 | ('zoom', models.IntegerField(default=4)), 25 | ('address', models.CharField(verbose_name='Direccion', max_length=100)), 26 | ('url', models.URLField(null=True, blank=True)), 27 | ('start_at', models.DateTimeField(null=True, verbose_name='Comienza a las', blank=True)), 28 | ('end_at', models.DateTimeField(null=True, verbose_name='Termina a las', blank=True)), 29 | ('created_at', models.DateTimeField(auto_now_add=True)), 30 | ('updated_at', models.DateTimeField(auto_now=True)), 31 | ('owner', models.ForeignKey(to=settings.AUTH_USER_MODEL)), 32 | ], 33 | options={ 34 | }, 35 | bases=(models.Model,), 36 | ), 37 | ] 38 | -------------------------------------------------------------------------------- /events/migrations/0002_auto_20141211_1638.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('events', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='event', 16 | name='end_at', 17 | field=models.DateField(verbose_name='Termina a las', blank=True, null=True), 18 | preserve_default=True, 19 | ), 20 | migrations.AlterField( 21 | model_name='event', 22 | name='start_at', 23 | field=models.DateField(verbose_name='Comienza a las', blank=True, null=True), 24 | preserve_default=True, 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /events/migrations/0003_auto_20150308_2006.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('events', '0002_auto_20141211_1638'), 11 | ] 12 | 13 | operations = [ 14 | migrations.RemoveField( 15 | model_name='event', 16 | name='lat', 17 | ), 18 | migrations.RemoveField( 19 | model_name='event', 20 | name='lng', 21 | ), 22 | migrations.RemoveField( 23 | model_name='event', 24 | name='zoom', 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /events/migrations/0004_auto_20150310_2120.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('events', '0003_auto_20150308_2006'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='event', 16 | name='end_at', 17 | field=models.DateField(verbose_name='Termina a las'), 18 | preserve_default=True, 19 | ), 20 | migrations.AlterField( 21 | model_name='event', 22 | name='start_at', 23 | field=models.DateField(verbose_name='Comienza a las'), 24 | preserve_default=True, 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /events/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/events/migrations/__init__.py -------------------------------------------------------------------------------- /events/mixins.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.core.urlresolvers import reverse_lazy 4 | 5 | from .models import Event 6 | 7 | 8 | class EventMixin(object): 9 | """Mixin for common attrs.""" 10 | 11 | model = Event 12 | 13 | def get_success_url(self): 14 | return reverse_lazy('events:events_list_all') 15 | -------------------------------------------------------------------------------- /events/models.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.models import User 2 | from django.db import models 3 | from django.utils.translation import ugettext_lazy as _ 4 | from django.core.urlresolvers import reverse 5 | 6 | 7 | class Event(models.Model): 8 | """A PyAr events.""" 9 | 10 | owner = models.ForeignKey(User) 11 | name = models.CharField(max_length=100, verbose_name=_('Título')) 12 | description = models.TextField(verbose_name=_('Descripcion')) 13 | place = models.CharField(max_length=100, verbose_name=_('Lugar')) 14 | address = models.CharField(max_length=100, verbose_name=_('Direccion')) 15 | url = models.URLField(blank=True, null=True) 16 | start_at = models.DateField(verbose_name=_('Comienza a las')) 17 | end_at = models.DateField(verbose_name=_('Termina a las')) 18 | created_at = models.DateTimeField(auto_now_add=True) 19 | updated_at = models.DateTimeField(auto_now=True) 20 | 21 | def __str__(self): 22 | return "%s by %s" % (self.name, self.owner) 23 | 24 | def get_absolute_url(self): 25 | return reverse('events:detail', args=[self.id]) 26 | -------------------------------------------------------------------------------- /events/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/events/templatetags/__init__.py -------------------------------------------------------------------------------- /events/templatetags/event_tags.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | 3 | from events.models import Event 4 | 5 | from django.utils import timezone 6 | 7 | register = template.Library() 8 | 9 | @register.inclusion_tag('events/next_events.html') 10 | def next_events(): 11 | events = Event.objects.filter( 12 | end_at__gte=timezone.now() 13 | ).order_by( 14 | '-updated_at' 15 | ) 16 | return {'events': events} 17 | -------------------------------------------------------------------------------- /events/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /events/urls.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.conf.urls import patterns, url 4 | from .views import (EventDetail, 5 | EventList, 6 | EventCreate, 7 | EventUpdate, 8 | EventDelete, 9 | EventsFeed) 10 | 11 | urlpatterns = patterns('', 12 | url(r'^$', EventList.as_view(), name='events_list_all'), 13 | url(r'^rss$', EventsFeed(), name='events_feed'), 14 | url(r'^(?P\d+)/$', EventDetail.as_view(), name='detail'), 15 | url(r'^add/$', EventCreate.as_view(), name='add'), 16 | url(r'^(?P\d+)/edit/$', EventUpdate.as_view(), name='edit'), 17 | url(r'^(?P\d+)/delete/$', EventDelete.as_view(), name='delete'), 18 | ) 19 | -------------------------------------------------------------------------------- /events/views.py: -------------------------------------------------------------------------------- 1 | from django.utils import timezone 2 | from django.views.generic import ListView, DetailView 3 | from django.views.generic.edit import (CreateView, 4 | UpdateView, 5 | DeleteView) 6 | 7 | from braces.views import LoginRequiredMixin 8 | 9 | from community.views import OwnedObject 10 | 11 | from .forms import EventForm 12 | from .models import Event 13 | from .mixins import EventMixin 14 | 15 | from django.contrib.syndication.views import Feed 16 | from django.core.urlresolvers import reverse_lazy 17 | 18 | 19 | class EventsFeed(Feed): 20 | title = "Feed de Próximos Eventos de PyAr" 21 | link = reverse_lazy("events:events_list_all") 22 | description = "Eventos de Python Argentina y relacionados" 23 | description_template = "events/event_detail_body.html" 24 | 25 | def items(self): 26 | return Event.objects.filter(end_at__gte=timezone.now()).order_by('-updated_at')[:10] 27 | 28 | def item_title(self, item): 29 | return item.name 30 | 31 | def item_pubdate(self, item): 32 | return item.created_at 33 | 34 | def item_updateddate(self, item): 35 | return item.updated_at 36 | 37 | def author_name(self, item): 38 | if item: 39 | return str(item.owner) 40 | return '' 41 | 42 | 43 | class EventList(ListView): 44 | queryset = Event.objects.filter( 45 | end_at__lt=timezone.now()).order_by('-updated_at') 46 | paginate_by = 5 47 | context_object_name = "eventos_pasados" 48 | 49 | def get_context_data(self, **kwargs): 50 | context = super(EventList, self).get_context_data(**kwargs) 51 | context['eventos_proximos'] = Event.objects.filter( 52 | end_at__gte=timezone.now()).order_by('-updated_at') 53 | 54 | return context 55 | 56 | 57 | class EventDetail(EventMixin, DetailView): 58 | context_object_name = "event" 59 | 60 | 61 | class EventCreate(LoginRequiredMixin, EventMixin, CreateView): 62 | form_class = EventForm 63 | 64 | def form_valid(self, form): 65 | form.instance.owner = self.request.user 66 | return super(EventCreate, self).form_valid(form) 67 | 68 | 69 | class EventUpdate(LoginRequiredMixin, EventMixin, OwnedObject, UpdateView): 70 | form_class = EventForm 71 | 72 | 73 | class EventDelete(LoginRequiredMixin, OwnedObject, DeleteView): 74 | model = Event 75 | success_url = reverse_lazy("events_list_all") 76 | -------------------------------------------------------------------------------- /fabfile.py: -------------------------------------------------------------------------------- 1 | from fabric.api import env, run, task 2 | from fabric.context_managers import cd 3 | from fabric.contrib.console import confirm 4 | 5 | env.hosts = ['python.org.ar'] 6 | env.user = 'www-pyar' 7 | env.project_path = '/home/www-pyar/pyarweb/pyarweb/' 8 | env.venv_path = '/home/www-pyar/pyarweb/pyarweb_venv/' 9 | env.pip_bin = '%sbin/pip' % (env.venv_path) 10 | env.python_bin = '%sbin/python' % (env.venv_path) 11 | env.gunicorn_bin = '%sbin/gunicorn' % (env.venv_path) 12 | 13 | 14 | @task 15 | def deploy(): 16 | """Deploy de PyArweb en python.org.ar.""" 17 | git_pull() 18 | if confirm("Install/upgrade requirements with pip?"): 19 | install_requeriments() 20 | django_command('collectstatic') 21 | django_command('migrate') 22 | restart() 23 | 24 | @task 25 | def restart(): 26 | """Restart gunicorn sending HUP signal to his pid.""" 27 | run('kill -HUP $(cat /tmp/pyar_web.pid)') 28 | 29 | 30 | def git_pull(): 31 | with cd(env.project_path): 32 | run('git pull') 33 | 34 | 35 | def django_command(command): 36 | with cd(env.project_path): 37 | run('%s manage.py %s --noinput' % (env.python_bin, command)) 38 | 39 | 40 | def install_requeriments(): 41 | with cd(env.project_path): 42 | run('%s install --upgrade -r requirements.txt' % (env.pip_bin)) 43 | -------------------------------------------------------------------------------- /faq/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/faq/__init__.py -------------------------------------------------------------------------------- /faq/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Topic, Question 3 | 4 | 5 | admin.site.register(Topic) 6 | admin.site.register(Question) 7 | -------------------------------------------------------------------------------- /faq/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Topic(models.Model): 5 | 6 | """Generic Topics for FAQ question grouping.""" 7 | 8 | name = models.CharField(max_length=150) 9 | slug = models.SlugField(max_length=150) 10 | sort_order = models.IntegerField(default=0) 11 | 12 | class Meta: 13 | ordering = ['sort_order', 'name'] 14 | 15 | def __str__(self): 16 | return self.name 17 | 18 | 19 | class Question(models.Model): 20 | text = models.TextField() 21 | slug = models.SlugField(max_length=150) 22 | answer = models.TextField() 23 | topic = models.ForeignKey(Topic) 24 | active = models.BooleanField(default=True) 25 | sort_order = models.IntegerField(default=0) 26 | 27 | class Meta: 28 | ordering = ['sort_order', 'text'] 29 | 30 | def __str__(self): 31 | return self.text 32 | -------------------------------------------------------------------------------- /faq/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /faq/urls.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.conf.urls import patterns, url 4 | from .views import ( 5 | list_all, 6 | ) 7 | 8 | urlpatterns = patterns('', url(r'^$', list_all, name='faq_all'),) 9 | -------------------------------------------------------------------------------- /faq/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | from .models import Question 3 | 4 | 5 | def list_all(request): 6 | """Return all FAQs ordered by topic.""" 7 | 8 | faqs_list = Question.objects.filter(active=True).order_by('topic') 9 | 10 | context = dict(faqs=faqs_list) 11 | return render(request, 'faq/all.html', context) 12 | -------------------------------------------------------------------------------- /jobs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/jobs/__init__.py -------------------------------------------------------------------------------- /jobs/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Job 3 | 4 | 5 | admin.site.register(Job) 6 | -------------------------------------------------------------------------------- /jobs/forms.py: -------------------------------------------------------------------------------- 1 | from random import choice 2 | from django import forms 3 | from django.utils.translation import ugettext_lazy as _ 4 | from django.core.urlresolvers import reverse 5 | from .models import Job 6 | from crispy_forms.layout import Submit, Reset, Layout 7 | from crispy_forms.helper import FormHelper 8 | from django.utils.safestring import mark_safe 9 | from django_summernote.widgets import SummernoteInplaceWidget 10 | 11 | 12 | class JobForm(forms.ModelForm): 13 | """A PyAr Jobs form.""" 14 | 15 | description = forms.CharField(widget=SummernoteInplaceWidget()) 16 | 17 | def __init__(self, *args, **kwargs): 18 | super(JobForm, self).__init__(*args, **kwargs) 19 | 20 | company_help_text = ''.join(( 21 | 'Opcionalmente elija la empresa que ofrece el puesto. ', 22 | 'Si la empresa no aparece en el listado, puede registrarla ', 23 | 'haciendo click {0}'.format( 24 | 'aquí' 25 | ).format( 26 | reverse('companies:add') 27 | ))) 28 | title_help_text = ''.join(( 29 | 'Título del empleo, por ejemplo: {0}'.format( 30 | choice([ 31 | 'Backend Developer', 32 | 'Django Developer', 33 | 'Frontend Developer', 34 | 'Senior Django Developer', 35 | 'Full Stack Python Developer', 36 | ]) 37 | ) 38 | )) 39 | tags_help_text = ''.join(( 40 | 'Agregue algunos tags / etiquetas ', 41 | 'que esten relacionadas con el puesto de trabajo. ' 42 | 'Los tags deben estar separados por comas, por ejemplo: ', 43 | 'Django, Python, MySQL, Linux' 44 | )) 45 | 46 | seniority_help_text = ''.join(( 47 | 'Opcionalmente puede especificar la experiencia requerida ', 48 | 'para el puesto.' 49 | )) 50 | 51 | remote_work_help_text = ''.join(( 52 | 'Se permite la modalidad de trabajo desde casa (homeworking).' 53 | )) 54 | 55 | self.fields['title'].label = 'Título de la oferta' 56 | self.fields['tags'].label = 'Etiquetas / Tags / Tecnologías' 57 | self.fields['title'].help_text = title_help_text 58 | self.fields['tags'].help_text = tags_help_text 59 | self.fields['seniority'].help_text = seniority_help_text 60 | self.fields['company'].help_text = company_help_text 61 | self.fields['remote_work'].help_text = remote_work_help_text 62 | self.fields['description'].label = 'Descripción' 63 | self.helper = FormHelper() 64 | self.helper.layout = Layout( 65 | 'title', 66 | 'company', 67 | 'location', 68 | 'email', 69 | 'seniority', 70 | 'remote_work', 71 | 'tags', 72 | 'description', 73 | ) 74 | self.helper.add_input(Submit('job_submit', _('Guardar'))) 75 | self.helper.add_input(Reset('job_reset', _('Limpiar'), 76 | css_class='btn-default')) 77 | 78 | class Meta: 79 | model = Job 80 | exclude = ('owner',) 81 | -------------------------------------------------------------------------------- /jobs/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | from django.conf import settings 6 | import taggit_autosuggest.managers 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 13 | ('pycompanies', '0002_auto_20141211_1638'), 14 | ('taggit', '0001_initial'), 15 | ] 16 | 17 | operations = [ 18 | migrations.CreateModel( 19 | name='Job', 20 | fields=[ 21 | ('id', models.AutoField(auto_created=True, serialize=False, primary_key=True, verbose_name='ID')), 22 | ('title', models.CharField(max_length=255, verbose_name='Título')), 23 | ('description', models.TextField(verbose_name='Descripción')), 24 | ('location', models.CharField(max_length=100, verbose_name='Lugar')), 25 | ('email', models.EmailField(max_length=75)), 26 | ('created', models.DateTimeField(auto_now_add=True)), 27 | ('modified', models.DateTimeField(auto_now=True)), 28 | ('company', models.ForeignKey(null=True, blank=True, to='pycompanies.Company', verbose_name='Empresa')), 29 | ('owner', models.ForeignKey(to=settings.AUTH_USER_MODEL)), 30 | ('tags', taggit_autosuggest.managers.TaggableManager(through='taggit.TaggedItem', to='taggit.Tag', help_text='A comma-separated list of tags.', verbose_name='Etiquetas')), 31 | ], 32 | options={ 33 | }, 34 | bases=(models.Model,), 35 | ), 36 | ] 37 | -------------------------------------------------------------------------------- /jobs/migrations/0002_auto_20150308_2348.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('jobs', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='job', 16 | name='remote_work', 17 | field=models.BooleanField(default=False, verbose_name='Trabajo Remoto'), 18 | preserve_default=True, 19 | ), 20 | migrations.AddField( 21 | model_name='job', 22 | name='seniority', 23 | field=models.CharField(default='', max_length=100, verbose_name='Experiencia', blank=True, choices=[('Trainee', 'Trainee'), ('Junior', 'Junior'), ('Semi Senior', 'Semi Senior'), ('Senior', 'Senior')]), 24 | preserve_default=True, 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /jobs/migrations/0003_job_slug.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | import autoslug.fields 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('jobs', '0002_auto_20150308_2348'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='job', 17 | name='slug', 18 | field=autoslug.fields.AutoSlugField(default='', editable=False), 19 | preserve_default=False, 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /jobs/migrations/0004_auto_20150316_2322.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | def update_slug(apps, schema_editor): 8 | # We can't import the Person model directly as it may be a newer 9 | # version than this migration expects. We use the historical version. 10 | Job = apps.get_model("jobs", "Job") 11 | for j in Job.objects.all(): 12 | j.save() 13 | 14 | 15 | class Migration(migrations.Migration): 16 | 17 | dependencies = [ 18 | ('jobs', '0003_job_slug'), 19 | ] 20 | 21 | operations = [ 22 | migrations.RunPython(update_slug) 23 | ] 24 | -------------------------------------------------------------------------------- /jobs/migrations/0005_auto_20150316_2326.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | import autoslug.fields 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('jobs', '0004_auto_20150316_2322'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='job', 17 | name='slug', 18 | field=autoslug.fields.AutoSlugField(unique=True, editable=False), 19 | preserve_default=True, 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /jobs/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/jobs/migrations/__init__.py -------------------------------------------------------------------------------- /jobs/models.py: -------------------------------------------------------------------------------- 1 | from autoslug import AutoSlugField 2 | from django.contrib.auth.models import User 3 | from django.core.urlresolvers import reverse 4 | from django.db import models 5 | from django.utils.translation import ugettext as _ 6 | from pycompanies.models import Company 7 | from taggit_autosuggest.managers import TaggableManager 8 | 9 | JOB_SENIORITIES = ( 10 | ('Trainee', 'Trainee'), 11 | ('Junior', 'Junior'), 12 | ('Semi Senior', 'Semi Senior'), 13 | ('Senior', 'Senior'), 14 | ) 15 | 16 | 17 | class Job(models.Model): 18 | """A PyAr Job.""" 19 | 20 | title = models.CharField(max_length=255, verbose_name=_('Título')) 21 | company = models.ForeignKey(Company, 22 | null=True, 23 | blank=True, 24 | verbose_name=_('Empresa')) 25 | description = models.TextField(verbose_name=_('Descripción')) 26 | location = models.CharField(max_length=100, verbose_name=_('Lugar')) 27 | email = models.EmailField() 28 | owner = models.ForeignKey(User) 29 | created = models.DateTimeField(auto_now_add=True) 30 | modified = models.DateTimeField(auto_now=True) 31 | tags = TaggableManager(verbose_name=_('Etiquetas')) 32 | remote_work = models.BooleanField( 33 | default=False, 34 | verbose_name=_('Trabajo Remoto')) 35 | seniority = models.CharField( 36 | max_length=100, 37 | blank=True, 38 | default='', 39 | choices=JOB_SENIORITIES, 40 | verbose_name=_('Experiencia')) 41 | slug = AutoSlugField(populate_from='title', unique=True) 42 | 43 | def __str__(self): 44 | return u'{0}'.format(self.title) 45 | 46 | @property 47 | def is_remote_work_allowed(self): 48 | return self.remote_work 49 | 50 | def get_absolute_url(self): 51 | return reverse('jobs_view', kwargs={'slug': self.slug}) 52 | 53 | -------------------------------------------------------------------------------- /jobs/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /jobs/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.decorators import login_required 2 | from django.views.generic.detail import DetailView 3 | from django.conf.urls import patterns, url 4 | from .models import Job 5 | from .views import JobCreate, JobList, JobDelete, JobUpdate, JobsFeed 6 | 7 | 8 | urlpatterns = patterns('', 9 | url(r'^$', JobList.as_view(), name='jobs_list_all'), 10 | url(r'^rss$', JobsFeed(), name='jobs_feed'), 11 | url(r'^add/$', login_required( 12 | JobCreate.as_view()), name='jobs_add'), 13 | url(r'^(?P[\w-]+)/$', 14 | DetailView.as_view(model=Job), 15 | name='jobs_view'), 16 | url(r'^(?P\d+)/delete/$', 17 | login_required(JobDelete.as_view()), 18 | name='jobs_delete'), 19 | url(r'^(?P\d+)/update/$', 20 | login_required(JobUpdate.as_view()), 21 | name='jobs_update'), 22 | url(r'^tag/(?P[\w-]+)/$', 23 | JobList.as_view(), 24 | name='jobs_list_by_tag'), 25 | ) 26 | -------------------------------------------------------------------------------- /jobs/views.py: -------------------------------------------------------------------------------- 1 | from django.core.urlresolvers import reverse_lazy 2 | from django.views.generic.edit import UpdateView, CreateView, DeleteView 3 | from django.views.generic import ListView 4 | from django.contrib.syndication.views import Feed 5 | from community.views import OwnedObject, FilterableList 6 | from .models import Job 7 | from .forms import JobForm 8 | 9 | 10 | class JobsFeed(Feed): 11 | title = "Feed de ofertas laborales de Pyar" 12 | link = reverse_lazy("jobs_list_all") 13 | description = "Todas las ofertas laborales con Python publicadas en Python Argentina" 14 | 15 | description_template = "jobs/job_detail_feed.html" 16 | 17 | def items(self): 18 | return Job.objects.order_by('-created')[0:10] 19 | 20 | def item_title(self, item): 21 | return item.title 22 | 23 | def item_pubdate(self, item): 24 | return item.created 25 | 26 | def author_name(self, item): 27 | if item and item.company: 28 | return item.company.name 29 | return '' 30 | 31 | def author_email(self, item): 32 | if item: 33 | return item.email 34 | return '' 35 | 36 | def author_link(self, item): 37 | if item and item.company: 38 | return item.company.get_absolute_url() 39 | return '' 40 | 41 | def categories(self, item): 42 | if item: 43 | return item.tags.values_list('name', flat=True) 44 | return () 45 | 46 | 47 | class JobCreate(CreateView): 48 | model = Job 49 | form_class = JobForm 50 | 51 | def form_valid(self, form): 52 | form.instance.owner = self.request.user 53 | return super(JobCreate, self).form_valid(form) 54 | 55 | 56 | class JobList(ListView, FilterableList): 57 | model = Job 58 | paginate_by = 20 59 | 60 | def get_queryset(self): 61 | tag_slugs = self.kwargs.get('tag') 62 | if tag_slugs: 63 | return Job.objects.filter(tags__slug__in=[tag_slugs]) 64 | return Job.objects.all() 65 | 66 | 67 | class JobUpdate(UpdateView, OwnedObject): 68 | 69 | """Edit jobs that use Python.""" 70 | model = Job 71 | form_class = JobForm 72 | 73 | 74 | class JobDelete(DeleteView, OwnedObject): 75 | 76 | """Delete a Job.""" 77 | model = Job 78 | success_url = reverse_lazy('jobs_list_all') 79 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pyarweb.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /newbie/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/newbie/__init__.py -------------------------------------------------------------------------------- /newbie/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import ( 3 | Project, 4 | Jedi, 5 | Padawan, 6 | ) 7 | 8 | admin.site.register(Project) 9 | admin.site.register(Jedi) 10 | admin.site.register(Padawan) 11 | -------------------------------------------------------------------------------- /newbie/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django.utils.translation import ugettext as _ 3 | from .models import Padawan, Jedi 4 | from taggit.forms import TagField 5 | 6 | 7 | class PadawanForm(forms.ModelForm): 8 | """A PyAr Padawan form.""" 9 | class Meta: 10 | model = Padawan 11 | fields = ('description', 'interests') 12 | 13 | interests = TagField(label=_("Intereses")) 14 | 15 | 16 | class JediForm(forms.ModelForm): 17 | """A PyAr Jedi form.""" 18 | class Meta: 19 | model = Jedi 20 | fields = ('description', 'available', 'skills') 21 | 22 | skills = TagField(label=_("Lo que puedo enseñar")) 23 | -------------------------------------------------------------------------------- /newbie/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /newbie/urls.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.conf.urls import patterns, url 4 | 5 | from .views import ( 6 | padawan_add, 7 | jedi_add, 8 | jedi_list, 9 | padawan_list, 10 | jedi_request, 11 | register, 12 | jedi_answer, 13 | ) 14 | 15 | 16 | urlpatterns = patterns('', 17 | 18 | url(r'^$', register, name='newbie.home'), 19 | url(r'^padawan/register$', padawan_add, name='padawan.add'), 20 | url(r'^jedi/register$', jedi_add, name='jedi.add'), 21 | 22 | url(r'^padawan/list$', padawan_list, name='padawan.list'), 23 | url(r'^jedi/list$', jedi_list, name='jedi.list'), 24 | 25 | url(r'^request/(?P\d+)$', jedi_request, name='jedi.request'), 26 | url( 27 | r'^send-answer/(?P\d+)/(?P\d+)/(?P.*)$', 28 | jedi_answer, 29 | name='jedi.answer' 30 | ) 31 | ) 32 | -------------------------------------------------------------------------------- /newbie/views.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.decorators import login_required 2 | from django.utils.translation import ugettext as _ 3 | from django.shortcuts import ( 4 | render, 5 | get_object_or_404, 6 | ) 7 | from django.http import HttpResponse 8 | from .forms import PadawanForm, JediForm 9 | from .models import Jedi, Padawan 10 | 11 | 12 | def register(request): 13 | is_padawan = Padawan.objects.filter(user=request.user).exists() 14 | is_jedi = Jedi.objects.filter(user=request.user).exists() 15 | return render(request, 'newbie/register.html', {"is_padawan": is_padawan, "is_jedi": is_jedi}) 16 | 17 | 18 | @login_required 19 | def padawan_add(request): 20 | """ Add a new Padawan """ 21 | form = PadawanForm(request.POST or None) 22 | if form.is_valid(): 23 | padawan = form.save(commit=False) 24 | padawan.user = request.user 25 | try: 26 | padawan.save() 27 | form.save_m2m() 28 | except Exception: 29 | return HttpResponse(_("En realidad ya eres un Padawan")) 30 | return render(request, 'newbie/add-padawan.html', {'success': True}) 31 | 32 | context = dict(form=form) 33 | return render(request, 'newbie/add-padawan.html', context) 34 | 35 | 36 | @login_required 37 | def jedi_add(request): 38 | """ Add a new Jedi """ 39 | 40 | form = JediForm(request.POST or None) 41 | if form.is_valid(): 42 | jedi = form.save(commit=False) 43 | jedi.user = request.user 44 | try: 45 | jedi.save() 46 | form.save_m2m() 47 | except Exception: 48 | return HttpResponse(_("En realidad ya eres un Jedi")) 49 | return render(request, 'newbie/add-jedi.html', {'success': True}) 50 | 51 | 52 | context = dict(form=form) 53 | return render(request, 'newbie/add-jedi.html', context) 54 | 55 | 56 | def jedi_list(request): 57 | """ List Jedi """ 58 | 59 | jedi_list = Jedi.objects.all() 60 | context = { 61 | "jedi_list": jedi_list 62 | } 63 | 64 | return render(request, 'newbie/list-jedi.html', context) 65 | 66 | 67 | def padawan_list(request): 68 | """ List Jedi """ 69 | 70 | padawan_list = Padawan.objects.all() 71 | context = { 72 | "padawan_list": padawan_list 73 | } 74 | return render(request, 'newbie/list-padawan.html', context) 75 | 76 | 77 | def jedi_request(request, jedi_id): 78 | """ Start the process to connect with a Jedi """ 79 | 80 | jedi = get_object_or_404(Jedi, id=jedi_id) 81 | padawan = get_object_or_404(Padawan, user=request.user) 82 | padawan.send_project_request(jedi) 83 | return render(request, 'newbie/jedi-request-successfully.html', {}) 84 | 85 | 86 | def jedi_answer(request, jedi_id, padawan_id, answer): 87 | jedi = get_object_or_404(Jedi, id=jedi_id) 88 | padawan = get_object_or_404(Padawan, user=request.user) 89 | jedi.accept_padawan(padawan_id) 90 | return render(request, 'newbie/jedi-request-successfully.html', 91 | { 92 | "padawan_email": padawan.user.email, 93 | "jedi_accept": True 94 | } 95 | ) 96 | -------------------------------------------------------------------------------- /news/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/news/__init__.py -------------------------------------------------------------------------------- /news/admin.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django.contrib import admin 3 | from .models import NewsArticle 4 | from django_summernote.widgets import SummernoteWidget 5 | 6 | 7 | class NewsAdminForm(forms.ModelForm): 8 | class Meta: 9 | model = NewsArticle 10 | widgets = {'body': SummernoteWidget()} 11 | 12 | 13 | class NewsAdmin(admin.ModelAdmin): 14 | form = NewsAdminForm 15 | 16 | admin.site.register(NewsArticle, NewsAdmin) 17 | -------------------------------------------------------------------------------- /news/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django_summernote.widgets import SummernoteInplaceWidget 3 | from django.utils.translation import ugettext_lazy as _ 4 | from crispy_forms.helper import FormHelper 5 | from crispy_forms.layout import Submit, Reset 6 | from .models import NewsArticle 7 | 8 | 9 | class NewsArticleForm(forms.ModelForm): 10 | """A PyAr news article form.""" 11 | 12 | body = forms.CharField(widget=SummernoteInplaceWidget()) 13 | 14 | def __init__(self, *args, **kwargs): 15 | super(NewsArticleForm, self).__init__(*args, **kwargs) 16 | self.helper = FormHelper() 17 | self.helper.add_input(Submit('news_submit', _('Guardar'))) 18 | self.helper.add_input(Reset('news_reset', _('Limpiar'), css_class='btn-default')) 19 | 20 | class Meta: 21 | model = NewsArticle 22 | exclude = ('owner',) 23 | -------------------------------------------------------------------------------- /news/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/news/migrations/__init__.py -------------------------------------------------------------------------------- /news/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.contrib.auth.models import User 3 | from django.utils.translation import ugettext as _ 4 | from taggit_autosuggest.managers import TaggableManager 5 | from model_utils.models import TimeStampedModel 6 | 7 | 8 | class NewsArticle(TimeStampedModel): 9 | 10 | """A PyAr news article.""" 11 | 12 | title = models.CharField(max_length=255, verbose_name=_('Título')) 13 | introduction = models.TextField(null=True, blank=True, 14 | verbose_name=_('Introducción')) 15 | body = models.TextField(verbose_name=_('Contenido')) 16 | owner = models.ForeignKey(User) 17 | tags = TaggableManager(verbose_name=_('Etiquetas'), blank=True) 18 | 19 | @models.permalink 20 | def get_absolute_url(self): 21 | return ('news_view', (self.id,), {}) 22 | 23 | def __unicode__(self): 24 | return u'{0}'.format(self.title) 25 | 26 | class Meta: 27 | ordering = ('-created',) -------------------------------------------------------------------------------- /news/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /news/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.decorators import login_required 2 | from django.views.generic.detail import DetailView 3 | from django.conf.urls import patterns, url 4 | from .models import NewsArticle 5 | from .views import ( 6 | NewsArticleCreate, 7 | NewsArticleDelete, 8 | NewsArticleList, 9 | NewsArticleUpdate, 10 | NewsArticleListTag, 11 | NewsFeed 12 | ) 13 | 14 | 15 | urlpatterns = patterns('', 16 | url(r'^$', NewsArticleList.as_view(), 17 | name='news_list_all'), 18 | url(r'^rss$', NewsFeed(), 19 | name='news_feed'), 20 | url(r'^add/$', 21 | login_required(NewsArticleCreate.as_view()), 22 | name='news_add'), 23 | url(r'^(?P\d+)/$', 24 | DetailView.as_view(model=NewsArticle), 25 | name='news_view'), 26 | url(r'^(?P\d+)/delete/$', 27 | login_required(NewsArticleDelete.as_view()), 28 | name='news_delete'), 29 | url(r'^(?P\d+)/update/$', 30 | login_required(NewsArticleUpdate.as_view()), 31 | name='news_update'), 32 | url(r'^tag/(?P[\w-]+)/$', 33 | login_required(NewsArticleListTag.as_view()), 34 | name='news_tags_list'), 35 | ) 36 | -------------------------------------------------------------------------------- /news/views.py: -------------------------------------------------------------------------------- 1 | from django.core.urlresolvers import reverse_lazy 2 | from django.views.generic.edit import UpdateView, CreateView, DeleteView 3 | from django.views.generic import ListView 4 | from django.utils.translation import ugettext as _ 5 | from community.views import OwnedObject, FilterableList 6 | from .models import NewsArticle 7 | from .forms import NewsArticleForm 8 | from django.contrib.syndication.views import Feed 9 | from django.core.urlresolvers import reverse 10 | 11 | 12 | 13 | class NewsFeed(Feed): 14 | title = "Feed de Noticias de Pyar" 15 | link = reverse_lazy("news_list_all") 16 | description = "Novedades e información de Python Argentina" 17 | 18 | def items(self): 19 | return NewsArticle.objects.order_by('-created')[0:10] 20 | 21 | def item_title(self, item): 22 | return item.title 23 | 24 | def item_description(self, item): 25 | return item.body 26 | 27 | def item_pubdate(self, item): 28 | return item.created 29 | 30 | def categories(self, item): 31 | if item: 32 | return item.tags.values_list('name', flat=True) 33 | return () 34 | 35 | 36 | class NewsArticleCreate(CreateView): 37 | model = NewsArticle 38 | form_class = NewsArticleForm 39 | 40 | def form_valid(self, form): 41 | form.instance.owner = self.request.user 42 | return super(NewsArticleCreate, self).form_valid(form) 43 | 44 | 45 | class NewsArticleDelete(DeleteView, OwnedObject): 46 | """Delete a News.""" 47 | model = NewsArticle 48 | success_url = reverse_lazy('news_list_all') 49 | 50 | 51 | class NewsArticleUpdate(UpdateView, OwnedObject): 52 | """Updates a NewsArticle.""" 53 | model = NewsArticle 54 | form_class = NewsArticleForm 55 | 56 | def get_context_data(self, **kwargs): 57 | context = super(NewsArticleUpdate, self).get_context_data(**kwargs) 58 | context['page_title'] = _('Editar noticia') 59 | return context 60 | 61 | 62 | class NewsArticleList(ListView, FilterableList): 63 | model = NewsArticle 64 | paginate_by = 10 65 | 66 | 67 | class NewsArticleListTag(ListView, FilterableList): 68 | model = NewsArticle 69 | paginate_by = 10 70 | 71 | def get_queryset(self): 72 | tag = self.kwargs['tag'] 73 | filter_news = NewsArticle.objects.filter( 74 | tags__slug__in=[tag]).distinct() 75 | 76 | return filter_news 77 | -------------------------------------------------------------------------------- /planet/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | VERSION = (0, 6, 2, "f") # following PEP 386 3 | 4 | def get_version(): 5 | version = "%s.%s" % (VERSION[0], VERSION[1]) 6 | if VERSION[2]: 7 | version = "%s.%s" % (version, VERSION[2]) 8 | if VERSION[3] != "f": 9 | version = "%s%s%s" % (version, VERSION[3], VERSION[4]) 10 | return version 11 | 12 | 13 | __version__ = get_version() 14 | -------------------------------------------------------------------------------- /planet/admin.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.contrib import admin 4 | 5 | from planet.models import (Blog, Generator, Feed, FeedLink, Post, PostLink, 6 | Author, PostAuthorData, Enclosure, Category) 7 | 8 | 9 | class PostLinkAdmin(admin.ModelAdmin): 10 | list_display = ("title", "rel", "mime_type", "post", "link") 11 | list_filter = ("rel", "mime_type") 12 | 13 | admin.site.register(PostLink, PostLinkAdmin) 14 | 15 | 16 | class PostAuthorDataAdmin(admin.ModelAdmin): 17 | list_display = ("author", "is_contributor", "post") 18 | list_filter = ("is_contributor", "author") 19 | 20 | admin.site.register(PostAuthorData, PostAuthorDataAdmin) 21 | 22 | 23 | class EnclosureAdmin(admin.ModelAdmin): 24 | list_display = ("post", "mime_type", "length", "link") 25 | list_filter = ("mime_type", ) 26 | 27 | admin.site.register(Enclosure, EnclosureAdmin) 28 | 29 | class FeedAdmin(admin.ModelAdmin): 30 | list_display = ("title", "url", "blog", "language", 31 | "category", "etag", "last_modified", "last_checked", "is_active") 32 | list_filter = ("language", "generator", "category") 33 | search_fields = ["title", "url", "blog__title"] 34 | 35 | admin.site.register(Feed, FeedAdmin) 36 | 37 | class AuthorAdmin(admin.ModelAdmin): 38 | list_display = ("name", "email") 39 | search_fields = ["name"] 40 | 41 | admin.site.register(Author, AuthorAdmin) 42 | 43 | class EnclosureInline(admin.StackedInline): 44 | model = Enclosure 45 | extra = 0 46 | 47 | class PostAdmin(admin.ModelAdmin): 48 | list_display = ("title", "feed", "guid", "date_created", "date_modified") 49 | list_filter = ("feed", ) 50 | search_fields = ["title", "feed__blog__title"] 51 | 52 | admin.site.register(Post, PostAdmin, inlines=[EnclosureInline]) 53 | 54 | 55 | class BlogAdmin(admin.ModelAdmin): 56 | list_display = ("title", "url", "date_created") 57 | search_fields = ["title", "url"] 58 | 59 | admin.site.register(Blog, BlogAdmin) 60 | 61 | 62 | class GeneratorAdmin(admin.ModelAdmin): 63 | list_display = ("name", "version", "link") 64 | 65 | admin.site.register(Generator, GeneratorAdmin) 66 | 67 | 68 | class FeedLinkAdmin(admin.ModelAdmin): 69 | list_display = ("feed", "mime_type", "rel", "link") 70 | list_filter = ("mime_type", "rel") 71 | 72 | admin.site.register(FeedLink, FeedLinkAdmin) 73 | 74 | class CategoryAdmin(admin.ModelAdmin): 75 | list_display = ("title", ) 76 | search_fields = ["title"] 77 | 78 | admin.site.register(Category, CategoryAdmin) 79 | -------------------------------------------------------------------------------- /planet/context_processors.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.conf import settings 4 | from django.contrib.sites.models import Site 5 | 6 | from planet.forms import SearchForm 7 | from planet.settings import PLANET_CONFIG 8 | 9 | 10 | def context(request): 11 | if request.method == "GET" and request.GET.get("search"): 12 | search_form = SearchForm(request.GET) 13 | else: 14 | search_form = SearchForm() 15 | 16 | site = Site.objects.get(pk=settings.SITE_ID) 17 | 18 | return {"site": site, "SITE_NAME": site.name, 19 | "search_form": search_form, "PLANET_CONFIG": PLANET_CONFIG} 20 | -------------------------------------------------------------------------------- /planet/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django.core.exceptions import ValidationError 3 | from django.utils.translation import ugettext as _ 4 | from django.conf import settings 5 | 6 | import feedparser 7 | 8 | from crispy_forms.layout import Submit, Reset 9 | from crispy_forms.helper import FormHelper 10 | 11 | from planet.models import Feed 12 | 13 | SEARCH_CHOICES = ( 14 | ("posts", _("Posts")), 15 | ("tags", _("Tags")), 16 | ("blogs", _("Blogs")), 17 | ("authors", _("Authors")), 18 | ("feeds", _("Feeds")), 19 | ) 20 | 21 | 22 | class SearchForm(forms.Form): 23 | w = forms.ChoiceField(choices=SEARCH_CHOICES, label="") 24 | q = forms.CharField(max_length=100, label="") 25 | 26 | 27 | class FeedForm(forms.Form): 28 | url = forms.URLField() 29 | 30 | def __init__(self, *args, **kwargs): 31 | super(FeedForm, self).__init__(*args, **kwargs) 32 | self.helper = FormHelper() 33 | self.helper.add_input(Submit('Submit', _('Guardar'))) 34 | self.helper.add_input( 35 | Reset('Reset', _('Limpiar'), css_class='btn-default')) 36 | 37 | def clean_url(self): 38 | url = self.cleaned_data['url'] 39 | if Feed.objects.filter(url=url).count() > 0: 40 | raise ValidationError(_('Ya existe un feed con esa URL.')) 41 | document = feedparser.parse(url, agent=settings.PLANET["USER_AGENT"]) 42 | if not document.feed.get('link'): 43 | raise ValidationError(_('La URL ingresada no pertenece a un feed.')) 44 | return url 45 | -------------------------------------------------------------------------------- /planet/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/planet/management/__init__.py -------------------------------------------------------------------------------- /planet/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/planet/management/commands/__init__.py -------------------------------------------------------------------------------- /planet/management/commands/planet_add_feed.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from django.core.management.base import BaseCommand 5 | from planet.tasks import process_feed 6 | from optparse import make_option 7 | 8 | class Command(BaseCommand): 9 | help = "Add a complete blog feed to our db." 10 | args = "" 11 | option_list = BaseCommand.option_list + ( 12 | make_option('-c', '--category', 13 | action='store', 14 | dest='category', 15 | default=None, 16 | metavar='Title', 17 | help='Add this feed to a Category'), 18 | ) 19 | 20 | def handle(self, *args, **options): 21 | if not len(args): 22 | print("You must provide the feed url as parameter") 23 | exit(0) 24 | 25 | feed_url = args[0] 26 | # process feed in create-mode 27 | process_feed(feed_url, create=True, category_title=options['category']) 28 | -------------------------------------------------------------------------------- /planet/management/commands/planet_update_all_feeds.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | from datetime import datetime 4 | from django.core.management.base import NoArgsCommand 5 | 6 | from planet.tasks import process_feed, update_feeds 7 | from planet.models import Feed 8 | 9 | 10 | class Command(NoArgsCommand): 11 | help = "Update all feeds" 12 | 13 | def handle(self, *args, **options): 14 | update_feeds.delay() 15 | 16 | -------------------------------------------------------------------------------- /planet/management/commands/planet_update_feed.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from django.core.management.base import BaseCommand 5 | 6 | from planet.tasks import process_feed 7 | 8 | 9 | class Command(BaseCommand): 10 | help = "Update a feed." 11 | args = "" 12 | 13 | def handle(self, *args, **options): 14 | if not len(args): 15 | print("You must provide the feed url as parameter") 16 | exit(0) 17 | 18 | feed_url = args[0] 19 | # process feed in create-mode 20 | process_feed(feed_url, create=False) 21 | -------------------------------------------------------------------------------- /planet/managers.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.db import models 4 | from django.conf import settings 5 | 6 | 7 | class FeedManager(models.Manager): 8 | """ 9 | """ 10 | def get_queryset(self): 11 | qs = super(FeedManager, self).get_queryset() 12 | return qs.filter(site=settings.SITE_ID, is_active=True) 13 | 14 | 15 | class FeedLinkManager(models.Manager): 16 | """ 17 | """ 18 | def get_queryset(self): 19 | qs = super(FeedLinkManager, self).get_queryset() 20 | return qs.filter(feed__site=settings.SITE_ID) 21 | 22 | 23 | class BlogManager(models.Manager): 24 | """ 25 | """ 26 | def get_queryset(self): 27 | qs = super(BlogManager, self).get_queryset() 28 | return qs.filter(feed__site=settings.SITE_ID).distinct() 29 | 30 | 31 | class GeneratorManager(models.Manager): 32 | """ 33 | """ 34 | def get_queryset(self): 35 | qs = super(GeneratorManager, self).get_queryset() 36 | return qs.filter(feed__site=settings.SITE_ID).distinct() 37 | 38 | 39 | class AuthorManager(models.Manager): 40 | """ 41 | """ 42 | def get_queryset(self): 43 | qs = super(AuthorManager, self).get_queryset() 44 | return qs.filter(post__feed__site=settings.SITE_ID).distinct() 45 | 46 | 47 | class PostManager(models.Manager): 48 | """ 49 | """ 50 | def get_queryset(self): 51 | qs = super(PostManager, self).get_queryset() 52 | return qs.filter(feed__site=settings.SITE_ID).distinct() 53 | 54 | 55 | class PostLinkManager(models.Manager): 56 | """ 57 | """ 58 | def get_queryset(self): 59 | qs = super(PostLinkManager, self).get_queryset() 60 | return qs.filter(post__feed__site=settings.SITE_ID).distinct() 61 | 62 | 63 | class EnclosureManager(models.Manager): 64 | """ 65 | """ 66 | def get_queryset(self): 67 | qs = super(EnclosureManager, self).get_queryset() 68 | return qs.filter(post__feed__site=settings.SITE_ID).distinct() 69 | -------------------------------------------------------------------------------- /planet/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/planet/migrations/__init__.py -------------------------------------------------------------------------------- /planet/settings.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.conf import settings 3 | 4 | try: 5 | PROJECT_PLANET = settings.PLANET 6 | except AttributeError: 7 | PROJECT_PLANET = {} 8 | 9 | PLANET_CONFIG = { 10 | "TAG_CLOUD_MIN_COUNT": 5, 11 | "BLOG_TAG_CLOUD_MIN_COUNT": 3, 12 | "FEED_TAG_CLOUD_MIN_COUNT": 3, 13 | "AUTHOR_TAG_CLOUD_MIN_COUNT": 3, 14 | "RELATED_TAGS_MIN_COUNT": 2, 15 | } 16 | 17 | PLANET_CONFIG.update(PROJECT_PLANET) 18 | -------------------------------------------------------------------------------- /planet/signals.py: -------------------------------------------------------------------------------- 1 | from django.dispatch import Signal 2 | 3 | post_created = Signal() 4 | feeds_updated = Signal() -------------------------------------------------------------------------------- /planet/sitemaps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from datetime import datetime 3 | 4 | from django.contrib.sitemaps import Sitemap 5 | from django.core.urlresolvers import reverse 6 | from django.template.defaultfilters import slugify 7 | 8 | from planet.models import Post, Blog, Feed, Author 9 | 10 | from tagging.models import Tag 11 | 12 | 13 | class BlogSitemap(Sitemap): 14 | 15 | changefreq = "monthly" 16 | priority = 1.0 17 | 18 | def items(self): 19 | return Blog.objects.values_list("id", "title", "date_created") 20 | 21 | def lastmod(self, obj): 22 | return obj[2] 23 | 24 | def location(self, obj): 25 | slug = slugify(obj[1]) or "no-title" 26 | return reverse("planet.views.blog_detail", 27 | kwargs=dict(blog_id=obj[0], slug=slug)) 28 | 29 | 30 | class PostSitemap(Sitemap): 31 | 32 | changefreq = "monthly" 33 | priority = 0.9 34 | 35 | def items(self): 36 | return Post.objects.values_list("id", "title", "date_created") 37 | 38 | def lastmod(self, obj): 39 | return obj[2] 40 | 41 | def location(self, obj): 42 | slug = slugify(obj[1]) or "no-title" 43 | return reverse("planet.views.post_detail", 44 | kwargs=dict(post_id=obj[0], slug=slug)) 45 | 46 | 47 | class AuthorSitemap(Sitemap): 48 | 49 | changefreq = "monthly" 50 | priority = 0.6 51 | 52 | def items(self): 53 | return Author.objects.values_list("id", "name") 54 | 55 | def location(self, obj): 56 | slug = slugify(obj[1]) or "no-title" 57 | return reverse("planet.views.author_detail", 58 | kwargs=dict(author_id=obj[0], slug=slug)) 59 | 60 | 61 | class FeedSitemap(Sitemap): 62 | 63 | changefreq = "monthly" 64 | priority = 0.5 65 | 66 | def items(self): 67 | return Feed.objects.values_list("id", "title", "last_modified") 68 | 69 | def lastmod(self, obj): 70 | return obj[2] 71 | 72 | def location(self, obj): 73 | slug = slugify(obj[1]) or "no-title" 74 | return reverse("planet.views.feed_detail", 75 | kwargs=dict(feed_id=obj[0], slug=slug)) 76 | 77 | 78 | class TagSitemap(Sitemap): 79 | 80 | changefreq = "daily" 81 | priority = 0.9 82 | 83 | def items(self): 84 | return Tag.objects.values_list("name", flat=True) 85 | 86 | def lastmod(self, obj): 87 | return datetime.now() 88 | 89 | def location(self, obj): 90 | return reverse("planet.views.tag_detail", 91 | kwargs=dict(tag=obj)) 92 | 93 | 94 | planet_sitemaps_dict = { 95 | "blogs": BlogSitemap(), 96 | "posts": PostSitemap(), 97 | "authors": AuthorSitemap(), 98 | "feeds": FeedSitemap(), 99 | "tags": TagSitemap() 100 | } 101 | -------------------------------------------------------------------------------- /planet/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/planet/templatetags/__init__.py -------------------------------------------------------------------------------- /planet/tests/__init__.py: -------------------------------------------------------------------------------- 1 | from planet.tests.managers import * 2 | from planet.tests.views import * 3 | -------------------------------------------------------------------------------- /planet/tests/managers.py: -------------------------------------------------------------------------------- 1 | from django.contrib.sites.models import Site 2 | from django.test import TestCase 3 | 4 | from planet.tests.factories import AuthorFactory, FeedFactory, PostFactory, SiteFactory 5 | from planet.models import Blog, Feed, Post, Author 6 | 7 | 8 | class ManagersTestCase(TestCase): 9 | 10 | def setUp(self): 11 | self.author1 = AuthorFactory.create() 12 | self.author2 = AuthorFactory.create() 13 | 14 | self.other_site = SiteFactory.create() 15 | self.other_feed = FeedFactory.create(site=self.other_site) 16 | self.other_posts = PostFactory.create_batch(size=4, feed=self.other_feed, authors=[self.author1]) 17 | 18 | self.my_site = Site.objects.get(pk=1) 19 | self.my_feed = FeedFactory.create(site=self.my_site) 20 | self.site_posts = PostFactory.create_batch(size=5, feed=self.my_feed, authors=[self.author2]) 21 | 22 | def test_posts(self): 23 | self.assertEqual(Post.objects.count(), 9) 24 | self.assertEqual(Post.site_objects.count(), 5) 25 | 26 | site_posts_qs = Post.site_objects.all() 27 | for post in self.site_posts: 28 | self.assertTrue(post in site_posts_qs) 29 | 30 | def test_feeds(self): 31 | self.assertEqual(Feed.objects.count(), 2) 32 | self.assertEqual(Feed.site_objects.count(), 1) 33 | self.assertTrue(self.my_feed in Feed.site_objects.all()) 34 | 35 | def test_blogs(self): 36 | self.assertEqual(Blog.objects.count(), 2) 37 | self.assertEqual(Blog.site_objects.count(), 1) 38 | self.assertTrue(self.my_feed.blog in Blog.site_objects.all()) 39 | 40 | def test_author_count(self): 41 | self.assertEqual(Author.objects.count(), 2) 42 | 43 | def test_author_posts_counts(self): 44 | self.assertEqual(Post.objects.filter(authors=self.author1).count(), 4) 45 | self.assertEqual(Post.objects.filter(authors=self.author2).count(), 5) 46 | -------------------------------------------------------------------------------- /projects/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/projects/__init__.py -------------------------------------------------------------------------------- /projects/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Project 3 | 4 | 5 | admin.site.register(Project) -------------------------------------------------------------------------------- /projects/apis.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import requests 4 | from urllib.parse import urljoin 5 | 6 | 7 | class API(object): 8 | """Base API object.""" 9 | 10 | def __init__(self, url): 11 | self.url = url 12 | 13 | 14 | class Resource(object): 15 | 16 | def __init__(self, path, api, **kwargs): 17 | self.method = kwargs.get('method') 18 | self.path = path 19 | self.api = api 20 | self.url = urljoin(self.api.url, self.path) 21 | 22 | def _make_request(self): 23 | """Make a request with requests and return the response.""" 24 | if self.method.upper() == 'GET': 25 | response = requests.get(self.url) 26 | 27 | return response 28 | 29 | def json(self): 30 | """Return the results from the API Request as json.""" 31 | response = self._make_request() 32 | return response.json() 33 | 34 | 35 | class BaseClient(object): 36 | """Base class for api clients.""" 37 | 38 | def __init__(self): 39 | self._resources = dict() 40 | 41 | def get(self, resource, **kwargs): 42 | if not resource in self._resources: 43 | kwargs['method'] ='GET' 44 | self._resources[resource] = \ 45 | Resource(resource, api=self.api, **kwargs) 46 | return self._resources[resource] 47 | 48 | 49 | class GithubClient(BaseClient): 50 | """Github API v3 client.""" 51 | 52 | def __init__(self, url): 53 | self.api = API(url) 54 | super(GithubClient, self).__init__() 55 | 56 | 57 | class BitbucketClient(BaseClient): 58 | """BitbucketClient, to be implemented.""" 59 | 60 | 61 | github = GithubClient('https://api.github.com') 62 | -------------------------------------------------------------------------------- /projects/forms.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django import forms 4 | from .models import Project 5 | from taggit.forms import TagWidget 6 | 7 | 8 | class ProjectForm(forms.ModelForm): 9 | """A PyAr news article form.""" 10 | class Meta: 11 | model = Project 12 | fields = ('name', 'description', 'repositoryType', 'repository', 'license', 'state', 'tags', 'mail', 'contribution', 'logo') 13 | labels = { 14 | 'name': 'Nombre', 15 | 'mail': 'Email', 16 | 'description': 'Descripción', 17 | 'repositoryType': 'Host del Repositorio', 18 | 'repository': 'URL del repositorio', 19 | 'license': 'Licencia del software', 20 | 'state': 'Estado del proyecto', 21 | 'contribution': 'Abierto a Contribuciones' 22 | } 23 | help_texts = { 24 | 'name': 'Nombre del proyecto', 25 | 'mail': 'Lista de correo o email para ponerse en contacto', 26 | 'description': 'Descripción del proyecto', 27 | 'repositoryType': 'Donde está hosteado el sistema de versionado del proyecto', 28 | 'repository': 'URL del repositorio del proyecto', 29 | 'license': 'Bajo que licenciacia se distribuye el proyecto', 30 | 'state': 'Si el proyecto se encuentra activo o inactivo', 31 | 'contribution': 'Abierto a contribuciones de la comunidad', 32 | } 33 | widgets = { 34 | 'tags': TagWidget(), 35 | } 36 | 37 | -------------------------------------------------------------------------------- /projects/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.contrib.auth.models import User 3 | from taggit_autosuggest.managers import TaggableManager 4 | 5 | 6 | class Project(models.Model): 7 | """PyAr projects.""" 8 | 9 | REPOSITORY_TYPES = ( 10 | ('G','Github'), 11 | ('B','Bitbucket'), 12 | ('O','Other') 13 | ) 14 | REPOSITORY_STATUS = ( 15 | ('0','Inactivo'), 16 | ('1','Activo'), 17 | ) 18 | LICENSES = ( 19 | ("GPL2", "GPLv2"), 20 | ("GPL3", "GPLv3"), 21 | ("AGPL", "Affero GPL"), 22 | ("APCH", "Apache License"), 23 | ("MITL", "MIT License"), 24 | ("BSD2", "BSD (2-Clause) License"), 25 | ("BSD3", "BSD (3-Clause) License"), 26 | ("ECLP", "Eclipse License"), 27 | ("LGP2", "LGPL v2.1"), 28 | ("LGP3", "LGPL v3"), 29 | ("MPL2", "Mozilla License"), 30 | ("NOLC", "No License"), 31 | ("PBDM", "Public Domain"), 32 | ("OTHER", "Other") 33 | ) # ToDo: Armar un listado de licencias exhaustivo 34 | name = models.CharField(max_length=255) 35 | owner = models.ForeignKey(User) 36 | description = models.TextField() 37 | repository = models.URLField() 38 | repositoryType = models.CharField(max_length=1, choices=REPOSITORY_TYPES) 39 | license = models.CharField(max_length=4, choices=LICENSES) 40 | state = models.CharField(max_length=1, default="1", choices=REPOSITORY_STATUS) 41 | tags = models.CharField(max_length=255) 42 | #tags = TaggableManager() 43 | mail = models.EmailField() 44 | contribution = models.BooleanField(default=True) 45 | logo = models.ImageField(upload_to='static/projects/logos', null=True, blank=True) 46 | 47 | def __str__(self): 48 | return self.name 49 | -------------------------------------------------------------------------------- /projects/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /projects/urls.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.conf.urls import patterns, url 4 | from .views import ( 5 | add, 6 | view, 7 | delete, 8 | update, 9 | list_all, 10 | ) 11 | 12 | 13 | urlpatterns = patterns('', 14 | url(r'^$', list_all, name='projects_list_all'), 15 | url(r'^add$', add, name='projects_add'), 16 | url(r'^(?P\d+)$', view, name='projects_view'), 17 | url(r'^(?P\d+)/delete$', delete, name='projects_delete'), 18 | url(r'^(?P\d+)/update$', update, name='projects_update'), 19 | ) 20 | -------------------------------------------------------------------------------- /projects/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from django.contrib.auth.decorators import login_required 4 | from django.core.urlresolvers import reverse 5 | from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 6 | from django.http import HttpResponseRedirect 7 | from django.shortcuts import render 8 | from django.shortcuts import get_object_or_404 9 | from .models import Project 10 | from .forms import ProjectForm 11 | from .apis import github 12 | 13 | 14 | @login_required 15 | def add(request): 16 | """Add a new Project.""" 17 | 18 | if request.method == 'POST': 19 | form = ProjectForm(request.POST, request.FILES) 20 | if form.is_valid(): 21 | form.instance.owner = request.user 22 | form.save() 23 | url = reverse('projects_list_all') 24 | return HttpResponseRedirect(url) 25 | else: 26 | form = ProjectForm() 27 | 28 | context = dict(form=form) 29 | return render(request, 'projects/add.html', context) 30 | 31 | 32 | def view(request, project_id): 33 | """Show a Project.""" 34 | 35 | project = get_object_or_404( 36 | Project, 37 | id=project_id 38 | ) 39 | 40 | 41 | context = dict(project=project) 42 | return render(request, 'projects/view.html', context) 43 | 44 | 45 | @login_required 46 | def delete(request, project_id): 47 | """Delete a Project.""" 48 | 49 | project = get_object_or_404( 50 | Project, 51 | id=project_id, 52 | owner=request.user, 53 | ) 54 | project.delete() 55 | url = reverse('projects_list_all') 56 | 57 | return HttpResponseRedirect(url) 58 | 59 | 60 | @login_required 61 | def update(request, project_id): 62 | """Update a Project.""" 63 | 64 | project = get_object_or_404( 65 | Project, 66 | id=project_id, 67 | owner=request.user, 68 | ) 69 | 70 | if request.method == 'POST': 71 | form = ProjectForm(request.POST, request.FILES, instance=project) 72 | if form.is_valid(): 73 | form.instance.owner = request.user 74 | form.save() 75 | url = reverse('projects_list_all') 76 | return HttpResponseRedirect(url) 77 | else: 78 | form = ProjectForm(instance=project) 79 | 80 | context = dict( 81 | form=form, 82 | project=project 83 | ) 84 | return render(request, 'projects/update.html', context) 85 | 86 | 87 | def list_all(request): 88 | """Return all projects ordered by name.""" 89 | 90 | projects_list = Project.objects.order_by('name') 91 | paginator = Paginator(projects_list, 20) # Show 20 projects per page 92 | page = request.GET.get('page') 93 | 94 | pyar_projects = github.get('/orgs/pyar/repos').json() 95 | pyar_projects_info = [ 96 | dict( 97 | url=d['url'], 98 | name=d['name'], 99 | description=d['description'] 100 | ) for d in pyar_projects] 101 | 102 | try: 103 | projects = paginator.page(page) 104 | except PageNotAnInteger: 105 | # If page is not an integer, deliver first page. 106 | projects = paginator.page(1) 107 | except EmptyPage: 108 | # If page is out of range (e.g. 9999), deliver last page of results. 109 | projects = paginator.page(paginator.num_pages) 110 | 111 | context = dict(projects=projects, pyar_projects=pyar_projects_info) 112 | return render(request, 'projects/all.html', context) 113 | 114 | 115 | -------------------------------------------------------------------------------- /pyarweb/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # from .celery import app as celery_app 4 | -------------------------------------------------------------------------------- /pyarweb/celery.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | """Configure Celery for PyAr Web.""" 5 | 6 | 7 | import os 8 | 9 | from celery import Celery 10 | 11 | from django.conf import settings 12 | 13 | 14 | # set the default Django settings module for the 'celery' program. 15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pyarweb.settings') 16 | 17 | app = Celery('pyarweb') 18 | 19 | # Using a string here means the worker will not have to 20 | # pickle the object when using Windows. 21 | app.config_from_object(settings) 22 | app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) 23 | -------------------------------------------------------------------------------- /pyarweb/formats/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/pyarweb/formats/__init__.py -------------------------------------------------------------------------------- /pyarweb/formats/es_AR/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/pyarweb/formats/es_AR/__init__.py -------------------------------------------------------------------------------- /pyarweb/formats/es_AR/formats.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | 3 | 4 | # The *_FORMAT strings use the Django date format syntax, 5 | # see http://docs.djangoproject.com/en/dev/ref/templates/builtins/#date 6 | DATE_FORMAT = r'j \d\e N \d\e Y' 7 | TIME_FORMAT = r'H:i' 8 | DATETIME_FORMAT = r'j \d\e N \d\e Y H:i' 9 | YEAR_MONTH_FORMAT = r'F Y' 10 | MONTH_DAY_FORMAT = r'j \d\e F' 11 | SHORT_DATE_FORMAT = r'd/m/Y' 12 | SHORT_DATETIME_FORMAT = r'd/m/Y H:i' 13 | FIRST_DAY_OF_WEEK = 0 # 0: Sunday, 1: Monday 14 | 15 | # The *_INPUT_FORMATS strings use the Python strftime format syntax, 16 | # see http://docs.python.org/library/datetime.html#strftime-strptime-behavior 17 | DATE_INPUT_FORMATS = ( 18 | '%d/%m/%Y', # '31/12/2009' 19 | '%d/%m/%y', # '31/12/09' 20 | ) 21 | DATETIME_INPUT_FORMATS = ( 22 | '%d/%m/%Y %H:%M:%S', 23 | '%d/%m/%Y %H:%M:%S.%f', 24 | '%d/%m/%Y %H:%M', 25 | '%d/%m/%y %H:%M:%S', 26 | '%d/%m/%y %H:%M:%S.%f', 27 | '%d/%m/%y %H:%M', 28 | ) 29 | DECIMAL_SEPARATOR = ',' 30 | THOUSAND_SEPARATOR = '.' 31 | NUMBER_GROUPING = 3 32 | -------------------------------------------------------------------------------- /pyarweb/urls.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | """URLS configurations for PyAr Web.""" 5 | 6 | 7 | from django.conf import settings 8 | from django.conf.urls import include, patterns, url 9 | from django.contrib import admin 10 | from waliki.settings import WALIKI_SLUG_PATTERN 11 | 12 | from .views import buscador, irc, old_url_redirect 13 | 14 | 15 | admin.autodiscover() 16 | 17 | 18 | urlpatterns = patterns( 19 | '', 20 | # Static files 21 | url(r'^static/(?P.*)$', 'django.views.static.serve', 22 | {'document_root': settings.STATIC_ROOT}), 23 | # Media files 24 | url(r'^media/(?P.*)$', 'django.views.static.serve', 25 | {'document_root': settings.MEDIA_ROOT}), 26 | 27 | url(r'^irc/$', irc, name='irc'), 28 | url(r'^buscador/$', buscador, name='buscador'), 29 | 30 | url(r'^$', 'community.views.homepage', name='homepage'), 31 | url(r'^aprendiendo-python/', 'community.views.learning', name='aprendiendo'), 32 | url(r'^nosotros/', 'community.views.about_pyar', name='about_pyar'), 33 | url(r'^miembros/', 'community.views.members', name='pyar_members'), 34 | url(r'^lista/', 'community.views.mailing_list', name='mailing_list'), 35 | 36 | url(r'^noticias/', include('news.urls')), 37 | url(r'^empresas/', include('pycompanies.urls', namespace='companies')), 38 | url(r'^taggit_autosuggest/', include('taggit_autosuggest.urls')), 39 | url(r'^summernote/', include('django_summernote.urls')), 40 | url(r'^trabajo/', include('jobs.urls')), 41 | url(r'^admin/', include(admin.site.urls)), 42 | url(r'^accounts/', include('allauth.urls')), 43 | url(r'^eventos/', include('events.urls', namespace='events')), 44 | # Descomentar cuando planet este funcionando 45 | # url(r'^planeta/', include('planet.urls')), 46 | # No se que va a pasar con la app de newbie, lanzamos primer release y 47 | # lo comento hasta que se decida que se hace 48 | # url(r'^newbie/', include('newbie.urls')), 49 | # No se que va a pasar con la app de project, lanzamos primer release y 50 | # lo comento hasta que se decida que se hace 51 | # url(r'^projects/', include('projects.urls')), 52 | # url(r'^faq/', include('faq.urls')), 53 | url(r'^wiki/', include('waliki.urls')), 54 | url(r'^(pyar/)?(?P' + WALIKI_SLUG_PATTERN + ')/?', 55 | old_url_redirect, name='old_url_redirect'), 56 | ) 57 | -------------------------------------------------------------------------------- /pyarweb/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | """Views for PyArWeb Django App.""" 5 | 6 | 7 | from django.http import Http404 8 | from django.shortcuts import redirect, render 9 | from waliki.models import Page, Redirect 10 | 11 | 12 | def irc(request): 13 | """Render the IRC Chat template.""" 14 | return render(request, 'irc/irc.html') 15 | 16 | 17 | def special_page(request, **kwargs): 18 | """Render a basic template of special pages.""" 19 | return render(request, 'special_page.html', kwargs) 20 | 21 | 22 | def buscador(request): 23 | """Render the Google Search template.""" 24 | return render(request, 'buscador.html', 25 | {'buscar': request.GET.get('buscar', '')}) 26 | 27 | 28 | def old_url_redirect(request, slug): 29 | """Redirect old URLs to the New site.""" 30 | try: 31 | waliki_redirect = Redirect.objects.get(old_slug=slug) 32 | slug = waliki_redirect.new_slug 33 | except Redirect.DoesNotExist: 34 | pass 35 | 36 | try: 37 | page = Page.objects.get(slug=slug) 38 | except Page.DoesNotExist: 39 | raise Http404 40 | 41 | return redirect(page.get_absolute_url(), permanent=True) 42 | -------------------------------------------------------------------------------- /pyarweb/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for pyarweb project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pyarweb.settings") 12 | 13 | from django.core.wsgi import get_wsgi_application 14 | application = get_wsgi_application() 15 | -------------------------------------------------------------------------------- /pycompanies/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/pycompanies/__init__.py -------------------------------------------------------------------------------- /pycompanies/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Company 3 | 4 | 5 | admin.site.register(Company) 6 | -------------------------------------------------------------------------------- /pycompanies/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django_summernote.widgets import SummernoteInplaceWidget 3 | from django.utils.translation import ugettext_lazy as _ 4 | 5 | from crispy_forms.helper import FormHelper 6 | from crispy_forms.layout import Div, ButtonHolder, Layout, Submit 7 | 8 | from .models import Company 9 | 10 | 11 | class CompanyForm(forms.ModelForm): 12 | """A PyAr companies form.""" 13 | 14 | description = forms.CharField(widget=SummernoteInplaceWidget()) 15 | 16 | def __init__(self, *args, **kwargs): 17 | super(CompanyForm, self).__init__(*args, **kwargs) 18 | self.helper = FormHelper(self) 19 | self.helper.layout = Layout( 20 | Div( 21 | 'name', 22 | 'photo', 23 | 'link', 24 | 'description' 25 | ), 26 | ButtonHolder( 27 | Submit(_('Guardar'), _('Guardar'), css_class='btn btn-default') 28 | ) 29 | ) 30 | 31 | class Meta: 32 | fields = ['name', 'photo', 'link', 'description'] 33 | model = Company 34 | -------------------------------------------------------------------------------- /pycompanies/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | import django.utils.timezone 6 | import model_utils.fields 7 | from django.conf import settings 8 | 9 | 10 | class Migration(migrations.Migration): 11 | 12 | dependencies = [ 13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 14 | ] 15 | 16 | operations = [ 17 | migrations.CreateModel( 18 | name='Company', 19 | fields=[ 20 | ('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)), 21 | ('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')), 22 | ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')), 23 | ('name', models.CharField(verbose_name='Nombre', unique=True, max_length=255)), 24 | ('description', models.TextField(verbose_name='Descripción')), 25 | ('photo', models.ImageField(upload_to='pycompanies/logos', verbose_name='Logo')), 26 | ('link', models.URLField(verbose_name='URL')), 27 | ('owner', models.ForeignKey(related_name='companies', to=settings.AUTH_USER_MODEL)), 28 | ], 29 | options={ 30 | 'abstract': False, 31 | }, 32 | bases=(models.Model,), 33 | ), 34 | ] 35 | -------------------------------------------------------------------------------- /pycompanies/migrations/0002_auto_20141211_1638.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('pycompanies', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='company', 16 | name='link', 17 | field=models.URLField(help_text='Dirección web de la empresa', verbose_name='URL'), 18 | preserve_default=True, 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /pycompanies/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/pycompanies/migrations/__init__.py -------------------------------------------------------------------------------- /pycompanies/models.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.models import User 2 | from django.db import models 3 | from django.db.models.signals import post_delete 4 | from django.dispatch import receiver 5 | from django.core.urlresolvers import reverse 6 | from django.utils.translation import ugettext_lazy as _ 7 | 8 | from model_utils.models import TimeStampedModel 9 | 10 | 11 | class Company(TimeStampedModel): 12 | """A PyAr Company that use Python.""" 13 | 14 | owner = models.ForeignKey(User, related_name='companies') 15 | name = models.CharField('Nombre', max_length=255, unique=True) 16 | description = models.TextField('Descripción') 17 | photo = models.ImageField('Logo', upload_to='pycompanies/logos') 18 | link = models.URLField('URL', 19 | help_text=_('Dirección web de la empresa') 20 | ) 21 | 22 | def get_absolute_url(self): 23 | return reverse('companies:detail', kwargs={'pk': self.pk}) 24 | 25 | def __str__(self): 26 | return u'%s' % self.name 27 | 28 | 29 | ###### SIGNALS ###### 30 | 31 | @receiver(post_delete, sender=Company) 32 | def post_delete_user(sender, instance, *args, **kwargs): 33 | "Delete logo image after delete company" 34 | 35 | instance.photo.delete(save=False) 36 | -------------------------------------------------------------------------------- /pycompanies/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /pycompanies/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import patterns, url 2 | 3 | from .views import ( 4 | CompanyDetail, 5 | CompanyList, 6 | CompanyCreate, 7 | CompanyUpdate, 8 | CompanyDelete) 9 | 10 | urlpatterns = patterns('', 11 | url(r'^$', CompanyList.as_view(), name='company_list_all'), 12 | url(r'^(?P\d+)/$', CompanyDetail.as_view(), name='detail'), 13 | url(r'^add/$', CompanyCreate.as_view(), name='add'), 14 | url(r'^(?P\d+)/edit/$', CompanyUpdate.as_view(), name='edit'), 15 | url(r'^(?P\d+)/delete/$', CompanyDelete.as_view(), name='delete'), 16 | ) 17 | -------------------------------------------------------------------------------- /pycompanies/views.py: -------------------------------------------------------------------------------- 1 | from django.core.urlresolvers import reverse 2 | from django.shortcuts import render 3 | from django.utils.translation import ugettext_lazy as _ 4 | from django.views.generic import ListView, DetailView 5 | from django.views.generic.edit import UpdateView, CreateView, DeleteView 6 | 7 | from braces.views import LoginRequiredMixin 8 | 9 | from pycompanies.forms import CompanyForm 10 | from pycompanies.models import Company 11 | from community.views import OwnedObject 12 | 13 | 14 | class CompanyDetail(DetailView): 15 | model = Company 16 | template_name = 'companies/company_detail.html' 17 | 18 | 19 | class CompanyList(ListView): 20 | template_name = 'companies/company_list.html' 21 | context_object_name = 'companies' 22 | 23 | def get_queryset(self): 24 | return Company.objects.all().order_by('?') 25 | 26 | def get_context_data(self, **kwargs): 27 | context = super(CompanyList, self).get_context_data(**kwargs) 28 | if self.request.user.is_anonymous() is False: 29 | context['own_companies_count'] = self.request.user.companies.all() \ 30 | .count() 31 | return context 32 | 33 | 34 | class CompanyCreate(LoginRequiredMixin, CreateView): 35 | form_class = CompanyForm 36 | model = Company 37 | success_url = '/empresas/' 38 | template_name = 'companies/company_form.html' 39 | 40 | def form_valid(self, form): 41 | form.instance.owner = self.request.user 42 | return super(CompanyCreate, self).form_valid(form) 43 | 44 | 45 | class CompanyUpdate(LoginRequiredMixin, OwnedObject, UpdateView): 46 | form_class = CompanyForm 47 | model = Company 48 | template_name = 'companies/company_form.html' 49 | 50 | def get_context_data(self, **kwargs): 51 | context = super(CompanyUpdate, self).get_context_data(**kwargs) 52 | context['page_title'] = _('Editar Empresa') 53 | return context 54 | 55 | 56 | class CompanyDelete(LoginRequiredMixin, OwnedObject, DeleteView): 57 | model = Company 58 | success_url = '/empresas/' 59 | template_name = 'companies/company_confirm_delete.html' 60 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Django==1.7.7 2 | Pillow==2.3.0 3 | amqp==1.4.6 4 | anyjson==0.3.3 5 | argparse==1.1 6 | beautifulsoup4==4.3.2 7 | billiard==3.3.0.18 8 | #celery==3.1.16 9 | django-bootstrap3==4.8.2 10 | django-bootstrap3-datetimepicker==2.2.3 11 | django-crispy-forms==1.4.0 12 | -e git+https://github.com/PyAr/django-disqus.git#egg=django-disqus.git 13 | django-email-obfuscator==0.1.3 14 | django-extensions==1.3.3 15 | django-model-utils==2.0.3 16 | django-pagination-py3==1.1.1 17 | django-summernote==0.5.13 18 | django-tagging==0.3.2 19 | django-taggit==0.12.2 20 | django-allauth==0.19.1 21 | django-taggit-autosuggest==0.2.5 22 | feedparser==5.1.3 23 | kombu==3.0.24 24 | lxml==3.3.5 25 | pytz==2014.4 26 | redis==2.10.1 27 | requests==2.2.1 28 | six==1.6.1 29 | ipython==3.1.0 30 | ipdb==0.8 31 | https://github.com/coleifer/micawber/archive/master.zip#egg=micawber 32 | https://github.com/mgaitan/waliki/archive/master.zip#egg=waliki[all] 33 | #rst2pdf==0.93 34 | django-braces==1.4.0 35 | django-sendfile==0.3.6 36 | hovercraft==1.1 37 | django-autoslug==1.7.2 38 | django-dbbackup==2.0.4 39 | -------------------------------------------------------------------------------- /static/bootstrap/3.1.1/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/bootstrap/3.1.1/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /static/bootstrap/3.1.1/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/bootstrap/3.1.1/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /static/bootstrap/3.1.1/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/bootstrap/3.1.1/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /static/css/event_map.css: -------------------------------------------------------------------------------- 1 | #map-canvas { 2 | height: 300px; 3 | margin: 0px; 4 | padding: 0px; 5 | margin-bottom: 10px; 6 | } 7 | 8 | /* override from style.css*/ 9 | #div_id_description > div { 10 | width: 100%; 11 | } -------------------------------------------------------------------------------- /static/img/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/img/banner.png -------------------------------------------------------------------------------- /static/img/icons/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/img/icons/icons.png -------------------------------------------------------------------------------- /static/img/icons/icons_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/img/icons/icons_active.png -------------------------------------------------------------------------------- /static/img/icons/pyar.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/img/icons/pyar.ico -------------------------------------------------------------------------------- /static/img/logo-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/img/logo-header.png -------------------------------------------------------------------------------- /static/img/moin-www.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/img/moin-www.png -------------------------------------------------------------------------------- /static/img/pyar-footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/img/pyar-footer.png -------------------------------------------------------------------------------- /static/img/python-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/img/python-banner.png -------------------------------------------------------------------------------- /static/img/python-footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/img/python-footer.png -------------------------------------------------------------------------------- /static/img/ribbon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/img/ribbon.png -------------------------------------------------------------------------------- /static/img/usla-footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonMexico/pymxweb/5eec3c9d5b979e8d4eadadac2fb54d134ad8097e/static/img/usla-footer.png -------------------------------------------------------------------------------- /static/js/web.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | if(window.location.pathname=="/") { 3 | $("header nav li a[href='/']").parent().addClass("active"); 4 | } else { 5 | $("header nav li.active").removeClass("active"); 6 | $("header nav li a[href='/"+window.location.pathname.split("/")[1]+"/']").parent().addClass("active"); 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /templates/account/base.html: -------------------------------------------------------------------------------- 1 | {% extends "base_site.html" %} 2 | 3 | 4 | -------------------------------------------------------------------------------- /templates/account/login.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% load account %} 5 | {% load crispy_forms_tags %} 6 | {% load url from future %} 7 | 8 | {% block head_title %}{% trans "Sign In" %}{% endblock %} 9 | 10 | {% block container %} 11 |
12 |
13 |
14 |

{% trans "Sign In" %}

15 | 16 | {% if socialaccount.providers %} 17 |

18 | {% blocktrans with site.name as site_name %}Please sign in with one 19 | of your existing third party accounts. Or, sign up 20 | for a {{site_name}} account and sign in below:{% endblocktrans %} 21 |

22 | 23 |
24 |
    25 | {% include "socialaccount/snippets/provider_list.html" with process="login" %} 26 |
27 | 28 |
29 | 30 | {% include "socialaccount/snippets/login_extra.html" %} 31 | 32 | {% else %} 33 |

{% blocktrans %}Si aún no tenes cuenta, podes registrarte 34 | acá.{% endblocktrans %}

35 | {% endif %} 36 |
37 | 46 |
47 |
48 | 49 | {% endblock %} 50 | -------------------------------------------------------------------------------- /templates/account/logout.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load url from future %} 4 | {% load i18n %} 5 | 6 | {% block head_title %}{% trans "Sign Out" %}{% endblock %} 7 | 8 | {% block container %} 9 |
10 |
11 |
12 |

{% trans "Sign Out" %}

13 | 14 |

{% trans 'Are you sure you want to sign out?' %}

15 | 16 |
17 | {% csrf_token %} 18 | {% if redirect_field_value %} 19 | 20 | {% endif %} 21 | 22 |
23 |
24 |
25 |
26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /templates/account/password_reset.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% load account %} 5 | {% load crispy_forms_tags %} 6 | {% load url from future %} 7 | 8 | {% block head_title %}{% trans "Password Reset" %}{% endblock %} 9 | 10 | {% block container %} 11 | 12 |
13 |
14 |
15 | 16 |

{% trans "Password Reset" %}

17 | {% if user.is_authenticated %} 18 | {% include "account/snippets/already_logged_in.html" %} 19 | {% endif %} 20 | 21 |

{% trans "Forgotten your password? Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it." %}

22 | 23 |
24 | {% csrf_token %} 25 | {{ form|crispy }} 26 | 27 |
28 | 29 |

{% blocktrans %}Please contact us if you have any trouble resetting your password.{% endblocktrans %}

30 |
31 |
32 |
33 | {% endblock %} 34 | 35 | {% block extra_body %} 36 | 39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /templates/account/password_reset_done.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% load account %} 5 | 6 | {% block head_title %}{% trans "Password Reset" %}{% endblock %} 7 | 8 | {% block container %} 9 |
10 |
11 |
12 |

{% trans "Password Reset" %}

13 | 14 | {% if user.is_authenticated %} 15 | {% include "account/snippets/already_logged_in.html" %} 16 | {% endif %} 17 | 18 |

{% blocktrans %}We have sent you an e-mail. Please contact us if you do not receive it within a few minutes.{% endblocktrans %}

19 |
20 |
21 |
22 | {% endblock %} 23 | -------------------------------------------------------------------------------- /templates/account/password_reset_from_key.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load url from future %} 4 | {% load i18n %} 5 | {% load crispy_forms_tags %} 6 | {% block head_title %}{% trans "Change Password" %}{% endblock %} 7 | 8 | {% block container %} 9 |
10 |
11 |
12 |

{% if token_fail %}{% trans "Bad Token" %}{% else %}{% trans "Change Password" %}{% endif %}

13 | 14 | {% if token_fail %} 15 | {% url 'account_reset_password' as passwd_reset_url %} 16 |

{% blocktrans %}The password reset link was invalid, possibly because it has already been used. Please request a new password reset.{% endblocktrans %}

17 | {% else %} 18 | {% if form %} 19 |
20 | {% csrf_token %} 21 | {{ form|crispy }} 22 | 23 |
24 | {% else %} 25 |

{% trans 'Your password is now changed.' %}

26 | {% endif %} 27 | {% endif %} 28 |
29 |
30 |
31 | {% endblock %} 32 | -------------------------------------------------------------------------------- /templates/account/password_reset_from_key_done.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load url from future %} 4 | {% load i18n %} 5 | {% block head_title %}{% trans "Change Password" %}{% endblock %} 6 | 7 | {% block container %} 8 |
9 |
10 |
11 |

{% trans "Change Password" %}

12 |

{% trans 'Your password is now changed.' %}

13 |
14 |
15 |
16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /templates/account/signup.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load url from future %} 4 | {% load i18n %} 5 | {% load crispy_forms_tags %} 6 | 7 | {% block head_title %}{% trans "Registrate" %}{% endblock %} 8 | 9 | {% block container %} 10 |
11 |
12 |
13 |

{% trans "Registrate" %}

14 | 15 |

16 | {% blocktrans %} 17 | ¿Ya tenes cuenta? Por favor inicia sesión. 18 | {% endblocktrans %} 19 |

20 |
21 | 29 |
30 |
31 | {% endblock %} 32 | 33 | 34 | -------------------------------------------------------------------------------- /templates/account/signup_closed.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load url from future %} 4 | {% load i18n %} 5 | 6 | {% block head_title %}{% trans "Sign Up Closed" %}{% endblock %} 7 | 8 | {% block content %} 9 |

{% trans "Sign Up Closed" %}

10 | 11 |

{% trans "We are sorry, but the sign up is currently closed." %}

12 | {% endblock %} 13 | 14 | 15 | -------------------------------------------------------------------------------- /templates/buscador.html: -------------------------------------------------------------------------------- 1 | {% extends "base_site.html" %} 2 | 3 | {% block title %} 4 | Resultados para «{{ buscar }}» 5 | {% endblock title %} 6 | 7 | 8 | {% block left-column %} 9 | 12 | 13 | 25 | 26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /templates/companies/company_confirm_delete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% load devtags %} 6 | 7 | {% block content %} 8 | 9 |
10 |
11 |
12 |
{% csrf_token %} 13 | {% trans "Are you sure you want to delete" %} "{{ object.name }}" ? 14 | 15 | No 16 |
17 |
18 |
19 |
20 | 21 | {% endblock %} 22 | -------------------------------------------------------------------------------- /templates/companies/company_detail.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load disqus_tags %} 3 | {% load i18n %} 4 | {% load staticfiles %} 5 | {% load devtags %} 6 | {% block title %} 7 | {{ object.title }} 8 | {% endblock title %} 9 | 10 | {% block content %} 11 |
12 |
13 | 24 |
25 |
26 |
27 |

{% autoescape off %}{{ object.description|linebreaks|safe }}{% endautoescape %}

28 |
29 |
30 |
31 | 32 | 33 | 34 |
35 |
36 |
37 |
38 | {% endblock %} 39 | -------------------------------------------------------------------------------- /templates/companies/company_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load i18n %} 3 | {% load crispy_forms_tags %} 4 | 5 | {% load devtags %} 6 | 7 | {% block stylesheets %} 8 | 9 | {% endblock %} 10 | 11 | {% block content %} 12 |
13 |
14 | 22 | {{ form.media }} 23 | {% crispy form %} 24 |
25 |
26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /templates/companies/company_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base_site.html" %} 2 | {% load devtags %} 3 | {% load i18n staticfiles pagination_tags devtags %} 4 | {% block title %}Empresas que utilizan Python{% endblock %} 5 | {% block left-column %} 6 | 7 |
8 |
9 | 16 | {% if object_list %} 17 | {% for object in object_list %} 18 |

19 | {{ object.name }} 20 |

21 |

{{ object.description|striptags|truncatewords:"20" }}

22 |

{% trans 'Más información...' %}

23 | {% endfor %} 24 | 25 | {% paginate %} 26 | {% else %} 27 |
28 |

{% trans 'La búsqueda no produjo resultados.' %}

29 |
30 | {% endif %} 31 |
32 |
33 | {% endblock %} 34 | 35 | {% block right-column %} 36 | {{ block.super }} 37 | {% include "_tags_filtering_form.html" %} 38 | {% endblock %} 39 | -------------------------------------------------------------------------------- /templates/events/event_confirm_delete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% load devtags %} 6 | 7 | {% block content %} 8 | 9 |
10 |
11 |
12 |
{% csrf_token %} 13 | {% trans "Are you sure you want to delete" %} "{{ object.name }}" ? 14 | 15 | No 16 |
17 |
18 |
19 |
20 | 21 | {% endblock %} -------------------------------------------------------------------------------- /templates/events/event_detail.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% load devtags %} 6 | 7 | {% block title %} 8 | {{ event.name }} 9 | {% endblock title %} 10 | 11 | 12 | {% block stylesheets %} 13 | 14 | {% endblock %} 15 | 16 | {% block javascripts %} 17 | 18 | 19 | {% endblock %} 20 | 21 | 22 | {% block content %} 23 | 24 |
25 |
26 |
27 | 28 | 48 | 49 |
50 |
51 | 52 |
53 | 54 | {% include "events/event_detail_body.html" with obj=event %} 55 | 56 |
57 | 58 | 59 | 60 | 61 | 62 | 63 |
64 | 65 | {% endblock %} 66 | 67 | 68 | -------------------------------------------------------------------------------- /templates/events/event_detail_body.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | 3 | 4 |
5 | 6 |

{% trans "¿De qué se trata?" %}

7 |

{{ obj.description|safe }}

8 | 9 |
10 | 11 |
12 | 13 |

{% trans "¿Cuándo?" %}

14 | {% if obj.start_at %} 15 |

{% trans "Comienza" %}: {{ obj.start_at }}

16 | {% endif %} 17 | 18 | {% if obj.end_at %} 19 |

{% trans "Termina" %}: {{ obj.end_at }}

20 | {% endif %} 21 | 22 |

{% trans "¿Dónde?" %}

23 |

{{ obj.place }} | {{ obj.address }}

24 | 25 | {% if obj.url %} 26 |

{% trans "Más Información" %}

27 |

28 | {{ obj.url }} 29 |

30 | {% endif %} 31 | -------------------------------------------------------------------------------- /templates/events/event_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load i18n %} 4 | {% load devtags %} 5 | {% load crispy_forms_tags %} 6 | 7 | {% block stylesheets %} 8 | 9 | {{ form.media.css }} 10 | {% endblock %} 11 | 12 | {% block content %} 13 | 14 |
15 |
16 | 31 | 32 | {% crispy form %} 33 | 34 |
35 |
36 | 37 | {% endblock %} 38 | 39 | {% block javascripts %} 40 | 41 | 42 | 43 | 44 | {{ form.media.js }} 45 | 46 | {% endblock %} 47 | 48 | -------------------------------------------------------------------------------- /templates/events/event_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base_site.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% load devtags %} 6 | 7 | {% block title %}Eventos {% endblock %} 8 | 9 | {% block left-column %} 10 | 11 | 12 | 13 |
14 | 35 | 36 | 37 | {% for event in eventos_proximos %} 38 | 39 | 48 | {% empty %} 49 |
50 |

{% trans "No hay eventos a futuro" %}

51 |
52 | {% endfor %} 53 | 54 |
55 | 56 | 61 | 62 | {% for event in eventos_pasados %} 63 | 64 | 73 | 74 | {% empty %} 75 |
76 |

{% trans "No hay eventos pasados" %}

77 |
78 | {% endfor %} 79 | 80 | 95 | 96 |
97 | {% endblock %} 98 | -------------------------------------------------------------------------------- /templates/events/next_events.html: -------------------------------------------------------------------------------- 1 | {% for event in events %} 2 |
3 |

4 | 5 | {{ event.name }} 6 | 7 |

8 | 9 |

10 | {{ event.start_at|date:"DATE_FORMAT" }} | 11 | {{ event.start_at|time:"TIME_FORMAT" }} | 12 | {{ event.place }} 13 |

14 |
15 | 16 | {% empty %} 17 |
18 |

No hay eventos a futuro

19 |
20 | {% endfor %} 21 | -------------------------------------------------------------------------------- /templates/faq/all.html: -------------------------------------------------------------------------------- 1 | {% extends "base_site.html" %} 2 | 3 | 4 | {% block left-column %} 5 | 6 | {% block title %}Preguntas frecuentes {% endblock %} 7 | 8 | 9 | {% regroup faqs by topic as topic_list %} 10 | 11 |
12 |
13 |
    14 | {% for topic in topic_list %} 15 |
  1. {{ topic.grouper.name }} 16 |
      17 | {% for question in topic.list %} 18 |
    1. 19 | {{ question.text }} 20 |
    2. 21 | {% endfor %} 22 |
    23 |
  2. 24 | {% endfor %} 25 |
26 |
27 |
28 | 29 | 30 |
    31 | {% for topic in topic_list %} 32 |
  1. 33 |

    {{ topic.grouper.name }}

    34 |
      35 | {% for question in topic.list %} 36 |
    1. 37 |

      {{ question.text }}

      38 |

      {{ question.answer }}

      39 |
    2. 40 | {% endfor %} 41 |
    42 |
  2. 43 | {% endfor %} 44 |
45 | {% endblock %} 46 | -------------------------------------------------------------------------------- /templates/irc/irc.html: -------------------------------------------------------------------------------- 1 | {% extends "base_site.html" %} 2 | 3 | {% load devtags %} 4 | 5 | {% block title %}Canal de chat IRC{% endblock %} 6 | 7 | {% block left-column %} 8 | 9 |

Archivo de IRC

10 |

El archivo del canal se encuentra disponible en http://irclogger.com/.pyar/

11 |

Accediendo al canal desde tu cliente favorito

12 |

Si querés usar otro cliente de IRC, ingresá al canal: #pyar en el server: irc.freenode.net

13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /templates/jobs/_jobs_tags.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% trans 'Etiquetas:' %} 3 | {% for tag in object.tags.all %} 4 | {{ tag.name }} 5 | {% endfor %} 6 | -------------------------------------------------------------------------------- /templates/jobs/job_confirm_delete.html: -------------------------------------------------------------------------------- 1 | {% extends "confirm_delete.html" %} 2 | {% load i18n %} 3 | 4 | {% block page_title %}{% trans 'Borrar trabajo' %}{% endblock %} 5 | 6 | {% block return_url %}{% url 'jobs_view' object.id %}{% endblock %} -------------------------------------------------------------------------------- /templates/jobs/job_detail.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load disqus_tags %} 3 | {% load i18n %} 4 | {% load email_obfuscator %} 5 | {% load devtags %} 6 | 7 | {% block title %} 8 | {{ object.title }} 9 | {% endblock %} 10 | 11 | {% block content %} 12 |
13 | 14 |
15 | 16 | 26 | 27 |
28 | 29 |
30 | 31 | 32 | {% autoescape off %} 33 | {{ object.description }} 34 | {% endautoescape %} 35 | {% include "jobs/_jobs_tags.html" %} 36 | 37 |
38 | 39 |
40 |
41 |
Datos de la oferta laboral
42 |
43 |
44 | {% include 'jobs/job_overview.html' with obj=object %} 45 |
46 |
47 |
48 |
49 | 50 |
51 | 52 |
53 | {% disqus_show_comments %} 54 |
55 | 56 |
57 | 58 | 59 |
60 | 61 | {% endblock %} 62 | -------------------------------------------------------------------------------- /templates/jobs/job_detail_feed.html: -------------------------------------------------------------------------------- 1 | {% load devtags %} 2 | {% include 'jobs/job_overview.html' %} 3 |

{{ obj.description|html2text }}

-------------------------------------------------------------------------------- /templates/jobs/job_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load i18n %} 3 | {% load crispy_forms_tags %} 4 | 5 | {% load devtags %} 6 | 7 | {% block content %} 8 |
9 |
10 | 18 | {{ form.media }} 19 | {% crispy form %} 20 |
21 |
22 | {% endblock %} 23 | -------------------------------------------------------------------------------- /templates/jobs/job_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base_site.html" %} 2 | {% load devtags %} 3 | {% load i18n staticfiles pagination_tags %} 4 | {% block title %}Ofertas laborales con Python{% endblock %} 5 | {% block left-column %} 6 | 7 | 8 |
9 |
10 | 17 | 18 | {% if object_list %} 19 | {% for object in object_list %} 20 |

21 | {{ object.title }} ({{ object.modified|date:"SHORT_DATE_FORMAT" }}, {{ object.location }}) 22 |

23 |

{{ object.description|html2text|truncatewords:50 }}

24 |
25 | {% include "jobs/_jobs_tags.html" %} 26 |

{% trans 'Leer más...' %}

27 | {% endfor %} 28 | 29 | {% paginate %} 30 | {% else %} 31 |
32 |

{% trans 'La búsqueda no produjo resultados.' %}

33 |
34 | {% endif %} 35 | 36 | 37 | 38 |
39 | 40 | RSS 41 | 42 |
43 |
44 |
45 | {% endblock %} 46 | 47 | {% block right-column %} 48 | {{ block.super }} 49 | {% include "_tags_filtering_form.html" %} 50 | {% endblock %} 51 | -------------------------------------------------------------------------------- /templates/jobs/job_overview.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
Fecha de publicación
4 |
5 | 6 |
7 |
Lugar de trabajo
8 |
{{ obj.location|title }}
9 | {% if obj.company %} 10 |
Empresa
11 |
12 | {{ obj.company.name }} 13 |
14 | {% endif %} 15 |
Permite trabajar remoto
16 |
{% if obj.remote_work %}Si{% else %}No{% endif %}
17 | {% if obj.seniority %} 18 |
Seniority requerido
19 |
{{ obj.seniority|title }}
20 | {% endif %} 21 |
Email de contacto
22 |
{{ obj.email }}
23 |
24 |
25 |
26 | 27 | -------------------------------------------------------------------------------- /templates/jobs/jobs_by_user.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load devtags %} 4 | 5 | {% block content %} 6 |
7 |
8 |
9 | 10 | 11 |
12 |
13 |

Companias que usan Python

14 |
15 | {% if companies|length < 1 %} 16 | 20 | {% else %} 21 | {% for company in companies %} 22 | 26 | {% endfor %} 27 | {% endif %} 28 |
29 |
30 |
31 | 32 | 33 | 34 |
35 | 36 | 37 | 40 | 41 |
42 | 43 | 44 | 45 |
46 |
47 |

Próximos eventos

48 |
49 | {% for i in 4|get_range %} 50 |
51 |

PyCon Argentina

52 |

23 de Agosto de 2012 | 20:00 hs | Audotorio UnQui

53 |
54 | {% endfor %} 55 |
56 | 57 | 58 | 59 |
60 |
61 |

Planeta PyAr

62 |
63 | {% for i in 4|get_range %} 64 |
65 |

Mi experiencia con PyQT y HTML5

66 |

via: http://elblogdefulanito... | 23-05-2012 | 22:05

67 |
68 | {% endfor %} 69 |
70 |
71 |
72 |
73 | {% endblock %} 74 | -------------------------------------------------------------------------------- /templates/newbie/add-jedi.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load devtags i18n %} 4 | 5 | {% block content %} 6 |
7 |
8 |
9 | {% if success %} 10 | {% trans "¡Ya eres un Jedi!" %} 11 | {% else %} 12 |
13 | {% csrf_token %} 14 | {{ form.as_p }} 15 | 16 |
17 | {% endif %} 18 |
19 |
20 |
21 | {% endblock %} 22 | -------------------------------------------------------------------------------- /templates/newbie/add-padawan.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load devtags i18n %} 4 | 5 | {% block content %} 6 |
7 |
8 |
9 | {% if success %} 10 | {% trans "¡Ya eres un Padawan!" %} 11 | {% else %} 12 |
13 | {% csrf_token %} 14 | {{ form.as_p }} 15 | 16 |
17 | {% endif %} 18 |
19 |
20 |
21 | {% endblock %} 22 | -------------------------------------------------------------------------------- /templates/newbie/jedi-receive-response.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block content %} 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /templates/newbie/jedi-request-successfully.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |
6 | {% if jedi_accept %} 7 |

{% blocktrans %}Ahora eres el Jedi de {{ padawan_email }}{% endblocktrans %}

8 | {% else %} 9 |

{% blocktrans %}Solicitud enviada.{% endblocktrans %}

10 | {% endif %} 11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /templates/newbie/list-jedi.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |
6 |
7 |
8 |

Jedis disponibles

9 | 10 | {% for jedi in jedi_list %} 11 | 12 | 13 | 14 | 17 | 18 | {% empty %} 19 |

No hay ningun Jedi por el momento :(

20 | {% endfor %} 21 |
{{ jedi.id }}{{ jedi.user.username }} 15 | {% trans "Enviar solicitud" %} 16 |
22 |
23 |
24 |
25 | {% endblock %} 26 | -------------------------------------------------------------------------------- /templates/newbie/list-padawan.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block content %} 6 |
7 |
8 |
9 |

{% trans "Lista de Padawan" %}

10 | 11 | {% for padawan in padawan_list %} 12 | 13 | 14 | 15 | 16 | {% endfor %} 17 |
{{ padawan.id }}{{ padawan.user.username }}
18 |
19 |
20 |
21 | {% endblock %} 22 | -------------------------------------------------------------------------------- /templates/newbie/register.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% load i18n %} 4 | 5 | {% block content %} 6 |
7 |

{% trans "Quiero aprender" %}

8 | 9 | {% if not is_jedi %} 10 |

{% trans "Quiero ser un Jedi" %}

11 | {% endif %} 12 | 13 | {% if not is_padawan %} 14 |

{% trans "Quiero ser un Padawan" %}

15 | {% endif %} 16 |
17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /templates/news/newsarticle_confirm_delete.html: -------------------------------------------------------------------------------- 1 | {% extends "confirm_delete.html" %} 2 | {% load i18n %} 3 | 4 | {% block page_title %}{% trans 'Borrar noticia' %}{% endblock %} 5 | 6 | {% block return_url %}{% url 'news_view' object.id %}{% endblock %} -------------------------------------------------------------------------------- /templates/news/newsarticle_detail.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load disqus_tags %} 3 | {% load i18n %} 4 | {% load email_obfuscator %} 5 | {% load devtags %} 6 | {% block title %} 7 | {{ object.title }} 8 | {% endblock title %} 9 | 10 | {% block content %} 11 |
12 |
13 | 28 |
29 |

{% autoescape off %}{{ object.body|linebreaks|safe }}{% endautoescape %}

30 |
31 |
32 | {% disqus_show_comments %} 33 |
34 |
35 |
36 | {% endblock %} 37 | -------------------------------------------------------------------------------- /templates/news/newsarticle_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load i18n %} 3 | {% load crispy_forms_tags %} 4 | 5 | {% load devtags %} 6 | 7 | {% block content %} 8 |
9 |
10 | 18 | {{ form.media }} 19 | {% crispy form %} 20 |
21 |
22 | {% endblock %} -------------------------------------------------------------------------------- /templates/news/newsarticle_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base_site.html" %} 2 | {% load devtags i18n staticfiles pagination_tags %} 3 | 4 | {% block title %}Noticias {% endblock %} 5 | 6 | {% block left-column %} 7 | 8 |
9 |
10 | 19 | {% if object_list %} 20 | {% for object in object_list %} 21 |

22 | {{ object.title }} ({{ object.modified|date:"SHORT_DATE_FORMAT" }}) 23 |

24 |

25 | {{ object.introduction|html2text|truncatewords:50 }} 26 |

27 |
{% trans 'Etiquetas:' %}{% for t in object.tags.all %} {{ t.name }} {% endfor %}
28 |

{% trans 'Leer más...' %}

29 | {% endfor %} 30 | {% paginate %} 31 | {% else %} 32 |
33 |

{% trans 'La búsqueda no produjo resultados.' %}

34 |
35 | {% endif %} 36 | 37 | 38 | 39 | 40 |
41 | 42 | RSS 43 | 44 |
45 |
46 |
47 | {% endblock %} 48 | 49 | {% block right-column %} 50 | {% with True as hide_sidebar_news %} 51 | {{ block.super }} 52 | {% endwith %} 53 | {% include "_tags_filtering_form.html" %} 54 | {% endblock %} 55 | -------------------------------------------------------------------------------- /templates/planet/authors/blocks/list.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% if authors %} 3 |

{% trans "Authors" %}

4 | 13 | {% endif %} 14 | -------------------------------------------------------------------------------- /templates/planet/authors/blocks/list_for_feed.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 |

{% trans "Authors for this feed" %}

3 | 12 | -------------------------------------------------------------------------------- /templates/planet/authors/blocks/list_for_tag.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load url from future %} 3 | {% ifnotequal authors|length 1 %} 4 | 14 | {% endifnotequal %} 15 | -------------------------------------------------------------------------------- /templates/planet/authors/detail.html: -------------------------------------------------------------------------------- 1 | {% extends "planet/base.html" %} 2 | {% load i18n pagination_tags tagging_tags planet_tags %} 3 | {% load url from future %} 4 | 5 | {% block head_title %}{{ author.name }}{% endblock %} 6 | 7 | {% block extra_head %} 8 | 9 | 10 | 11 | 12 | {% endblock %} 13 | 14 | {% block breadcrumb_section %} 15 |
  • Authors /
  • 16 | {% if tag %} 17 |
  • {{ author.name }} /
  • 18 | {% endif %} 19 | {% endblock %} 20 | {% block breadcrumb_detail %} 21 | {% if tag %} 22 |
  • Tag: {{ tag.name }}
  • 23 | {% else %} 24 |
  • {{ author.name }}
  • 25 | {% endif %} 26 | {% endblock %} 27 | 28 | {% block head_feeds %} 29 | 30 | {% endblock %} 31 | 32 | {% block rss_feed %} 33 | 34 | RSS 2.0 Feed 35 | 36 | {% endblock %} 37 | 38 | {% block content %} 39 |

    {{ author.name }}

    40 | 41 | {% for blog in author|get_blogs %} 42 | 43 | 44 | 45 | 46 | {% endfor %} 47 | {% for blog in author|get_blogs %} 48 | 49 | 50 | 51 | 52 | {% endfor %} 53 | 54 | 55 | 56 | 57 |
    {% trans 'Blog Info' %}{{ blog.title }}
    {% trans 'Blog website' %}link
    {% trans 'Stats' %}Has written {{ author|post_count }} posts about or related to Django
    58 | 59 | {% if tag %} 60 |
    61 |

    {% trans 'Posts under tag' %}: {{ tag|safe }}

    62 | 63 | {% trans 'See the complete list of posts by this author' %} 64 | 65 |
    66 | {% endif %} 67 | 68 | {% autopaginate posts 20 %} 69 | {% for post in posts %} 70 |
    71 | {% post_details post "planet/posts/short.html" %} 72 |
    73 | {% endfor %} 74 | {% paginate %} 75 | {% endblock %} 76 | 77 | {% block right_column %} 78 | {% if tag %} 79 |
    80 | {% authors_about tag %} 81 |
    82 | {% endif %} 83 | 84 | {% cloud_for_author author %} 85 | {% endblock %} 86 | -------------------------------------------------------------------------------- /templates/planet/authors/list.html: -------------------------------------------------------------------------------- 1 | {% extends "planet/base.html" %} 2 | {% load i18n pagination_tags planet_tags %} 3 | {% load url from future %} 4 | 5 | {% block head_title %}{% trans 'Authors list' %}{% endblock %} 6 | 7 | {% block extra_head %} 8 | 9 | 10 | 11 | {% endblock %} 12 | 13 | {% block breadcrumb_section %}
  • {% trans 'Blog Authors' %}
  • {% endblock %} 14 | 15 | {% block authors_class %}class="active"{% endblock %} 16 | 17 | {% block content %} 18 |

    {% trans "Authors" %}

    19 |
    20 | {% autopaginate authors_list 20 %} 21 | {% for author in authors_list %} 22 |
    23 |
    24 |

    25 | 26 | {{ author.name }} 27 | 28 |

    29 |
    30 |
    31 | writes for: 32 | {% for blog in author|get_blogs %} 33 | {{ blog.title }} 34 | {% if not forloop.last %}, {% endif %} 35 | {% endfor %} 36 |
    37 |
    38 | {% endfor %} 39 | {% paginate %} 40 |
    41 | {% endblock %} 42 | -------------------------------------------------------------------------------- /templates/planet/authors/list_for_tag.html: -------------------------------------------------------------------------------- 1 | {% extends "planet/base.html" %} 2 | {% load i18n pagination_tags %} 3 | {% load url from future %} 4 | 5 | {% block head_title %}{% trans 'Authors under tag' %} {{ tag|safe }}{% endblock %} 6 | 7 | {% block extra_head %} 8 | 9 | 10 | 11 | {% endblock %} 12 | 13 | {% block breadcrumb_section %} 14 |
  • Tags /
  • 15 |
  • {{ tag|safe }} /
  • 16 | {% endblock %} 17 | {% block breadcrumb_detail %}
  • {% trans 'Authors' %}
  • {% endblock %} 18 | 19 | {% block content %} 20 |

    {% trans 'Authors talking about' %} {{ tag|safe }}

    21 |
    22 | {% autopaginate authors 40 %} 23 | {% for author in authors %} 24 |

    25 | 26 | {{ author.name }} 27 | 28 |

    29 | {% endfor %} 30 | {% paginate %} 31 |
    32 | {% endblock %} 33 | 34 | {% block right_column %} 35 | {% endblock %} 36 | -------------------------------------------------------------------------------- /templates/planet/base.html: -------------------------------------------------------------------------------- 1 | {% extends 'base_site.html' %} 2 | {% load i18n tagging_tags planet_tags %} 3 | {% load url from future %} 4 | 5 | {% block head_title_base %}{% block head_title %}{% endblock %}{% endblock %} 6 | 7 | {% block extra_head %} 8 | 9 | 10 | 11 | 12 | {% endblock %} 13 | 14 | {% block search %} 15 |
    16 | 17 | {{ search_form }} 18 | 19 |
    20 | {% endblock %} 21 | 22 | {% block right_column %} 23 | {% include 'planet/feeds/blocks/syndication_block.html' %} 24 | {% tag_cloud_for_model planet.Post as tags_cloud with steps=7 min_count=5 distribution=log %} 25 | {% include 'planet/tags/blocks/cloud.html' %} 26 | {% endblock %} 27 | 28 | {% block footer %} 29 | {{ block.super }} 30 |

    {% blocktrans %}A django-planet powered site{% endblocktrans %}

    31 | {% endblock %} 32 | -------------------------------------------------------------------------------- /templates/planet/blogs/confirm_delete.html: -------------------------------------------------------------------------------- 1 | {% extends "confirm_delete.html" %} 2 | {% load i18n %} 3 | 4 | {% block page_title %}{% trans 'Borrar blog' %}{% endblock %} 5 | 6 | {% block return_url %}{% url 'planet_blog_list_by_user' %}{% endblock %} 7 | -------------------------------------------------------------------------------- /templates/planet/blogs/list.html: -------------------------------------------------------------------------------- 1 | {% extends "planet/base.html" %} 2 | {% load i18n pagination_tags %} 3 | {% load url from future %} 4 | 5 | {% block head_title %}{% trans "Blogs list" %}{% endblock %} 6 | 7 | {% block extra_head %} 8 | 9 | 10 | 11 | {% endblock %} 12 | 13 | {% block breadcrumb_section %}
  • {% trans 'Blogs' %}
  • {% endblock %} 14 | 15 | {% block blogs_class %}class="active"{% endblock %} 16 | 17 | {% block content %} 18 |

    {% trans "Blogs" %}

    19 | {% autopaginate blogs_list 50 %} 20 | {% for blog in blogs_list %} 21 |
    22 |
    23 |

    24 | {{ blog.title }} 25 |

    26 |
    27 |
    28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | {% for feed in blog.feed_set.all %} 36 | 37 | 38 | 42 | 43 | {% endfor %} 44 |
    {% trans 'web' %}{{ blog.url }}
    {% trans 'browse' %}{% trans 'latest posts' %}
    {% trans 'feed' %} 39 | 40 | RSS 41 |
    45 |
    46 |
    47 | {% endfor %} 48 | {% paginate %} 49 | {% endblock %} 50 | -------------------------------------------------------------------------------- /templates/planet/dummy.html: -------------------------------------------------------------------------------- 1 | {% extends template %} -------------------------------------------------------------------------------- /templates/planet/feeds/blocks/list_for_author.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | 14 | -------------------------------------------------------------------------------- /templates/planet/feeds/blocks/list_for_tag.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | -------------------------------------------------------------------------------- /templates/planet/feeds/blocks/syndication_block.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load url from future %} 3 |
    4 | 22 | -------------------------------------------------------------------------------- /templates/planet/feeds/detail.html: -------------------------------------------------------------------------------- 1 | {% extends "planet/base.html" %} 2 | {% load i18n pagination_tags tagging_tags planet_tags %} 3 | {% load url from future %} 4 | 5 | {% block head_title %}{% trans "Feed" %}: {{ feed.title }}{% endblock %} 6 | 7 | {% block extra_head %} 8 | 9 | 10 | 11 | 12 | {% endblock %} 13 | 14 | {% block breadcrumb_section %} 15 |
  • Blogs /
  • 16 |
  • {{ feed.blog.title }} /
  • 17 | {% if tag %} 18 |
  • Feed: {{ feed.title }} /
  • 19 | {% endif %} 20 | {% endblock %} 21 | {% block breadcrumb_detail %} 22 | {% if tag %} 23 |
  • Tag: {{ tag.name }}
  • 24 | {% else %} 25 |
  • Feed: {{ feed.title }}
  • 26 | {% endif %} 27 | {% endblock %} 28 | 29 | {% block content %} 30 | {% if feed.icon %} 31 | {% trans 'Feed icon' %} 32 | {% endif %} 33 |

    {% trans "Feed" %}: {{ feed.title }}

    34 | {% if feed.subtitle %} 35 |

    {{ feed.subtitle|striptags }}

    36 | {% endif %} 37 | 38 | {% if not tag %} 39 | 40 | 41 | 43 | 44 | 45 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
    {% trans 'Blog' %} 42 | {{ feed.blog.title }}
    {% trans 'RSS 2.0 Feed' %} 46 | {{ feed.title }}
    {% trans 'web' %}{{ feed.blog.url }}
    {% trans 'Last Update' %}{{ feed.last_checked|date:"m.d.Y" }}
    {% trans 'Posts' %}{{ feed.post_set.count }}
    58 | {% endif %} 59 | 60 | {% if tag %} 61 |

    {% trans 'Posts under tag' %}: {{ tag|safe }}

    62 | {% endif %} 63 | 64 | {% autopaginate posts 20 %} 65 | {% for post in posts %} 66 |
    67 | {% post_details post "planet/posts/short.html" %} 68 |
    69 | {% endfor %} 70 | {% paginate %} 71 | {% endblock %} 72 | 73 | {% block right_column %} 74 | {# this is too slow % authors_for_feed feed %#} 75 | {% include 'planet/feeds/blocks/syndication_block.html' %} 76 | 77 | {% if tag %} 78 |
    79 | {% related_tags_for tag %} 80 |
    81 |
    82 | {% feeds_about tag %} 83 |
    84 | {% endif %} 85 | 86 | {% cloud_for_feed feed %} 87 | {% endblock %} 88 | -------------------------------------------------------------------------------- /templates/planet/feeds/form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load i18n %} 3 | {% load crispy_forms_tags %} 4 | 5 | {% load devtags %} 6 | 7 | {% block content %} 8 |
    9 |
    10 | 18 |
    19 |
    20 | 21 |

    Warning!

    22 |

    Best check yo self, you're not looking too good. Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

    23 |
    24 |
    25 | {% crispy form %} 26 |
    27 |
    28 | {% endblock %} -------------------------------------------------------------------------------- /templates/planet/feeds/list.html: -------------------------------------------------------------------------------- 1 | {% extends "planet/base.html" %} 2 | {% load i18n pagination_tags %} 3 | 4 | {% block head_title %}{% trans "Feeds list" %}{% endblock %} 5 | 6 | {% block extra_head %} 7 | 8 | 9 | 10 | {% endblock %} 11 | 12 | {% block breadcrumb_section %}
  • Feeds
  • {% endblock %} 13 | 14 | {% block content %} 15 |

    {% trans "Feeds" %}

    16 |
    17 | {% autopaginate feeds_list 50 %} 18 |
    39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /templates/planet/feeds/list_for_tag.html: -------------------------------------------------------------------------------- 1 | {% extends "planet/base.html" %} 2 | {% load i18n pagination_tags %} 3 | {% load url from future %} 4 | 5 | {% block head_title %}{% trans "Feeds under tag" %} {{ tag|safe }}{% endblock %} 6 | 7 | {% block extra_head %} 8 | 9 | 10 | 11 | {% endblock %} 12 | 13 | {% block breadcrumb_section %} 14 |
  • Tags /
  • 15 |
  • {{ tag|safe }} /
  • 16 | {% endblock %} 17 | {% block breadcrumb_detail %}
  • {% trans 'Blog Feeds' %}
  • {% endblock %} 18 | 19 | {% block content %} 20 |

    {% trans 'Feeds talking about' %} {{ tag|safe }}

    21 |
    22 | {% autopaginate feeds_list 40 %} 23 | {% for feed in feeds_list %} 24 |

    25 | 26 | Feed 27 | 28 | 29 | {{ feed.title }} 30 | 31 |

    32 | {% endfor %} 33 | {% paginate %} 34 |
    35 | {% endblock %} 36 | -------------------------------------------------------------------------------- /templates/planet/list.html: -------------------------------------------------------------------------------- 1 | {% load i18n pagination_tags planet_tags %} 2 | 3 |

    {% trans "Latest posts" %}

    4 | {% for post in posts %} 5 |
    6 | {% post_details post %} 7 |
    8 | {% endfor %} 9 | -------------------------------------------------------------------------------- /templates/planet/microformats/foaf.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | {{ site.name }} 13 | {{ site.domain }} 14 | 15 | 16 | {% for feed in feeds %} 17 | 18 | 19 | {{ feed.title }} 20 | 21 | 22 | {{ feed.blog.title }} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {% endfor %} 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /templates/planet/microformats/opml.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ site.name }} 5 | 6 | 7 | {% for feed in feeds %} 8 | 9 | {% endfor %} 10 | 11 | 12 | -------------------------------------------------------------------------------- /templates/planet/posts/confirm_delete.html: -------------------------------------------------------------------------------- 1 | {% extends "confirm_delete.html" %} 2 | {% load i18n %} 3 | 4 | {% block page_title %}{% trans 'Borrar entrada' %}{% endblock %} 5 | 6 | {% block return_url %}{% url 'planet_blog_list_by_user' %}{% endblock %} -------------------------------------------------------------------------------- /templates/planet/posts/detail.html: -------------------------------------------------------------------------------- 1 | {% extends "base_site.html" %} 2 | {% load i18n devtags pagination_tags planet_tags staticfiles %} 3 | {% load url from future %} 4 | 5 | {% block left-column %} 6 | 7 |
    8 |
    9 | 18 | 19 | {% post_full_details post %} 20 |
    21 | {{ post.content|safe }} 22 |
    23 |
    24 |
    25 | {% endblock %} 26 | {% block right-column %} 27 |
    28 |
    29 |

    {% trans 'Filtrar por etiqueta' %}

    30 |
    31 |
    32 |
    33 |
    34 | {% csrf_token %} 35 | {% for tag in tags %} 36 | 41 | 44 | {% endfor %} 45 |
    46 |
    47 |
    48 | 49 | 50 |
    51 |
    52 |
    53 |
    54 |
    55 |
    56 | 57 | {% endblock %} 58 | -------------------------------------------------------------------------------- /templates/planet/posts/details.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load url from future %} 3 |

    4 | 6 | {{ post.title|striptags|safe }} 7 | 8 |

    9 |

    10 | {{ post.date_modified|date:"d/m/y" }} ▪ 11 | 13 | {% trans "[Archived Version]" %} 14 | ▪ 15 | Published at {{ post.feed.blog.title }} 16 | {% if post.tags.count %} under tags  17 | {% for tag in post.tags.all|slice:":5" %} 18 | {{ tag.name }} 19 | {% endfor %} 20 | {% endif %} 21 |

    22 | {{ post.content|safe }} 23 |
    24 |

    25 | -------------------------------------------------------------------------------- /templates/planet/posts/full_details.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load url from future %} 3 |
    {{ post.date_modified|date:"M d Y" }}
    4 | 5 | {% for author in post.authors.all %} 6 | 7 | 11 | 12 | {% endfor %} 13 | 14 | 17 | 18 | 19 | 21 |
    {% trans 'published by' %} 8 | 9 | {{ author.name }} 10 |
    {% trans 'in blog' %} 15 | {{ post.feed.blog.title }} 16 |
    {% trans 'original entry' %}{{ post.title|safe }} 20 |
    22 |

    23 | {% for tag in post.tags.all %} 24 | {{ tag.name }} 25 | {% endfor %} 26 |

    27 | -------------------------------------------------------------------------------- /templates/planet/posts/list.html: -------------------------------------------------------------------------------- 1 | {% extends "base_site.html" %} 2 | {% load devtags i18n staticfiles pagination_tags planet_tags %} 3 | 4 | {% block title %}Planeta {% endblock %} 5 | 6 | {% block left-column %} 7 | 8 |
    9 |
    10 | 37 | {% autopaginate posts 15 %} 38 | {% for post in posts %} 39 |
    40 | {% post_details post %} 41 |
    42 | {% endfor %} 43 | 44 | {% paginate %} 45 |
    46 |
    47 | {% endblock %} 48 | {% block right-column %} 49 | {{ block.super }} 50 |
    51 |
    52 |

    {% trans 'Filtrar por etiqueta' %}

    53 |
    54 |
    55 |
    56 |
    57 | {% csrf_token %} 58 | {% for tag in tags %} 59 | 64 | 67 | {% endfor %} 68 |
    69 |
    70 |
    71 | 72 | 73 |
    74 |
    75 |
    76 |
    77 |
    78 |
    79 | 80 | {% endblock %} 81 | -------------------------------------------------------------------------------- /templates/planet/posts/short.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load url from future %} 3 |

    4 | 6 | {{ post.title|striptags|safe }} 7 | 8 |

    9 |

    10 | {{ post.date_modified|date:"M d Y" }} □ 11 | 14 | {% trans "[Archived Version]" %} 15 | □ 16 | Published at {{ post.feed.blog.title }} 17 | {% if post.tags.count %} under tags  18 | {% for tag in post.tags.all|slice:":5" %} 19 | {{ tag.name }} 20 | {% endfor %} 21 | {% endif %} 22 |

    -------------------------------------------------------------------------------- /templates/planet/tags/blocks/authors_cloud.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load url from future %} 3 | {% if tags_cloud %} 4 |

    {% trans "Tag cloud" %}

    5 | 10 | {% endif %} 11 | -------------------------------------------------------------------------------- /templates/planet/tags/blocks/blogs_cloud.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load url from future %} 3 | {% if tags_cloud %} 4 |

    {% trans "Tag cloud" %}

    5 |
    6 | {% for tag in tags_cloud %} 7 | {{ tag|safe }}  8 | {% endfor %} 9 |
    10 | {% endif %} 11 | -------------------------------------------------------------------------------- /templates/planet/tags/blocks/cloud.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load url from future %} 3 |

    {% trans "Tag cloud" %}

    4 |
    5 | {% for tag in tags_cloud %} 6 | {{ tag|safe }}  7 | {% endfor %} 8 |
    9 | -------------------------------------------------------------------------------- /templates/planet/tags/blocks/feeds_cloud.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load url from future %} 3 | {% if tags_cloud %} 4 |

    {% trans "Tag cloud" %}

    5 |
    6 | {% for tag in tags_cloud %} 7 | {{ tag|safe }}  8 | {% endfor %} 9 |
    10 | {% endif %} 11 | -------------------------------------------------------------------------------- /templates/planet/tags/blocks/related_list.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load url from future %} 3 | {% if related_tags %} 4 | 10 | {% endif %} 11 | -------------------------------------------------------------------------------- /templates/planet/tags/cloud.html: -------------------------------------------------------------------------------- 1 | {% extends "planet/base.html" %} 2 | {% load i18n pagination_tags %} 3 | {% load url from future %} 4 | 5 | {% block head_title %}{% trans "Tags cloud" %}{% endblock %} 6 | 7 | {% block extra_head %} 8 | 9 | 10 | 11 | {% endblock %} 12 | 13 | {% block breadcrumb_section %}
  • Tags
  • {% endblock %} 14 | 15 | {% block tags_class %}class="active"{% endblock %} 16 | 17 | {% block content %} 18 |

    {% trans "Tag cloud" %}

    19 |
    20 | {% autopaginate tags_cloud 200 %} 21 | {% for tag in tags_cloud %} 22 | {{ tag|safe }}  23 | {% endfor %} 24 | {% paginate %} 25 |
    26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /templates/planet/tags/detail.html: -------------------------------------------------------------------------------- 1 | {% extends "planet/base.html" %} 2 | {% load i18n pagination_tags tagging_tags planet_tags %} 3 | {% load url from future %} 4 | 5 | {% block head_title %} 6 | {{ tag|safe }}: {% trans "django blog posts news" %} 7 | {% endblock %} 8 | 9 | {% block extra_head %} 10 | 11 | 12 | 13 | 14 | {% endblock %} 15 | 16 | {% block head_feeds %} 17 | 18 | 19 | {% endblock %} 20 | 21 | {% block rss_feed %} 22 | 23 | RSS 2.0 Feed 24 | 25 | {% endblock %} 26 | 27 | {% block breadcrumb_section %}
  • Tags /
  • {% endblock %} 28 | {% block breadcrumb_detail %}
  • {{ tag.name }}
  • {% endblock %} 29 | 30 | {% block content %} 31 |

    {% trans "Tag" %}: {{ tag|safe }}

    32 | {% autopaginate posts 20 %} 33 | {% for post in posts %} 34 |
    35 | {% post_details post "planet/posts/short.html" %} 36 |
    37 | {% endfor %} 38 | 39 | {% paginate %} 40 | {% endblock %} 41 | 42 | {% block right_column %} 43 | {% include 'planet/feeds/blocks/syndication_block.html' %} 44 |
    45 | {% related_tags_for tag %} 46 |
    47 |
    48 | {% feeds_about tag %} 49 |
    50 | 58 | {% endblock %} 59 | -------------------------------------------------------------------------------- /templates/planet/tags/list.html: -------------------------------------------------------------------------------- 1 | {% extends "planet/base.html" %} 2 | {% load i18n pagination_tags planet_tags %} 3 | {% load url from future %} 4 | 5 | {% block head_title %}{% trans "List of tags and categories" %}{% endblock %} 6 | 7 | {% block extra_head %} 8 | 9 | 10 | 11 | {% endblock %} 12 | 13 | {% block content %} 14 |

    {% trans "Tags" %}

    15 |
    16 | {% autopaginate tags_list 50 %} 17 |
      18 | {% for tag in tags_list %} 19 |
    • {{ tag|safe }}
    • 20 | {% endfor %} 21 |
    22 | {% paginate %} 23 |
    24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /templates/projects/add.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load bootstrap3 %} 3 | 4 | {% load devtags %} 5 | 6 | {% block content %} 7 |
    8 |
    9 |
    10 |
    11 | {% csrf_token %} 12 | {% bootstrap_form form %} 13 | {% buttons %} 14 | 17 | {% endbuttons %} 18 |
    19 |
    20 |
    21 |
    22 | {% endblock %} 23 | -------------------------------------------------------------------------------- /templates/projects/all.html: -------------------------------------------------------------------------------- 1 | {% extends "base_site.html" %} 2 | {% load devtags %} 3 | 4 | {% block title %}Proyectos {% endblock %} 5 | 6 | {% block left-column %} 7 | 8 |
    9 | 16 | {% for project in pyar_projects %} 17 | 29 | {% endfor %} 30 | {% for project in projects %} 31 |
    32 |

    33 | 34 | {{ project.name }} 35 | 36 | 37 | ( Autor: {{ project.owner }} ) 38 | 39 |

    40 |

    {{ project.description|slice:":200" }} ...

    41 |
    42 |

    43 | {% if project.owner == user %} 44 | Borrar | 45 | Modificar 46 | {% endif %} 47 |

    48 |
    49 |
    50 | {% endfor %} 51 |
    52 | 53 | 68 | {% endblock %} 69 | -------------------------------------------------------------------------------- /templates/projects/update.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load devtags %} 3 | 4 | {% block content %} 5 |
    6 |
    7 |
    8 |
    9 | {% csrf_token %} 10 | {{ form.as_p }} 11 | 12 |
    13 |
    14 |
    15 |
    16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /templates/projects/view.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load disqus_tags %} 3 | {% load devtags %} 4 | {% disqus_dev %} 5 | 6 | {% block content %} 7 |
    8 |
    9 |
    10 |
    11 |
    12 |

    13 | {{ project.name }} | Volver
    14 | Autor: {{project.owner}} 15 |

    16 |
    17 |
    18 |

    {{ project.description }}

    19 |

    Repositorio | Licencia: {{ project.license }}

    20 |

    Tags: 21 | {{project.tags}} 22 | {% comment %} 23 | {% for tag in project.tags.all %} 24 | {{ tag }}, 25 | {% endfor %} 26 | {% endcomment %} 27 |

    28 |
    29 |
    30 | {% if project.owner == user %} 31 | Borrar | 32 | Modificar 33 | {% endif %} 34 |
    35 |
    36 |
    37 |
    38 | {% disqus_show_comments %} 39 |
    40 |
    41 |
    42 | {% endblock %} 43 | -------------------------------------------------------------------------------- /templates/registration/activate.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load devtags %} 4 | 5 | {% block content %} 6 |
    7 |
    8 |
    9 |
    10 |

    Error al activar su cuenta con el key {{ activation_key }}.

    11 |
    12 |
    13 |
    14 | 15 | 16 | 17 |
    18 | 19 | 20 | 23 | 24 |
    25 | 26 | 27 | 28 |
    29 |
    30 |

    Próximos eventos

    31 |
    32 | {% for i in 4|get_range %} 33 |
    34 |

    PyCon Argentina

    35 |

    23 de Agosto de 2012 | 20:00 hs | Audotorio UnQui

    36 |
    37 | {% endfor %} 38 |
    39 | 40 | 41 | 42 |
    43 |
    44 |

    Planeta PyAr

    45 |
    46 | {% for i in 4|get_range %} 47 |
    48 |

    Mi experiencia con PyQT y HTML5

    49 |

    via: http://elblogdefulanito... | 23-05-2012 | 22:05

    50 |
    51 | {% endfor %} 52 |
    53 |
    54 |
    55 |
    56 | {% endblock %} 57 | -------------------------------------------------------------------------------- /templates/registration/activation_complete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load devtags %} 4 | 5 | {% block content %} 6 |
    7 |
    8 |
    9 |
    10 |

    Su cuenta ha sido activada satisfactoriamente.

    11 |
    12 |
    13 |
    14 | 15 | 16 | 17 |
    18 | 19 | 20 | 23 | 24 |
    25 | 26 | 27 | 28 |
    29 |
    30 |

    Próximos eventos

    31 |
    32 | {% for i in 4|get_range %} 33 |
    34 |

    PyCon Argentina

    35 |

    23 de Agosto de 2012 | 20:00 hs | Audotorio UnQui

    36 |
    37 | {% endfor %} 38 |
    39 | 40 | 41 | 42 |
    43 |
    44 |

    Planeta PyAr

    45 |
    46 | {% for i in 4|get_range %} 47 |
    48 |

    Mi experiencia con PyQT y HTML5

    49 |

    via: http://elblogdefulanito... | 23-05-2012 | 22:05

    50 |
    51 | {% endfor %} 52 |
    53 |
    54 |
    55 |
    56 | {% endblock %} 57 | -------------------------------------------------------------------------------- /templates/registration/activation_email.txt: -------------------------------------------------------------------------------- 1 | Gracias por registrarse en PyAr! 2 | Para activar su cuenta haga click en el siguiente link: 3 | Activar 4 | -------------------------------------------------------------------------------- /templates/registration/activation_email_subject.txt: -------------------------------------------------------------------------------- 1 | Activar su nueva cuenta en PyAr 2 | -------------------------------------------------------------------------------- /templates/registration/login.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load devtags %} 4 | 5 | {% block content %} 6 |
    7 |
    8 |
    9 |
    10 | 16 |
    17 |
    18 |
    19 | 20 | 21 | 22 |
    23 | 24 | 25 | 28 | 29 |
    30 | 31 | 32 | 33 |
    34 |
    35 |

    Próximos eventos

    36 |
    37 | {% for i in 4|get_range %} 38 |
    39 |

    PyCon Argentina

    40 |

    23 de Agosto de 2012 | 20:00 hs | Audotorio UnQui

    41 |
    42 | {% endfor %} 43 |
    44 | 45 | 46 | 47 |
    48 |
    49 |

    Planeta PyAr

    50 |
    51 | {% for i in 4|get_range %} 52 |
    53 |

    Mi experiencia con PyQT y HTML5

    54 |

    via: http://elblogdefulanito... | 23-05-2012 | 22:05

    55 |
    56 | {% endfor %} 57 |
    58 |
    59 |
    60 |
    61 | {% endblock %} 62 | -------------------------------------------------------------------------------- /templates/registration/logout.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load devtags %} 4 | 5 | {% block content %} 6 |
    7 |
    8 |
    9 |
    10 |

    Sesion cerrada, nos vemos luego!

    11 |
    12 |
    13 |
    14 | 15 | 16 | 17 |
    18 | 19 | 20 | 23 | 24 |
    25 | 26 | 27 | 28 |
    29 |
    30 |

    Próximos eventos

    31 |
    32 | {% for i in 4|get_range %} 33 |
    34 |

    PyCon Argentina

    35 |

    23 de Agosto de 2012 | 20:00 hs | Audotorio UnQui

    36 |
    37 | {% endfor %} 38 |
    39 | 40 | 41 | 42 |
    43 |
    44 |

    Planeta PyAr

    45 |
    46 | {% for i in 4|get_range %} 47 |
    48 |

    Mi experiencia con PyQT y HTML5

    49 |

    via: http://elblogdefulanito... | 23-05-2012 | 22:05

    50 |
    51 | {% endfor %} 52 |
    53 |
    54 |
    55 |
    56 | {% endblock %} 57 | -------------------------------------------------------------------------------- /templates/registration/registration_complete.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load devtags %} 4 | 5 | {% block content %} 6 |
    7 |
    8 |
    9 |
    10 |

    Proceso completo! Un email ha sido envíado para confirmar su registro.

    11 |
    12 |
    13 |
    14 | 15 | 16 | 17 |
    18 | 19 | 20 | 23 | 24 |
    25 | 26 | 27 | 28 |
    29 |
    30 |

    Próximos eventos

    31 |
    32 | {% for i in 4|get_range %} 33 |
    34 |

    PyCon Argentina

    35 |

    23 de Agosto de 2012 | 20:00 hs | Audotorio UnQui

    36 |
    37 | {% endfor %} 38 |
    39 | 40 | 41 | 42 |
    43 |
    44 |

    Planeta PyAr

    45 |
    46 | {% for i in 4|get_range %} 47 |
    48 |

    Mi experiencia con PyQT y HTML5

    49 |

    via: http://elblogdefulanito... | 23-05-2012 | 22:05

    50 |
    51 | {% endfor %} 52 |
    53 |
    54 |
    55 |
    56 | {% endblock %} 57 | -------------------------------------------------------------------------------- /templates/registration/registration_form.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load devtags %} 4 | 5 | {% block content %} 6 |
    7 |
    8 |
    9 |
    10 | 11 | 17 |
    18 |
    19 |
    20 | 21 | 22 | 23 |
    24 | 25 | 26 | 29 | 30 |
    31 | 32 | 33 | 34 |
    35 |
    36 |

    Próximos eventos

    37 |
    38 | {% for i in 4|get_range %} 39 |
    40 |

    PyCon Argentina

    41 |

    23 de Agosto de 2012 | 20:00 hs | Audotorio UnQui

    42 |
    43 | {% endfor %} 44 |
    45 | 46 | 47 | 48 |
    49 |
    50 |

    Planeta PyAr

    51 |
    52 | {% for i in 4|get_range %} 53 |
    54 |

    Mi experiencia con PyQT y HTML5

    55 |

    via: http://elblogdefulanito... | 23-05-2012 | 22:05

    56 |
    57 | {% endfor %} 58 |
    59 |
    60 |
    61 |
    62 | {% endblock %} 63 | -------------------------------------------------------------------------------- /templates/special_page.html: -------------------------------------------------------------------------------- 1 | {% extends "base_site.html" %} 2 | {% load waliki_tags %} 3 | {% block title %} 4 | {{ title }} 5 | {% endblock title %} 6 | 7 | 8 | {% block left-column %} 9 | {% if title %} 10 | 13 | {% endif %} 14 | {% waliki_box slug %} 15 | {% endblock %} 16 | --------------------------------------------------------------------------------