From 9c9796a5bd5ced3ebbe4e2b143906d0bce9f0024 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Wed, 16 May 2012 12:56:44 +0200 Subject: Fix RSS feeds for django 1.4 - reintegrate them in the main application --- chimere/actions.py | 4 +- chimere/admin.py | 5 +- chimere/feeds.py | 222 ++++++++++++++++++++ .../0024_auto__add_field_marker_available_date.py | 211 +++++++++++++++++++ chimere/models.py | 7 +- chimere/static/chimere/js/edit_area.js | 2 +- chimere/templates/chimere/contactus.html | 1 - chimere/templates/chimere/main_map.html | 2 +- chimere/tests.py | 105 +++++++--- chimere/urls.py | 16 ++ chimere/views.py | 126 ++++++++++- chimere/widgets.py | 4 +- chimere_rss/__init__.py | 1 - chimere_rss/feeds.py | 230 --------------------- chimere_rss/templates/rss.html | 73 ------- chimere_rss/templates/rss_descr.html | 8 - chimere_rss/templates/rss_title.html | 2 - chimere_rss/urls.py | 43 ---- chimere_rss/views.py | 140 ------------- example_project/extra-locales/chimere_rss | 1 - example_project/settings.py | 9 +- example_project/urls.py | 4 - 22 files changed, 662 insertions(+), 554 deletions(-) create mode 100644 chimere/feeds.py create mode 100644 chimere/migrations/0024_auto__add_field_marker_available_date.py delete mode 100644 chimere_rss/__init__.py delete mode 100644 chimere_rss/feeds.py delete mode 100644 chimere_rss/templates/rss.html delete mode 100644 chimere_rss/templates/rss_descr.html delete mode 100644 chimere_rss/templates/rss_title.html delete mode 100644 chimere_rss/urls.py delete mode 100644 chimere_rss/views.py delete mode 120000 example_project/extra-locales/chimere_rss diff --git a/chimere/actions.py b/chimere/actions.py index 4fe9bff..0363d54 100644 --- a/chimere/actions.py +++ b/chimere/actions.py @@ -34,8 +34,8 @@ actions = [(Action('view', '', _('View')), []), Action('edit-route', 'edit-route/', _('Add a new route'))), ),] -if 'chimere_rss' in settings.INSTALLED_APPS: - actions.append((Action('rss', 'rss', _('RSS feeds')), [])) +if settings.CHIMERE_FEEDS: + actions.append((Action('rss', 'feeds', _('RSS feeds')), [])) if settings.EMAIL_HOST: actions.append((Action('contact', 'contact', _('Contact us')), []),) diff --git a/chimere/admin.py b/chimere/admin.py index bfa90c5..060306f 100644 --- a/chimere/admin.py +++ b/chimere/admin.py @@ -98,10 +98,9 @@ class MarkerAdmin(admin.ModelAdmin): list_display = ('name', 'status') list_filter = ('status', 'categories') actions = [validate, export_to_kml, export_to_shapefile] - exclude = ['submiter_session_key', 'import_key', 'import_version'] + exclude = ['submiter_session_key', 'import_key', 'import_version', + 'available_date'] readonly_fields = ['submiter_email', 'submiter_comment', 'import_source'] - if 'chimere_rss' in settings.INSTALLED_APPS: - exclude.append('available_date') form = MarkerAdminForm inlines = [MultimediaInline, PictureInline] diff --git a/chimere/feeds.py b/chimere/feeds.py new file mode 100644 index 0000000..4fcef1e --- /dev/null +++ b/chimere/feeds.py @@ -0,0 +1,222 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2010 Pierre Clarenc , +# Samuel Renard , +# Étienne Loks + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# See the file COPYING for details. + +from django.conf import settings +from django.contrib.gis.geos import * +from django.contrib.syndication.views import Feed, FeedDoesNotExist +from django.core.exceptions import ObjectDoesNotExist +from django.utils.translation import ugettext as _ + +from django.shortcuts import get_object_or_404 + +from chimere.models import Category, SubCategory, Marker, Area + +class BaseFeed(Feed): + """ + Base feed for Chimere objects + """ + def item_link(self, item): + ''' Return POI permalink ''' + coord = item.point + cat = 0 + if item.categories.all() and item.categories.all()[0]: + cat = item.categories.all()[0].pk + return settings.BASE_URL + '?zoom=16&lat=%d&lon=%d¤t_feature=%d'\ + '&checked_categories=%d' % (coord.y, coord.x, item.id, cat) + + def item_pubdate(self, item): + """ + Date of the Marker when it has been available + """ + return item.available_date + + def description(self, obj): + return "" + +class LatestPOIsByCategory(BaseFeed): + ''' + Last Points of interests by category in Feeds + ''' + title_template = "rss_title.html" + description_template = "rss_descr.html" + + def get_object(self, request, category_id): + return get_object_or_404(Category, id=category_id) + + def title(self, obj): + """ + Define the title of the feed + """ + return u"%s - %s" % (settings.PROJECT_NAME, obj.name) + + def link(self, obj): + """ + Define the link of the feed. + """ + if not obj: + raise FeedDoesNotExist + return settings.BASE_URL + 'rss/category/' + str(obj.id) + + def items(self, obj): + """ + Requests to marker where its category match the category is requested + and its status is available + This returns a list of the 15 last markers/POIs ordering by date + """ + q = Marker.objects.filter(status__exact='A', + categories__category__id__exact=obj.id, + available_date__isnull=False).order_by('-available_date')[:15] + return q + +class LatestPOIsBySubCategory(BaseFeed): + ''' + Last Points of interests by SubCategory in Feeds + ''' + title_template = "rss_title.html" + description_template = "rss_descr.html" + + def get_object(self, request, category_id): + return get_object_or_404(SubCategory, id=category_id) + + def title(self, obj): + return u"%s - %s - %s" % (settings.PROJECT_NAME, obj.category.name, + obj.name) + + def link(self, obj): + if not obj: + raise FeedDoesNotExist + return settings.BASE_URL + 'rss/subcategory/' + str(obj.id) + + def items(self, obj): + q = Marker.objects.filter(categories__id__exact=obj.id, + available_date__isnull=False, status__exact='A').order_by( + '-available_date')[:15] + return q + +class LatestPOIs(BaseFeed): + ''' + Last Points of interests + ''' + title_template = "rss_title.html" + description_template = "rss_descr.html" + + def title(self): + return settings.PROJECT_NAME + u" - " + _(u"Last points of interest") + + def link(self): + return settings.BASE_URL + 'rss/categories/' + + def description(self): + return _("Latest points of interest from ") + settings.PROJECT_NAME + + def items(self): + q = Marker.objects.filter(status__exact='A', + available_date__isnull=False).order_by('-available_date')[:15] + return q + +class LatestPOIsByZone(BaseFeed): + ''' + Last Points of interests by zone by coordinates + ''' + title_template = "rss_title.html" + description_template = "rss_descr.html" + upper_left_lat = 0 + upper_left_lon = 0 + lower_right_lat = 0 + lower_right_lon = 0 + + def get_object(self, request, area): + """ + Get the extra url. Parameters are the coordinates of the zone (the + upper left and lower right points) + """ + if not area: + raise ObjectDoesNotExist + # Then define the upper right and lower left points + coordinates = str(area).split('_') + upper_left_lat = float(coordinates[0]) + upper_left_lon = float(coordinates[1]) + lower_right_lat = float(coordinates[2]) + lower_right_lon = float(coordinates[3]) + upper_right_lat = upper_left_lat + upper_right_lon = lower_right_lon + lower_left_lat = lower_right_lat + lower_left_lon = upper_left_lon + # Define a Polygon with the 4 points of the zone. + areaBox = Polygon(((upper_left_lon, upper_left_lat), + (upper_right_lon, upper_right_lat), + (lower_right_lon, lower_right_lat), + (lower_left_lon, lower_left_lat), + (upper_left_lon, upper_left_lat)), + srid=settings.EPSG_DISPLAY_PROJECTION) + return areaBox + + def title(self, obj): + return settings.PROJECT_NAME + u" - " +\ + _(u"Last points of interest by area") + + def link(self, obj): + """ + Define the link of the feed. It's the same url as we get in the method + get_object + """ + if not obj: + raise FeedDoesNotExist + return settings.BASE_URL + 'rss/area/' \ + + str(self.upper_left_lat) + '_' + str(self.upper_left_lon) + \ + '_' + str(self.lower_right_lat) + '_' + str(self.lower_right_lon) + + def items(self, obj): + """ + Request to return Markers WHERE there points are containes in the zone + which is requested. + This returns a list of the 15 last markers/POIs ordering by date + """ + q = Marker.objects.filter(point__contained=obj, status__exact='A', + available_date__isnull=False).order_by('-available_date')[:15] + return q + +class LatestPOIsByZoneID(BaseFeed): + ''' + Last Points of interests by zone by id + ''' + title_template = "rss_title.html" + description_template = "rss_descr.html" + + def get_object(self, request, area_id): + return get_object_or_404(Area, id=area_id) + + def title(self, obj): + return settings.PROJECT_NAME + u" - " + \ + _(u"Last points of interest") + u" - " + obj.name + + def link(self, obj): + if not obj: + raise FeedDoesNotExist + return settings.BASE_URL + 'rss/areaid/' + str(obj.id) + + def items(self, obj): + sql = 'select * from "chimere_marker" where ' + obj.getIncludeSql() + sql += ' and "chimere_marker".available_date is not null' + sql += ' and "chimere_marker".status=\'A\'' + sql += ' order by "chimere_marker".available_date desc limit 15' + q = Marker.objects.raw(sql) + return q diff --git a/chimere/migrations/0024_auto__add_field_marker_available_date.py b/chimere/migrations/0024_auto__add_field_marker_available_date.py new file mode 100644 index 0000000..78b5a68 --- /dev/null +++ b/chimere/migrations/0024_auto__add_field_marker_available_date.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Marker.available_date' + db.add_column('chimere_marker', 'available_date', + self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True), + keep_default=False) + + def backwards(self, orm): + # Deleting field 'Marker.available_date' + db.delete_column('chimere_marker', 'available_date') + + models = { + 'chimere.area': { + 'Meta': {'ordering': "('order', 'name')", 'object_name': 'Area'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'default_subcategories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False', 'blank': 'True'}), + 'external_css': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'layers': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'through': "orm['chimere.AreaLayers']", 'to': "orm['chimere.Layer']"}), + 'lower_right_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {}), + 'restrict_to_extent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'db_table': "'chimere_subcategory_areas'", 'to': "orm['chimere.SubCategory']"}), + 'upper_left_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}), + 'urn': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'blank': 'True'}), + 'welcome_message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + 'chimere.arealayers': { + 'Meta': {'ordering': "('order',)", 'object_name': 'AreaLayers'}, + 'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Area']"}), + 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'layer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Layer']"}), + 'order': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.category': { + 'Meta': {'ordering': "['order']", 'object_name': 'Category'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.color': { + 'Meta': {'ordering': "['order']", 'object_name': 'Color'}, + 'code': ('django.db.models.fields.CharField', [], {'max_length': '6'}), + 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.colortheme': { + 'Meta': {'object_name': 'ColorTheme'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'chimere.icon': { + 'Meta': {'object_name': 'Icon'}, + 'height': ('django.db.models.fields.IntegerField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'width': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.importer': { + 'Meta': {'object_name': 'Importer'}, + 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}), + 'filtr': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'importer_type': ('django.db.models.fields.CharField', [], {'max_length': '4'}), + 'source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'srid': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'zipped': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'chimere.layer': { + 'Meta': {'object_name': 'Layer'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'layer_code': ('django.db.models.fields.TextField', [], {'max_length': '300'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'chimere.marker': { + 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Marker'}, + 'available_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'point': ('chimere.widgets.PointField', [], {}), + 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_marker'", 'null': 'True', 'to': "orm['chimere.Marker']"}), + 'route': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'associated_marker'", 'null': 'True', 'to': "orm['chimere.Route']"}), + 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'submiter_comment': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}) + }, + 'chimere.multimediafile': { + 'Meta': {'object_name': 'MultimediaFile'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'multimedia_files'", 'to': "orm['chimere.Marker']"}), + 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.MultimediaType']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) + }, + 'chimere.multimediatype': { + 'Meta': {'object_name': 'MultimediaType'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'iframe': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'media_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'chimere.news': { + 'Meta': {'object_name': 'News'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'content': ('django.db.models.fields.TextField', [], {}), + 'date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'chimere.picturefile': { + 'Meta': {'object_name': 'PictureFile'}, + 'height': ('django.db.models.fields.IntegerField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pictures'", 'to': "orm['chimere.Marker']"}), + 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}), + 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), + 'width': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.property': { + 'Meta': {'object_name': 'Property'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'marker': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Marker']"}), + 'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.PropertyModel']"}), + 'value': ('django.db.models.fields.TextField', [], {}) + }, + 'chimere.propertymodel': { + 'Meta': {'ordering': "('order',)", 'object_name': 'PropertyModel'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '1'}) + }, + 'chimere.route': { + 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Route'}, + 'associated_file': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.RouteFile']", 'null': 'True', 'blank': 'True'}), + 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}), + 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_route'", 'null': 'True', 'to': "orm['chimere.Route']"}), + 'route': ('chimere.widgets.RouteField', [], {}), + 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'submiter_comment': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) + }, + 'chimere.routefile': { + 'Meta': {'ordering': "('name',)", 'object_name': 'RouteFile'}, + 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'raw_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + 'simplified_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}) + }, + 'chimere.subcategory': { + 'Meta': {'ordering': "['category', 'order']", 'object_name': 'SubCategory'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Category']"}), + 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']", 'null': 'True', 'blank': 'True'}), + 'icon': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Icon']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'item_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.tinyurl': { + 'Meta': {'object_name': 'TinyUrl'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'parameters': ('django.db.models.fields.CharField', [], {'max_length': '500'}) + } + } + + complete_apps = ['chimere'] \ No newline at end of file diff --git a/chimere/models.py b/chimere/models.py index c286422..8b15f29 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -289,9 +289,8 @@ class Marker(GeographicItem): verbose_name=_(u"Reference marker"), related_name='submited_marker') point = PointField(_(u"Localisation"), srid=settings.CHIMERE_EPSG_DISPLAY_PROJECTION) - if 'chimere_rss' in settings.INSTALLED_APPS: - available_date = models.DateTimeField(_(u"Available Date"), blank=True, - null=True) + available_date = models.DateTimeField(_(u"Available Date"), blank=True, + null=True) # used by feeds route = models.ForeignKey(u"Route", blank=True, null=True, related_name='associated_marker') description = models.TextField(_(u"Description"), blank=True, null=True) @@ -833,7 +832,7 @@ class Area(models.Model, SimpleArea): self.lower_right_corner.x, self.lower_right_corner.y, self.upper_left_corner.x, self.lower_right_corner.y, self.upper_left_corner.x, self.upper_left_corner.y, - settings.EPSG_DISPLAY_PROJECTION + settings.CHIMERE_EPSG_DISPLAY_PROJECTION ) sql = "ST_Contains(" + area + ", " + geometry + ")" return sql diff --git a/chimere/static/chimere/js/edit_area.js b/chimere/static/chimere/js/edit_area.js index 7695e6b..f22d6e3 100644 --- a/chimere/static/chimere/js/edit_area.js +++ b/chimere/static/chimere/js/edit_area.js @@ -1,4 +1,4 @@ -/* Copyright (C) 2008 Étienne Loks +/* Copyright (C) 2008-2012 Étienne Loks This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/chimere/templates/chimere/contactus.html b/chimere/templates/chimere/contactus.html index 4a44d77..cfb0d38 100644 --- a/chimere/templates/chimere/contactus.html +++ b/chimere/templates/chimere/contactus.html @@ -1,6 +1,5 @@ {% extends "chimere/base.html" %} {% load i18n chimere_tags %} -{% load i18n %} {% block extra_head %} {{ block.super }} {{ form.media }} diff --git a/chimere/templates/chimere/main_map.html b/chimere/templates/chimere/main_map.html index 3d1e016..02ffc5c 100644 --- a/chimere/templates/chimere/main_map.html +++ b/chimere/templates/chimere/main_map.html @@ -2,8 +2,8 @@ {% load i18n unlocalize_point chimere_tags %} {% block extra_head %} {{ block.super }} -{% head_chimere %} {% head_jquery %} +{% head_chimere %} {% head_jme %} {% endblock %} diff --git a/chimere/tests.py b/chimere/tests.py index 005cfcb..8ff3d25 100644 --- a/chimere/tests.py +++ b/chimere/tests.py @@ -1,42 +1,73 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import datetime +import lxml.etree import os test_path = os.path.abspath(__file__) test_dir_path = os.path.dirname(test_path) + os.sep from django.conf import settings +from django.core.urlresolvers import reverse from django.test import TestCase -from chimere.models import Icon, Importer, Category, SubCategory, Marker +from chimere.models import Area, Icon, Importer, Category, SubCategory, Marker + +def area_setup(): + area_1 = Area.objects.create(name='area 1', order=1, available=True, + upper_left_corner='SRID=4326;POINT(-4.907753 48.507656)', + lower_right_corner='SRID=4326;POINT(-4.049447 48.279688)') + return area_1 + +def subcategory_setup(): + category = Category.objects.create(name='Main category', + available=True, + order=1, + description='') + + icon = Icon.objects.create(name='Default icon', + image='icons/marker.png', + height=25, + width=21) + + subcategory_1 = SubCategory.objects.create(category=category, + name='Subcategory 1', + available=True, + icon=icon, + order=1, + item_type='M',) + + subcategory_2 = SubCategory.objects.create(category=category, + name='Subcategory 2', + available=True, + icon=icon, + order=1, + item_type='M',) + return [subcategory_1, subcategory_2] + +def marker_setup(sub_categories=[]): + if not sub_categories: + sub_categories = subcategory_setup() + current_date = datetime.datetime.now() + markers = [] + marker_1 = Marker.objects.create(name="Marker 1", status='A', + point='SRID=4326;POINT(-4.5 48.4)', + available_date=current_date) + marker_1.categories.add(sub_categories[0]) + markers.append(marker_1) + marker_2 = Marker.objects.create(name="Marker 2", status='A', + point='SRID=4326;POINT(-3.5 48.4)', + available_date=current_date) + marker_2.categories.add(sub_categories[1]) + markers.append(marker_2) + marker_3 = Marker.objects.create(name="Marker 3", status='A', + point='SRID=4326;POINT(-4.5 48.45)', + available_date=current_date - datetime.timedelta(days=60)) + marker_3.categories.add(sub_categories[1]) + markers.append(marker_3) + return markers class ImporterTest: - def _baseSetUp(self): - category = Category.objects.create(name='Main category', - available=True, - order=1, - description='') - - icon = Icon.objects.create(name='Default icon', - image='icons/marker.png', - height=25, - width=21) - - subcategory_1 = SubCategory.objects.create(category=category, - name='Subcategory 1', - available=True, - icon=icon, - order=1, - item_type='M',) - - subcategory_2 = SubCategory.objects.create(category=category, - name='Subcategory 2', - available=True, - icon=icon, - order=1, - item_type='M',) - return [subcategory_1, subcategory_2] - def test_get(self): nb_by_cat = {} for importer, awaited_nb in self.marker_importers: @@ -63,7 +94,7 @@ class ImporterTest: class KMLImporterTest(TestCase, ImporterTest): def setUp(self): - subcategory_1, subcategory_2 = self._baseSetUp() + subcategory_1, subcategory_2 = subcategory_setup() importer1 = Importer.objects.create(importer_type='KML', source=test_dir_path+'tests/sample.kml', filtr="Category 1") @@ -89,7 +120,7 @@ class KMLImporterTest(TestCase, ImporterTest): class ShapefileImporterTest(TestCase, ImporterTest): def setUp(self): - subcategory_1, subcategory_2 = self._baseSetUp() + subcategory_1, subcategory_2 = subcategory_setup() importer = Importer.objects.create(importer_type='SHP', source=test_dir_path+'tests/sample.shp.zip', zipped=True) importer.categories.add(subcategory_1) @@ -98,7 +129,8 @@ class ShapefileImporterTest(TestCase, ImporterTest): class OSMImporterTest(TestCase, ImporterTest): def setUp(self): - subcategory_1, subcategory_2 = self._baseSetUp() + subcategory_1, subcategory_2 = subcategory_setup() + markers = marker_setup() importer1 = Importer.objects.create(importer_type='OSM', source='OSM', filtr="node[amenity=pub]"\ @@ -107,3 +139,16 @@ class OSMImporterTest(TestCase, ImporterTest): self.marker_importers = [(importer1, None)] +class FeedsTest(TestCase): + def setUp(self): + self.area = area_setup() + self.markers = marker_setup() + + def test_rss(self): + # global + url = reverse('chimere:feeds-global') + response = self.client.get(url) + self.assertEqual(200, response.status_code) + doc = lxml.etree.fromstring(response.content) + self.assertEqual(int(doc.xpath('count(//item)')), len(self.markers)) + diff --git a/chimere/urls.py b/chimere/urls.py index d7c4463..197eb09 100644 --- a/chimere/urls.py +++ b/chimere/urls.py @@ -23,6 +23,8 @@ from django.contrib import admin admin.autodiscover() from chimere.models import Area +from chimere.feeds import LatestPOIsByCategory, LatestPOIsBySubCategory, \ + LatestPOIs, LatestPOIsByZone, LatestPOIsByZoneID def i18n_javascript(request): return admin.site.i18n_javascript(request) @@ -33,6 +35,20 @@ urlpatterns = patterns('chimere.views', name="simple_index") ) +if settings.CHIMERE_FEEDS: + urlpatterns = patterns('', + url(r'^feeds$', 'chimere.views.rss', name='feeds-form'), + url(r'^feeds/category/(?P\d+)$', LatestPOIsByCategory(), + name='feeds-cat'), + url(r'^feeds/subcategory/(?P\d+)$', + LatestPOIsBySubCategory(), name='feeds-subcat'), + url(r'^feeds/global/$', LatestPOIs(), name='feeds-global'), + url(r'^feeds/area/(?P[0-9-_.]+)$', LatestPOIs(), + name='feeds-area'), + url(r'^feeds/areaid/(?P\d+)$', LatestPOIsByZoneID(), + name='feeds-areaid'), + ) + urlpatterns += patterns('chimere.views', url(r'^charte/?$', 'charte', name="charte"), url(r'^(?P\w+)?/?contact/?$', 'contactus', name="contact"), diff --git a/chimere/views.py b/chimere/views.py index 371731d..891078e 100644 --- a/chimere/views.py +++ b/chimere/views.py @@ -1,6 +1,9 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (C) 2008-2012 Étienne Loks +# +# RSS : Copyright (C) 2010 Pierre Clarenc , +# Samuel Renard , # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as @@ -41,10 +44,10 @@ from chimere.models import Category, SubCategory, PropertyModel, \ Marker, Route, News, SimpleArea, Area, Color, TinyUrl, RouteFile from chimere.widgets import getMapJS, PointChooserWidget, \ - RouteChooserWidget + RouteChooserWidget, AreaWidget from chimere.forms import MarkerForm, RouteForm, ContactForm, FileForm, \ FullFileForm, MultimediaFileFormSet, PictureFileFormSet, notifySubmission,\ - notifyStaff + notifyStaff, AreaForm #TODO: convert to requestcontext def get_base_response(area_name=""): @@ -592,3 +595,122 @@ def redirectFromTinyURN(request, area_name='', tiny_urn=''): if redir: return redir return HttpResponseRedirect(response_dct['extra_url'] + parameters) + +def rss(request, area_name=''): + ''' + Redirect to RSS subscription page + ''' + response_dct, redir = get_base_response(area_name) + if redir: + return redir + response_dct.update({'actions':actions, 'action_selected':('rss',), + 'category_rss_feed':'',}) + # If the form has been submited + if request.method == "POST": + # User has defined the kind of POI he is interested in : POI in a area + # (GET method is used for the link with RSS icon in the browser) + if 'rss_category' in request.POST: + #User wants to follow all the new POI + if request.POST['rss_category'] == 'global': + feeds_link = reverse('chimere:feeds-global') + return redirect(feeds_link) + # User wants to follow all the new POI by category or subcategory + elif request.POST['rss_category'] == 'poi': + response_dct['category_rss_feed'] = 'category' + response_dct['sub_categories'] = SubCategory.getAvailable() + return render_to_response('chimere/feeds/rss.html', + response_dct, + context_instance=RequestContext(request)) + # User wants to follow all the new POI situated in a defined area + elif request.POST['rss_category'] == 'area': + # An unbound form + form = AreaForm() + area_widget = AreaWidget().render('area', None) + response_dct.update({ + 'map_layer':settings.CHIMERE_DEFAULT_MAP_LAYER, + 'extra_head':form.media, + 'form':form, + 'category_rss_feed':'area', + 'area_id':Area.getAvailable(), + 'area_widget':area_widget + }) + return render_to_response('chimere/feeds/rss.html', + response_dct, + context_instance=RequestContext(request)) + # Error when submitting the form + else: + error = _("Incorrect choice in the list") + response_dct.update({'error_message':error, + 'category_rss_feed':'', + 'sub_categories':SubCategory.getAvailable()}) + return render_to_response('chimere/feeds/rss.html', + response_dct, + context_instance=RequestContext(request)) + + # User has specified the category or subcategory he wants to follow => + # we redirect him towards the related rss feed + if 'subcategory' in request.POST and request.POST['subcategory'] != '': + cat_id = request.POST['subcategory'] + if cat_id.find("cat_") != -1 : + cat_id = cat_id.split('_')[1] + feeds_link = reverse('chimere:feeds-cat', + kwargs={'category_id':cat_id}) + return redirect(feeds_link) + + else: + feeds_link = reverse('chimere:feeds-subcat', + kwargs={'category_id':cat_id}) + return redirect(feeds_link) + + # User has specified the ID of the area he wants to follow + if 'id_area' in request.POST and request.POST['id_area'] != '': + feeds_link = reverse('chimere:feeds-areaid', + kwargs={'area_id':request.POST['id_area']}) + return redirect(feeds_link) + + # User has specified the area he wants to follow => we redirect him + # towards the related rss feed (using upper left and lower right + # coordinates) + elif 'upper_left_lat' in request.POST and \ + request.POST['upper_left_lat'] != '' and \ + 'upper_left_lon' in request.POST and \ + request.POST['upper_left_lon'] != '' and \ + 'lower_right_lon' in request.POST and \ + request.POST['lower_right_lon'] != '' and \ + 'lower_right_lat' in request.POST and \ + request.POST['lower_right_lat'] != '' : + coords = request.POST['upper_left_lat'] + '_' + \ + request.POST['upper_left_lon'] + '_' + \ + request.POST['lower_right_lat'] + '_' + \ + request.POST['lower_right_lon'] + feeds_link = reverse('chimere:feeds-area', + kwargs={'area':coords}) + return redirect(feeds_link) + + # GET method is used for linking with the RSS icon in the browser when user + # wants to choose a category to follow + elif request.method == "GET" and 'rss_category' in request.GET: + if request.GET['rss_category'] == 'global': + feeds_link = reverse('chimere:feeds-global') + return redirect(feeds_link) + if request.GET['rss_category'] == 'poi': + response_dct['category_rss_feed'] = 'category' + response_dct['sub_categories'] = SubCategory.getAvailable(['M','B']) + return render_to_response('chimere/feeds/rss.html', response_dct, + context_instance=RequestContext(request)) + if request.GET['rss_category'] == 'area': + # An unbound form + form = AreaForm() + response_dct.update({'map_layer':settings.MAP_LAYER, + 'extra_head':form.media, + 'form':form, + 'category_rss_feed':'area', + 'area_id':Area.getAvailable(), + 'area_widget':AreaWidget().render('area', None)}) + return render_to_response('chimere/feeds/rss.html', response_dct, + context_instance=RequestContext(request)) + + # User access to the RSS tab + else: + return render_to_response('chimere/feeds/rss.html', response_dct, + context_instance=RequestContext(request)) diff --git a/chimere/widgets.py b/chimere/widgets.py index e9a391e..da4ff26 100644 --- a/chimere/widgets.py +++ b/chimere/widgets.py @@ -361,13 +361,13 @@ class AreaWidget(forms.TextInput): u"\n" % ( upper_left_lat, upper_left_lon, lower_right_lat, lower_right_lon) - tpl += u"\n
\n" + tpl += u"\n
\n" return mark_safe(tpl) def value_from_datadict(self, data, files, name): diff --git a/chimere_rss/__init__.py b/chimere_rss/__init__.py deleted file mode 100644 index 792d600..0000000 --- a/chimere_rss/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/chimere_rss/feeds.py b/chimere_rss/feeds.py deleted file mode 100644 index 454b6ef..0000000 --- a/chimere_rss/feeds.py +++ /dev/null @@ -1,230 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (C) 2010 Pierre Clarenc , -# Samuel Renard , -# Étienne Loks - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# See the file COPYING for details. - -from django.utils.translation import ugettext as _ -from django.contrib.syndication.feeds import Feed -from django.contrib.syndication.feeds import FeedDoesNotExist -from chimere.main.models import Category, SubCategory, Marker, Area -from django.core.exceptions import ObjectDoesNotExist -from django.contrib.gis.geos import * - -from django.conf import settings - -class BaseFeed(Feed): - """ - Base feed for Chimere objects - """ - def item_link(self, item): - ''' Return POI permalink ''' - coord = item.point - cat = 0 - if item.categories.all() and item.categories.all()[0]: - cat = item.categories.all()[0].pk - return settings.BASE_URL + '?zoom=16&lat=%d&lon=%d¤t_feature=%d&\ -checked_categories=%d' % (coord.y, coord.x, item.id, cat) - - def item_pubdate(self, item): - """ - Date of the Marker when it has been available - """ - return item.available_date - - def description(self, obj): - return "" - -class LatestPOIsByCategory(BaseFeed): - ''' - Last Points of interests by category in Feeds - ''' - title_template = "rss_title.html" - description_template = "rss_descr.html" - - def get_object(self, bits): - """ - Get extra url, after rss/category/ id of category - """ - if len(bits) != 1: - raise ObjectDoesNotExist - return Category.objects.get(id__exact=bits[0]) - - def title(self, obj): - """ - Define the title of the feed - """ - return u"%s - %s" % (settings.PROJECT_NAME, obj.name) - - def link(self, obj): - """ - Define the link of the feed. - """ - if not obj: - raise FeedDoesNotExist - return settings.BASE_URL + 'rss/category/' + str(obj.id) - - def items(self, obj): - """ - Requests to marker where its category match the category is requested - and its status is available - This returns a list of the 15 last markers/POIs ordering by date - """ - q = Marker.objects.filter(status__exact='A', - categories__category__id__exact=obj.id, - available_date__isnull=False).order_by('-available_date')[:15] - return q - -class LatestPOIsBySubCategory(BaseFeed): - ''' - Last Points of interests by SubCategory in Feeds - ''' - title_template = "rss_title.html" - description_template = "rss_descr.html" - - def get_object(self, bits): - if len(bits) != 1: - raise ObjectDoesNotExist - return SubCategory.objects.get(id__exact=bits[0]) - - def title(self, obj): - return u"%s - %s - %s" % (settings.PROJECT_NAME, obj.category.name, - obj.name) - - def link(self, obj): - if not obj: - raise FeedDoesNotExist - return settings.BASE_URL + 'rss/subcategory/' + str(obj.id) - - def items(self, obj): - q = Marker.objects.filter(categories__id__exact=obj.id, - available_date__isnull=False, status__exact='A').order_by( - '-available_date')[:15] - return q - -class LatestPOIs(BaseFeed): - ''' - Last Points of interests - ''' - title_template = "rss_title.html" - description_template = "rss_descr.html" - - def title(self): - return settings.PROJECT_NAME + u" - " + _(u"Last points of interest") - - def link(self): - return settings.BASE_URL + 'rss/categories/' - - def description(self): - return _("Latest points of interest from ") + settings.PROJECT_NAME - - def items(self): - q = Marker.objects.filter(status__exact='A', - available_date__isnull=False).order_by('-available_date')[:15] - return q - -class LatestPOIsByZone(BaseFeed): - ''' - Last Points of interests by zone by coordinates - ''' - title_template = "rss_title.html" - description_template = "rss_descr.html" - upper_left_lat = 0 - upper_left_lon = 0 - lower_right_lat = 0 - lower_right_lon = 0 - - def get_object(self, bits): - """ - Get the extra url. Parameters are the coordinates of the zone (the - upper left and lower right points) - """ - if len(bits) != 1: - raise ObjectDoesNotExist - # Then define the upper right and lower left points - coordinates = str(bits[0]).split('_') - upper_left_lat = float(coordinates[0]) - upper_left_lon = float(coordinates[1]) - lower_right_lat = float(coordinates[2]) - lower_right_lon = float(coordinates[3]) - upper_right_lat = upper_left_lat - upper_right_lon = lower_right_lon - lower_left_lat = lower_right_lat - lower_left_lon = upper_left_lon - # Define a Polygon with the 4 points of the zone. - areaBox = Polygon(((upper_left_lon, upper_left_lat), - (upper_right_lon, upper_right_lat), - (lower_right_lon, lower_right_lat), - (lower_left_lon, lower_left_lat), - (upper_left_lon, upper_left_lat)), - srid=settings.EPSG_DISPLAY_PROJECTION) - return areaBox - - def title(self, obj): - return settings.PROJECT_NAME + u" - " +\ - _(u"Last points of interest by area") - - def link(self, obj): - """ - Define the link of the feed. It's the same url as we get in the method - get_object - """ - if not obj: - raise FeedDoesNotExist - return settings.BASE_URL + 'rss/area/' \ - + str(self.upper_left_lat) + '_' + str(self.upper_left_lon) + \ - '_' + str(self.lower_right_lat) + '_' + str(self.lower_right_lon) - - def items(self, obj): - """ - Request to return Markers WHERE there points are containes in the zone - which is requested. - This returns a list of the 15 last markers/POIs ordering by date - """ - q = Marker.objects.filter(point__contained=obj, status__exact='A', - available_date__isnull=False).order_by('-available_date')[:15] - return q - -class LatestPOIsByZoneID(BaseFeed): - ''' - Last Points of interests by zone by id - ''' - title_template = "rss_title.html" - description_template = "rss_descr.html" - - def get_object(self, bits): - if len(bits) != 1: - raise ObjectDoesNotExist - return Area.objects.get(id__exact=bits[0]) - - def title(self, obj): - return settings.PROJECT_NAME + u" - " + \ - _(u"Last points of interest") + u" - " + obj.name - - def link(self, obj): - if not obj: - raise FeedDoesNotExist - return settings.BASE_URL + 'rss/areaid/' + str(obj.id) - - def items(self, obj): - sql = 'select * from "main_marker" where ' + obj.getIncludeSql() - sql += ' and "main_marker".available_date is not null' - sql += ' and "main_marker".status=\'A\'' - sql += ' order by "main_marker".available_date desc limit 15' - q = Marker.objects.raw(sql) - return q diff --git a/chimere_rss/templates/rss.html b/chimere_rss/templates/rss.html deleted file mode 100644 index 0c895ed..0000000 --- a/chimere_rss/templates/rss.html +++ /dev/null @@ -1,73 +0,0 @@ -{% extends "base.html" %} -{% load i18n %} - -{% block sidebar %} -{% endblock %} - -{% block content %} -
-
-{% trans "Subscribe to RSS feed" %} - -

{{ error_message }}

- -
-{%if not category_rss_feed %} -
- - -
-{% endif %} - -{%ifequal category_rss_feed "category" %} -

{% trans "New points of interest by category" %}

-
- - -
-{% endifequal %} - -{%ifequal category_rss_feed "area" %} -

{% trans "New points of interest by area" %}

-{% if area_id %} -
- - -
- -
- -
-{% endif %} -
- -
- {{form.area}} -
-
-

-{% endifequal %} - -
- -
-
-{% endblock %} diff --git a/chimere_rss/templates/rss_descr.html b/chimere_rss/templates/rss_descr.html deleted file mode 100644 index 4f75ac6..0000000 --- a/chimere_rss/templates/rss_descr.html +++ /dev/null @@ -1,8 +0,0 @@ -{% load i18n %} -{% load sanitize %} -
-{% if obj.picture %}{{obj.name}}{%endif%} -
{% for property in obj.getProperties %} -

{{ property.value|sanitize:"p b i br hr strong em span:style a:href:target ul li ol h1 h2 h3 h4"|safe }}

-{% endfor %}
-
diff --git a/chimere_rss/templates/rss_title.html b/chimere_rss/templates/rss_title.html deleted file mode 100644 index 5b379e7..0000000 --- a/chimere_rss/templates/rss_title.html +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{{ obj.name }} diff --git a/chimere_rss/urls.py b/chimere_rss/urls.py deleted file mode 100644 index 915c1cc..0000000 --- a/chimere_rss/urls.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (C) 2010 Pierre Clarenc , -# Samuel Renard , -# Copyright (C) 2010-2012 -# Étienne Loks - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# See the file COPYING for details. - - -from django.conf.urls.defaults import * - -from chimere_rss.feeds import LatestPOIsByCategory, LatestPOIsBySubCategory, \ - LatestPOIs, LatestPOIsByZone, LatestPOIsByZoneID - - -feeds = { - 'category': LatestPOIsByCategory, - 'subcategory': LatestPOIsBySubCategory, - 'global': LatestPOIs, - 'area': LatestPOIsByZone, - 'areaid': LatestPOIsByZoneID -} - -urlpatterns = patterns('', - (r'$', 'chimere_rss.views.rss'), - (r'/(?P.*)/$', - 'django.contrib.syndication.views.feed', {'feed_dict': feeds}), -) - diff --git a/chimere_rss/views.py b/chimere_rss/views.py deleted file mode 100644 index 1d6381d..0000000 --- a/chimere_rss/views.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (C) 2010 Pierre Clarenc , -# Samuel Renard , -# Étienne Loks - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# See the file COPYING for details. - -""" -Views of the project -""" - -from django.shortcuts import render_to_response -from django.http import HttpResponseRedirect -from django.utils.translation import ugettext as _ - -from chimere import settings -from chimere.main.views import get_base_response -from chimere.main.actions import actions -from chimere.main.models import SubCategory,Area -from chimere.main.forms import AreaForm -from chimere.main.widgets import AreaWidget - -def rss(request, area_name=''): - ''' - Redirect to RSS subscription page - ''' - response_dct = get_base_response() - response_dct.update({'actions':actions, 'action_selected':('rss',), - 'category_rss_feed':'',}) - # If the form has been submited - if request.method == "POST": - # User has defined the kind of POI he is interested in : POI in a area - # (GET method is used for the link with RSS icon in the browser) - if 'rss_category' in request.POST: - #User wants to follow all the new POI - if request.POST['rss_category'] == 'global': - feeds_link = '/' + settings.EXTRA_URL + 'rss/global/' - return HttpResponseRedirect(feeds_link) - # User wants to follow all the new POI by category or subcategory - elif request.POST['rss_category'] == 'poi': - response_dct['category_rss_feed'] = 'category' - response_dct['sub_categories'] = SubCategory.getAvailable() - return render_to_response('rss.html', response_dct) - # User wants to follow all the new POI situated in a defined area - elif request.POST['rss_category'] == 'area': - # An unbound form - form = AreaForm() - area_widget = AreaWidget().render('area', None) - response_dct.update({'map_layer':settings.MAP_LAYER, - 'extra_head':form.media, - 'form':form, - 'category_rss_feed':'area', - 'area_id':Area.getAvailable(), - 'area_widget':area_widget - }) - return render_to_response('rss.html', response_dct) - # Error when submitting the form - else: - error = _("Incorrect choice in the list") - response_dct.update({'error_message':error, - 'category_rss_feed':'', - 'sub_categories':SubCategory.getAvailable()}) - return render_to_response('rss.html', response_dct) - - # User has specified the category or subcategory he wants to follow => - # we redirect him towards the related rss feed - if 'subcategory' in request.POST and request.POST['subcategory'] != '': - idCat = request.POST['subcategory'] - if idCat.find("cat_") != -1 : - list_Cat = idCat.split('_') - feeds_link = '/' + settings.EXTRA_URL + 'rss/category/' - feeds_link += list_Cat[1] - return HttpResponseRedirect(feeds_link) - - else: - feeds_link = '/' + settings.EXTRA_URL + 'rss/subcategory/' + \ - idCat - return HttpResponseRedirect(feeds_link) - - # User has specified the ID of the area he wants to follow - if 'id_area' in request.POST and request.POST['id_area'] != '': - feeds_link = '/' + settings.EXTRA_URL + 'rss/areaid/' \ - + request.POST['id_area'] - return HttpResponseRedirect(feeds_link) - - # User has specified the area he wants to follow => we redirect him - # towards the related rss feed (using upper left and lower right - # coordinates) - elif 'upper_left_lat' in request.POST and \ - request.POST['upper_left_lat'] != '' and \ - 'upper_left_lon' in request.POST and \ - request.POST['upper_left_lon'] != '' and \ - 'lower_right_lon' in request.POST and \ - request.POST['lower_right_lon'] != '' and \ - 'lower_right_lat' in request.POST and \ - request.POST['lower_right_lat'] != '' : - feeds_link = '/' + settings.EXTRA_URL + 'rss/area/' + \ -request.POST['upper_left_lat'] + '_' + request.POST['upper_left_lon'] + '_' + \ -request.POST['lower_right_lat'] + '_' + request.POST['lower_right_lon'] - return HttpResponseRedirect(feeds_link) - - - # GET method is used for linking with the RSS icon in the browser when user - # wants to choose a category to follow - elif request.method == "GET" and 'rss_category' in request.GET: - if request.GET['rss_category'] == 'global': - feeds_link = '/' + settings.EXTRA_URL + 'rss/global/' - return HttpResponseRedirect(feeds_link) - if request.GET['rss_category'] == 'poi': - response_dct['category_rss_feed'] = 'category' - response_dct['sub_categories'] = SubCategory.getAvailable(['M','B']) - return render_to_response('rss.html', response_dct) - if request.GET['rss_category'] == 'area': - # An unbound form - form = AreaForm() - response_dct.update({'map_layer':settings.MAP_LAYER, - 'extra_head':form.media, - 'form':form, - 'category_rss_feed':'area', - 'area_id':Area.getAvailable(), - 'area_widget':AreaWidget().render('area', None)}) - return render_to_response('rss.html', response_dct) - - # User access to the RSS tab - else: - return render_to_response('rss.html', response_dct) diff --git a/example_project/extra-locales/chimere_rss b/example_project/extra-locales/chimere_rss deleted file mode 120000 index 1a8285a..0000000 --- a/example_project/extra-locales/chimere_rss +++ /dev/null @@ -1 +0,0 @@ -../../chimere_rss/ \ No newline at end of file diff --git a/example_project/settings.py b/example_project/settings.py index ddd8261..82c4454 100644 --- a/example_project/settings.py +++ b/example_project/settings.py @@ -54,6 +54,8 @@ CHIMERE_DISPLAY_AREAS = True # don't forget to run the upgrade.py script to create appropriate fields in # the database CHIMERE_DAYS_BEFORE_EVENT = 30 +# allow feeds +CHIMERE_FEEDS = True CHIMERE_ICON_WIDTH = 21 CHIMERE_ICON_HEIGHT = 25 @@ -180,15 +182,10 @@ INSTALLED_APPS = ( 'djcelery', 'south', 'chimere', - # activate it if you want to use migration scripts + # activate it if you want to use old migration scripts #'chimere.scripts', - # activate it if you want to use RSS feeds - #'chimere_rss' ) -if 'chimere_rss' in INSTALLED_APPS: - TEMPLATE_DIRS.append(ROOT_PATH + 'chimere_rss/templates') - LOGGING = {'version': 1, 'disable_existing_loggers': False, 'handlers': { diff --git a/example_project/urls.py b/example_project/urls.py index 6dc5e32..a49cb4f 100644 --- a/example_project/urls.py +++ b/example_project/urls.py @@ -30,10 +30,6 @@ urlpatterns = patterns('django.views.static', ) urlpatterns += staticfiles_urlpatterns() -if 'chimere_rss' in settings.INSTALLED_APPS: - urlpatterns += patterns('', - url(r'^feeds/', include('chimere_rss.urls', namespace="chimere-rss")),) - urlpatterns += patterns('', (r'^admin/doc/', include('django.contrib.admindocs.urls')), (r'^admin/', include(admin.site.urls)), -- cgit v1.2.3