├── .gitignore
├── LICENSE
├── Makefile
├── README.rst
├── __init__.py
├── apps
├── __init__.py
├── home_page
│ ├── __init__.py
│ ├── features
│ │ ├── resources
│ │ │ ├── erp5.png
│ │ │ ├── nsi.png
│ │ │ └── x.png
│ │ ├── show_index.feature
│ │ └── steps.py
│ ├── templates
│ │ └── index.html
│ ├── tests.py
│ └── views.py
├── members
│ ├── __init__.py
│ ├── admin.py
│ ├── features
│ │ ├── manage_members.feature
│ │ ├── resources
│ │ │ ├── batata_photo.png
│ │ │ ├── pedro_photo.png
│ │ │ └── pluck_photo.png
│ │ └── steps.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── 0002_auto__chg_field_member_current_team.py
│ │ ├── 0003_auto__del_field_member_current_team.py
│ │ ├── 0004_auto__add_participation__del_field_member_project_memberships.py
│ │ ├── 0005_auto__add_field_member_function__chg_field_member_slideshare__chg_fiel.py
│ │ ├── 0006_auto__add_field_member_is_renegade.py
│ │ ├── 0007_auto__add_field_member_slug__chg_field_member_photo.py
│ │ ├── 0008_auto__del_unique_member_slug.py
│ │ ├── 0009_add_nickname.py
│ │ ├── 0010_auto__add_field_member_phone.py
│ │ └── __init__.py
│ ├── models.py
│ ├── templates
│ │ ├── show_all_current_members.html
│ │ ├── show_all_former_members.html
│ │ └── show_member.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── news
│ ├── __init__.py
│ ├── admin.py
│ ├── features
│ │ ├── manage_news.feature
│ │ ├── resources
│ │ │ ├── erp5.png
│ │ │ ├── nsi.png
│ │ │ └── x.png
│ │ └── steps.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── 0002_auto.py
│ │ ├── 0003_auto__del_new__add_news.py
│ │ ├── 0004_auto__chg_field_news_image.py
│ │ ├── 0005_auto__del_field_news_datetime__add_field_news_date_and_time.py
│ │ ├── 0006_add_slug.py
│ │ └── __init__.py
│ ├── models.py
│ ├── templates
│ │ ├── detail_news.html
│ │ └── show_news.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── nsi_info
│ ├── __init__.py
│ ├── admin.py
│ ├── features
│ │ ├── manage_history.feature
│ │ └── steps.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ └── __init__.py
│ ├── models.py
│ ├── templates
│ │ └── show_about.html
│ ├── tests.py
│ └── views.py
├── projects
│ ├── __init__.py
│ ├── admin.py
│ ├── features
│ │ ├── link_documents_to_project.feature
│ │ ├── manage_projects.feature
│ │ ├── resources
│ │ │ ├── erp5.png
│ │ │ └── nsi.png
│ │ └── steps.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── 0002_auto__chg_field_project_end_date.py
│ │ ├── 0003_auto__add_document.py
│ │ ├── 0004_add_slug.py
│ │ ├── 0005_auto__add_field_project_github.py
│ │ └── __init__.py
│ ├── models.py
│ ├── templates
│ │ ├── show_all_projects.html
│ │ └── show_project.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── tools
│ ├── __init__.py
│ ├── admin.py
│ ├── features
│ │ ├── manage_tools.feature
│ │ ├── resources
│ │ │ ├── ludibrio.png
│ │ │ ├── ricks.png
│ │ │ └── should-dsl.png
│ │ └── steps.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── 0002_auto__add_field_tool_logo.py
│ │ ├── 0003_auto__add_field_tool_status.py
│ │ ├── 0004_auto__add_field_tool_short_description.py
│ │ ├── 0005_add_slug.py
│ │ └── __init__.py
│ ├── models.py
│ ├── templates
│ │ ├── show_all.html
│ │ └── show_tool.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── wiki
│ ├── __init__.py
│ ├── features
│ ├── manage_wiki.feature
│ └── steps.py
│ ├── forms.py
│ ├── models.py
│ ├── templates
│ ├── add_wiki_item.html
│ ├── delete_wiki_item.html
│ ├── edit_wiki_item.html
│ ├── wiki_item.html
│ ├── wiki_item_successfully_added.html
│ ├── wiki_item_successfully_deleted.html
│ ├── wiki_item_successfully_updated.html
│ └── wiki_items.html
│ ├── tests
│ ├── test_forms.py
│ ├── test_models.py
│ └── test_views.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── paths.py
├── settings.py
├── settings_test.py
├── setup_on_debian_like.sh
├── site_media
├── css
│ ├── base.css
│ ├── index.css
│ ├── members.css
│ ├── news.css
│ ├── nsi_info.css
│ ├── projects.css
│ ├── tools.css
│ └── wiki.css
├── files
│ └── projects
│ │ └── .gitignore
├── images
│ ├── base
│ │ ├── background_head.jpg
│ │ ├── favicon.ico
│ │ ├── feed.32x32.png
│ │ ├── github.32x32.png
│ │ ├── icon_github.png
│ │ ├── icon_lattes.png
│ │ ├── icon_site.png
│ │ ├── icon_slideshare.png
│ │ ├── icon_twitter.png
│ │ ├── logo.png
│ │ ├── news.png
│ │ ├── planetaNSI.png
│ │ ├── projects.32x32.png
│ │ ├── projects.png
│ │ ├── tools.32x32.png
│ │ └── tools.png
│ ├── members
│ │ └── .gitignore
│ ├── news
│ │ └── .gitignore
│ ├── projects
│ │ └── .gitignore
│ └── wiki
│ │ ├── add.png
│ │ ├── add_hover.png
│ │ ├── back.png
│ │ ├── delete.png
│ │ ├── delete_hover.png
│ │ ├── edit.png
│ │ └── edit_hover.png
└── javascripts
│ ├── coderwall.js
│ ├── github_activities.js
│ └── jquery-1.7.1.min.js
├── templates
└── base.html
├── terrain.py
├── thumbs.py
├── urls.py
└── web_steps.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *.db
3 | *.swp
4 | *.komodoproject
5 | .komodotools
6 | build/
7 | site_media/files
8 | site_media/images/members
9 | site_media/images/news
10 | site_media/images/projects
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2011 by NSI-IFF_Campos-Brazil
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | PYTHON=python
2 | PIP=pip
3 |
4 | export DJANGO_SETTINGS_MODULE=settings
5 |
6 | all: deps test_database test remove_test_database
7 |
8 | database:
9 | @$(PYTHON) manage.py syncdb
10 | @$(PYTHON) manage.py migrate
11 |
12 | test_database:
13 | @echo ==============================================
14 | @echo ========== Creating test database ============
15 | @echo
16 | @$(PYTHON) manage.py syncdb --settings=settings_test
17 | @$(PYTHON) manage.py migrate --settings=settings_test
18 |
19 |
20 | remove_test_database:
21 | @echo Deleting test database...
22 | @rm nsi_site-test.db
23 |
24 | deps: app_deps functional_deps unit_deps
25 |
26 | app_deps: django pil south docutils django-pagination linaro_django_pagination
27 |
28 | functional_deps: selenium lettuce splinter should-dsl nose lxml
29 |
30 | unit_deps: should-dsl model_mommy specloud nosedjango
31 |
32 | selenium:
33 | @$(PYTHON) -c 'import selenium' 2>/dev/null || $(PIP) install selenium==2.0rc3
34 |
35 | should-dsl:
36 | @$(PYTHON) -c 'import should_dsl' 2>/dev/null || $(PIP) install http://github.com/hugobr/should-dsl/tarball/master
37 |
38 | django:
39 | @$(PYTHON) -c 'import django' 2>/dev/null || $(PIP) install django
40 |
41 | splinter:
42 | @$(PYTHON) -c 'import splinter' 2>/dev/null || $(PIP) install http://github.com/cobrateam/splinter/tarball/master
43 |
44 | pil:
45 | @$(PYTHON) -c 'import pil' 2>/dev/null || $(PIP) install PIL
46 |
47 | south:
48 | @$(PYTHON) -c 'import south' 2>/dev/null || $(PIP) install South
49 |
50 | docutils:
51 | @$(PYTHON) -c 'import docutils' 2>/dev/null || $(PIP) install docutils
52 |
53 | lettuce:
54 | @$(PYTHON) -c 'import lettuce' 2>/dev/null || $(PIP) install lettuce
55 |
56 | nose:
57 | @$(PYTHON) -c 'import nose' 2>/dev/null || $(PIP) install nose
58 |
59 | lxml:
60 | @$(PYTHON) -c 'import lxml' 2>/dev/null || $(PIP) install lxml
61 |
62 | specloud:
63 | @$(PYTHON) -c 'import specloud' 2>/dev/null || $(PIP) install specloud --no-deps -r http://github.com/hugobr/specloud/raw/master/requirements.txt
64 |
65 | nosedjango:
66 | @$(PYTHON) -c 'import nosedjango' 2>/dev/null || $(PIP) install -U nosedjango nose
67 |
68 | model_mommy:
69 | @$(PYTHON) -c 'import model_mommy' 2>/dev/null || $(PIP) install http://github.com/vandersonmota/model_mommy/tarball/master
70 |
71 | django-pagination:
72 | @$(PYTHON) -c 'import pagination' 2>/dev/null || $(PIP) install -e git+https://github.com/tiagosc/django-pagination.git#egg=pagination
73 |
74 | linaro_django_pagination:
75 | @$(PYTHON) -c 'import linaro_django_pagination' 2>/dev/null || $(PIP) install -U linaro_django_pagination
76 |
77 | test: functional unit
78 |
79 | functional: functional_deps deps
80 | @echo ==============================================
81 | @echo ========= Running acceptance specs ===========
82 | @python manage.py harvest --settings=settings_test
83 | @echo
84 |
85 | unit: unit_deps deps
86 | @echo ==============================================
87 | @echo ============ Running unit specs ==============
88 | @specloud --with-django --nocapture
89 | @echo
90 |
91 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | NSI Site
2 | ========
3 |
4 | How to Install
5 | --------------
6 |
7 | On Debian like
8 | ~~~~~~~~~~~~~~
9 | Just run::
10 |
11 | ./setup_on_debian_like.sh
12 |
13 | On Windows
14 | ~~~~~~~~~~
15 | I don't know, sorry.
16 |
17 |
18 | Python dependencies
19 | ~~~~~~~~~~~~~~~~~~~
20 | Run::
21 |
22 | make deps
23 |
24 | How to create the databases
25 | ---------------------------
26 | Just run::
27 |
28 | make database
29 |
30 | For test database, run::
31 |
32 | make test_database
33 |
34 | Note: after you run functional tests, the admin user on test database will be "admin" with password "admin".
35 |
36 | How to Run Tests
37 | ----------------
38 | Run `make test` to install all Python dependencies (if they are not installed) and run all tests. Depending on your environment, this script may need root permissions in order to install the dependencies.
39 |
40 | You can run `make functional` for executing only acceptance tests, and `make unit` to execute only unit tests.
41 |
42 | Remember to install all dependencies and create the test database before run any test.
43 |
44 | How to Contribute
45 | -----------------
46 | Please:
47 | - Fork the project and submit pull request
48 | - Create an issue
49 | - Close an issue
50 |
51 |
--------------------------------------------------------------------------------
/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/__init__.py
--------------------------------------------------------------------------------
/apps/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/__init__.py
--------------------------------------------------------------------------------
/apps/home_page/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/home_page/__init__.py
--------------------------------------------------------------------------------
/apps/home_page/features/resources/erp5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/home_page/features/resources/erp5.png
--------------------------------------------------------------------------------
/apps/home_page/features/resources/nsi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/home_page/features/resources/nsi.png
--------------------------------------------------------------------------------
/apps/home_page/features/resources/x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/home_page/features/resources/x.png
--------------------------------------------------------------------------------
/apps/home_page/features/show_index.feature:
--------------------------------------------------------------------------------
1 | Feature: User visitor
2 | As a visitor NSI Site
3 | I want see home index data
4 |
5 | Scenario: showing News in index home
6 | Given exist a author:
7 | | name |
8 | | herman |
9 | | ronaldo |
10 | Given exist a news:
11 | | title | image | author | date_and_time |
12 | | Notícia sobre o NSI Site | test/images/news/nsi.png | herman | 15/01/2011 20:00 |
13 | | Notícia sobre o ERP5 Lek | test/images/news/erp5.png | herman | 05/04/2011 20:00 |
14 | | Notícia sobre o ERP5 e o NSI Site | test/images/news/x.png | ronaldo | 01/01/2010 20:00 |
15 |
16 | When I go to "the NSI home page"
17 | And I should see "Notícia sobre o NSI Site"
18 | And I should see an image called "nsi.png"
19 | And I should see "Postado por: herman"
20 | And I should see "15/01/2011"
21 |
22 | And I should see "Notícia sobre o ERP5 Lek"
23 | And I should see an image called "erp5.png"
24 | And I should see "Postado por: herman"
25 | And I should see "05/04/2011"
26 |
27 | And I should see "Notícia sobre o ERP5 e o NSI Site"
28 | And I should see an image called "x.png"
29 | And I should see "Postado por: ronaldo"
30 | And I should see "01/01/2010"
31 |
32 | Scenario: showing a open Projects in index home
33 | Given exist a project:
34 | | name | status |
35 | | NSI Site | aberto |
36 | | ERP5 Lek | aberto |
37 | | Abodorock | aberto |
38 | | Batata Ricks | finalizado |
39 |
40 | When I go to "the NSI home page"
41 | And I should see "NSI Site"
42 | And I should see "ERP5 Lek"
43 | And I should see "Abodorock"
44 |
45 | Scenario: showing a highlight Tools in index home
46 | Given exist a tool:
47 | | name | highlight |
48 | | Should-dsl | True |
49 | | Ludibrio | True |
50 | | rock-py | False |
51 | | Restful-py | True |
52 |
53 | When I go to "the NSI home page"
54 | And I should see "Should-dsl"
55 | And I should see "Ludibrio"
56 | And I should see "Restful-py"
57 |
--------------------------------------------------------------------------------
/apps/home_page/features/steps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import os
3 | import shutil
4 | from datetime import datetime
5 | from django.conf import settings
6 | from lettuce import step
7 | from model_mommy import mommy
8 | from apps.news.models import News
9 | from apps.projects.models import Project
10 | from apps.tools.models import Tool
11 | from django.contrib.auth.models import User
12 |
13 |
14 | @step(u'exist a author:')
15 | def exist_a_author(step):
16 | for user in step.hashes:
17 | mommy.make_one(User, username=user.get('name'), email='a@a.com')
18 |
19 | @step(u'exist a news:')
20 | def exist_a_news(step):
21 | for news_hashes in step.hashes:
22 | author = User.objects.get(username__exact=news_hashes.get('author'))
23 | date, hour = news_hashes.get('date_and_time').split()
24 | day, month, year = date.split('/')
25 | hours, minutes = hour.split(':')
26 | date_time = datetime(int(year), int(month), int(day), int(hours), int(minutes))
27 | news = mommy.make_one(News, title=news_hashes.get('title'), image=news_hashes.get('image'), author=author, date_and_time=date_time).save()
28 | file_name = news_hashes.get('image').split('/')[-1]
29 | shutil.copy2(os.path.join(settings.PROJECT_ROOT_PATH, 'apps', 'home_page',
30 | 'features', 'resources', file_name),
31 | os.path.join(settings.MEDIA_ROOT, 'test', 'images', 'news'))
32 |
33 | @step(u'exist a project:')
34 | def exist_a_project(step):
35 | for project_hashes in step.hashes:
36 | project = mommy.make_one(Project, name=project_hashes.get('name'), status=project_hashes.get('status'))
37 |
38 | @step(u'exist a tool:')
39 | def exist_a_tool(step):
40 | for tool_hashes in step.hashes:
41 | tool = mommy.make_one(Tool, name=tool_hashes.get('name'), highlight=tool_hashes.get('highlight'))
42 |
43 |
--------------------------------------------------------------------------------
/apps/home_page/templates/index.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 |
3 | {% block styles %}
4 | {{ block.super }}
5 |
6 | {% endblock styles %}
7 |
8 |
9 | {% block content %}
10 |
11 |
12 |
13 | Projetos
14 |
15 | {% for project_obj in projects %}
16 |
17 |
18 |
21 |
22 | {% endfor %}
23 |
24 |
25 |
26 |
27 | Notícias
28 |
29 | {% for news_obj in news %}
30 |
31 | {% if news_obj.image %}
32 |
36 |
37 | {% else %}
38 |
42 |
Postado por: {{ news_obj.author }}
43 |
{{ news_obj.date_and_time|date:"d/m/Y" }}
44 |
45 | {% endfor %}
46 |
49 |
50 |
51 |
64 |
65 |
66 |
67 | Planeta NSI
68 |
69 |
70 |
71 |
74 |
75 |
76 |
77 |
80 |
81 |
82 |
83 |
84 |
85 | {% endblock content %}
86 |
--------------------------------------------------------------------------------
/apps/home_page/tests.py:
--------------------------------------------------------------------------------
1 | #-*- coding:utf-8 -*-
2 |
3 | from django.test import TestCase
4 |
5 |
6 | class HomePageTest(TestCase):
7 | pass
8 |
9 |
--------------------------------------------------------------------------------
/apps/home_page/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render_to_response
2 | from django.template import RequestContext
3 | from apps.news.models import News
4 | from apps.projects.models import Project
5 | from apps.tools.models import Tool
6 |
7 | def show_index(request):
8 | news = News.objects.all()[:3]
9 | projects = Project.objects.filter(status='aberto')
10 | tools = Tool.objects.filter(highlight=True)
11 | return render_to_response(
12 | 'index.html',
13 | {'news': news, 'projects': projects, 'tools': tools},
14 | context_instance=RequestContext(request)
15 | )
16 |
--------------------------------------------------------------------------------
/apps/members/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/members/__init__.py
--------------------------------------------------------------------------------
/apps/members/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from apps.members.models import Member
3 | from apps.members.models import Participation
4 |
5 |
6 | class ParticipationInline(admin.TabularInline):
7 | model = Participation
8 | extra = 1
9 |
10 | class MemberAdmin(admin.ModelAdmin):
11 | list_display = ('name', 'function', 'site','github', 'twitter','slideshare','lattes','phone','started_nsi_date', 'is_renegade')
12 | list_filter = ('function','started_nsi_date','is_renegade')
13 | inlines = [ParticipationInline]
14 |
15 |
16 | admin.site.register(Member, MemberAdmin)
17 | admin.site.register(Participation)
18 |
--------------------------------------------------------------------------------
/apps/members/features/resources/batata_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/members/features/resources/batata_photo.png
--------------------------------------------------------------------------------
/apps/members/features/resources/pedro_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/members/features/resources/pedro_photo.png
--------------------------------------------------------------------------------
/apps/members/features/resources/pluck_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/members/features/resources/pluck_photo.png
--------------------------------------------------------------------------------
/apps/members/features/steps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import os
3 | import shutil
4 | from lettuce import step, world
5 | from django.conf import settings
6 | from lettuce.django import django_url
7 | from should_dsl import should
8 | from model_mommy import mommy
9 | from apps.members.models import Member
10 | from apps.members.models import Participation
11 | from apps.projects.models import Project
12 |
13 | @step(u'exist a project:')
14 | def given_exist_a_project(step):
15 | for project in step.hashes:
16 | mommy.make_one(Project, name=project.get('name'), logo=None)
17 |
18 | @step(u'exist a member:')
19 | def exist_a_member(step):
20 | for member in step.hashes:
21 | Member(**member).save()
22 | file_name = member.get('photo').split('/')[-1]
23 | shutil.copy2(os.path.join(settings.PROJECT_ROOT_PATH, 'apps', 'members',
24 | 'features', 'resources', file_name),
25 | os.path.join(settings.MEDIA_ROOT, 'test', 'images', 'members'))
26 |
27 | @step(r'"(.*)" member started participation the "(.*)" project in "(.*)"')
28 | def and_member_participation_the_project_in(step, member_name, project_name, start_participation_date):
29 | member = Member.objects.get(name=member_name)
30 | project = Project.objects.get(name=project_name)
31 | Participation(member=member, project=project, start_date=start_participation_date).save()
32 |
33 | @step(r'"(.*)" member participated on "(.*)" project between "(.*)" and "(.*)"')
34 | def and_member_participated_on_project_between(step, member_name, project_name, start_participation_date, end_participation_date):
35 | member = Member.objects.get(name=member_name)
36 | project = Project.objects.get(name=project_name)
37 | Participation(member=member, project=project, start_date=start_participation_date, end_date=end_participation_date).save()
38 |
39 | @step(r'I go to the "(.+)" member page')
40 | def i_go_to_member_page(step, member_name):
41 | member_obj = Member.objects.get(name=member_name)
42 | world.browser.visit(django_url('/membro/%s' % member_obj.slug))
43 |
44 | @step(r'I go to the "(.+)" former member page')
45 | def i_go_to_former_member_page(step, member_name):
46 | member_obj = Member.objects.get(name=member_name)
47 | world.browser.visit(django_url('/ex-membro/%s' % member_obj.slug))
48 |
49 | @step(u'I should see a label "(.*)" with the link to "(.*)"')
50 | def i_should_see_a_label_with_link(step, link_text, link_href):
51 | links = world.browser.find_link_by_href(link_href)
52 | links |should| have_at_least(1).item
53 | link_value = links[0].value
54 | link_label, link_value_text = link_value.split(': ')
55 | link_value_text |should| equal_to(link_text)
56 |
57 | @step(r'I should see the following members')
58 | def i_should_see_the_following_members(step):
59 |
60 | for member_data in step.hashes:
61 | member = Member.objects.get(name=member_data['name'])
62 |
63 | container_photo = world.browser.find_by_css('#member%s .avatar' % member.id)
64 | container_image_name = container_photo[0]['src'].split("/")[-1]
65 | container_image_name |should| equal_to(member_data['photo'])
66 |
67 | title_text = world.browser.find_by_css('#member%s h1' % member.id)
68 | title_text[0].value |should| equal_to(member_data['name'])
69 |
70 | function_text = world.browser.find_by_css('#member%s span' % member.id)
71 | function_text[0].value |should| equal_to(member_data['function'])
72 |
73 | currently_does_text = world.browser.find_by_css('#member%s p' % member.id)
74 | currently_does_text[0].value |should| equal_to(member_data['currently_does'])
75 |
76 | container_links = world.browser.find_by_css('#member%s .links a' % member.id)
77 | container_links_href = [x['href'] for x in container_links]
78 |
79 | member_data['site'] |should| be_into(container_links_href)
80 | member_data['github'] |should| be_into(container_links_href)
81 | member_data['twitter'] |should| be_into(container_links_href)
82 | member_data['slideshare'] |should| be_into(container_links_href)
83 |
--------------------------------------------------------------------------------
/apps/members/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding model 'Member'
12 | db.create_table('members_member', (
13 | ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
14 | ('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
15 | ('current_team', self.gf('django.db.models.fields.CharField')(max_length=100)),
16 | ('currently_does', self.gf('django.db.models.fields.TextField')()),
17 | ('life_and_work', self.gf('django.db.models.fields.TextField')()),
18 | ('site', self.gf('django.db.models.fields.URLField')(max_length=200, null=True)),
19 | ('github', self.gf('django.db.models.fields.URLField')(max_length=200, null=True)),
20 | ('twitter', self.gf('django.db.models.fields.URLField')(max_length=200, null=True)),
21 | ('slideshare', self.gf('django.db.models.fields.URLField')(max_length=200, null=True)),
22 | ('lattes', self.gf('django.db.models.fields.URLField')(max_length=200, null=True)),
23 | ('photo', self.gf('django.db.models.fields.files.ImageField')(max_length=100)),
24 | ('project_memberships', self.gf('django.db.models.fields.CharField')(max_length=100)),
25 | ('started_nsi_date', self.gf('django.db.models.fields.DateField')()),
26 | ('desertion_nsi_date', self.gf('django.db.models.fields.DateField')(null=True)),
27 | ))
28 | db.send_create_signal('members', ['Member'])
29 |
30 |
31 | def backwards(self, orm):
32 |
33 | # Deleting model 'Member'
34 | db.delete_table('members_member')
35 |
36 |
37 | models = {
38 | 'members.member': {
39 | 'Meta': {'object_name': 'Member'},
40 | 'current_team': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
41 | 'currently_does': ('django.db.models.fields.TextField', [], {}),
42 | 'desertion_nsi_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
43 | 'github': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
44 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
45 | 'lattes': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
46 | 'life_and_work': ('django.db.models.fields.TextField', [], {}),
47 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
48 | 'photo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
49 | 'project_memberships': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
50 | 'site': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
51 | 'slideshare': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
52 | 'started_nsi_date': ('django.db.models.fields.DateField', [], {}),
53 | 'twitter': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'})
54 | }
55 | }
56 |
57 | complete_apps = ['members']
58 |
--------------------------------------------------------------------------------
/apps/members/migrations/0002_auto__chg_field_member_current_team.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Changing field 'Member.current_team'
12 | db.alter_column('members_member', 'current_team', self.gf('django.db.models.fields.CharField')(max_length=100, null=True))
13 |
14 |
15 | def backwards(self, orm):
16 |
17 | # User chose to not deal with backwards NULL issues for 'Member.current_team'
18 | raise RuntimeError("Cannot reverse this migration. 'Member.current_team' and its values cannot be restored.")
19 |
20 |
21 | models = {
22 | 'members.member': {
23 | 'Meta': {'object_name': 'Member'},
24 | 'current_team': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}),
25 | 'currently_does': ('django.db.models.fields.TextField', [], {}),
26 | 'desertion_nsi_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
27 | 'github': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
28 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
29 | 'lattes': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
30 | 'life_and_work': ('django.db.models.fields.TextField', [], {}),
31 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
32 | 'photo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
33 | 'project_memberships': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
34 | 'site': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
35 | 'slideshare': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
36 | 'started_nsi_date': ('django.db.models.fields.DateField', [], {}),
37 | 'twitter': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'})
38 | }
39 | }
40 |
41 | complete_apps = ['members']
42 |
--------------------------------------------------------------------------------
/apps/members/migrations/0003_auto__del_field_member_current_team.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Deleting field 'Member.current_team'
12 | db.delete_column('members_member', 'current_team')
13 |
14 | # Adding M2M table for field current_team on 'Member'
15 | db.create_table('members_member_current_team', (
16 | ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
17 | ('member', models.ForeignKey(orm['members.member'], null=False)),
18 | ('team', models.ForeignKey(orm['teams.team'], null=False))
19 | ))
20 | db.create_unique('members_member_current_team', ['member_id', 'team_id'])
21 |
22 |
23 | def backwards(self, orm):
24 |
25 | # Adding field 'Member.current_team'
26 | db.add_column('members_member', 'current_team', self.gf('django.db.models.fields.CharField')(max_length=100, null=True), keep_default=False)
27 |
28 | # Removing M2M table for field current_team on 'Member'
29 | db.delete_table('members_member_current_team')
30 |
31 |
32 | models = {
33 | 'members.member': {
34 | 'Meta': {'object_name': 'Member'},
35 | 'current_team': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['teams.Team']", 'symmetrical': 'False'}),
36 | 'currently_does': ('django.db.models.fields.TextField', [], {}),
37 | 'desertion_nsi_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
38 | 'github': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
39 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
40 | 'lattes': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
41 | 'life_and_work': ('django.db.models.fields.TextField', [], {}),
42 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
43 | 'photo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
44 | 'project_memberships': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
45 | 'site': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
46 | 'slideshare': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
47 | 'started_nsi_date': ('django.db.models.fields.DateField', [], {}),
48 | 'twitter': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'})
49 | },
50 | 'teams.team': {
51 | 'Meta': {'object_name': 'Team'},
52 | 'description': ('django.db.models.fields.TextField', [], {}),
53 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
54 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
55 | }
56 | }
57 |
58 | complete_apps = ['members']
59 |
--------------------------------------------------------------------------------
/apps/members/migrations/0004_auto__add_participation__del_field_member_project_memberships.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding model 'Participation'
12 | db.create_table('members_participation', (
13 | ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
14 | ('member', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['members.Member'])),
15 | ('project', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['projects.Project'])),
16 | ('start_date', self.gf('django.db.models.fields.DateField')()),
17 | ('end_date', self.gf('django.db.models.fields.DateField')(null=True)),
18 | ))
19 | db.send_create_signal('members', ['Participation'])
20 |
21 | # Deleting field 'Member.project_memberships'
22 | db.delete_column('members_member', 'project_memberships')
23 |
24 | # Removing M2M table for field current_team on 'Member'
25 | db.delete_table('members_member_current_team')
26 |
27 |
28 | def backwards(self, orm):
29 |
30 | # Deleting model 'Participation'
31 | db.delete_table('members_participation')
32 |
33 | # User chose to not deal with backwards NULL issues for 'Member.project_memberships'
34 | raise RuntimeError("Cannot reverse this migration. 'Member.project_memberships' and its values cannot be restored.")
35 |
36 | # Adding M2M table for field current_team on 'Member'
37 | db.create_table('members_member_current_team', (
38 | ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
39 | ('member', models.ForeignKey(orm['members.member'], null=False)),
40 | ('team', models.ForeignKey(orm['teams.team'], null=False))
41 | ))
42 | db.create_unique('members_member_current_team', ['member_id', 'team_id'])
43 |
44 |
45 | models = {
46 | 'members.member': {
47 | 'Meta': {'object_name': 'Member'},
48 | 'currently_does': ('django.db.models.fields.TextField', [], {}),
49 | 'desertion_nsi_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
50 | 'github': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
51 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
52 | 'lattes': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
53 | 'life_and_work': ('django.db.models.fields.TextField', [], {}),
54 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
55 | 'photo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
56 | 'site': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
57 | 'slideshare': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
58 | 'started_nsi_date': ('django.db.models.fields.DateField', [], {}),
59 | 'twitter': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'})
60 | },
61 | 'members.participation': {
62 | 'Meta': {'object_name': 'Participation'},
63 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
64 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
65 | 'member': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['members.Member']"}),
66 | 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']"}),
67 | 'start_date': ('django.db.models.fields.DateField', [], {})
68 | },
69 | 'projects.project': {
70 | 'Meta': {'object_name': 'Project'},
71 | 'description': ('django.db.models.fields.TextField', [], {}),
72 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
73 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
74 | 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
75 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
76 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
77 | 'start_date': ('django.db.models.fields.DateField', [], {}),
78 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
79 | }
80 | }
81 |
82 | complete_apps = ['members']
83 |
--------------------------------------------------------------------------------
/apps/members/migrations/0005_auto__add_field_member_function__chg_field_member_slideshare__chg_fiel.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding field 'Member.function'
12 | db.add_column('members_member', 'function', self.gf('django.db.models.fields.CharField')(default='nao informado', max_length=100), keep_default=False)
13 |
14 | # Changing field 'Member.slideshare'
15 | db.alter_column('members_member', 'slideshare', self.gf('django.db.models.fields.CharField')(max_length=50, null=True))
16 |
17 | # Changing field 'Member.twitter'
18 | db.alter_column('members_member', 'twitter', self.gf('django.db.models.fields.CharField')(max_length=50, null=True))
19 |
20 | # Changing field 'Member.github'
21 | db.alter_column('members_member', 'github', self.gf('django.db.models.fields.CharField')(max_length=50, null=True))
22 |
23 |
24 | def backwards(self, orm):
25 |
26 | # Deleting field 'Member.function'
27 | db.delete_column('members_member', 'function')
28 |
29 | # Changing field 'Member.slideshare'
30 | db.alter_column('members_member', 'slideshare', self.gf('django.db.models.fields.URLField')(max_length=200, null=True))
31 |
32 | # Changing field 'Member.twitter'
33 | db.alter_column('members_member', 'twitter', self.gf('django.db.models.fields.URLField')(max_length=200, null=True))
34 |
35 | # Changing field 'Member.github'
36 | db.alter_column('members_member', 'github', self.gf('django.db.models.fields.URLField')(max_length=200, null=True))
37 |
38 |
39 | models = {
40 | 'members.member': {
41 | 'Meta': {'object_name': 'Member'},
42 | 'currently_does': ('django.db.models.fields.TextField', [], {}),
43 | 'desertion_nsi_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
44 | 'function': ('django.db.models.fields.CharField', [], {'default': "'nao informado'", 'max_length': '100'}),
45 | 'github': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
46 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
47 | 'lattes': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
48 | 'life_and_work': ('django.db.models.fields.TextField', [], {}),
49 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
50 | 'photo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
51 | 'site': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
52 | 'slideshare': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
53 | 'started_nsi_date': ('django.db.models.fields.DateField', [], {}),
54 | 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'})
55 | },
56 | 'members.participation': {
57 | 'Meta': {'object_name': 'Participation'},
58 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
59 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
60 | 'member': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['members.Member']"}),
61 | 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']"}),
62 | 'start_date': ('django.db.models.fields.DateField', [], {})
63 | },
64 | 'projects.project': {
65 | 'Meta': {'object_name': 'Project'},
66 | 'description': ('django.db.models.fields.TextField', [], {}),
67 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
68 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
69 | 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
70 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
71 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
72 | 'start_date': ('django.db.models.fields.DateField', [], {}),
73 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
74 | }
75 | }
76 |
77 | complete_apps = ['members']
78 |
--------------------------------------------------------------------------------
/apps/members/migrations/0006_auto__add_field_member_is_renegade.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding field 'Member.is_renegade'
12 | db.add_column('members_member', 'is_renegade', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False)
13 |
14 |
15 | def backwards(self, orm):
16 |
17 | # Deleting field 'Member.is_renegade'
18 | db.delete_column('members_member', 'is_renegade')
19 |
20 |
21 | models = {
22 | 'members.member': {
23 | 'Meta': {'object_name': 'Member'},
24 | 'currently_does': ('django.db.models.fields.TextField', [], {}),
25 | 'desertion_nsi_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
26 | 'function': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
27 | 'github': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
28 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
29 | 'is_renegade': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
30 | 'lattes': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
31 | 'life_and_work': ('django.db.models.fields.TextField', [], {}),
32 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
33 | 'photo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
34 | 'site': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
35 | 'slideshare': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
36 | 'started_nsi_date': ('django.db.models.fields.DateField', [], {}),
37 | 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'})
38 | },
39 | 'members.participation': {
40 | 'Meta': {'object_name': 'Participation'},
41 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
42 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
43 | 'member': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['members.Member']"}),
44 | 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']"}),
45 | 'start_date': ('django.db.models.fields.DateField', [], {})
46 | },
47 | 'projects.project': {
48 | 'Meta': {'object_name': 'Project'},
49 | 'description': ('django.db.models.fields.TextField', [], {}),
50 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
51 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
52 | 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
53 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
54 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
55 | 'start_date': ('django.db.models.fields.DateField', [], {}),
56 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
57 | }
58 | }
59 |
60 | complete_apps = ['members']
61 |
--------------------------------------------------------------------------------
/apps/members/migrations/0007_auto__add_field_member_slug__chg_field_member_photo.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding field 'Member.slug'
12 | db.add_column('members_member', 'slug', self.gf('django.db.models.fields.SlugField')(db_index=True, default='', unique=True, max_length=100, blank=True), keep_default=False)
13 |
14 | # Changing field 'Member.photo'
15 | db.alter_column('members_member', 'photo', self.gf('thumbs.ImageWithThumbsField')(max_length=100, name='photo', sizes=((100, 100),)))
16 |
17 |
18 | def backwards(self, orm):
19 |
20 | # Deleting field 'Member.slug'
21 | db.delete_column('members_member', 'slug')
22 |
23 | # Changing field 'Member.photo'
24 | db.alter_column('members_member', 'photo', self.gf('django.db.models.fields.files.ImageField')(max_length=100))
25 |
26 |
27 | models = {
28 | 'members.member': {
29 | 'Meta': {'object_name': 'Member'},
30 | 'currently_does': ('django.db.models.fields.TextField', [], {}),
31 | 'desertion_nsi_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
32 | 'function': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
33 | 'github': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
34 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
35 | 'is_renegade': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
36 | 'lattes': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
37 | 'life_and_work': ('django.db.models.fields.TextField', [], {}),
38 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
39 | 'photo': ('thumbs.ImageWithThumbsField', [], {'max_length': '100', 'name': "'photo'", 'sizes': '((100, 100),)'}),
40 | 'site': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
41 | 'slideshare': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
42 | 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'unique': 'True', 'max_length': '100', 'blank': 'True'}),
43 | 'started_nsi_date': ('django.db.models.fields.DateField', [], {}),
44 | 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'})
45 | },
46 | 'members.participation': {
47 | 'Meta': {'object_name': 'Participation'},
48 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
49 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
50 | 'member': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['members.Member']"}),
51 | 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']"}),
52 | 'start_date': ('django.db.models.fields.DateField', [], {})
53 | },
54 | 'projects.project': {
55 | 'Meta': {'object_name': 'Project'},
56 | 'description': ('django.db.models.fields.TextField', [], {}),
57 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
58 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
59 | 'logo': ('thumbs.ImageWithThumbsField', [], {'name': "'logo'", 'sizes': '((200, 200), (90, 90))', 'max_length': '100', 'blank': 'True', 'null': 'True'}),
60 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
61 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
62 | 'start_date': ('django.db.models.fields.DateField', [], {}),
63 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
64 | }
65 | }
66 |
67 | complete_apps = ['members']
68 |
--------------------------------------------------------------------------------
/apps/members/migrations/0008_auto__del_unique_member_slug.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Removing unique constraint on 'Member', fields ['slug']
12 | db.delete_unique('members_member', ['slug'])
13 |
14 |
15 | def backwards(self, orm):
16 |
17 | # Adding unique constraint on 'Member', fields ['slug']
18 | db.create_unique('members_member', ['slug'])
19 |
20 |
21 | models = {
22 | 'members.member': {
23 | 'Meta': {'object_name': 'Member'},
24 | 'currently_does': ('django.db.models.fields.TextField', [], {}),
25 | 'desertion_nsi_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
26 | 'function': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
27 | 'github': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
28 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
29 | 'is_renegade': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
30 | 'lattes': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
31 | 'life_and_work': ('django.db.models.fields.TextField', [], {}),
32 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
33 | 'photo': ('thumbs.ImageWithThumbsField', [], {'max_length': '100', 'name': "'photo'", 'sizes': '((100, 100),)'}),
34 | 'site': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
35 | 'slideshare': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
36 | 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '100', 'blank': 'True'}),
37 | 'started_nsi_date': ('django.db.models.fields.DateField', [], {}),
38 | 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'})
39 | },
40 | 'members.participation': {
41 | 'Meta': {'object_name': 'Participation'},
42 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
43 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
44 | 'member': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['members.Member']"}),
45 | 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']"}),
46 | 'start_date': ('django.db.models.fields.DateField', [], {})
47 | },
48 | 'projects.project': {
49 | 'Meta': {'object_name': 'Project'},
50 | 'description': ('django.db.models.fields.TextField', [], {}),
51 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
52 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
53 | 'logo': ('thumbs.ImageWithThumbsField', [], {'name': "'logo'", 'sizes': '((200, 200), (90, 90))', 'max_length': '100', 'blank': 'True', 'null': 'True'}),
54 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
55 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
56 | 'start_date': ('django.db.models.fields.DateField', [], {}),
57 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
58 | }
59 | }
60 |
61 | complete_apps = ['members']
62 |
--------------------------------------------------------------------------------
/apps/members/migrations/0009_add_nickname.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding field 'Member.nickname'
12 | db.add_column('members_member', 'nickname', self.gf('django.db.models.fields.CharField')(max_length=100, null=True, blank=True), keep_default=False)
13 |
14 |
15 | def backwards(self, orm):
16 |
17 | # Deleting field 'Member.nickname'
18 | db.delete_column('members_member', 'nickname')
19 |
20 |
21 | models = {
22 | 'members.member': {
23 | 'Meta': {'object_name': 'Member'},
24 | 'currently_does': ('django.db.models.fields.TextField', [], {}),
25 | 'desertion_nsi_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
26 | 'function': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
27 | 'github': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
28 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
29 | 'is_renegade': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
30 | 'lattes': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
31 | 'life_and_work': ('django.db.models.fields.TextField', [], {}),
32 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
33 | 'nickname': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
34 | 'photo': ('thumbs.ImageWithThumbsField', [], {'max_length': '100', 'name': "'photo'", 'sizes': '((100, 100),)'}),
35 | 'site': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
36 | 'slideshare': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
37 | 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '100', 'blank': 'True'}),
38 | 'started_nsi_date': ('django.db.models.fields.DateField', [], {}),
39 | 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'})
40 | },
41 | 'members.participation': {
42 | 'Meta': {'object_name': 'Participation'},
43 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
44 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
45 | 'member': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['members.Member']"}),
46 | 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']"}),
47 | 'start_date': ('django.db.models.fields.DateField', [], {})
48 | },
49 | 'projects.project': {
50 | 'Meta': {'object_name': 'Project'},
51 | 'description': ('django.db.models.fields.TextField', [], {}),
52 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
53 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
54 | 'logo': ('thumbs.ImageWithThumbsField', [], {'name': "'logo'", 'sizes': '((200, 200), (90, 90))', 'max_length': '100', 'blank': 'True', 'null': 'True'}),
55 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
56 | 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '100', 'blank': 'True'}),
57 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
58 | 'start_date': ('django.db.models.fields.DateField', [], {}),
59 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
60 | }
61 | }
62 |
63 | complete_apps = ['members']
64 |
--------------------------------------------------------------------------------
/apps/members/migrations/0010_auto__add_field_member_phone.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding field 'Member.phone'
12 | db.add_column('members_member', 'phone', self.gf('django.db.models.fields.CharField')(max_length=13, null=True, blank=True), keep_default=False)
13 |
14 |
15 | def backwards(self, orm):
16 |
17 | # Deleting field 'Member.phone'
18 | db.delete_column('members_member', 'phone')
19 |
20 |
21 | models = {
22 | 'members.member': {
23 | 'Meta': {'object_name': 'Member'},
24 | 'currently_does': ('django.db.models.fields.TextField', [], {}),
25 | 'desertion_nsi_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
26 | 'function': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
27 | 'github': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
28 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
29 | 'is_renegade': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
30 | 'lattes': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
31 | 'life_and_work': ('django.db.models.fields.TextField', [], {}),
32 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
33 | 'nickname': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
34 | 'phone': ('django.db.models.fields.CharField', [], {'max_length': '13', 'null': 'True', 'blank': 'True'}),
35 | 'photo': ('thumbs.ImageWithThumbsField', [], {'max_length': '100', 'name': "'photo'", 'sizes': '((100, 100),)'}),
36 | 'site': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
37 | 'slideshare': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
38 | 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '100', 'blank': 'True'}),
39 | 'started_nsi_date': ('django.db.models.fields.DateField', [], {}),
40 | 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'})
41 | },
42 | 'members.participation': {
43 | 'Meta': {'object_name': 'Participation'},
44 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
45 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
46 | 'member': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['members.Member']"}),
47 | 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']"}),
48 | 'start_date': ('django.db.models.fields.DateField', [], {})
49 | },
50 | 'projects.project': {
51 | 'Meta': {'object_name': 'Project'},
52 | 'description': ('django.db.models.fields.TextField', [], {}),
53 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
54 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
55 | 'logo': ('thumbs.ImageWithThumbsField', [], {'name': "'logo'", 'sizes': '((200, 200), (90, 90))', 'max_length': '100', 'blank': 'True', 'null': 'True'}),
56 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
57 | 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '100', 'blank': 'True'}),
58 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
59 | 'start_date': ('django.db.models.fields.DateField', [], {}),
60 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
61 | }
62 | }
63 |
64 | complete_apps = ['members']
65 |
--------------------------------------------------------------------------------
/apps/members/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/members/migrations/__init__.py
--------------------------------------------------------------------------------
/apps/members/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.template.defaultfilters import slugify
3 | from thumbs import ImageWithThumbsField
4 | from apps.projects.models import Project
5 |
6 |
7 | MEMBER_FUNCTIONS = (
8 | ('0', 'gerente'),
9 | ('1', 'coordenador'),
10 | ('2', 'pesquisador'),
11 | ('3', 'bolsista'),
12 | ('4', 'colaborador'))
13 |
14 |
15 | class Participation(models.Model):
16 | member = models.ForeignKey('Member')
17 | project = models.ForeignKey(Project)
18 | start_date = models.DateField()
19 | end_date = models.DateField(null=True, blank=True)
20 |
21 | def __unicode__(self):
22 | return self.member.name + ' - ' + self.project.name
23 |
24 | class Member(models.Model):
25 | name = models.CharField(max_length=100)
26 | nickname = models.CharField(max_length=100, null=True, blank=True)
27 | phone = models.CharField(max_length=13, null=True, blank=True)
28 | currently_does = models.TextField()
29 | life_and_work = models.TextField()
30 | function = models.CharField(max_length=100, choices=MEMBER_FUNCTIONS)
31 | site = models.URLField(null=True, blank=True)
32 | github = models.CharField(max_length=50, null=True, blank=True)
33 | twitter = models.CharField(max_length=50, null=True, blank=True)
34 | slideshare = models.CharField(max_length=50, null=True, blank=True)
35 | lattes = models.URLField(null=True, blank=True)
36 | photo = ImageWithThumbsField(upload_to='images/members', sizes=((100, 100), ))
37 | started_nsi_date = models.DateField()
38 | desertion_nsi_date = models.DateField(null=True, blank=True)
39 | is_renegade = models.BooleanField(editable=False)
40 | slug = models.SlugField(max_length=100, blank=True)
41 |
42 | def github_link(self):
43 | return "http://github.com/" + self.github
44 |
45 | def twitter_link(self):
46 | return "http://twitter.com/" + self.twitter
47 |
48 | def slideshare_link(self):
49 | return "http://www.slideshare.net/" + self.slideshare
50 |
51 | def github_feed(self):
52 | return self.github_link() + '.atom'
53 |
54 | def __unicode__(self):
55 | return self.name
56 |
57 | def save(self, *args, **kwargs):
58 | self.slug = slugify(self.name)
59 | if self.desertion_nsi_date is not None:
60 | self.is_renegade = True
61 | super(Member, self).save(*args, **kwargs)
62 | else:
63 | self.is_renegade = False
64 | super(Member, self).save(*args, **kwargs)
65 |
66 |
--------------------------------------------------------------------------------
/apps/members/templates/show_all_current_members.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block styles %}
4 | {{ block.super }}
5 |
6 | {% endblock styles %}
7 |
8 | {% block content %}
9 |
10 | {% for member in members %}
11 |
12 |
13 |
14 |
15 |
16 |
19 |
{{ member.get_function_display }}
20 |
{{ member.currently_does }}
21 |
22 |
23 | {% if member.site %}
24 |
25 |
26 |
27 |
28 |
29 | {% endif %}
30 | {% if member.lattes %}
31 |
32 |
33 |
34 |
35 |
36 | {% endif %}
37 | {% if member.github %}
38 |
39 |
40 |
41 |
42 |
43 | {% endif %}
44 | {%if member.twitter %}
45 |
46 |
47 |
48 |
49 |
50 | {% endif %}
51 | {% if member.slideshare %}
52 |
53 |
54 |
55 |
56 |
57 | {% endif %}
58 |
59 |
60 | {% endfor %}
61 |
62 | {% endblock content %}
63 |
64 |
--------------------------------------------------------------------------------
/apps/members/templates/show_all_former_members.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block styles %}
4 | {{ block.super }}
5 |
6 | {% endblock styles %}
7 |
8 | {% block content %}
9 |
10 | {% for member in members %}
11 |
12 |
13 |
14 |
15 |
16 |
19 |
{{ member.get_function_display }}
20 |
{{ member.currently_does }}
21 |
22 |
23 | {% if member.site %}
24 |
25 |
26 |
27 |
28 |
29 | {% endif %}
30 | {% if member.lattes %}
31 |
32 |
33 |
34 |
35 |
36 | {% endif %}
37 | {% if member.github %}
38 |
39 |
40 |
41 |
42 |
43 | {% endif %}
44 | {%if member.twitter %}
45 |
46 |
47 |
48 |
49 |
50 | {% endif %}
51 | {% if member.slideshare %}
52 |
53 |
54 |
55 |
56 |
57 | {% endif %}
58 |
59 |
60 | {% endfor %}
61 |
62 | {% endblock content %}
63 |
64 |
--------------------------------------------------------------------------------
/apps/members/templates/show_member.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% block styles %}
3 | {{ block.super }}
4 | {% endblock styles %}
5 |
6 | {% block scripts %}
7 | {{ block.super }}
8 |
9 |
10 | {% endblock scripts %}
11 |
12 | {% block content %}
13 |
14 |
15 |
16 |
{{ member.name }}
17 | {% if member.nickname %}
18 |
({{ member.nickname }})
19 | {% endif %}
20 | {% if user.is_authenticated %}
21 | {% if member.phone %}
22 |
{{ member.phone }}
23 | {% endif %}
24 | {% endif %}
25 |
{{ member.currently_does }}
26 |
{{ member.life_and_work }}
27 |
Função: {{ member.get_function_display }}
28 |
60 | {% if member.desertion_nsi_date %}
61 |
Data de início no NSI: {{ member.started_nsi_date|date:"d/m/Y" }}
62 |
63 |
Data de saída do NSI: {{ member.desertion_nsi_date|date:"d/m/Y" }}
64 | {% else %}
65 |
Membro desde: {{ member.started_nsi_date|date:"d/m/Y" }}
66 | {% endif %}
67 | {% if participation_list %}
68 |
69 |
Participações:
70 |
71 | {% for participation in participation_list %}
72 |
73 | {{ participation.project.name }}
74 | {% if participation.end_date %}
75 | Duração: {{ participation.start_date|date:"d/m/Y" }} a {{ participation.end_date|date:"d/m/Y" }}
76 | {% else %}
77 | Início: {{ participation.start_date|date:"d/m/Y" }}
78 | {% endif %}
79 |
80 | {% endfor %}
81 |
82 |
83 | {% endif %}
84 | {% if member.github %}
85 |
86 |
Atividades no Github:
87 |
88 |
89 |
91 |
92 | {% endif %}
93 |
94 |
95 |
96 |
97 | {% endblock content %}
98 |
99 |
--------------------------------------------------------------------------------
/apps/members/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 | from should_dsl import should
3 | from model_mommy import mommy
4 | from apps.members.models import Member
5 |
6 |
7 | class MemberTest(TestCase):
8 | def test_github_link(self):
9 | m = mommy.make_one(Member, github="pluck", photo="ricks_sunshine.png")
10 | m.github_link() |should| equal_to("http://github.com/pluck")
11 |
12 | def test_twitter_link(self):
13 | m = mommy.make_one(Member, twitter="pluck", photo="ricks_sunshine.png")
14 | m.twitter_link() |should| equal_to("http://twitter.com/pluck")
15 |
16 | def test_slideshare_link(self):
17 | m = mommy.make_one(Member, slideshare="pluck", photo="ricks_sunshine.png")
18 | m.slideshare_link() |should| equal_to("http://www.slideshare.net/pluck")
19 |
20 |
--------------------------------------------------------------------------------
/apps/members/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls.defaults import *
2 | from django.views.generic.simple import direct_to_template
3 | from django.conf import settings
4 |
5 | from django.contrib import admin
6 | admin.autodiscover()
7 |
8 | urlpatterns = patterns('',
9 | (r'^membros/$', 'apps.members.views.show_all_current_members'),
10 | (r'^membro/(?P[\w_-]+)$', 'apps.members.views.show_member'),
11 |
12 | (r'^ex-membros/$', 'apps.members.views.show_all_former_members'),
13 | (r'^ex-membro/(?P[\w_-]+)$', 'apps.members.views.show_member'),
14 |
15 | )
16 |
--------------------------------------------------------------------------------
/apps/members/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render_to_response
2 | from django.template import RequestContext
3 | from apps.members.models import Member
4 |
5 |
6 | def show_all_current_members(request):
7 | members = Member.objects.filter(is_renegade=False).order_by('function', 'started_nsi_date')
8 | return render_to_response(
9 | 'show_all_current_members.html',
10 | {'members': members},
11 | context_instance=RequestContext(request)
12 | )
13 |
14 | def show_member(request, slug):
15 | member = Member.objects.get(slug=slug)
16 | participation_list = member.participation_set.all()
17 | members = Member.objects.all()
18 | return render_to_response(
19 | 'show_member.html',
20 | {'member': member, 'participation_list': participation_list, 'members': members},
21 | context_instance=RequestContext(request)
22 | )
23 |
24 | def show_all_former_members(request):
25 | members = Member.objects.filter(is_renegade=True)
26 | return render_to_response(
27 | 'show_all_former_members.html',
28 | {'members': members},
29 | context_instance=RequestContext(request)
30 | )
31 |
--------------------------------------------------------------------------------
/apps/news/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/news/__init__.py
--------------------------------------------------------------------------------
/apps/news/admin.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 | from django.contrib.admin import site
4 |
5 | from apps.news.models import News
6 |
7 | site.register(News)
8 |
--------------------------------------------------------------------------------
/apps/news/features/manage_news.feature:
--------------------------------------------------------------------------------
1 | Feature: News maintenance
2 | As a NSI site administrator
3 | I want to handle news data
4 | In order to know details about whats happening at NSI
5 |
6 | Scenario: showing a news
7 | Given exist a author:
8 | | name |
9 | | rogerio |
10 | And exist a project:
11 | | name |
12 | | NSI Site |
13 | And exist a news:
14 | | title | summary | body | image | author | date_and_time |
15 | | Notícia sobre o NSI Site | O site do NSI está no ar | Já está no ar o site do NSI! | test/images/news/nsi.png | rogerio | 15/01/2011 20:00 |
16 | And the news "Notícia sobre o NSI Site" is related with project "NSI Site"
17 | When I go to "the news page"
18 | Then I should see "Notícia sobre o NSI Site"
19 | And I should see "O site do NSI está no ar"
20 | And I should see "Já está no ar o site do NSI!"
21 | And I should see an image called "nsi.png"
22 | And I should see "Postado por: rogerio"
23 | And I should see "Data: 15/01/2011 às 20:00"
24 |
25 | Scenario: showing many news
26 | Given exist a author:
27 | | name |
28 | | rogerio |
29 | | ronaldo |
30 | | herman |
31 | And exist a project:
32 | | name |
33 | | NSI Site |
34 | | ERP5 |
35 |
36 | And exist a news:
37 | | title | summary | body | image | author | date_and_time |
38 | | Notícia sobre o NSI Site | O site do NSI está no ar | Já está no ar o site do NSI! | test/images/news/nsi.png | rogerio | 15/01/2011 20:00 | NSI Site |
39 | | Notícia sobre o ERP5 Lek | Rick Rock Sunshine Project | ERP5 Lek, muita coisa pronta | test/images/news/erp5.png | ronaldo | 16/01/2011 20:00 | ERP5 |
40 | | Notícia sobre o ERP5 e o NSI Site | Rick Rock Sunshine Project NSI e ERP5 | NSI power site e ERP5 Lek, muita coisa pronta | test/images/news/x.png | herman | 16/01/2011 23:00 | ERP5 NSI Site |
41 |
42 | And the news "Notícia sobre o NSI Site" is related with project "NSI Site"
43 | And the news "Notícia sobre o ERP5 Lek" is related with project "ERP5"
44 | And the news "Notícia sobre o ERP5 e o NSI Site" is related with project "ERP5"
45 | And the news "Notícia sobre o ERP5 e o NSI Site" is related with project "NSI Site"
46 | When I go to "the news page"
47 | Then I should see "Notícia sobre o NSI Site"
48 | And I should see "O site do NSI está no ar"
49 | And I should see "Já está no ar o site do NSI!"
50 | And I should see an image called "nsi.png"
51 | And I should see "Postado por: rogerio"
52 | And I should see "Data: 15/01/2011 às 20:00"
53 |
54 | And I should see "Notícia sobre o ERP5 Lek"
55 | And I should see "Rick Rock Sunshine Project"
56 | And I should see "ERP5 Lek, muita coisa pronta"
57 | And I should see an image called "erp5.png"
58 | And I should see "Postado por: ronaldo"
59 | And I should see "Data: 16/01/2011 às 20:00"
60 |
61 | And I should see "Notícia sobre o ERP5 e o NSI Site"
62 | And I should see "Rick Rock Sunshine Project NSI e ERP5"
63 | And I should see "NSI power site e ERP5 Lek, muita coisa pronta"
64 | And I should see an image called "x.png"
65 | And I should see "Postado por: herman"
66 | And I should see "Data: 16/01/2011 às 23:00"
67 |
68 | Scenario: showing a especific news
69 | Given exist a author:
70 | | name |
71 | | herman |
72 |
73 | And exist a project:
74 | | name |
75 | | NSI Site |
76 |
77 | And exist a news:
78 | | title | summary | body | image | author | date_and_time |
79 | | Notícia sobre o NSI Site | O site do NSI está no ar | Já está no ar o site do NSI! | test/images/news/nsi.png | herman | 15/01/2011 20:00 |
80 |
81 | And the news "Notícia sobre o NSI Site" is related with project "NSI Site"
82 | When I go to "the news page"
83 | And I click "Notícia sobre o NSI Site"
84 | Then I should see "Notícia sobre o NSI Site"
85 | And I should see "O site do NSI está no ar"
86 | And I should see "Já está no ar o site do NSI!"
87 | And I should see an image called "nsi.png"
88 | And I should see "Postado por: herman"
89 | And I should see "Data: 15/01/2011 às 20:00"
90 | And I should see "NSI Site"
91 |
92 |
93 | Scenario: News are rendered as RST
94 | Given exist a author:
95 | | name |
96 | | herman |
97 | And exist a project:
98 | | name |
99 | | NSI Site |
100 | And exist a news:
101 | | title | summary | body | image | author | date_and_time |
102 | | Notícia sobre o NSI Site | O site do NSI está no ar | Já está no ar o *site do NSI*! | test/images/news/nsi.png | herman | 15/01/2011 20:00 |
103 | When I go to "the news page"
104 | And I click "Notícia sobre o NSI Site"
105 | Then I should have "Já está no ar o site do NSI !" as HTML
106 |
107 |
--------------------------------------------------------------------------------
/apps/news/features/resources/erp5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/news/features/resources/erp5.png
--------------------------------------------------------------------------------
/apps/news/features/resources/nsi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/news/features/resources/nsi.png
--------------------------------------------------------------------------------
/apps/news/features/resources/x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/news/features/resources/x.png
--------------------------------------------------------------------------------
/apps/news/features/steps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import os
3 | import shutil
4 | from lettuce import step
5 | from datetime import datetime
6 | from django.conf import settings
7 | from model_mommy import mommy
8 | from django.contrib.auth.models import User
9 | from apps.projects.models import Project
10 | from apps.news.models import News
11 |
12 |
13 | @step(u'exist a author:')
14 | def exist_a_author(step):
15 | for user in step.hashes:
16 | mommy.make_one(User, username=user.get('name'), email='a@a.com')
17 |
18 | @step(u'exist a project:')
19 | def exist_a_project(step):
20 | for project in step.hashes:
21 | mommy.make_one(Project, name=project.get('name'), logo=None)
22 |
23 | @step(u'the news "(.*)" is related with project "(.*)"')
24 | def the_news_is_related_with_project(step, news_title, project_name):
25 | project_obj = Project.objects.get(name=project_name)
26 | news_obj = News.objects.get(title=news_title)
27 | news_obj.projects_relateds.add(project_obj)
28 | news_obj.save()
29 |
30 | @step(u'exist a news:')
31 | def exist_a_news(step):
32 | for news_hashes in step.hashes:
33 | author = User.objects.get(username__exact=news_hashes.get('author'))
34 | date, hour = news_hashes.get('date_and_time').split()
35 | day, month, year = date.split('/')
36 | hours, minutes = hour.split(':')
37 | date_time = datetime(int(year), int(month), int(day), int(hours), int(minutes))
38 | News(title=news_hashes.get('title'), summary=news_hashes.get('summary'), body=news_hashes.get('body'), image=news_hashes.get('image'), author=author, date_and_time=date_time).save()
39 | file_name = news_hashes.get('image').split('/')[-1]
40 | shutil.copy2(os.path.join(settings.PROJECT_ROOT_PATH, 'apps', 'news',
41 | 'features', 'resources', file_name),
42 | os.path.join(settings.MEDIA_ROOT, 'test', 'images', 'news'))
43 |
--------------------------------------------------------------------------------
/apps/news/migrations/0004_auto__chg_field_news_image.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Changing field 'News.image'
12 | db.alter_column('news_news', 'image', self.gf('thumbs.ImageWithThumbsField')(name='image', sizes=((300, 300), (90, 90)), max_length=100, null=True))
13 |
14 |
15 | def backwards(self, orm):
16 |
17 | # Changing field 'News.image'
18 | db.alter_column('news_news', 'image', self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True))
19 |
20 |
21 | models = {
22 | 'auth.group': {
23 | 'Meta': {'object_name': 'Group'},
24 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
25 | 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
26 | 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
27 | },
28 | 'auth.permission': {
29 | 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
30 | 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
31 | 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
32 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
33 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
34 | },
35 | 'auth.user': {
36 | 'Meta': {'object_name': 'User'},
37 | 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
38 | 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
39 | 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
40 | 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
41 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
42 | 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
43 | 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
44 | 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
45 | 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
46 | 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
47 | 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
48 | 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
49 | 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
50 | },
51 | 'contenttypes.contenttype': {
52 | 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
53 | 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
54 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
55 | 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
56 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
57 | },
58 | 'news.news': {
59 | 'Meta': {'object_name': 'News'},
60 | 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
61 | 'body': ('django.db.models.fields.TextField', [], {}),
62 | 'datetime': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2011, 3, 24, 19, 16, 47, 662542)'}),
63 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
64 | 'image': ('thumbs.ImageWithThumbsField', [], {'name': "'image'", 'sizes': '((300, 300), (90, 90))', 'max_length': '100', 'blank': 'True', 'null': 'True'}),
65 | 'projects_relateds': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['projects.Project']", 'null': 'True', 'blank': 'True'}),
66 | 'summary': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
67 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
68 | },
69 | 'projects.project': {
70 | 'Meta': {'object_name': 'Project'},
71 | 'description': ('django.db.models.fields.TextField', [], {}),
72 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
73 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
74 | 'logo': ('thumbs.ImageWithThumbsField', [], {'name': "'logo'", 'sizes': '((200, 200), (90, 90))', 'max_length': '100', 'blank': 'True', 'null': 'True'}),
75 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
76 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
77 | 'start_date': ('django.db.models.fields.DateField', [], {}),
78 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
79 | }
80 | }
81 |
82 | complete_apps = ['news']
83 |
--------------------------------------------------------------------------------
/apps/news/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/news/migrations/__init__.py
--------------------------------------------------------------------------------
/apps/news/models.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime as dt
2 | from django.db import models
3 | from django.template.defaultfilters import slugify
4 | from django.contrib.auth.models import User
5 | from thumbs import ImageWithThumbsField
6 | from docutils.core import publish_parts
7 | from apps.projects.models import Project
8 |
9 |
10 | class News(models.Model):
11 |
12 | class Meta:
13 | verbose_name_plural = 'News'
14 | ordering = ['-date_and_time']
15 |
16 | title = models.CharField(max_length=200)
17 | summary = models.CharField(max_length=200, null=True, blank=True)
18 | body = models.TextField()
19 | image = ImageWithThumbsField(null=True, blank=True, upload_to='images/news', sizes=((150, 150), (90, 90), ))
20 | author = models.ForeignKey(User)
21 | date_and_time = models.DateTimeField(default=dt.now())
22 | projects_relateds = models.ManyToManyField(Project, null=True, blank=True)
23 | slug = models.SlugField(max_length=200, blank=True)
24 |
25 | def __unicode__(self):
26 | return self.title
27 |
28 | def body_as_html(self):
29 | parts = publish_parts(source=self.body, writer_name="html4css1")
30 | return parts['fragment']
31 |
32 | def save(self, *args, **kwargs):
33 | self.slug = slugify(self.title)
34 | super(News, self).save(*args, **kwargs)
35 |
36 |
--------------------------------------------------------------------------------
/apps/news/templates/detail_news.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block scripts %}
4 | {{ bloc.super }}
5 |
6 | {% endblock scripts %}
7 |
8 | {% block content %}
9 |
10 | {% if news_obj.image %}
11 |
12 |
13 |
14 | {% endif %}
15 |
{{ news_obj.title }}
16 |
{{ news_obj.summary }}
17 |
{{ news_obj.body_as_html|safe }}
18 |
Postado por: {{ news_obj.author }}
19 |
Data: {{ news_obj.date_and_time|date:"d/m/Y à\s H:i" }}
20 | {% if news_obj.projects_relateds.all %}
21 |
Projetos relacionados:
22 |
23 | {% for project in news_obj.projects_relateds.all %}
24 | {{ project.name }}
25 | {% endfor %}
26 |
27 | {% endif %}
28 |
29 | {% endblock content %}
30 |
31 |
--------------------------------------------------------------------------------
/apps/news/templates/show_news.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load pagination_tags %}
4 |
5 | {% block styles %}
6 | {{ block.super }}
7 |
8 | {% endblock styles %}
9 |
10 | {% block content %}
11 |
12 | {% autopaginate news 5 %}
13 | {% for new in news %}
14 |
15 | {% if new.image %}
16 |
17 |
18 |
19 | {% endif %}
20 |
21 |
{{ new.summary }}
22 |
{{ new.body|slice:"200" }} ...
23 |
24 | Data: {{ new.date_and_time|date:"d/m/Y à\s H:i" }} - Postado por: {{ new.author }}
25 | Leia mais +
26 |
27 |
28 | {% endfor %}
29 |
30 | {% paginate %}
31 | {% endblock content %}
32 |
--------------------------------------------------------------------------------
/apps/news/tests.py:
--------------------------------------------------------------------------------
1 | #-*- coding:utf-8 -*-
2 | from django.test import TestCase
3 | from should_dsl import should
4 | from apps.news.models import News
5 |
6 |
7 | class TestNews(TestCase):
8 |
9 | def test_convert_its_RST_body_to_HTML(self):
10 | h = News(body="*NSI* site rulz!")
11 | h.body_as_html() |should| contain('NSI site rulz!')
12 |
13 |
--------------------------------------------------------------------------------
/apps/news/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls.defaults import *
2 | from django.views.generic.simple import direct_to_template
3 | from django.conf import settings
4 |
5 | from django.contrib import admin
6 | admin.autodiscover()
7 |
8 | urlpatterns = patterns('',
9 |
10 | (r'^noticias/$', 'apps.news.views.show_news'),
11 | (r'^noticia/(?P[\w_-]+)$', 'apps.news.views.detail_news'),
12 |
13 | )
14 |
--------------------------------------------------------------------------------
/apps/news/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render_to_response
2 | from django.template import RequestContext
3 | from apps.news.models import News
4 |
5 |
6 | def show_news(request):
7 | news = News.objects.all()
8 | return render_to_response(
9 | 'show_news.html',
10 | {'news': news},
11 | context_instance=RequestContext(request)
12 | )
13 |
14 | def detail_news(request, news_slug):
15 | news_obj = News.objects.get(slug=news_slug)
16 | return render_to_response(
17 | 'detail_news.html',
18 | {'news_obj':news_obj},
19 | context_instance=RequestContext(request)
20 | )
21 |
--------------------------------------------------------------------------------
/apps/nsi_info/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/nsi_info/__init__.py
--------------------------------------------------------------------------------
/apps/nsi_info/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from apps.nsi_info.models import NSIInfo
3 |
4 |
5 | admin.site.register(NSIInfo)
6 |
7 |
--------------------------------------------------------------------------------
/apps/nsi_info/features/manage_history.feature:
--------------------------------------------------------------------------------
1 | Feature: NSI info maintenance
2 | As a NSI site administrator
3 | I want to maintain NSI-related data
4 | In order to keep people informed about the glorious NSI
5 |
6 | Scenario Outline: Info page
7 | Given current is "Hello, we are the glorious NSI."
8 | When I go to "the page"
9 | Then I should see "Hello, we are the glorious NSI."
10 |
11 | Examples:
12 | | field |
13 | | about |
14 |
15 | Scenario Outline: Accepts restructuredText format input
16 | Given current is "*NSI* rules!"
17 | When I go to "the page"
18 | Then I should have "NSI rules!" as HTML
19 |
20 | Examples:
21 | | field |
22 | | about |
23 |
--------------------------------------------------------------------------------
/apps/nsi_info/features/steps.py:
--------------------------------------------------------------------------------
1 | from lettuce import step
2 | from apps.nsi_info.models import NSIInfo
3 |
4 |
5 | @step(u'current about is "(.*)"')
6 | def current_about_is(step, about_text):
7 | if len(NSIInfo.objects.all()) == 0:
8 | NSIInfo(about=about_text).save()
9 | else:
10 | info = NSIInfo.objects.all()[0]
11 | info.about = about_text
12 | info.save()
13 |
14 |
--------------------------------------------------------------------------------
/apps/nsi_info/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding model 'NSIInfo'
12 | db.create_table('nsi_info_nsiinfo', (
13 | ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
14 | ('about', self.gf('django.db.models.fields.TextField')()),
15 | ('updated_at', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
16 | ))
17 | db.send_create_signal('nsi_info', ['NSIInfo'])
18 |
19 |
20 | def backwards(self, orm):
21 |
22 | # Deleting model 'NSIInfo'
23 | db.delete_table('nsi_info_nsiinfo')
24 |
25 |
26 | models = {
27 | 'nsi_info.nsiinfo': {
28 | 'Meta': {'object_name': 'NSIInfo'},
29 | 'about': ('django.db.models.fields.TextField', [], {}),
30 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
31 | 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
32 | }
33 | }
34 |
35 | complete_apps = ['nsi_info']
36 |
--------------------------------------------------------------------------------
/apps/nsi_info/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/nsi_info/migrations/__init__.py
--------------------------------------------------------------------------------
/apps/nsi_info/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from docutils.core import publish_parts
3 |
4 |
5 | class NSIInfo(models.Model):
6 | about = models.TextField(blank=False)
7 | updated_at = models.DateTimeField(auto_now=True)
8 |
9 | class Meta:
10 | verbose_name_plural = 'nsi_info'
11 |
12 | def about_as_html(self):
13 | return self._to_html(self.about)
14 |
15 | def _to_html(self, rst_source):
16 | parts = publish_parts(source=rst_source, writer_name="html4css1")
17 | return parts['fragment']
18 |
19 |
--------------------------------------------------------------------------------
/apps/nsi_info/templates/show_about.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% block styles %}
3 | {{ block.super }}
4 | {% endblock styles %}
5 | {% block content %}
6 |
7 |
8 |
{{ nsi_info.about_as_html|safe }}
9 |
10 |
11 | {% endblock content %}
12 |
--------------------------------------------------------------------------------
/apps/nsi_info/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 | from should_dsl import should
3 | from apps.nsi_info.models import NSIInfo
4 |
5 |
6 | class HistoryTest(TestCase):
7 |
8 | def test_convert_its_RST_text_to_HTML(self):
9 | h = NSIInfo(about="*NSI* site rulz!")
10 | h.about_as_html() |should| contain('NSI site rulz!')
11 |
12 |
--------------------------------------------------------------------------------
/apps/nsi_info/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render_to_response
2 | from django.template import RequestContext
3 | from apps.nsi_info.models import NSIInfo
4 |
5 |
6 | def show_about(request):
7 | if len(NSIInfo.objects.all()):
8 | nsi_info = NSIInfo.objects.latest('updated_at')
9 | else:
10 | nsi_info = list()
11 | return render_to_response(
12 | 'show_about.html',
13 | {'nsi_info': nsi_info},
14 | context_instance=RequestContext(request)
15 | )
16 |
--------------------------------------------------------------------------------
/apps/projects/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/projects/__init__.py
--------------------------------------------------------------------------------
/apps/projects/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from apps.projects.models import Project, Document
3 |
4 |
5 | class DocumentInline(admin.StackedInline):
6 | model = Document
7 | extra = 1
8 |
9 |
10 | class ProjectAdmin(admin.ModelAdmin):
11 | inlines = [DocumentInline]
12 |
13 |
14 | admin.site.register(Project, ProjectAdmin)
15 |
16 |
--------------------------------------------------------------------------------
/apps/projects/features/link_documents_to_project.feature:
--------------------------------------------------------------------------------
1 | Feature: Link documents to project
2 | As a NSI site administrator
3 | I want to link documents to projects
4 | In order to provide additional information on our projects
5 |
6 | Scenario: Show documents related to a project
7 | Given exist a project:
8 | | name | description | logo | sponsor | status | start_date | end_date |
9 | | NSI Site | The terrific site of NSI | test/images/projects/nsi.png | NSI | aberto | 2010-11-10 | 2011-02-01 |
10 | And "NSI Site" project has attached the following documents:
11 | | title | description | file |
12 | | UML model | UML detailed diagrams for project documentation | test/files/projects/nsi.png |
13 | When I go to "the projects page"
14 | And I click "NSI Site"
15 | Then I should see "UML model"
16 | And I should see "UML detailed diagrams for project documentation"
17 | And I should see a link to "nsi.png" with label "Download"
18 |
19 |
--------------------------------------------------------------------------------
/apps/projects/features/manage_projects.feature:
--------------------------------------------------------------------------------
1 | Feature: Project maintenance
2 | As a NSI site administrator
3 | I want to handle project data
4 | In order to know what we are doing and what we did
5 |
6 | Scenario: Projects page
7 | Given exist a project:
8 | | name | description | github | logo | sponsor | status | start_date | end_date |
9 | | NSI Site | The terrific site of NSI | nsi-iff/nsi_site | test/images/projects/nsi.png | NSI | finalizado | 2010-11-10 | 2011-02-01 |
10 |
11 | When I go to "the projects page"
12 | Then I should see "1 projeto"
13 | And I should see "NSI Site"
14 | And I should see "The terrific site of NSI"
15 | And I should see an image called "nsi.png"
16 |
17 | When I go to the "NSI Site" project page
18 |
19 | Then I should see a label "nsi-iff/nsi_site" with the link to "http://github.com/nsi-iff/nsi_site"
20 |
21 |
22 | Scenario: Projects page for non-closed projects
23 | Given exist a project:
24 | | name | description | logo | sponsor | status | start_date |
25 | | NSI Site | The terrific site of NSI | test/images/projects/nsi.png | NSI | aberto | 2010-11-10 |
26 | When I go to "the projects page"
27 | Then I should see "1 projeto"
28 | And I should see "NSI Site"
29 | And I should see "The terrific site of NSI"
30 | And I should see an image called "nsi.png"
31 |
32 |
33 | Scenario: Showing a especific project
34 | Given exist a project:
35 | | name | description | logo | sponsor | status | start_date | end_date |
36 | | NSI Site | The terrific site of NSI | test/images/projects/nsi.png | NSI | finalizado | 2010-11-10 | 2011-02-01 |
37 | | ERP5 | ERP5, lek | test/images/projects/erp5.png | NSI | finalizado | 2010-11-10 | 2011-02-01 |
38 |
39 | And exist a member:
40 | | name |
41 | | Pluck |
42 | | Batata |
43 | | Pedro |
44 |
45 | And "Pluck" member started participation on "NSI Site" project
46 | And "Batata" member started participation on "NSI Site" project
47 | And "Pedro" member started participation on "ERP5" project
48 |
49 | When I go to the "NSI Site" project page
50 | And I should see "NSI Site"
51 | And I should see "The terrific site of NSI"
52 | And I should see "Patrocinador: NSI"
53 | And I should see "Status: finalizado"
54 | And I should see "Duração: 10/11/2010 a 01/02/2011"
55 | And I should see an image called "nsi.png"
56 | And I should see "Pluck"
57 | And I should see "Batata"
58 |
59 |
--------------------------------------------------------------------------------
/apps/projects/features/resources/erp5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/projects/features/resources/erp5.png
--------------------------------------------------------------------------------
/apps/projects/features/resources/nsi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/projects/features/resources/nsi.png
--------------------------------------------------------------------------------
/apps/projects/features/steps.py:
--------------------------------------------------------------------------------
1 | import os
2 | import shutil
3 | from django.conf import settings
4 | from lettuce import step, world
5 | from lettuce.django import django_url
6 | from should_dsl import should
7 | from model_mommy import mommy
8 | from apps.members.models import Member
9 | from apps.members.models import Participation
10 | from apps.projects.models import Project, Document
11 |
12 | @step(u'exist a project:')
13 | def exist_a_project(step):
14 | for project in step.hashes:
15 | Project(**project).save()
16 | file_name = project['logo'].split('/')[-1]
17 | shutil.copy2(os.path.join(settings.PROJECT_ROOT_PATH, 'apps', 'projects',
18 | 'features', 'resources', file_name),
19 | os.path.join(settings.MEDIA_ROOT, 'test', 'images', 'projects'))
20 |
21 | @step(u'exist a member:')
22 | def exist_a_member(step):
23 | for member in step.hashes:
24 | mommy.make_one(Member, name=member.get('name'), site=None, lattes=None, photo=None)
25 |
26 | @step(r'"(.*)" member started participation on "(.*)" project')
27 | def member_started_participation_on_project(step, member_name, project_name):
28 | member_obj = Member.objects.get(name=member_name)
29 | project_obj = Project.objects.get(name=project_name)
30 | mommy.make_one(Participation, member=member_obj, project=project_obj)
31 |
32 | @step(r'I go to the "(.+)" project page')
33 | def i_go_to_project_page(step, project_name):
34 | project_obj = Project.objects.get(name=project_name)
35 | world.browser.visit(django_url('/projeto/%s' % project_obj.slug))
36 |
37 | @step(u'"(.*)" project has attached the following documents:')
38 | def project_has_attached_the_following_documents(step, project_name):
39 | project = Project.objects.get(name=project_name)
40 | document = Document(**step.hashes[0])
41 | document.project = project
42 | document.save()
43 |
44 | @step(u'I should see a label "(.*)" with the link to "(.*)"')
45 | def i_should_see_a_label_with_link(step, link_text, link_href):
46 | links = world.browser.find_link_by_href(link_href)
47 | links |should| have_at_least(1).item
48 | link_value = links[0].value
49 | link_value |should| equal_to(link_text)
50 |
--------------------------------------------------------------------------------
/apps/projects/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding model 'Project'
12 | db.create_table('projects_project', (
13 | ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
14 | ('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
15 | ('description', self.gf('django.db.models.fields.TextField')()),
16 | ('logo', self.gf('django.db.models.fields.files.ImageField')(max_length=100)),
17 | ('sponsor', self.gf('django.db.models.fields.CharField')(max_length=100)),
18 | ('status', self.gf('django.db.models.fields.CharField')(max_length=100)),
19 | ('start_date', self.gf('django.db.models.fields.DateField')()),
20 | ('end_date', self.gf('django.db.models.fields.DateField')()),
21 | ))
22 | db.send_create_signal('projects', ['Project'])
23 |
24 |
25 | def backwards(self, orm):
26 |
27 | # Deleting model 'Project'
28 | db.delete_table('projects_project')
29 |
30 |
31 | models = {
32 | 'projects.project': {
33 | 'Meta': {'object_name': 'Project'},
34 | 'description': ('django.db.models.fields.TextField', [], {}),
35 | 'end_date': ('django.db.models.fields.DateField', [], {}),
36 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
37 | 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
38 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
39 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
40 | 'start_date': ('django.db.models.fields.DateField', [], {}),
41 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
42 | }
43 | }
44 |
45 | complete_apps = ['projects']
46 |
--------------------------------------------------------------------------------
/apps/projects/migrations/0002_auto__chg_field_project_end_date.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Changing field 'Project.end_date'
12 | db.alter_column('projects_project', 'end_date', self.gf('django.db.models.fields.DateField')(null=True))
13 |
14 |
15 | def backwards(self, orm):
16 |
17 | # Changing field 'Project.end_date'
18 | db.alter_column('projects_project', 'end_date', self.gf('django.db.models.fields.DateField')(default=datetime.date(2011, 2, 1)))
19 |
20 |
21 | models = {
22 | 'projects.project': {
23 | 'Meta': {'object_name': 'Project'},
24 | 'description': ('django.db.models.fields.TextField', [], {}),
25 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
26 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
27 | 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
28 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
29 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
30 | 'start_date': ('django.db.models.fields.DateField', [], {}),
31 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
32 | }
33 | }
34 |
35 | complete_apps = ['projects']
36 |
--------------------------------------------------------------------------------
/apps/projects/migrations/0003_auto__add_document.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding model 'Document'
12 | db.create_table('projects_document', (
13 | ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
14 | ('title', self.gf('django.db.models.fields.CharField')(max_length=100)),
15 | ('description', self.gf('django.db.models.fields.TextField')()),
16 | ('file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
17 | ('project', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['projects.Project'])),
18 | ('uploaded_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
19 | ))
20 | db.send_create_signal('projects', ['Document'])
21 |
22 |
23 | def backwards(self, orm):
24 |
25 | # Deleting model 'Document'
26 | db.delete_table('projects_document')
27 |
28 |
29 | models = {
30 | 'projects.document': {
31 | 'Meta': {'object_name': 'Document'},
32 | 'description': ('django.db.models.fields.TextField', [], {}),
33 | 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
34 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
35 | 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']"}),
36 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
37 | 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
38 | },
39 | 'projects.project': {
40 | 'Meta': {'object_name': 'Project'},
41 | 'description': ('django.db.models.fields.TextField', [], {}),
42 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True'}),
43 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
44 | 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
45 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
46 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
47 | 'start_date': ('django.db.models.fields.DateField', [], {}),
48 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
49 | }
50 | }
51 |
52 | complete_apps = ['projects']
53 |
--------------------------------------------------------------------------------
/apps/projects/migrations/0004_add_slug.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 | from django.template.defaultfilters import slugify
7 |
8 | class Migration(SchemaMigration):
9 |
10 | def forwards(self, orm):
11 |
12 | # Adding field 'Project.slug'
13 | db.add_column('projects_project', 'slug', self.gf('django.db.models.fields.SlugField')(db_index=True, default='', max_length=100, blank=True), keep_default=False)
14 |
15 | # Changing field 'Project.logo'
16 | db.alter_column('projects_project', 'logo', self.gf('thumbs.ImageWithThumbsField')(name='logo', sizes=((200, 200), (90, 90)), max_length=100, null=True))
17 |
18 | for project in orm.Project.objects.all():
19 | project.slug = slugify(project.name)
20 | project.save()
21 |
22 | def backwards(self, orm):
23 |
24 | # Deleting field 'Project.slug'
25 | db.delete_column('projects_project', 'slug')
26 |
27 | # User chose to not deal with backwards NULL issues for 'Project.logo'
28 | raise RuntimeError("Cannot reverse this migration. 'Project.logo' and its values cannot be restored.")
29 |
30 |
31 | models = {
32 | 'projects.document': {
33 | 'Meta': {'object_name': 'Document'},
34 | 'description': ('django.db.models.fields.TextField', [], {}),
35 | 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
36 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
37 | 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']"}),
38 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
39 | 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
40 | },
41 | 'projects.project': {
42 | 'Meta': {'object_name': 'Project'},
43 | 'description': ('django.db.models.fields.TextField', [], {}),
44 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
45 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
46 | 'logo': ('thumbs.ImageWithThumbsField', [], {'name': "'logo'", 'sizes': '((200, 200), (90, 90))', 'max_length': '100', 'blank': 'True', 'null': 'True'}),
47 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
48 | 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '100', 'blank': 'True'}),
49 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
50 | 'start_date': ('django.db.models.fields.DateField', [], {}),
51 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
52 | }
53 | }
54 |
55 | complete_apps = ['projects']
56 |
--------------------------------------------------------------------------------
/apps/projects/migrations/0005_auto__add_field_project_github.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding field 'Project.github'
12 | db.add_column('projects_project', 'github', self.gf('django.db.models.fields.CharField')(max_length=80, null=True, blank=True), keep_default=False)
13 |
14 |
15 | def backwards(self, orm):
16 |
17 | # Deleting field 'Project.github'
18 | db.delete_column('projects_project', 'github')
19 |
20 |
21 | models = {
22 | 'projects.document': {
23 | 'Meta': {'object_name': 'Document'},
24 | 'description': ('django.db.models.fields.TextField', [], {}),
25 | 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
26 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
27 | 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']"}),
28 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
29 | 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
30 | },
31 | 'projects.project': {
32 | 'Meta': {'object_name': 'Project'},
33 | 'description': ('django.db.models.fields.TextField', [], {}),
34 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
35 | 'github': ('django.db.models.fields.CharField', [], {'max_length': '80', 'null': 'True', 'blank': 'True'}),
36 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
37 | 'logo': ('thumbs.ImageWithThumbsField', [], {'name': "'logo'", 'sizes': '((200, 200), (90, 90))', 'max_length': '100', 'blank': 'True', 'null': 'True'}),
38 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
39 | 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '100', 'blank': 'True'}),
40 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
41 | 'start_date': ('django.db.models.fields.DateField', [], {}),
42 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
43 | }
44 | }
45 |
46 | complete_apps = ['projects']
47 |
--------------------------------------------------------------------------------
/apps/projects/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/projects/migrations/__init__.py
--------------------------------------------------------------------------------
/apps/projects/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.template.defaultfilters import slugify
3 | from thumbs import ImageWithThumbsField
4 |
5 |
6 | PROJECT_STATES = (
7 | ('0', 'aberto'),
8 | ('1', 'finalizado'),
9 | ('2', 'paralisado'),
10 | ('3', 'cancelado'))
11 |
12 |
13 | class Project(models.Model):
14 | name = models.CharField(max_length=100)
15 | description = models.TextField()
16 | logo = ImageWithThumbsField(upload_to='images/projects', null=True, blank=True, sizes=((200, 200), (90, 90), ))
17 | sponsor = models.CharField(max_length=100)
18 | github = models.CharField(max_length=80, null=True, blank=True)
19 | status = models.CharField(max_length=100, choices=PROJECT_STATES)
20 | start_date = models.DateField()
21 | end_date = models.DateField(null=True, blank=True)
22 | slug = models.SlugField(max_length=100, blank=True)
23 |
24 | def github_link(self):
25 | return "http://github.com/" + self.github
26 |
27 | def github_feed(self):
28 | return self.github_link() + "/commits/master.atom"
29 |
30 |
31 | def finished(self):
32 | return self.end_date is not None
33 |
34 | def __unicode__(self):
35 | return self.name
36 |
37 | def save(self, *args, **kwargs):
38 | self.slug = slugify(self.name)
39 | if self.finished():
40 | self.status = 'finalizado'
41 | super(Project, self).save(*args, **kwargs)
42 | else:
43 | super(Project, self).save(*args, **kwargs)
44 |
45 |
46 | class Document(models.Model):
47 | title = models.CharField(max_length=100)
48 | description = models.TextField()
49 | file = models.FileField(upload_to='files/projects')
50 | project = models.ForeignKey(Project)
51 | uploaded_at = models.DateTimeField(auto_now_add=True)
52 |
53 | def __unicode__(self):
54 | return self.title + ' - ' + self.description
55 |
--------------------------------------------------------------------------------
/apps/projects/templates/show_all_projects.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load pagination_tags %}
4 |
5 | {% block scripts %}
6 | {{ block.super }}
7 |
8 | {% endblock scripts %}
9 |
10 | {% block content %}
11 |
12 | {{ project_count }} projeto{{ project_count|pluralize }}
13 |
14 |
15 | {% autopaginate projects 5 %}
16 | {% for project in projects %}
17 |
18 | {% if project.logo %}
19 |
20 | {% endif %}
21 |
22 |
{{ project.description|slice:"250"}} ...
23 |
Saiba mais +
24 |
25 | {% endfor %}
26 |
27 | {% paginate %}
28 | {% endblock content %}
29 |
--------------------------------------------------------------------------------
/apps/projects/templates/show_project.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block scripts %}
4 | {{ block.super }}
5 |
6 |
7 |
8 | {% endblock scripts %}
9 |
10 | {% block content %}
11 |
12 | {% if project.logo %}
13 |
14 |
15 |
16 | {% endif %}
17 |
18 |
{{ project.name }}
19 |
20 |
{{ project.description }}
21 |
22 |
Patrocinador: {{ project.sponsor }}
23 |
24 | {% if project.github %}
25 |
Github:
26 |
27 | {{ project.github }}
28 |
29 | {% endif %}
30 |
31 |
Status: {{ project.get_status_display }}
32 | {% if project.finished %}
33 |
Duração: {{ project.start_date|date:"d/m/Y" }} a {{ project.end_date|date:"d/m/Y" }}
34 | {% else %}
35 |
Início: {{ project.start_date|date:"d/m/Y" }}
36 | {% endif %}
37 |
38 | {% if project.document_set.all %}
39 |
Documentos relacionados:
40 |
41 |
42 | Nome Descrição Enviado
43 |
44 |
45 | {% for document in project.document_set.all %}
46 |
47 | {{ document.title }}
48 | {{ document.description }}
49 | {{ document.uploaded_at|date:"d/m/Y à\s H:i" }}
50 | Download
51 |
52 | {% endfor %}
53 |
54 |
55 | {% endif %}
56 |
57 | {% if participations %}
58 |
Membros:
59 |
60 | {% for participation in participations %}
61 | {% if participation.project.name == project.name %}
62 | {{ participation.member.name }}
63 | {% endif %}
64 | {% endfor %}
65 |
66 | {% endif %}
67 |
68 | {% if project.github %}
69 |
77 | {% endif %}
78 |
79 |
80 |
81 | {% endblock content %}
82 |
--------------------------------------------------------------------------------
/apps/projects/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 | from should_dsl import should, should_not
3 | from apps.projects.models import Project
4 |
5 |
6 | class ProjectTest(TestCase):
7 |
8 | def test_finishing(self):
9 | project = Project(start_date='2011-01-01', end_date=None)
10 | project |should_not| be_finished
11 | project.end_date = '2011-01-31'
12 | project |should| be_finished
13 |
14 | def test_change_status_to_finished(self):
15 | project = Project(start_date='2011-01-01', end_date=None)
16 | project |should_not| be_finished
17 | project.end_date = '2011-01-31'
18 | project.save()
19 | project.status |should| equal_to('finalizado')
20 |
--------------------------------------------------------------------------------
/apps/projects/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls.defaults import *
2 | from django.views.generic.simple import direct_to_template
3 | from django.conf import settings
4 |
5 | from django.contrib import admin
6 | admin.autodiscover()
7 |
8 | urlpatterns = patterns('',
9 |
10 | (r'^projetos/$', 'apps.projects.views.show_all'),
11 | (r'^projeto/(?P[\w_-]+)/$', 'apps.projects.views.show_project'),
12 |
13 | )
14 |
--------------------------------------------------------------------------------
/apps/projects/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render_to_response
2 | from django.template import RequestContext
3 | from apps.projects.models import Project
4 | from apps.members.models import Participation
5 |
6 |
7 | def show_all(request):
8 | projects = Project.objects.all().order_by('status', 'start_date')
9 | return render_to_response(
10 | 'show_all_projects.html',
11 | {'projects': projects, 'project_count': len(projects)},
12 | context_instance=RequestContext(request)
13 | )
14 |
15 | def show_project(request, project_slug):
16 | project = Project.objects.get(slug=project_slug)
17 | participations = Participation.objects.all()
18 | return render_to_response(
19 | 'show_project.html',
20 | {'project': project, 'participations': participations},
21 | context_instance=RequestContext(request)
22 | )
23 |
24 |
25 |
--------------------------------------------------------------------------------
/apps/tools/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/tools/__init__.py
--------------------------------------------------------------------------------
/apps/tools/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from apps.tools.models import Tool
3 |
4 | admin.site.register(Tool)
5 |
--------------------------------------------------------------------------------
/apps/tools/features/manage_tools.feature:
--------------------------------------------------------------------------------
1 | Feature: Tool maintenance
2 | As a NSI site administrator
3 | I want to handle tools data
4 | In order to keep tools information up to date
5 |
6 | Scenario: showing a tool
7 | Given exist a tool:
8 | | name | description | repository | site | logo | status | highlight |
9 | | Should DSL| A tool to write should expectations | http://github.com/hugobr/should-dsl | http://www.should-dsl.info | test/images/tools/should-dsl.png | ativo | True |
10 |
11 | And given there exist a project:
12 | | name |
13 | | NSI Site |
14 |
15 | And "Should DSL" has related projects:
16 | | name |
17 | | NSI Site |
18 |
19 | When I go to the "Should DSL" tool page
20 | Then I should see an image called "should-dsl.png"
21 | And I should see "Should DSL"
22 | And I should see "A tool to write should expectations"
23 | And I should see "http://github.com/hugobr/should-dsl"
24 | And I should see "http://www.should-dsl.info"
25 | And I should see "Status: ativo"
26 | And I should see "Projetos relacionados:"
27 | And I should see "NSI Site"
28 |
29 | Scenario: showing all tools
30 | Given exist a tool:
31 | | name | short_description | logo | status |
32 | | Should DSL | A tool to write should expectations | test/images/tools/should-dsl.png | ativo |
33 | | Ludibrio | A tool for mock | test/images/tools/ludibrio.png | descontinuado |
34 | | Ricks | A tool for sunshine | test/images/tools/ricks.png | ativo |
35 |
36 | When I go to "the tools page"
37 | Then I should see an image called "should-dsl.png"
38 | And I should see "Should DSL"
39 | And I should see "A tool to write should expectations"
40 | And I should see "Status: ativo"
41 | And I should see an image called "ludibrio.png"
42 | And I should see "Ludibrio"
43 | And I should see "A tool for mock"
44 | And I should see "Status: descontinuado"
45 | And I should see an image called "ricks.png"
46 | And I should see "Ricks"
47 | And I should see "A tool for sunshine"
48 | And I should see "Status: ativo"
49 |
--------------------------------------------------------------------------------
/apps/tools/features/resources/ludibrio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/tools/features/resources/ludibrio.png
--------------------------------------------------------------------------------
/apps/tools/features/resources/ricks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/tools/features/resources/ricks.png
--------------------------------------------------------------------------------
/apps/tools/features/resources/should-dsl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/tools/features/resources/should-dsl.png
--------------------------------------------------------------------------------
/apps/tools/features/steps.py:
--------------------------------------------------------------------------------
1 | import os
2 | import shutil
3 | from lettuce import step
4 | from model_mommy import mommy
5 | from apps.projects.models import Project
6 | from apps.tools.models import Tool
7 |
8 | @step(u'exist a tool:')
9 | def there_exist_a_tool(step):
10 | for tool_hashes in step.hashes:
11 | Tool.objects.create(**tool_hashes)
12 | if tool_hashes.get('logo'):
13 | file_name = tool_hashes['logo'].split('/')[-1]
14 | shutil.copy2(os.path.join(settings.PROJECT_ROOT_PATH, 'apps', 'tools',
15 | 'features', 'resources', file_name),
16 | os.path.join(settings.MEDIA_ROOT, 'test', 'images', 'tools'))
17 |
18 | @step(u'exist a project:')
19 | def exist_a_project(step):
20 | for project_hashes in step.hashes:
21 | project = mommy.make_one(Project, name=project_hashes.get('name'))
22 |
23 |
24 | @step(u'And "(.*)" has related projects:')
25 | def and_tool_has_related_projects(step, tool_name):
26 | tool = Tool.objects.get(name=tool_name)
27 | for project_hashes in step.hashes:
28 | project = Project.objects.get(name=project_hashes.get('name'))
29 | tool.relateds_projects.add(project)
30 | tool.save()
31 |
32 |
33 | @step(r'I go to the "(.+)" tool page')
34 | def i_go_to_tool_page(step, tool_name):
35 | tool_obj = Tool.objects.get(name=tool_name)
36 | world.browser.visit(django_url('/ferramenta/%s' % tool_obj.slug))
37 |
--------------------------------------------------------------------------------
/apps/tools/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding model 'Tool'
12 | db.create_table('tools_tool', (
13 | ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
14 | ('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
15 | ('description', self.gf('django.db.models.fields.TextField')()),
16 | ('repository', self.gf('django.db.models.fields.CharField')(max_length=100)),
17 | ('site', self.gf('django.db.models.fields.CharField')(max_length=100)),
18 | ('highlight', self.gf('django.db.models.fields.BooleanField')(default=False)),
19 | ))
20 | db.send_create_signal('tools', ['Tool'])
21 |
22 | # Adding M2M table for field relateds_projects on 'Tool'
23 | db.create_table('tools_tool_relateds_projects', (
24 | ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
25 | ('tool', models.ForeignKey(orm['tools.tool'], null=False)),
26 | ('project', models.ForeignKey(orm['projects.project'], null=False))
27 | ))
28 | db.create_unique('tools_tool_relateds_projects', ['tool_id', 'project_id'])
29 |
30 |
31 | def backwards(self, orm):
32 |
33 | # Deleting model 'Tool'
34 | db.delete_table('tools_tool')
35 |
36 | # Removing M2M table for field relateds_projects on 'Tool'
37 | db.delete_table('tools_tool_relateds_projects')
38 |
39 |
40 | models = {
41 | 'projects.project': {
42 | 'Meta': {'object_name': 'Project'},
43 | 'description': ('django.db.models.fields.TextField', [], {}),
44 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
45 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
46 | 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
47 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
48 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
49 | 'start_date': ('django.db.models.fields.DateField', [], {}),
50 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
51 | },
52 | 'tools.tool': {
53 | 'Meta': {'object_name': 'Tool'},
54 | 'description': ('django.db.models.fields.TextField', [], {}),
55 | 'highlight': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
56 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
57 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
58 | 'relateds_projects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['projects.Project']", 'null': 'True', 'blank': 'True'}),
59 | 'repository': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
60 | 'site': ('django.db.models.fields.CharField', [], {'max_length': '100'})
61 | }
62 | }
63 |
64 | complete_apps = ['tools']
65 |
--------------------------------------------------------------------------------
/apps/tools/migrations/0002_auto__add_field_tool_logo.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding field 'Tool.logo'
12 | db.add_column('tools_tool', 'logo', self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True), keep_default=False)
13 |
14 |
15 | def backwards(self, orm):
16 |
17 | # Deleting field 'Tool.logo'
18 | db.delete_column('tools_tool', 'logo')
19 |
20 |
21 | models = {
22 | 'projects.project': {
23 | 'Meta': {'object_name': 'Project'},
24 | 'description': ('django.db.models.fields.TextField', [], {}),
25 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
26 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
27 | 'logo': ('thumbs.ImageWithThumbsField', [], {'name': "'logo'", 'sizes': '((200, 200), (90, 90))', 'max_length': '100', 'blank': 'True', 'null': 'True'}),
28 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
29 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
30 | 'start_date': ('django.db.models.fields.DateField', [], {}),
31 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
32 | },
33 | 'tools.tool': {
34 | 'Meta': {'object_name': 'Tool'},
35 | 'description': ('django.db.models.fields.TextField', [], {}),
36 | 'highlight': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
37 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
38 | 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
39 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
40 | 'relateds_projects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['projects.Project']", 'null': 'True', 'blank': 'True'}),
41 | 'repository': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
42 | 'site': ('django.db.models.fields.CharField', [], {'max_length': '100'})
43 | }
44 | }
45 |
46 | complete_apps = ['tools']
47 |
--------------------------------------------------------------------------------
/apps/tools/migrations/0003_auto__add_field_tool_status.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding field 'Tool.status'
12 | db.add_column('tools_tool', 'status', self.gf('django.db.models.fields.CharField')(default='ativo', max_length=100), keep_default=False)
13 |
14 |
15 | def backwards(self, orm):
16 |
17 | # Deleting field 'Tool.status'
18 | db.delete_column('tools_tool', 'status')
19 |
20 |
21 | models = {
22 | 'projects.project': {
23 | 'Meta': {'object_name': 'Project'},
24 | 'description': ('django.db.models.fields.TextField', [], {}),
25 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
26 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
27 | 'logo': ('thumbs.ImageWithThumbsField', [], {'name': "'logo'", 'sizes': '((200, 200), (90, 90))', 'max_length': '100', 'blank': 'True', 'null': 'True'}),
28 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
29 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
30 | 'start_date': ('django.db.models.fields.DateField', [], {}),
31 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
32 | },
33 | 'tools.tool': {
34 | 'Meta': {'object_name': 'Tool'},
35 | 'description': ('django.db.models.fields.TextField', [], {}),
36 | 'highlight': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
37 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
38 | 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
39 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
40 | 'relateds_projects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['projects.Project']", 'null': 'True', 'blank': 'True'}),
41 | 'repository': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
42 | 'site': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
43 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
44 | }
45 | }
46 |
47 | complete_apps = ['tools']
48 |
--------------------------------------------------------------------------------
/apps/tools/migrations/0004_auto__add_field_tool_short_description.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding field 'Tool.short_description'
12 | db.add_column('tools_tool', 'short_description', self.gf('django.db.models.fields.TextField')(default='N\xc3\xa3o Informado', max_length=200), keep_default=False)
13 |
14 |
15 | def backwards(self, orm):
16 |
17 | # Deleting field 'Tool.short_description'
18 | db.delete_column('tools_tool', 'short_description')
19 |
20 |
21 | models = {
22 | 'projects.project': {
23 | 'Meta': {'object_name': 'Project'},
24 | 'description': ('django.db.models.fields.TextField', [], {}),
25 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
26 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
27 | 'logo': ('thumbs.ImageWithThumbsField', [], {'name': "'logo'", 'sizes': '((200, 200), (90, 90))', 'max_length': '100', 'blank': 'True', 'null': 'True'}),
28 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
29 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
30 | 'start_date': ('django.db.models.fields.DateField', [], {}),
31 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
32 | },
33 | 'tools.tool': {
34 | 'Meta': {'object_name': 'Tool'},
35 | 'description': ('django.db.models.fields.TextField', [], {}),
36 | 'highlight': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
37 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
38 | 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
39 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
40 | 'relateds_projects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['projects.Project']", 'null': 'True', 'blank': 'True'}),
41 | 'repository': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
42 | 'short_description': ('django.db.models.fields.TextField', [], {'max_length': '200'}),
43 | 'site': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
44 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
45 | }
46 | }
47 |
48 | complete_apps = ['tools']
49 |
--------------------------------------------------------------------------------
/apps/tools/migrations/0005_add_slug.py:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 | import datetime
3 | from south.db import db
4 | from south.v2 import SchemaMigration
5 | from django.db import models
6 |
7 | class Migration(SchemaMigration):
8 |
9 | def forwards(self, orm):
10 |
11 | # Adding field 'Tool.slug'
12 | db.add_column('tools_tool', 'slug', self.gf('django.db.models.fields.SlugField')(db_index=True, default='', max_length=100, blank=True), keep_default=False)
13 |
14 | for tool in orm.Tool.objects.all():
15 | tool.slug = slugify(tool.name)
16 | tool.save()
17 |
18 | def backwards(self, orm):
19 |
20 | # Deleting field 'Tool.slug'
21 | db.delete_column('tools_tool', 'slug')
22 |
23 |
24 | models = {
25 | 'projects.project': {
26 | 'Meta': {'object_name': 'Project'},
27 | 'description': ('django.db.models.fields.TextField', [], {}),
28 | 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
29 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
30 | 'logo': ('thumbs.ImageWithThumbsField', [], {'name': "'logo'", 'sizes': '((200, 200), (90, 90))', 'max_length': '100', 'blank': 'True', 'null': 'True'}),
31 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
32 | 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '100', 'blank': 'True'}),
33 | 'sponsor': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
34 | 'start_date': ('django.db.models.fields.DateField', [], {}),
35 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
36 | },
37 | 'tools.tool': {
38 | 'Meta': {'object_name': 'Tool'},
39 | 'description': ('django.db.models.fields.TextField', [], {}),
40 | 'highlight': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
41 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
42 | 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
43 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
44 | 'relateds_projects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['projects.Project']", 'null': 'True', 'blank': 'True'}),
45 | 'repository': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
46 | 'short_description': ('django.db.models.fields.TextField', [], {'max_length': '200'}),
47 | 'site': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
48 | 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '100', 'blank': 'True'}),
49 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '100'})
50 | }
51 | }
52 |
53 | complete_apps = ['tools']
54 |
--------------------------------------------------------------------------------
/apps/tools/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/tools/migrations/__init__.py
--------------------------------------------------------------------------------
/apps/tools/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.template.defaultfilters import slugify
3 | from apps.projects.models import Project
4 |
5 |
6 | TOOLS_STATES = (
7 | ('ativo', 'ativo'),
8 | ('descontinuado', 'descontinuado'))
9 |
10 | class Tool(models.Model):
11 | name = models.CharField(max_length=100)
12 | short_description = models.TextField(max_length=200)
13 | description = models.TextField()
14 | repository = models.CharField(max_length=100)
15 | site = models.CharField(max_length=100)
16 | logo = models.ImageField(upload_to='images/tools', null=True, blank=True)
17 | status = models.CharField(max_length=100, choices=TOOLS_STATES)
18 | highlight = models.BooleanField()
19 | relateds_projects = models.ManyToManyField(Project, null=True, blank=True)
20 | slug = models.SlugField(max_length=100, blank=True)
21 |
22 | def __unicode__(self):
23 | return self.name
24 |
25 | def save(self, *args, **kwargs):
26 | self.slug = slugify(self.name)
27 | super(Tool, self).save(*args, **kwargs)
28 |
29 |
--------------------------------------------------------------------------------
/apps/tools/templates/show_all.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load pagination_tags %}
4 |
5 | {% block styles %}
6 | {{ block.super }}
7 |
8 | {% endblock styles %}
9 |
10 | {% block content %}
11 | {% autopaginate tools 5 %}
12 | {% for tool in tools %}
13 |
30 | {% endfor %}
31 | {% paginate %}
32 | {% endblock content %}
33 |
34 |
--------------------------------------------------------------------------------
/apps/tools/templates/show_tool.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block scripts %}
4 | {{ block.super }}
5 |
6 | {% endblock scripts %}
7 |
8 | {% block content %}
9 |
37 | {% endblock content %}
38 |
--------------------------------------------------------------------------------
/apps/tools/tests.py:
--------------------------------------------------------------------------------
1 | #-*- coding:utf-8 -*-
2 |
3 | from django.test import TestCase
4 |
5 |
6 | class ToolsTest(TestCase):
7 | pass
8 |
9 |
--------------------------------------------------------------------------------
/apps/tools/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls.defaults import *
2 | from django.views.generic.simple import direct_to_template
3 | from django.conf import settings
4 |
5 | from django.contrib import admin
6 | admin.autodiscover()
7 |
8 | urlpatterns = patterns('',
9 |
10 | (r'^ferramentas/$', 'apps.tools.views.show_all'),
11 | (r'^ferramenta/(?P[\w_-]+)$', 'apps.tools.views.show_tool'),
12 |
13 | )
14 |
--------------------------------------------------------------------------------
/apps/tools/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render_to_response
2 | from django.template import RequestContext
3 | from apps.tools.models import Tool
4 |
5 |
6 | def show_tool(request, tool_slug):
7 | tool = Tool.objects.get(slug=tool_slug)
8 | return render_to_response(
9 | 'show_tool.html',
10 | {'tool': tool},
11 | context_instance=RequestContext(request)
12 | )
13 |
14 | def show_all(request):
15 | tools = Tool.objects.all().order_by('status')
16 | return render_to_response(
17 | 'show_all.html',
18 | {'tools': tools},
19 | context_instance=RequestContext(request)
20 | )
21 |
--------------------------------------------------------------------------------
/apps/wiki/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/apps/wiki/__init__.py
--------------------------------------------------------------------------------
/apps/wiki/features/manage_wiki.feature:
--------------------------------------------------------------------------------
1 | Feature: Wiki maintenance
2 | As a visitor NSI Site
3 | I want see home wiki data
4 | In order to learn more about Plone
5 |
6 |
7 | Scenario: listing all wiki items without be logged in
8 |
9 | Given exist a wiki item:
10 | | id | title | content |
11 | | 1 | Adding a Plone Site | Just click in 'Add Plone Site' |
12 | | 2 | Installing Plone 4 | Run "install.sh" |
13 |
14 | When I go to "the NSI home page"
15 | And I click "Wiki"
16 |
17 | Then I should see a link with text "Adding a Plone Site"
18 | And I should see a link with text "Installing Plone 4"
19 |
20 |
21 | Scenario: listing all wiki items logged in
22 |
23 | Given exist a wiki item:
24 | | id | title | content |
25 | | 1 | Adding a Plone Site | Just click in 'Add Plone Site' |
26 | | 2 | Installing Plone 4 | Run "install.sh" |
27 | And that i'm logged in
28 |
29 | When I go to "the NSI home page"
30 | And I click "Wiki"
31 |
32 | Then I should see a link with text "Adding a Plone Site"
33 | And I should have a link that ends in "adding-a-plone-site/editar/"
34 | And I should have a link that ends in "adding-a-plone-site/excluir/"
35 | And I should see a link with text "Installing Plone 4"
36 | And I should have a link that ends in "installing-plone-4/editar/"
37 | And I should have a link that ends in "installing-plone-4/excluir/"
38 |
39 |
40 | Scenario: adding some item to the wiki
41 |
42 | Given that i'm logged in
43 |
44 | When I go to "the NSI home page"
45 | And I click "Wiki"
46 | And I click "Adicionar um item"
47 | And I fill in "title" with "Teste"
48 | And I fill in "nicEdit-main" with "Conteúdo do teste"
49 | And I press "send"
50 | Then I should see "Item salvo com sucesso!"
51 | And I should see a link with text "Voltar para a wiki"
52 |
53 |
54 | Scenario: viewing a wiki item
55 |
56 | Given exist a wiki item:
57 | | id | title | content |
58 | | 1 | Adding a Plone Site | Just click in 'Add Plone Site' |
59 |
60 | When I go to "the NSI home page"
61 | And I click "Wiki"
62 | And I should have a link that ends in "adding-a-plone-site/"
63 | And I click "Adding a Plone Site"
64 |
65 | Then I should see "Adding a Plone Site"
66 | And I should see "Just click in 'Add Plone Site'"
67 |
68 |
69 | Scenario: editing some wiki item
70 |
71 | Given exist a wiki item:
72 | | id | title | content |
73 | | 1 | Adding a Plone Site | Just click in 'Add Plone Site' |
74 | And that i'm logged in
75 |
76 | When I go to "the NSI home page"
77 | And I click "Wiki"
78 | And I click on link that ends in "adding-a-plone-site/editar/"
79 | And I fill in "title" with "How to install django"
80 | And I fill in "nicEdit-main" with "Run: pip install django"
81 | And I press "send"
82 |
83 | Then I should see "Item editado com sucesso!"
84 | And I should see a link with text "Voltar para a wiki"
85 |
86 |
87 | Scenario: deleting some wiki item
88 |
89 | Given exist a wiki item:
90 | | id | title | content |
91 | | 1 | Adding a Plone Site | Just click in 'Add Plone Site' |
92 | And that i'm logged in
93 |
94 | When I go to "the NSI home page"
95 | And I click "Wiki"
96 | And I click on link that ends in "adding-a-plone-site/excluir/"
97 | And I should see "Deseja excluir o item 'Adding a Plone Site'?"
98 | And I press "yes"
99 |
100 | Then I should see "Item excluído com sucesso!"
101 | And I should see a link with text "Voltar para a wiki"
102 |
103 |
104 | Scenario: giving up of deleting some wiki item
105 |
106 | Given exist a wiki item:
107 | | id | title | content |
108 | | 1 | Adding a Plone Site | Just click in 'Add Plone Site' |
109 | And that i'm logged in
110 |
111 | When I go to "the NSI home page"
112 | And I click "Wiki"
113 | And I click on link that ends in "adding-a-plone-site/excluir/"
114 | And I should see "Deseja excluir o item 'Adding a Plone Site'?"
115 | And I press "no"
116 |
117 | Then I should see a link with text "Adding a Plone Site"
118 | And I should have a link that ends in "adding-a-plone-site/editar/"
119 | And I should have a link that ends in "adding-a-plone-site/excluir/"
120 |
--------------------------------------------------------------------------------
/apps/wiki/features/steps.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from django.contrib.auth.models import User
4 |
5 | from lettuce import step, world
6 | from lettuce.django import django_url
7 | from should_dsl import should
8 |
9 | from apps.wiki.models import WikiItem
10 |
11 |
12 | @step(u'exist a wiki item:')
13 | def exist_a_wiki_item(step):
14 | for wiki_item in step.hashes:
15 | WikiItem(id=wiki_item['id'], title=wiki_item['title'], content=wiki_item['content']).save()
16 |
17 | @step(u'I should have a link that ends in "(.*)"')
18 | def i_should_have_a_link_with_ends_in(step, url):
19 | links = world.browser.find_by_tag('a')
20 | end_links = [end_link for end_link in links if end_link['href'].endswith(url)]
21 | end_links |should| have_at_least(1).end_link
22 |
23 | @step(u'I click on link that ends in "(.*)"')
24 | def i_click_on_link_that_ends_in(step, url):
25 | links = world.browser.find_by_tag('a')
26 | end_link = [end_link for end_link in links if end_link['href'].endswith(url)]
27 | end_link |should| have(1).end_link
28 | end_link[0].click()
29 |
30 | @step(u"that i'm logged in")
31 | def that_i_m_logged_in(step):
32 | user = User.objects.create_user('test', 'test@test.com', 'test')
33 | user.is_staff = True
34 | user.save()
35 | world.browser.visit(django_url('/admin'))
36 | world.browser.fill('username', 'test')
37 | world.browser.fill('password', 'test')
38 | world.browser.find_by_value('Acessar').first.click()
39 |
--------------------------------------------------------------------------------
/apps/wiki/forms.py:
--------------------------------------------------------------------------------
1 | from django.forms import ModelForm
2 |
3 | from models import WikiItem
4 |
5 |
6 | class WikiItemForm(ModelForm):
7 |
8 | class Meta:
9 | model = WikiItem
10 | exclude = ('slug', )
11 |
--------------------------------------------------------------------------------
/apps/wiki/models.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | from django.db import models
4 | from django.db.models import signals
5 | from django.template.defaultfilters import slugify
6 |
7 |
8 | class WikiItem(models.Model):
9 | title = models.CharField(verbose_name='Título',max_length=100)
10 | content = models.TextField(verbose_name='Conteúdo')
11 | slug = models.SlugField(max_length=100, blank=True, unique=True)
12 |
13 |
14 | def wiki_item_pre_save(signal, instance, sender, **kwargs):
15 | slug = slugify(instance.title)
16 | new_slug = slug
17 | counter = 0
18 |
19 | while WikiItem.objects.filter(slug=new_slug).exclude(id=instance.id).count() > 0:
20 | counter += 1
21 | new_slug = '%s-%d' % (slug, counter)
22 |
23 | instance.slug = new_slug
24 |
25 |
26 | signals.pre_save.connect(wiki_item_pre_save, sender=WikiItem)
27 |
--------------------------------------------------------------------------------
/apps/wiki/templates/add_wiki_item.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block styles %}
4 | {{ block.super }}
5 |
6 | {% endblock styles %}
7 |
8 | {% block scripts %}
9 | {{ block.super }}
10 |
11 |
17 | {% endblock scripts %}
18 |
19 | {% block content %}
20 |
21 |
25 |
26 | {% endblock content %}
27 |
28 |
--------------------------------------------------------------------------------
/apps/wiki/templates/delete_wiki_item.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block styles %}
4 | {{ block.super }}
5 |
6 | {% endblock styles %}
7 |
8 | {% block content %}
9 |
10 | Deseja excluir o item '{{ object.title }}'?
11 |
15 |
16 | {% endblock content %}
17 |
--------------------------------------------------------------------------------
/apps/wiki/templates/edit_wiki_item.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block styles %}
4 | {{ block.super }}
5 |
6 | {% endblock styles %}
7 |
8 | {% block scripts %}
9 | {{ block.super }}
10 |
11 |
17 | {% endblock scripts %}
18 |
19 | {% block content %}
20 |
21 |
34 |
35 | {% endblock content %}
36 |
--------------------------------------------------------------------------------
/apps/wiki/templates/wiki_item.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block styles %}
4 | {{ block.super }}
5 |
6 | {% endblock styles %}
7 |
8 | {% block content %}
9 |
10 |
21 |
22 |
23 |
{{ wiki_item.title }}
24 |
25 | {{ wiki_item.content|safe }}
26 |
27 |
28 | {% endblock content %}
29 |
--------------------------------------------------------------------------------
/apps/wiki/templates/wiki_item_successfully_added.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block styles %}
4 | {{ block.super }}
5 |
6 | {% endblock styles %}
7 |
8 | {% block content %}
9 |
10 | Item salvo com sucesso!
11 |
12 | Voltar para a wiki
13 |
14 | {% endblock content %}
15 |
16 |
--------------------------------------------------------------------------------
/apps/wiki/templates/wiki_item_successfully_deleted.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block styles %}
4 | {{ block.super }}
5 |
6 | {% endblock styles %}
7 |
8 | {% block content %}
9 |
10 | Item excluído com sucesso!
11 |
12 | Voltar para a wiki
13 |
14 | {% endblock content %}
15 |
16 |
--------------------------------------------------------------------------------
/apps/wiki/templates/wiki_item_successfully_updated.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block styles %}
4 | {{ block.super }}
5 |
6 | {% endblock styles %}
7 |
8 | {% block content %}
9 |
10 | Item editado com sucesso!
11 |
12 | Voltar para a wiki
13 |
14 | {% endblock content %}
15 |
16 |
--------------------------------------------------------------------------------
/apps/wiki/templates/wiki_items.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load pagination_tags %}
4 |
5 | {% block styles %}
6 | {{ block.super }}
7 |
8 | {% endblock styles %}
9 |
10 | {% block content %}
11 |
12 | {% if user.is_authenticated %}
13 |
24 | {% endif %}
25 |
26 | {% autopaginate wiki_items 5 %}
27 | {% for wiki_item in wiki_items %}
28 |
37 | {% endfor %}
38 | {% paginate %}
39 |
40 | {% endblock content %}
41 |
--------------------------------------------------------------------------------
/apps/wiki/tests/test_forms.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | from should_dsl import should
4 |
5 | from apps.wiki.forms import WikiItemForm
6 | from apps.wiki.models import WikiItem
7 |
8 |
9 | class WikiFormsTests(TestCase):
10 |
11 | def setUp(self):
12 | self.wiki_item_form = WikiItemForm()
13 |
14 | def test_it_is_an_instance_of_WikiItem(self):
15 | self.wiki_item_form.instance |should| be_instance_of(WikiItem)
16 |
17 | def test_it_has_title_and_content(self):
18 | self.wiki_item_form.fields.keys() |should| equal_to(['title', 'content'])
19 | self.wiki_item_form.fields.keys() |should| have(2).fields
20 |
--------------------------------------------------------------------------------
/apps/wiki/tests/test_models.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | from apps.wiki.models import WikiItem
4 |
5 | from should_dsl import should, should_not
6 |
7 |
8 | class WikiModelsTests(TestCase):
9 |
10 | def test_it_has_title_and_content_and_slug(self):
11 | self.wiki_item = WikiItem(
12 | title='Add Plone Site',
13 | content='Click on "Add Plone Site"',
14 | slug='add-plone-site'
15 | )
16 | self.wiki_item.title |should| equal_to('Add Plone Site')
17 | self.wiki_item.content |should| equal_to('Click on "Add Plone Site"')
18 | self.wiki_item.slug |should| equal_to('add-plone-site')
19 |
20 | def test_it_can_has_a_blank_slug(self):
21 | self.wiki_item = WikiItem(
22 | title='Install Django',
23 | content='Run "pip install django".',
24 | )
25 | self.wiki_item.full_clean() |should_not| throw('ValidationError')
26 |
27 | def test_it_fills_slug_with_title_when_pre_save_wiki_item(self):
28 | self.wiki_item = WikiItem(
29 | title='Add Plone Site', content='Click on "Add Plone Site"').save()
30 | self.wiki_item = WikiItem.objects.get(title='Add Plone Site')
31 | self.wiki_item.slug |should| equal_to('add-plone-site')
32 |
33 | def test_it_can_adds_many_wiki_items_with_same_title(self):
34 | self.first_wiki_item = WikiItem(
35 | id=1, title='Add Plone Site', content='Click on "Add Plone Site"').save()
36 | self.first_wiki_item = WikiItem.objects.get(id=1)
37 | self.first_wiki_item.slug |should| equal_to('add-plone-site')
38 | self.second_wiki_item = WikiItem(
39 | id=2, title='Add Plone Site', content='Second way to add Plone Site').save()
40 | self.second_wiki_item = WikiItem.objects.get(id=2)
41 | self.second_wiki_item.slug |should| equal_to('add-plone-site-1')
42 |
--------------------------------------------------------------------------------
/apps/wiki/tests/test_views.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase, Client
2 | from django.contrib.auth.models import User
3 |
4 | from should_dsl import should
5 |
6 | from apps.wiki.models import WikiItem
7 |
8 |
9 | class WikiViewsTests(TestCase):
10 |
11 | def setUp(self):
12 | self.client = Client()
13 | user = User.objects.create_user('test', 'test@test.com', 'test').save()
14 |
15 | def test_it_shows_all_wiki_items(self):
16 | response = self.client.get('/wiki/')
17 | response.status_code |should| equal_to(200)
18 | response.template[0].name |should| equal_to('wiki_items.html')
19 | response.context[0].has_key('wiki_items') |should| equal_to(True)
20 |
21 | def test_it_can_add_a_wiki_item(self):
22 | self.client.login(username='test', password='test')
23 | response = self.client.get('/wiki/novo_item/')
24 | response.status_code |should| equal_to(200)
25 | response.template[0].name |should| equal_to('add_wiki_item.html')
26 | response.context[0].has_key('wiki_item_form') |should| equal_to(True)
27 |
28 | def test_it_adds_a_wiki_item(self):
29 | response = self.client.post(
30 | '/wiki/novo_item/',
31 | {'title':'Adding a Plone Site', 'content': 'Just clik "Add Plone Site"'})
32 | response.status_code |should| equal_to(302)
33 |
34 | def test_it_can_view_a_wiki_item(self):
35 | wiki_item = WikiItem(id=3, title='Add Plone Site', content='Click on "Add Plone Site"').save()
36 | response = self.client.get('/wiki/add-plone-site/')
37 | response.status_code |should| equal_to(200)
38 | response.template[0].name |should| equal_to('wiki_item.html')
39 | response.context[0].has_key('wiki_item') |should| be(True)
40 |
41 | def test_it_can_edit_a_wiki_item(self):
42 | self.client.login(username='test', password='test')
43 | WikiItem(id=3, title='Add Plone Site', content='Click on "Add Plone Site"').save()
44 | wiki_item = WikiItem.objects.get(pk=3)
45 | response = self.client.get('/wiki/add-plone-site/editar/')
46 | response.status_code |should| equal_to(200)
47 | response.template[0].name |should| equal_to('edit_wiki_item.html')
48 | response.context[0].has_key('form') |should| be(True)
49 |
50 | def test_it_can_delete_a_wiki_item(self):
51 | self.client.login(username='test', password='test')
52 | WikiItem(id=3, title='Add Plone Site', content='Click on "Add Plone Site"').save()
53 | wiki_item = WikiItem.objects.get(pk=3)
54 | response = self.client.get('/wiki/add-plone-site/excluir/')
55 | response.status_code |should| equal_to(200)
56 | response.template[0].name |should| equal_to('delete_wiki_item.html')
57 | response.context[0].has_key('object') |should| be(True)
58 |
--------------------------------------------------------------------------------
/apps/wiki/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls.defaults import patterns
2 | from django.views.generic.simple import direct_to_template
3 | from django.views.generic.create_update import update_object, delete_object
4 |
5 | from apps.wiki.models import WikiItem
6 |
7 |
8 | urlpatterns = patterns('apps.wiki.views',
9 | (r'^$', 'show_all_wiki_items'),
10 | (r'^novo_item/$', 'add_wiki_item'),
11 | (r'^item_editado_com_sucesso/$',
12 | direct_to_template, {'template': 'wiki_item_successfully_updated.html'}
13 | ),
14 | (r'^item_excluido_com_sucesso/$',
15 | direct_to_template, {'template': 'wiki_item_successfully_deleted.html'}
16 | ),
17 | (r'^novo_item/adicionado_com_sucesso/$',
18 | direct_to_template, {'template': 'wiki_item_successfully_added.html'}
19 | ),
20 | (r'^(?P[\w_-]+)/$', 'view_wiki_item'),
21 | (r'^(?P[\w_-]+)/editar/$', update_object,
22 | {'model': WikiItem, 'template_name': 'edit_wiki_item.html',
23 | 'post_save_redirect': '/wiki/item_editado_com_sucesso/',
24 | 'login_required': True}
25 | ),
26 | (r'^(?P[\w_-]+)/excluir/$', delete_object,
27 | {'model': WikiItem, 'template_name': 'delete_wiki_item.html',
28 | 'post_delete_redirect': '/wiki/item_excluido_com_sucesso/',
29 | 'login_required': True}
30 | ),
31 | )
32 |
--------------------------------------------------------------------------------
/apps/wiki/views.py:
--------------------------------------------------------------------------------
1 | from django.template import RequestContext
2 | from django.shortcuts import render_to_response, get_object_or_404
3 | from django.http import HttpResponseRedirect
4 | from django.contrib.auth.decorators import login_required
5 |
6 | from models import WikiItem
7 | from forms import WikiItemForm
8 |
9 |
10 | def show_all_wiki_items(request):
11 | wiki_items = WikiItem.objects.all()
12 |
13 | return render_to_response(
14 | 'wiki_items.html',
15 | {'wiki_items': wiki_items},
16 | context_instance=RequestContext(request)
17 | )
18 |
19 | @login_required
20 | def add_wiki_item(request):
21 | wiki_item_form = WikiItemForm()
22 | if request.method == 'POST':
23 | wiki_item_form = WikiItemForm(request.POST)
24 | if wiki_item_form.is_valid():
25 | wiki_item_form.save()
26 | return HttpResponseRedirect('/wiki/novo_item/adicionado_com_sucesso/')
27 |
28 | return render_to_response(
29 | 'add_wiki_item.html',
30 | {'wiki_item_form': wiki_item_form},
31 | context_instance=RequestContext(request)
32 | )
33 |
34 | def view_wiki_item(request, wiki_item_slug):
35 | wiki_item = get_object_or_404(WikiItem, slug=wiki_item_slug)
36 |
37 | return render_to_response(
38 | 'wiki_item.html',
39 | {'wiki_item': wiki_item},
40 | context_instance=RequestContext(request)
41 | )
42 |
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | from django.core.management import execute_manager
3 |
4 | try:
5 | import settings # Assumed to be in the same directory.
6 | except ImportError:
7 | import sys
8 | sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
9 | sys.exit(1)
10 |
11 | if __name__ == "__main__":
12 | execute_manager(settings)
13 |
--------------------------------------------------------------------------------
/paths.py:
--------------------------------------------------------------------------------
1 | from lettuce.django import django_url
2 |
3 |
4 | def path_to(page_name):
5 | return django_url(
6 | {
7 | 'the NSI home page': '/',
8 | 'the about page': '/sobre',
9 | 'the projects page': '/projetos',
10 | 'the page list all current members': '/membros',
11 | 'the news page': '/noticias',
12 | 'the tools page': '/ferramentas',
13 | 'the tool page': '/ferramenta',
14 | 'page that list all former members': '/ex-membros',
15 | }[page_name])
16 |
--------------------------------------------------------------------------------
/settings.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 |
4 | PROJECT_ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
5 |
6 | DEBUG = True
7 | TEMPLATE_DEBUG = DEBUG
8 |
9 | ADMINS = (
10 | # ('Your Name', 'your_email@domain.com'),
11 | )
12 |
13 | MANAGERS = ADMINS
14 |
15 | DATABASES = {
16 | 'default': {
17 | 'ENGINE': 'django.db.backends.sqlite3',
18 | 'NAME': os.path.join(PROJECT_ROOT_PATH, 'nsi_site.db'),
19 | 'USER': '',
20 | 'PASSWORD': '',
21 | 'HOST': '',
22 | 'PORT': '',
23 | }
24 | }
25 |
26 | TIME_ZONE = 'America/Sao_Paulo'
27 | LANGUAGE_CODE = 'pt-br'
28 |
29 | SITE_ID = 1
30 | USE_I18N = True
31 | USE_L10N = True
32 |
33 | MEDIA_ROOT = os.path.join(PROJECT_ROOT_PATH, 'site_media')
34 | MEDIA_URL = '/site_media'
35 | #ADMIN_MEDIA_PREFIX = '/admin_media/'
36 |
37 | SECRET_KEY = 'orv%lcr5o-_@#uq+)@^krb)fh*_p$v*!xtayj4sly@d1s)r^1+'
38 |
39 | TEMPLATE_LOADERS = (
40 | 'django.template.loaders.filesystem.Loader',
41 | 'django.template.loaders.app_directories.Loader',
42 | # 'django.template.loaders.eggs.Loader',
43 | )
44 |
45 | TEMPLATE_CONTEXT_PROCESSORS = (
46 | "django.core.context_processors.auth",
47 | "django.core.context_processors.debug",
48 | "django.core.context_processors.i18n",
49 | "django.core.context_processors.media",
50 | "django.core.context_processors.request"
51 | )
52 |
53 | MIDDLEWARE_CLASSES = (
54 | 'django.middleware.common.CommonMiddleware',
55 | 'django.contrib.sessions.middleware.SessionMiddleware',
56 | 'django.middleware.csrf.CsrfViewMiddleware',
57 | 'django.middleware.csrf.CsrfResponseMiddleware',
58 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
59 | 'django.contrib.messages.middleware.MessageMiddleware',
60 | 'linaro_django_pagination.middleware.PaginationMiddleware',
61 | )
62 |
63 | ROOT_URLCONF = 'urls'
64 |
65 | TEMPLATE_DIRS = (
66 | os.path.join(PROJECT_ROOT_PATH, 'templates'),
67 | )
68 |
69 | LETTUCE_AVOID_APPS = (
70 | 'south',
71 | 'linaro_django_pagination',
72 | )
73 |
74 | INSTALLED_APPS = (
75 | 'django.contrib.auth',
76 | 'django.contrib.contenttypes',
77 | 'django.contrib.sessions',
78 | 'django.contrib.sites',
79 | 'django.contrib.messages',
80 | 'django.contrib.admin',
81 | 'lettuce.django',
82 | 'south',
83 | 'linaro_django_pagination',
84 | 'apps.home_page',
85 | 'apps.nsi_info',
86 | 'apps.projects',
87 | 'apps.news',
88 | 'apps.tools',
89 | 'apps.members',
90 | 'apps.wiki',
91 | )
92 |
93 | PAGINATION_DEFAULT_WINDOW = 1
94 |
--------------------------------------------------------------------------------
/settings_test.py:
--------------------------------------------------------------------------------
1 | from settings import *
2 |
3 | DEBUG = True
4 |
5 | DATABASES = {
6 | 'default': {
7 | 'ENGINE': 'django.db.backends.sqlite3',
8 | 'NAME': os.path.join(PROJECT_ROOT_PATH, 'nsi_site-test.db'),
9 | 'USER': '',
10 | 'PASSWORD': '',
11 | 'HOST': '',
12 | 'PORT': '',
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/setup_on_debian_like.sh:
--------------------------------------------------------------------------------
1 | sudo apt-get install python-dev libxml2 libxslt1.1 libxslt1-dev libjpeg62-dev
2 | sudo apt-get install python-setuptools
3 | easy_install pip
4 |
5 |
--------------------------------------------------------------------------------
/site_media/css/base.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: verdana,arial,sans-serif;
5 | font-size: 0.625em;
6 | }
7 |
8 | #main {
9 | font-size: 1em;
10 | }
11 |
12 | #header {
13 | height: 100px;
14 | background-color: #E6E6E6;
15 | font-family: "trebuchet ms",arial,sans-serif;
16 | }
17 |
18 | #header #center_header {
19 | background: url("/site_media/images/base/background_head.jpg") repeat scroll 0px 0px transparent;
20 | height: 100px;
21 | width: 900px;
22 | margin: 0 auto;
23 | }
24 |
25 | #header #center_header #logo_nsi {
26 | margin-top: 17px;
27 | margin-left: 10px;
28 | border: none;
29 | }
30 |
31 | #header #menu {
32 | height: 40px;
33 | width: 898px;
34 | margin: 0 auto;
35 | color: #4B4B4B;
36 | font-size: 1.3em;
37 | border-left: 1px solid #AFAFAF;
38 | border-right: 1px solid #AFAFAF;
39 | border-bottom: 1px solid #AFAFAF;
40 | -moz-border-radius-bottomleft: 5px;
41 | -moz-border-radius-bottomright: 5px;
42 | -webkit-border-bottom-right-radius: 5px;
43 | -webkit-border-bottom-left-radius: 5px;
44 | -khtml-border-bottom-right-radius: 5px;
45 | -khtml-border-bottom-left-radius: 5px;
46 | border-bottom-right-radius: 5px;
47 | border-bottom-left-radius: 5px;
48 | }
49 |
50 | #header #menu ul {
51 | list-style-type: none;
52 | margin: 0;
53 | padding: 0;
54 | width: 900px;
55 | }
56 |
57 | #header #menu ul li {
58 | border-right: 1px solid #AFAFAF;
59 | float: left;
60 | position: relative;
61 | z-index: auto !important;
62 | width: 128px;
63 | }
64 |
65 | #header #menu ul li#last {
66 | border-right: none;
67 | width: 126px;
68 | color: #646464;
69 | font-weight: bold;
70 | line-height: 3.1em;
71 | text-align: center;
72 | }
73 |
74 | #header #menu ul li#last:hover {
75 | background-color: #d2d2d2;
76 | -webkit-border-bottom-right-radius: 5px;
77 | -khtml-border-bottom-right-radius: 5px;
78 | border-bottom-right-radius: 5px;
79 | }
80 |
81 | #header #menu ul li a {
82 | color: #646464;
83 | display: block;
84 | float: none !important;
85 | font-weight: bold;
86 | height: 3.1em;
87 | line-height: 3.1em;
88 | text-align: center;
89 | text-decoration: none;
90 | }
91 |
92 | #header #menu ul li:hover a {
93 | background-color: #d2d2d2;
94 | text-decoration:none;
95 | }
96 |
97 | #header #menu ul li ul {
98 | border: medium none;
99 | display: none;
100 | }
101 |
102 | #header #menu ul li:hover ul {
103 | display: block;
104 | position: absolute;
105 | width: auto;
106 | }
107 |
108 | #header #menu ul li:hover ul li {
109 | width: 126px;
110 | }
111 |
112 | #header #menu ul li:hover ul li a {
113 | border-left:solid 1px #AFAFAF;
114 | border-bottom: solid 1px #AFAFAF;
115 | background-color:#ededed;
116 | }
117 |
118 | #header #menu ul li:hover ul li a:hover {
119 | background-color:#d2d2d2;
120 | }
121 |
122 | #content {
123 | clear: both;
124 | width: 900px;
125 | margin: 60px auto 25px;
126 | }
127 |
128 | #footer {
129 | clear: both;
130 | margin: 0 auto;
131 | padding: 5px;
132 | background-color: #E6E6E6;
133 | text-align: center;
134 | }
135 |
136 | .floated_image {
137 | max-width: 100px;
138 | max-height: 100px;
139 | }
140 |
141 | .pagination {
142 | text-align: center;
143 | }
144 |
145 | .pagination .current {
146 | border-radius: 10px;
147 | -moz-border-radius: 10px;
148 | background-color: lightGrey;
149 | padding: 3px;
150 | }
151 |
152 | .pagination a, .pagination a:visited {
153 | color: black;
154 |
--------------------------------------------------------------------------------
/site_media/css/index.css:
--------------------------------------------------------------------------------
1 | #content #highlights {
2 | width: 900px;
3 | }
4 |
5 | #content #highlights .title_highlights {
6 | font-size: 1.8em;
7 | margin-left: 5px;
8 | height: 64px;
9 | padding-left: 70px;
10 | line-height: 65px;
11 | }
12 |
13 | #content #highlights #projects,
14 | #content #highlights #news,
15 | #content #highlights #tools,
16 | #content #highlights #planetaNSI {
17 | float: left;
18 | margin-left: 5px;
19 | margin-right: 5px;
20 | margin-bottom: 5px;
21 | padding: 10px;
22 | background-color: #EEEEEE;
23 | -moz-border-radius: 10px;
24 | -webkit-border-radius: 10px;
25 | -khtml-border-radius: 10px;
26 | border-radius: 10px;
27 | border: thin solid #9BCD9B;
28 | }
29 |
30 | #content #highlights #projects {
31 | width: 187px;
32 | }
33 | #content #highlights #news {
34 | width: 430px;
35 | }
36 | #content #highlights #tools {
37 | width: 187px;
38 | }
39 |
40 | #content #highlights #planetaNSI {
41 | width: 187px;
42 | }
43 |
44 | #content #highlights #projects #title_projects {
45 | background: transparent url("/site_media/images/base/projects.png") no-repeat;
46 | margin-bottom: 15px;
47 | }
48 |
49 | #content #highlights #projects .entry {
50 | margin-bottom: 10px;
51 | }
52 |
53 | #content #highlights #projects img {
54 | float: left;
55 | margin-right: 10px;
56 | }
57 |
58 | .text_entry {
59 | height: 32px;
60 | display: table-cell;
61 | vertical-align: middle;
62 | }
63 |
64 | .text_entry a {
65 | font-size: 14px;
66 | }
67 |
68 | .text_entry a:link, .text_entry a:visited {
69 | color: black;
70 | text-decoration: none;
71 | }
72 |
73 | .text_entry a:hover {
74 | color: gray;
75 | text-decoration: underline;
76 | }
77 |
78 | #content #highlights #news #title_news {
79 | background: transparent url("/site_media/images/base/news.png") 140px 0px no-repeat;
80 | padding-left: 210px;
81 | margin-bottom: 15px;
82 | }
83 |
84 | #content #highlights #tools #title_tools {
85 | background: transparent url("/site_media/images/base/tools.png") no-repeat;
86 | margin-bottom: 15px;
87 | }
88 |
89 | #content #highlights #news .entry {
90 | border-bottom: 1px dotted #000;
91 | margin-bottom: 20px;
92 | overflow: hidden;
93 |
94 | }
95 |
96 | #content #highlights #planetaNSI #title_planetaNSI {
97 | background: transparent url("/site_media/images/base/planetaNSI.png") no-repeat;
98 |
99 | margin-bottom: 15px;
100 | }
101 |
102 | #content #highlights #planetaNSI .entry img {
103 | float: left;
104 | margin-right: 10px;
105 | }
106 |
107 | #content #highlights #planetaNSI #feed,
108 | #content #highlights #planetaNSI #github {
109 | height: 32px;
110 | vertical-align: middle;
111 | }
112 |
113 | #content #highlights #news .entry .image_news {
114 | float: left;
115 | margin-right: 7px;
116 | }
117 |
118 | #content #highlights #news .entry .image_news img {
119 | border: none;
120 | }
121 |
122 | #content #highlights #news .entry .text_news {
123 | clear: both;
124 | }
125 |
126 | #content #highlights #news .entry .news_title_without_image {
127 | margin-bottom: 20px;
128 | }
129 |
130 | #content #highlights #news .entry .news_title_with_image a,
131 | #content #highlights #news .entry .news_title_without_image a{
132 | text-decoration: none;
133 | color: black;
134 | font-size: 1.4em;
135 | }
136 |
137 | #content #highlights #news .entry .news_title_with_image a p,
138 | #content #highlights #news .entry .news_title_without_image a p {
139 | text-align: justify;
140 | }
141 |
142 | #content #highlights #news .entry .news_title_with_image {
143 | display: table-cell;
144 | height: 75px;
145 | vertical-align: middle;
146 | }
147 |
148 | #content #highlights #news .entry .news_title_with_image a:hover,
149 | #content #highlights #news .entry .news_title_without_image a:hover {
150 | color: gray;
151 | text-decoration: underline;
152 | }
153 |
154 | #content #highlights #news #read_more {
155 | float: right;
156 | }
157 |
158 | #content #highlights #news #read_more a,
159 | #content #highlights #news #read_more a:visited {
160 | color: black;
161 | font-size: 14px;
162 | }
163 |
164 | #content #highlights #news #read_more a:hover p {
165 | text-decoration: underline;
166 | }
167 |
168 | #content #highlights #news #read_more p span {
169 | color: green;
170 | font-weight: bold;
171 | font-size: 18px;
172 | }
173 |
174 | #content #highlights #tools .entry {
175 | margin-bottom: 10px;
176 | }
177 |
178 | #content #highlights #tools .entry img {
179 | float: left;
180 | margin-right: 10px;
181 | }
182 |
183 | .text_highlight {
184 | font-weight: bold;
185 | }
186 |
187 | .text_data {
188 | font-weight: bold;
189 | float: right;
190 | }
191 |
192 | .index_image {
193 | max-width: 100px;
194 | max-height: 100px;
195 | }
196 |
--------------------------------------------------------------------------------
/site_media/css/members.css:
--------------------------------------------------------------------------------
1 | .member {
2 | padding: 10px 0px 15px 10px;
3 | float: left;
4 | height: 140px;
5 | width: 270px;
6 | margin-right: 9px;
7 | margin-left: 9px;
8 | margin-bottom: 15px;
9 | background-color: #E6E6E6;
10 | border-width: thin;
11 | border-color: #9BCD9B;
12 | border-style: solid;
13 | border-radius: 7px;
14 | -moz-border-radius: 7px;
15 | }
16 |
17 |
18 | .members_content {
19 | display: table;
20 | border-collapse: collapse;
21 | table-layout:fixed;
22 | }
23 |
24 | .avatar {
25 | float: left;
26 | border: none;
27 | border: 2px solid white;
28 | max-width: 100px;
29 | max-height: 100px;
30 | }
31 |
32 | .member_data {
33 | float: left;
34 | margin-left: 15px;
35 | width: 145px;
36 | }
37 |
38 | .member_data h1 {
39 | font-size: 14px;
40 | margin: 0;
41 | }
42 |
43 | .member_data h1 a {
44 | text-decoration: none;
45 | }
46 |
47 | .member_data h1 a:link, .member_data h1 a:visited {
48 | color: black;
49 | }
50 |
51 | .member_data h1 a:hover {
52 | color: gray;
53 | }
54 |
55 | .member_data span {
56 | font-style: italic;
57 | }
58 |
59 | .links{
60 | clear: left;
61 | padding: 7px 0 0 0;
62 |
63 | position: absolute;
64 | margin-top: 110px;
65 | list-style: none;
66 | }
67 |
68 | .links li {
69 | display: inline;
70 | }
71 |
72 | ul.links li a {
73 | text-decoration: none;
74 | }
75 |
76 | .links a img {
77 | border: none;
78 | width: 22px;
79 | }
80 |
81 | .member_details {
82 | padding: 10px;
83 | border-radius: 15px;
84 | -moz-border-radius: 15px;
85 | margin-bottom: 20px;
86 | overflow: hidden;
87 | border: thin solid #9BCD9B;
88 | }
89 |
90 | .member_details h2 {
91 | text-align: justify;
92 | }
93 |
94 | .member_details img {
95 | float: left;
96 | margin: 0 10px 0 0;
97 | position: relative;
98 | top: -4px;
99 | }
100 |
101 | .member_details a {
102 | display: block;
103 | clear: both;
104 | text-decoration: none;
105 | color: black;
106 | }
107 |
108 | .member_details a h3 {
109 | display: inline;
110 | margin-left: -6px;
111 | }
112 |
113 | .member_details .data{
114 | margin-left: 150px;
115 | }
116 |
117 | .member_details a img {
118 | margin-bottom: 4px;
119 | position: relative;
120 | top: -10px;
121 | border: none
122 | }
123 |
124 | .member_details .avatar {
125 | float: left;
126 | border: 2px solid white;
127 | margin-left: 15px;
128 | margin-top: 20px;
129 | }
130 |
131 | .member_links {
132 | margin-left: -2px;
133 | padding-top: 15px;
134 | overflow: hidden;
135 | }
136 |
137 | .member_details .text_highlight {
138 | font-size: 12px;
139 | font-weight: bold;
140 | }
141 |
142 | #coderwall_link {
143 | font-size: 12px;
144 | font-weight: bold;
145 | }
146 |
147 | div.github_activities ul.activities li {
148 | padding: 3px 0 3px 0;
149 | }
150 |
151 | div.github_activities ul.activities a:hover {
152 | text-decoration: underline;
153 | }
154 |
155 |
--------------------------------------------------------------------------------
/site_media/css/news.css:
--------------------------------------------------------------------------------
1 | .new {
2 | background-color: #E6E6E6;
3 | padding: 10px;
4 | border-radius: 10px;
5 | -moz-border-radius: 10px;
6 | margin-bottom: 20px;
7 | overflow: hidden;
8 | border: thin solid #9BCD9B;
9 | }
10 |
11 | .new img {
12 | float: left;
13 | margin-right: 20px;
14 | margin-bottom: 10px;
15 | border: 3px solid white;
16 | }
17 |
18 | .new #new_image {
19 | float: left;
20 | }
21 |
22 | .new h1 {
23 | margin: 0;
24 | }
25 |
26 | .new h1 a, .new h1 a:visited {
27 | color: black;
28 | text-decoration: none;
29 | }
30 |
31 | .new h1 a:hover {
32 | text-decoration: underline;
33 | }
34 |
35 | .new p span {
36 | font-weight: bold;
37 | }
38 |
39 | .new ul li a, .new ul li a:visited {
40 | color: black;
41 | text-decoration: none;
42 | }
43 |
44 | .new ul li a:hover {
45 | text-decoration: underline;
46 | }
47 |
48 | .new p a {
49 | float: right;
50 | }
51 |
52 | .new p a, .new p a:visited {
53 | color: black;
54 | text-decoration: none;
55 | }
56 |
57 | .new p a:hover {
58 | text-decoration: underline;
59 | }
60 |
61 | .new p a span {
62 | color: green;
63 | font-weight: bold;
64 | font-size: 18px;
65 | }
66 |
67 | .new h3 {
68 | text-align: justify;
69 | font-weight: normal;
70 | }
71 |
72 | .pagination {
73 | text-align: center;
74 | }
75 |
76 | .pagination .current {
77 | border-radius: 10px;
78 | -moz-border-radius: 10px;
79 | background-color: lightGrey;
80 | padding: 3px;
81 | }
82 |
83 | .pagination a, .pagination a:visited {
84 | color: black;
85 | }
86 |
--------------------------------------------------------------------------------
/site_media/css/nsi_info.css:
--------------------------------------------------------------------------------
1 | .nsi_info {
2 | text-align: justify;
3 | font-size: 1.2em;
4 | background-color: #E6E6E6;
5 | padding: 10px;
6 | border-radius: 10px;
7 | -moz-border-radius: 10px;
8 | overflow: hidden;
9 | border: thin solid #9BCD9B;
10 | }
11 |
--------------------------------------------------------------------------------
/site_media/css/projects.css:
--------------------------------------------------------------------------------
1 | .project {
2 | background-color: #E6E6E6;
3 | padding: 10px;
4 | border-radius: 5px;
5 | -moz-border-radius: 5px;
6 | margin-bottom: 20px;
7 | overflow: hidden;
8 | border: thin solid #9BCD9B;
9 | }
10 |
11 | .project h2 {
12 | margin: 0;
13 | }
14 |
15 | .project h2 a:link, .project h2 a:visited {
16 | color: black;
17 | text-decoration: none;
18 | }
19 |
20 | .project h2 a:hover {
21 | text-decoration: underline;
22 | }
23 |
24 | .project img {
25 | float: left;
26 | margin-right: 20px;
27 | border: 3px solid white;
28 | }
29 |
30 | .project p {
31 | font-size: 12px;
32 | text-align: justify;
33 | }
34 |
35 | .project #know_more:link, .project #know_more:visited {
36 | float: right;
37 | color: black;
38 | text-decoration: none;
39 | }
40 |
41 | .project #know_more:hover {
42 | text-decoration: underline;
43 | }
44 |
45 | .project #know_more span {
46 | font-size: 18px;
47 | color: green;
48 | }
49 |
50 | #project_details {
51 | background-color: #E6E6E6;
52 | padding: 10px;
53 | border-radius: 10px;
54 | -moz-border-radius: 10px;
55 | overflow: hidden;
56 | border: thin solid #9BCD9B;
57 | }
58 |
59 | #project_details img {
60 | border: 3px solid white;
61 | float: left;
62 | margin-right: 20px;
63 | margin-bottom: 10px;
64 | }
65 |
66 | #project_details #project_logo {
67 | float: left;
68 | }
69 |
70 | #project_details #data p {
71 | text-align: justify;
72 | font-size: 1.2em;
73 | }
74 |
75 | #project_details #data h1 {
76 | margin: 0;
77 | }
78 |
79 | #project_details #data .text_highlight {
80 | font-size: 12px;
81 | font-weight: bold;
82 | }
83 |
84 | #project_details #data #documents {
85 | border: 1px solid #BDBDBD;
86 | border-collapse: collapse;
87 | }
88 |
89 | #project_details #data #documents tr th, #project_details #documents tr td {
90 | padding: 5px;
91 | }
92 |
93 | #project_details #data #documents tr th, #project_details #documents tr td {
94 | border: 1px solid #BDBDBD;
95 | }
96 |
97 | #project_details #data ul li a:link, #project_details #data ul li a:visited, span#github_project {
98 | color: black;
99 | text-decoration: none;
100 | }
101 |
102 | #project_details #data ul li a:hover, span#github_project a {
103 | text-decoration: underline;
104 | }
105 |
106 | #project_details a {
107 | clear: both;
108 | color: black;
109 | text-decoration:none;
110 | }
111 |
112 | #project_details #data ul a:hover, span#github_project a {
113 | text-decoration: underline;
114 | }
115 |
116 | div.github_activities ul.activities li {
117 | padding: 3px 0 3px 0;
118 | }
119 |
--------------------------------------------------------------------------------
/site_media/css/tools.css:
--------------------------------------------------------------------------------
1 | .tool {
2 | background-color: #E6E6E6;
3 | padding: 10px;
4 | border-radius: 5px;
5 | -moz-border-radius: 5px;
6 | margin-bottom: 20px;
7 | overflow: hidden;
8 | border: thin solid #9BCD9B;
9 | }
10 |
11 | .tool img {
12 | border: 3px solid white;
13 | float: left;
14 | margin-bottom: 10px;
15 | margin-right: 20px;
16 | }
17 |
18 | .tool h1 {
19 | margin: 0;
20 | }
21 |
22 | .tool p {
23 | font-size: 12px;
24 | }
25 |
26 | .tool p span {
27 | font-weight: bold;
28 | }
29 |
30 | .tool a:link, .tool a:visited {
31 | color: black;
32 | text-decoration: none;
33 | }
34 |
35 | .more_info {
36 | float: right;
37 | }
38 |
39 | .tool p a span {
40 | color: green;
41 | font-size: 18px;
42 | font-weight: bold;
43 |
--------------------------------------------------------------------------------
/site_media/css/wiki.css:
--------------------------------------------------------------------------------
1 | .edit {
2 | background-image: url("/site_media/images/wiki/edit.png");
3 | display: block;
4 | width: 24px;
5 | height: 24px;
6 | float: left;
7 | text-decoration: none;
8 | }
9 |
10 | .edit:hover {
11 | background-image: url("/site_media/images/wiki/edit_hover.png");
12 | }
13 |
14 | .delete {
15 | background-image: url("/site_media/images/wiki/delete.png");
16 | display: block;
17 | width: 24px;
18 | height: 24px;
19 | float: left;
20 | text-decoration: none;
21 | }
22 |
23 | .delete:hover {
24 | background-image: url("/site_media/images/wiki/delete_hover.png");
25 | }
26 |
27 | .wiki_item {
28 | clear: both;
29 | background-color: #ECECEC;
30 | height: 30px;
31 | margin-bottom: 15px;
32 | border-radius: 10px;
33 | box-shadow: black 1px 1px 1px;
34 | }
35 |
36 | .wiki_item .wiki_item_title {
37 | color: black;
38 | font-size: 2em;
39 | font-weight: bold;
40 | margin-left: 10px;
41 | text-decoration: none;
42 | }
43 |
44 | .wiki_item .wiki_item_title:hover {
45 | text-decoration: underline;
46 | }
47 |
48 | .manage_wiki_item {
49 | float: right;
50 | margin-top: 4px;
51 | margin-right: 5px;
52 | }
53 |
54 | #new_item {
55 | float: right;
56 | margin-bottom: 20px;
57 | }
58 |
59 | #new_item a {
60 | text-decoration: none;
61 | color: black;
62 | }
63 |
64 | #new_item a:hover {
65 | text-decoration: underline;
66 | }
67 |
68 | #new_item_image {
69 | float: left;
70 | margin-right: 5px;
71 | }
72 |
73 | #new_item_image a {
74 | background-image: url("/site_media/images/wiki/add.png");
75 | display: block;
76 | width: 24px;
77 | height: 24px;
78 | }
79 |
80 | #new_item_image a:hover {
81 | background-image: url("/site_media/images/wiki/add_hover.png");
82 | text-decoration: none;
83 | }
84 |
85 | #new_item_text {
86 | display: table-cell;
87 | font-size: 1.5em;
88 | height: 24px;
89 | vertical-align: middle;
90 | width: 167px;
91 | }
92 |
93 | label {
94 | font-size: 1.3em;
95 | }
96 | input[type=text] {
97 | padding-top: 10px;
98 | padding-bottom: 10px;
99 | padding-left: 10px;
100 | width: 890px;
101 | }
102 | textarea {
103 | width: 900px;
104 | height: 300px;
105 | }
106 |
107 | #back_to_wiki_page {
108 | float: right;
109 | }
110 |
111 | #back_to_wiki_page a {
112 | text-decoration: none;
113 | color: black;
114 | }
115 |
116 | #back_to_wiki_page a:hover {
117 | text-decoration: underline;
118 | }
119 |
120 | #back_to_wiki_page_image {
121 | float: left;
122 | margin-right: 5px;
123 | }
124 |
125 | #back_to_wiki_page_image a {
126 | background-image: url("/site_media/images/wiki/back.png");
127 | display: block;
128 | width: 24px;
129 | height: 24px;
130 | }
131 |
132 | #back_to_wiki_page_text {
133 | display: table-cell;
134 | font-size: 1.5em;
135 | height: 24px;
136 | vertical-align: middle;
137 | width: 200px;
138 | }
139 |
140 | #wiki_item_page {
141 | text-align: justify;
142 | font-size: 1.2em;
143 | background-color: #E6E6E6;
144 | padding: 10px;
145 | border-radius: 10px;
146 | -moz-border-radius: 10px;
147 | overflow: hidden;
148 | border: thin solid #9BCD9B;
149 | }
150 |
151 | .pagination {
152 | text-align: center;
153 | }
154 |
155 | .pagination .current {
156 | border-radius: 10px;
157 | -moz-border-radius: 10px;
158 | background-color: lightGrey;
159 | padding: 3px;
160 | }
161 |
162 | .pagination a, .pagination a:visited {
163 | color: black;
164 | }
165 |
--------------------------------------------------------------------------------
/site_media/files/projects/.gitignore:
--------------------------------------------------------------------------------
1 | DON'T DELETE THIS FILE!!
2 |
3 |
--------------------------------------------------------------------------------
/site_media/images/base/background_head.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/background_head.jpg
--------------------------------------------------------------------------------
/site_media/images/base/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/favicon.ico
--------------------------------------------------------------------------------
/site_media/images/base/feed.32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/feed.32x32.png
--------------------------------------------------------------------------------
/site_media/images/base/github.32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/github.32x32.png
--------------------------------------------------------------------------------
/site_media/images/base/icon_github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/icon_github.png
--------------------------------------------------------------------------------
/site_media/images/base/icon_lattes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/icon_lattes.png
--------------------------------------------------------------------------------
/site_media/images/base/icon_site.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/icon_site.png
--------------------------------------------------------------------------------
/site_media/images/base/icon_slideshare.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/icon_slideshare.png
--------------------------------------------------------------------------------
/site_media/images/base/icon_twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/icon_twitter.png
--------------------------------------------------------------------------------
/site_media/images/base/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/logo.png
--------------------------------------------------------------------------------
/site_media/images/base/news.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/news.png
--------------------------------------------------------------------------------
/site_media/images/base/planetaNSI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/planetaNSI.png
--------------------------------------------------------------------------------
/site_media/images/base/projects.32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/projects.32x32.png
--------------------------------------------------------------------------------
/site_media/images/base/projects.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/projects.png
--------------------------------------------------------------------------------
/site_media/images/base/tools.32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/tools.32x32.png
--------------------------------------------------------------------------------
/site_media/images/base/tools.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/base/tools.png
--------------------------------------------------------------------------------
/site_media/images/members/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/members/.gitignore
--------------------------------------------------------------------------------
/site_media/images/news/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/news/.gitignore
--------------------------------------------------------------------------------
/site_media/images/projects/.gitignore:
--------------------------------------------------------------------------------
1 | DON'T DELETE THIS FILE!!
2 |
3 |
--------------------------------------------------------------------------------
/site_media/images/wiki/add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/wiki/add.png
--------------------------------------------------------------------------------
/site_media/images/wiki/add_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/wiki/add_hover.png
--------------------------------------------------------------------------------
/site_media/images/wiki/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/wiki/back.png
--------------------------------------------------------------------------------
/site_media/images/wiki/delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/wiki/delete.png
--------------------------------------------------------------------------------
/site_media/images/wiki/delete_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/wiki/delete_hover.png
--------------------------------------------------------------------------------
/site_media/images/wiki/edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/wiki/edit.png
--------------------------------------------------------------------------------
/site_media/images/wiki/edit_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nsi-iff/nsi_site/a70056d227ea7404364583221b21e83498405b29/site_media/images/wiki/edit_hover.png
--------------------------------------------------------------------------------
/site_media/javascripts/coderwall.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Code to display coderwall.com badges
3 | */
4 |
5 | $(document).ready(function(){
6 | var member = $('#github_user').text();
7 | var coderwallJSONurl ="http://www.coderwall.com/" + member + ".json?callback=?";
8 | var height = 75;
9 | var width = 75;
10 |
11 | $.getJSON(coderwallJSONurl, function(data) {
12 | $("Coderwall Achievements
").appendTo("#coderwall");
13 | $.each(data.data.badges, function(i, item) {
14 | $(" ").attr("src", item.badge)
15 | .attr("float", "left")
16 | .attr("title", item.name + ": " + item.description)
17 | .attr("alt", item.name)
18 | .attr("height", height)
19 | .attr("width", width)
20 | .appendTo("#coderwall")
21 | .hover(
22 | function(){
23 | $(this).css("opacity","0.6");
24 | },
25 | function(){
26 | $(this).css("opacity","1.0");
27 | }
28 | )
29 | });
30 | });
31 | });
32 |
33 |
--------------------------------------------------------------------------------
/site_media/javascripts/github_activities.js:
--------------------------------------------------------------------------------
1 | // jQuery plugin to show github user's activities
2 | // https://github.com/bernardofire/github-activities
3 |
4 | (function($) {
5 | function parse(feed, container, settings) {
6 | if (feed.entries.length > 0) {
7 | $(feed.entries).each(function(key, entry){
8 | var content = entry.contentSnippet;
9 | //convert special chars and remove unnecessary " ..." from content
10 | var description = $(' ').html(content).text().trim().replace(new RegExp("[\n ]+...$"),'');
11 | var title = entry.title;
12 | if (settings.hide_username)
13 | title = title.replace(new RegExp('^' + entry.author + ' '), '');
14 | var li_entry = $(' ').text(title);
15 | var div_entry = $(' ').append(li_entry);
16 | div_entry.attr({
17 | 'href': entry.link,
18 | 'target': '_blank',
19 | 'title': description
20 | });
21 | $(container).append(div_entry);
22 | });
23 | }
24 | }
25 |
26 | $.fn.extend({
27 | activities:
28 | function(options) {
29 | var defaults = {
30 | 'username': '',
31 | 'hide_username': false,
32 | }
33 |
34 | var settings = $.extend(defaults, options);
35 |
36 | return this.each(function() {
37 | var container = $(this)
38 | $.ajax({
39 | url: 'http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=10&callback=?&q=' + encodeURIComponent('http://github.com/' + settings.username + '.atom'),
40 | async: true,
41 | dataType: 'json',
42 | success: function(data) {
43 | parse(data.responseData.feed, container, settings);
44 | }
45 | });
46 | });
47 | }
48 | });
49 | })(jQuery);
50 |
--------------------------------------------------------------------------------
/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {% block title %}NSI - Núcleo de Pesquisa em Sistemas de Informação{% endblock title %}
6 |
7 |
8 | {% block styles %}
9 |
10 | {% endblock styles %}
11 |
12 | {% block scripts %}
13 |
14 | {% endblock scripts %}
15 |
16 |
17 |
18 |
19 |
63 |
64 | {% block content %}
65 | {% endblock content %}
66 |
67 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/terrain.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 | import shutil
4 | from django.core.management import call_command
5 | from django.conf import settings
6 | from splinter.browser import Browser
7 | from lettuce import after, before, world
8 | from web_steps import *
9 |
10 |
11 | PROJECT_ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
12 |
13 | @before.harvest
14 | def initial_run_time(variables):
15 | world.time_before_harvest = time.time()
16 | test_directories_list = [
17 | os.path.join(PROJECT_ROOT_PATH, 'site_media', 'test', 'files', 'projects'),
18 | os.path.join(PROJECT_ROOT_PATH, 'site_media', 'test', 'images', 'members'),
19 | os.path.join(PROJECT_ROOT_PATH, 'site_media', 'test', 'images', 'news'),
20 | os.path.join(PROJECT_ROOT_PATH, 'site_media', 'test', 'images', 'projects'),
21 | os.path.join(PROJECT_ROOT_PATH, 'site_media', 'test', 'images', 'tools'),
22 | ]
23 |
24 | for directory in test_directories_list:
25 | if not os.path.exists(directory):
26 | os.makedirs(directory)
27 |
28 | @before.all
29 | def set_browser():
30 | world.browser = Browser()
31 |
32 | @before.each_scenario
33 | def clean_database(scenario):
34 | clean_data()
35 | clean_media()
36 |
37 | def clean_data():
38 | call_command('flush', interactive=False)
39 | call_command('loaddata', 'all')
40 |
41 | def clean_media():
42 | clean_media_by_kind('images')
43 | clean_media_by_kind('files')
44 |
45 | def clean_media_by_kind(kind, skip_dir=None):
46 | images_dir = os.path.join(settings.MEDIA_ROOT, 'test', kind)
47 | for file_name in os.listdir(images_dir):
48 | clean_all(os.path.join(images_dir, file_name))
49 |
50 | def clean_all(directory, skip_dir=None):
51 | for file_name in os.listdir(directory):
52 | absname = os.path.join(directory, file_name)
53 | if skip_dir and skip_dir in absname:
54 | pass
55 | elif os.path.isdir(absname) and file_name not in ['.', '..']:
56 | clean_all(absname)
57 | elif not file_name.startswith('.'):
58 | os.unlink(absname)
59 |
60 | @after.all
61 | def finish_him(total_result):
62 | world.browser.quit()
63 | clean_media()
64 |
65 | @after.harvest
66 | def run_time(results):
67 | shutil.rmtree(os.path.join(PROJECT_ROOT_PATH, 'site_media', 'test'))
68 | time_after_harvest = time.time()
69 | time_before_harvest = world.time_before_harvest
70 | total_time = int(time_after_harvest - time_before_harvest)
71 | minutes = total_time / 60
72 | seconds = total_time % 60
73 | total_features_ran = 0
74 | total_scenarios_ran = 0
75 | total_scenarios_passed = 0
76 | total_scenarios_failed = dict()
77 | for app in results:
78 | total_features_ran += app.features_ran
79 | total_scenarios_ran += app.scenarios_ran
80 | total_scenarios_passed += app.scenarios_passed
81 | for result in app.scenario_results:
82 | if result.passed == False:
83 | total_scenarios_failed.update({result.scenario.name: result.scenario.feature})
84 |
85 | print '\n================================================'
86 | print '=========== Acceptance tests results ===========\n'
87 | print '\033[32m\033[1m%i features ran.\033[0;0m' % total_features_ran
88 | print '\033[32m\033[1m%i scenarios ran.\033[0;0m' % total_scenarios_ran
89 | print '\033[32m\033[1m%i scenarios passed.\033[0;0m' % total_scenarios_passed
90 | if total_scenarios_failed:
91 | print '\033[31m\033[1mError in:\033[0;0m'
92 | for scenario, feature in total_scenarios_failed.iteritems():
93 | print '\033[31m\033[1m' + feature.name + ' ~> ' + scenario + '\033[0;0m'
94 | else:
95 | print '\033[32m\033[1mNo errors! Congratulations!\033[0;0m'
96 | print '----------------------------------------------------------------------'
97 | print 'Everything ran in %i minute(s) and %i second(s).' % (minutes, seconds)
98 |
99 |
--------------------------------------------------------------------------------
/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls.defaults import *
2 | from django.conf import settings
3 | from django.contrib import admin
4 |
5 |
6 | admin.autodiscover()
7 |
8 | urlpatterns = patterns('',
9 | (r'^admin/', include(admin.site.urls)),
10 |
11 | (r'^$', 'apps.home_page.views.show_index'),
12 |
13 | url(r'^', include('apps.news.urls')),
14 |
15 | (r'^sobre/$', 'apps.nsi_info.views.show_about'),
16 |
17 | url(r'^', include('apps.projects.urls')),
18 |
19 | url(r'^', include('apps.members.urls')),
20 |
21 | url(r'^', include('apps.tools.urls')),
22 |
23 | (r'^wiki/', include('apps.wiki.urls')),
24 |
25 | (r'^site_media/(.*)$', 'django.views.static.serve', {"document_root": settings.MEDIA_ROOT}),
26 | )
27 |
--------------------------------------------------------------------------------
/web_steps.py:
--------------------------------------------------------------------------------
1 | import re
2 | from lettuce import world, step
3 | from should_dsl import should
4 | from paths import path_to
5 |
6 |
7 | @step(r'I fill in "(.*)" with "(.*)"')
8 | def fill_field(step, label, value):
9 | world.browser.fill(label, value)
10 |
11 | @step(r'I go to "(.+)"')
12 | def i_go_to(step, page_name):
13 | world.browser.visit(path_to(page_name))
14 |
15 | @step(r'I press "(.*)"')
16 | def press_button(step, name):
17 | world.browser.find_by_name(name.lower()).click()
18 |
19 | @step(u'I click "(.*)"')
20 | def i_click(step, link):
21 | world.browser.find_link_by_text(link).first.click()
22 |
23 | # a "little" help from http://love-python.blogspot.com/2008/07/strip-html-tags-using-python.html
24 | def remove_html_tags(data):
25 | p = re.compile(r'<.*?>')
26 | return p.sub('', data)
27 |
28 | def remove_extra_spaces(data):
29 | p = re.compile(r'\s+')
30 | return p.sub(' ', data)
31 |
32 | @step(r'I should see "(.*)"$')
33 | def i_should_see(step, content):
34 | page_content = remove_extra_spaces(remove_html_tags(world.browser.html))
35 | page_content |should| contain(content)
36 |
37 | @step(u'I should have "(.*)" as HTML')
38 | def i_should_have_as_html(step, html_output):
39 | world.browser.html |should| contain(html_output)
40 |
41 | @step(u'I should see an image called "(.*)"')
42 | def and_i_should_see_an_image_called_group1(step, image_name):
43 | images = world.browser.find_by_css('img')
44 | found_image = [image for image in images if image['src'].endswith(image_name)]
45 | found_image |should| have_at_least(1).image
46 |
47 | @step(u'I should see a link to "(.*)" with label "(.*)"')
48 | def i_should_see_a_link_to_with_label(step, link_href, link_text):
49 | links = world.browser.find_link_by_text(link_text)
50 | links |should| have_at_least(1).item
51 | link = links[0]
52 | link['href'] |should| end_with(link_href)
53 |
54 | @step(u'I should see a link with text "(.*)"')
55 | def i_should_see_a_link_with_text(step, link_text):
56 | world.browser.find_link_by_text(link_text) |should| have(1).item
57 |
58 |
--------------------------------------------------------------------------------