From 9eaa28c80e5e49e2e22d673aed0ce22ac01b354d Mon Sep 17 00:00:00 2001 From: Thomas NOEL Date: Thu, 21 Apr 2011 03:06:46 +0200 Subject: [PATCH] premier jet --- .gitignore | 4 ++ __init__.py | 0 base/__init__.py | 0 base/admin.py | 32 +++++++++++ base/fixtures/initial_data.json | 10 ++++ base/models.py | 70 +++++++++++++++++++++++ base/tests.py | 23 ++++++++ base/views.py | 1 + manage.py | 11 ++++ settings.py | 99 +++++++++++++++++++++++++++++++++ urls.py | 14 +++++ 11 files changed, 264 insertions(+) create mode 100644 .gitignore create mode 100644 __init__.py create mode 100644 base/__init__.py create mode 100644 base/admin.py create mode 100644 base/fixtures/initial_data.json create mode 100644 base/models.py create mode 100644 base/tests.py create mode 100644 base/views.py create mode 100755 manage.py create mode 100644 settings.py create mode 100644 urls.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f901487 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.pyc +*.pyo +*.db +.*.swp diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/base/__init__.py b/base/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/base/admin.py b/base/admin.py new file mode 100644 index 0000000..0198a13 --- /dev/null +++ b/base/admin.py @@ -0,0 +1,32 @@ +from base.models import Feed, Item +from django.contrib import admin + +class FeedAdmin(admin.ModelAdmin): + list_display = ['name', 'url', 'parsed_date'] + ordering = ['parsed_date'] + actions = ['read_feed'] + + def read_feed(modeladmin, request, queryset): + for feed in queryset: + feed.read() + read_feed.short_description = "Read selected feeds" + +admin.site.register(Feed, FeedAdmin) + + +class ItemAdmin(admin.ModelAdmin): + list_display = ['mark', 'title_with_link', 'expire_date', 'published_date', 'source'] + list_filter = ['mark', 'source', 'expire_date'] + ordering = ['-expire_date'] + actions = ['mark_item', 'unmark_item'] + + def mark_item(modeladmin, request, queryset): + queryset.update(mark=True) + mark_item.short_description = "Mark selected items" + + def unmark_item(modeladmin, request, queryset): + queryset.update(mark=False) + unmark_item.short_description = "Unmark selected items" + +admin.site.register(Item, ItemAdmin) + diff --git a/base/fixtures/initial_data.json b/base/fixtures/initial_data.json new file mode 100644 index 0000000..da6c07b --- /dev/null +++ b/base/fixtures/initial_data.json @@ -0,0 +1,10 @@ +[ + { + "pk": 1, + "model": "base.feed", + "fields": { + "name": "e-marchespublics Fourniture", + "url": "http://www.e-marchespublics.com/rss/rss.php?v=2&l=10&c=Fourniture" + } + } +] diff --git a/base/models.py b/base/models.py new file mode 100644 index 0000000..7e86597 --- /dev/null +++ b/base/models.py @@ -0,0 +1,70 @@ +from django.db import models +import feedparser +import datetime +import re + +UNKNOWN_DATE = datetime.datetime(1970,1,1) + +class Feed(models.Model): + url = models.URLField() + name = models.CharField(max_length=200) + regex = models.CharField(max_length=500, default='.*(web|internet|logiciel|informati|grc|citoyen)') + regex_exclude = models.CharField(max_length=500, default='', blank=True) + add_date = models.DateTimeField(auto_now_add=True) + parsed_date = models.DateTimeField(default=UNKNOWN_DATE) + + def __unicode__(self): + return u'%s' % self.name + + def read(self): + added = 0 + feed = feedparser.parse(self.url) + re_in = re.compile(self.regex) + if self.regex_exclude != '': + print 'exclusion ON' + re_out = re.compile(self.regex_exclude) + else: + re_out = None + for e in feed.entries: + if re_in.match(e.title) or re_in.match(e.description): + if re_out != None: + if re_out.match(e.title) or re_out.match(e.description): + continue + print 'add item %s (%s)' % (e.title, e.link) + d = e.date_parsed + dt = datetime.datetime(d[0],d[1],d[2],d[3],d[4],d[5]) + try: + Item(title=e.title, + link=e.link, + published_date=dt, + expire_date=UNKNOWN_DATE, + description=e.description, + source=self).save() + added += 1 + except e,m: + print 'WARN : cannot add this (duplicate ?)' + raise e + self.parsed_date = datetime.datetime.now() + self.save() + return added + +class Item(models.Model): + # from feed + title = models.CharField(max_length=200) + link = models.URLField() + description = models.CharField(max_length=500) + published_date = models.DateTimeField() + # + source = models.ForeignKey(Feed) + add_date = models.DateTimeField(auto_now_add=True) + # user content + mark = models.BooleanField(default=False) + expire_date = models.DateTimeField(blank=True) + comments = models.CharField(max_length=1000, blank=True) + + def title_with_link(self): + return '%s' % (self.link, self.title) + title_with_link.short_description = "title" + title_with_link.allow_tags = True + title_with_link.admin_order_field = 'title' + diff --git a/base/tests.py b/base/tests.py new file mode 100644 index 0000000..2247054 --- /dev/null +++ b/base/tests.py @@ -0,0 +1,23 @@ +""" +This file demonstrates two different styles of tests (one doctest and one +unittest). These will both pass when you run "manage.py test". + +Replace these with more appropriate tests for your application. +""" + +from django.test import TestCase + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.failUnlessEqual(1 + 1, 2) + +__test__ = {"doctest": """ +Another way to test that 1 + 1 is equal to 2. + +>>> 1 + 1 == 2 +True +"""} + diff --git a/base/views.py b/base/views.py new file mode 100644 index 0000000..60f00ef --- /dev/null +++ b/base/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/manage.py b/manage.py new file mode 100755 index 0000000..bcdd55e --- /dev/null +++ b/manage.py @@ -0,0 +1,11 @@ +#!/usr/bin/python +from django.core.management import execute_manager +try: + import settings # Assumed to be in the same directory. +except ImportError: + import sys + 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__) + sys.exit(1) + +if __name__ == "__main__": + execute_manager(settings) diff --git a/settings.py b/settings.py new file mode 100644 index 0000000..c6f1fa9 --- /dev/null +++ b/settings.py @@ -0,0 +1,99 @@ +# Django settings for surveillao project. + +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +ADMINS = ( + # ('Your Name', 'your_email@domain.com'), +) + +MANAGERS = ADMINS + +import os +_PROJECT_PATH = os.path.join(os.path.dirname(__file__)) +_DATABASE_NAME = os.path.join(_PROJECT_PATH, 'surveillao.db') + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. + 'NAME': _DATABASE_NAME, # Or path to database file if using sqlite3. + 'USER': '', # Not used with sqlite3. + 'PASSWORD': '', # Not used with sqlite3. + 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. + 'PORT': '', # Set to empty string for default. Not used with sqlite3. + } +} + +# Local time zone for this installation. Choices can be found here: +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name +# although not all choices may be available on all operating systems. +# On Unix systems, a value of None will cause Django to use the same +# timezone as the operating system. +# If running in a Windows environment this must be set to the same as your +# system time zone. +TIME_ZONE = 'Europe/Paris' + +# Language code for this installation. All choices can be found here: +# http://www.i18nguy.com/unicode/language-identifiers.html +LANGUAGE_CODE = 'fr-fr' + +SITE_ID = 1 + +# If you set this to False, Django will make some optimizations so as not +# to load the internationalization machinery. +USE_I18N = True + +# If you set this to False, Django will not format dates, numbers and +# calendars according to the current locale +USE_L10N = True + +# Absolute path to the directory that holds media. +# Example: "/home/media/media.lawrence.com/" +MEDIA_ROOT = '' + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash if there is a path component (optional in other cases). +# Examples: "http://media.lawrence.com", "http://example.com/media/" +MEDIA_URL = '' + +# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a +# trailing slash. +# Examples: "http://foo.com/media/", "/media/". +ADMIN_MEDIA_PREFIX = '/media/' + +# Make this unique, and don't share it with anybody. +SECRET_KEY = 'zfo3_!k*ypj=2v)pte6(&_7=6up#fr@gpa-=t#%4vtsq%gre%s' + +# List of callables that know how to import templates from various sources. +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', +# 'django.template.loaders.eggs.Loader', +) + +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', +) + +ROOT_URLCONF = 'surveillao.urls' + +TEMPLATE_DIRS = ( + # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. +) + +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', + 'django.contrib.messages', + 'django.contrib.admin', + 'django.contrib.admindocs', + 'base', +) diff --git a/urls.py b/urls.py new file mode 100644 index 0000000..aacc978 --- /dev/null +++ b/urls.py @@ -0,0 +1,14 @@ +from django.conf.urls.defaults import * + +# enable the admin: +from django.contrib import admin +admin.autodiscover() + +urlpatterns = patterns('', + # Example: + # (r'^surveillao/', include('surveillao.foo.urls')), + # Uncomment the admin/doc line below to enable admin documentation: + # (r'^admin/doc/', include('django.contrib.admindocs.urls')), + + (r'^admin/', include(admin.site.urls)), +)