diff --git a/BUGS b/BUGS deleted file mode 100644 index bb82d53..0000000 --- a/BUGS +++ /dev/null @@ -1,4 +0,0 @@ -Infinite loop: -- qca-cyrus-sasl-2.0.0-beta3 http://delta.affinix.com/download/qca/2.0/plugins/qca-cyrus-sasl-2.0.0-beta3.tar.bz2 -- alsamixer -- patchself diff --git a/euscanwww/annoying/__init__.py b/euscanwww/annoying/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/euscanwww/annoying/__init__.pyc b/euscanwww/annoying/__init__.pyc new file mode 100644 index 0000000..6915190 Binary files /dev/null and b/euscanwww/annoying/__init__.pyc differ diff --git a/euscanwww/annoying/decorators.py b/euscanwww/annoying/decorators.py new file mode 100644 index 0000000..86655c5 --- /dev/null +++ b/euscanwww/annoying/decorators.py @@ -0,0 +1,194 @@ +from django.shortcuts import render_to_response +from django import forms +from django.template import RequestContext +from django.db.models import signals as signalmodule +from django.http import HttpResponse +from django.utils import simplejson + +__all__ = ['render_to', 'signals', 'ajax_request', 'autostrip'] + + +try: + from functools import wraps +except ImportError: + def wraps(wrapped, assigned=('__module__', '__name__', '__doc__'), + updated=('__dict__',)): + def inner(wrapper): + for attr in assigned: + setattr(wrapper, attr, getattr(wrapped, attr)) + for attr in updated: + getattr(wrapper, attr).update(getattr(wrapped, attr, {})) + return wrapper + return inner + + +def render_to(template=None, mimetype=None): + """ + Decorator for Django views that sends returned dict to render_to_response + function. + + Template name can be decorator parameter or TEMPLATE item in returned + dictionary. RequestContext always added as context instance. + If view doesn't return dict then decorator simply returns output. + + Parameters: + - template: template name to use + - mimetype: content type to send in response headers + + Examples: + # 1. Template name in decorator parameters + + @render_to('template.html') + def foo(request): + bar = Bar.object.all() + return {'bar': bar} + + # equals to + def foo(request): + bar = Bar.object.all() + return render_to_response('template.html', + {'bar': bar}, + context_instance=RequestContext(request)) + + + # 2. Template name as TEMPLATE item value in return dictionary. + if TEMPLATE is given then its value will have higher priority + than render_to argument. + + @render_to() + def foo(request, category): + template_name = '%s.html' % category + return {'bar': bar, 'TEMPLATE': template_name} + + #equals to + def foo(request, category): + template_name = '%s.html' % category + return render_to_response(template_name, + {'bar': bar}, + context_instance=RequestContext(request)) + + """ + def renderer(function): + @wraps(function) + def wrapper(request, *args, **kwargs): + output = function(request, *args, **kwargs) + if not isinstance(output, dict): + return output + tmpl = output.pop('TEMPLATE', template) + return render_to_response(tmpl, output, \ + context_instance=RequestContext(request), mimetype=mimetype) + return wrapper + return renderer + + + +class Signals(object): + ''' + Convenient wrapper for working with Django's signals (or any other + implementation using same API). + + Example of usage:: + + + # connect to registered signal + @signals.post_save(sender=YourModel) + def sighandler(instance, **kwargs): + pass + + # connect to any signal + signals.register_signal(siginstance, signame) # and then as in example above + + or + + @signals(siginstance, sender=YourModel) + def sighandler(instance, **kwargs): + pass + + In any case defined function will remain as is, without any changes. + + (c) 2008 Alexander Solovyov, new BSD License + ''' + def __init__(self): + self._signals = {} + + # register all Django's default signals + for k, v in signalmodule.__dict__.iteritems(): + # that's hardcode, but IMHO it's better than isinstance + if not k.startswith('__') and k != 'Signal': + self.register_signal(v, k) + + def __getattr__(self, name): + return self._connect(self._signals[name]) + + def __call__(self, signal, **kwargs): + def inner(func): + signal.connect(func, **kwargs) + return func + return inner + + def _connect(self, signal): + def wrapper(**kwargs): + return self(signal, **kwargs) + return wrapper + + def register_signal(self, signal, name): + self._signals[name] = signal + +signals = Signals() + + + +class JsonResponse(HttpResponse): + """ + HttpResponse descendant, which return response with ``application/json`` mimetype. + """ + def __init__(self, data): + super(JsonResponse, self).__init__(content=simplejson.dumps(data), mimetype='application/json') + + + +def ajax_request(func): + """ + If view returned serializable dict, returns JsonResponse with this dict as content. + + example: + + @ajax_request + def my_view(request): + news = News.objects.all() + news_titles = [entry.title for entry in news] + return {'news_titles': news_titles} + """ + @wraps(func) + def wrapper(request, *args, **kwargs): + response = func(request, *args, **kwargs) + if isinstance(response, dict): + return JsonResponse(response) + else: + return response + return wrapper + + +def autostrip(cls): + """ + strip text fields before validation + + example: + class PersonForm(forms.Form): + name = forms.CharField(min_length=2, max_length=10) + email = forms.EmailField() + + PersonForm = autostrip(PersonForm) + + #or you can use @autostrip in python >= 2.6 + + Author: nail.xx + """ + fields = [(key, value) for key, value in cls.base_fields.iteritems() if isinstance(value, forms.CharField)] + for field_name, field_object in fields: + def get_clean_func(original_clean): + return lambda value: original_clean(value and value.strip()) + clean_func = get_clean_func(getattr(field_object, 'clean')) + setattr(field_object, 'clean', clean_func) + return cls + diff --git a/euscanwww/annoying/decorators.pyc b/euscanwww/annoying/decorators.pyc new file mode 100644 index 0000000..2ed3c22 Binary files /dev/null and b/euscanwww/annoying/decorators.pyc differ diff --git a/euscanwww/annoying/exceptions.py b/euscanwww/annoying/exceptions.py new file mode 100644 index 0000000..1cef123 --- /dev/null +++ b/euscanwww/annoying/exceptions.py @@ -0,0 +1,5 @@ +class Redirect(Exception): + def __init__(self, *args, **kwargs): + self.args = args + self.kwargs = kwargs + diff --git a/euscanwww/annoying/fields.py b/euscanwww/annoying/fields.py new file mode 100644 index 0000000..3b3725c --- /dev/null +++ b/euscanwww/annoying/fields.py @@ -0,0 +1,69 @@ +from django.db import models +from django.db.models import OneToOneField +from django.utils import simplejson as json +from django.core.serializers.json import DjangoJSONEncoder +from django.db.models.fields.related import SingleRelatedObjectDescriptor + + +class AutoSingleRelatedObjectDescriptor(SingleRelatedObjectDescriptor): + def __get__(self, instance, instance_type=None): + try: + return super(AutoSingleRelatedObjectDescriptor, self).__get__(instance, instance_type) + except self.related.model.DoesNotExist: + obj = self.related.model(**{self.related.field.name: instance}) + obj.save() + return obj + + +class AutoOneToOneField(OneToOneField): + ''' + OneToOneField creates related object on first call if it doesnt exist yet. + Use it instead of original OneToOne field. + + example: + + class MyProfile(models.Model): + user = AutoOneToOneField(User, primary_key=True) + home_page = models.URLField(max_length=255, blank=True) + icq = models.IntegerField(max_length=255, null=True) + ''' + def contribute_to_related_class(self, cls, related): + setattr(cls, related.get_accessor_name(), AutoSingleRelatedObjectDescriptor(related)) + + +class JSONField(models.TextField): + """ + JSONField is a generic textfield that neatly serializes/unserializes + JSON objects seamlessly. + Django snippet #1478 + + example: + class Page(models.Model): + data = JSONField(blank=True, null=True) + + + page = Page.objects.get(pk=5) + page.data = {'title': 'test', 'type': 3} + page.save() + """ + + __metaclass__ = models.SubfieldBase + + def to_python(self, value): + if value == "": + return None + + try: + if isinstance(value, basestring): + return json.loads(value) + except ValueError: + pass + return value + + def get_db_prep_save(self, value, *args, **kwargs): + if value == "": + return None + if isinstance(value, dict): + value = json.dumps(value, cls=DjangoJSONEncoder) + return super(JSONField, self).get_db_prep_save(value, *args, **kwargs) + diff --git a/euscanwww/annoying/functions.py b/euscanwww/annoying/functions.py new file mode 100644 index 0000000..7b7f49a --- /dev/null +++ b/euscanwww/annoying/functions.py @@ -0,0 +1,32 @@ +from django.shortcuts import _get_queryset +from django.conf import settings + + +def get_object_or_None(klass, *args, **kwargs): + """ + Uses get() to return an object or None if the object does not exist. + + klass may be a Model, Manager, or QuerySet object. All other passed + arguments and keyword arguments are used in the get() query. + + Note: Like with get(), a MultipleObjectsReturned will be raised if more than one + object is found. + """ + queryset = _get_queryset(klass) + try: + return queryset.get(*args, **kwargs) + except queryset.model.DoesNotExist: + return None + + + +def get_config(key, default): + """ + Get settings from django.conf if exists, + return default value otherwise + + example: + + ADMIN_EMAIL = get_config('ADMIN_EMAIL', 'default@email.com') + """ + return getattr(settings, key, default) diff --git a/euscanwww/annoying/middlewares.py b/euscanwww/annoying/middlewares.py new file mode 100644 index 0000000..8075a12 --- /dev/null +++ b/euscanwww/annoying/middlewares.py @@ -0,0 +1,32 @@ +import re + +from django.conf import settings +from django.views.static import serve +from django.shortcuts import redirect + +from .exceptions import Redirect + + +class StaticServe(object): + """ + Django middleware for serving static files instead of using urls.py + """ + regex = re.compile(r'^%s(?P.*)$' % settings.MEDIA_URL) + + def process_request(self, request): + if settings.DEBUG: + match = self.regex.search(request.path) + if match: + return serve(request, match.group(1), settings.MEDIA_ROOT) + + +class RedirectMiddleware(object): + """ + You must add this middleware to MIDDLEWARE_CLASSES list, + to make work Redirect exception. All arguments passed to + Redirect will be passed to django built in redirect function. + """ + def process_exception(self, request, exception): + if not isinstance(exception, Redirect): + return + return redirect(*exception.args, **exception.kwargs) diff --git a/euscanwww/annoying/templatetags/__init__.py b/euscanwww/annoying/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/euscanwww/annoying/templatetags/annoying.py b/euscanwww/annoying/templatetags/annoying.py new file mode 100644 index 0000000..1d92526 --- /dev/null +++ b/euscanwww/annoying/templatetags/annoying.py @@ -0,0 +1,14 @@ +import django +from django import template + +from smart_if import smart_if + + +register = template.Library() + + +try: + if int(django.get_version()[-5:]) < 11806: + register.tag('if', smart_if) +except ValueError: + pass diff --git a/euscanwww/annoying/templatetags/smart_if.py b/euscanwww/annoying/templatetags/smart_if.py new file mode 100644 index 0000000..9839690 --- /dev/null +++ b/euscanwww/annoying/templatetags/smart_if.py @@ -0,0 +1,240 @@ +from django import template + +__author__ = "SmileyChris" + +#============================================================================== +# Calculation objects +#============================================================================== + +class BaseCalc(object): + def __init__(self, var1, var2=None, negate=False): + self.var1 = var1 + self.var2 = var2 + self.negate = negate + + def resolve(self, context): + try: + var1, var2 = self.resolve_vars(context) + outcome = self.calculate(var1, var2) + except: + outcome = False + if self.negate: + return not outcome + return outcome + + def resolve_vars(self, context): + var2 = self.var2 and self.var2.resolve(context) + return self.var1.resolve(context), var2 + + def calculate(self, var1, var2): + raise NotImplementedError() + + +class Or(BaseCalc): + def calculate(self, var1, var2): + return var1 or var2 + + +class And(BaseCalc): + def calculate(self, var1, var2): + return var1 and var2 + + +class Equals(BaseCalc): + def calculate(self, var1, var2): + return var1 == var2 + + +class Greater(BaseCalc): + def calculate(self, var1, var2): + return var1 > var2 + + +class GreaterOrEqual(BaseCalc): + def calculate(self, var1, var2): + return var1 >= var2 + + +class In(BaseCalc): + def calculate(self, var1, var2): + return var1 in var2 + + +OPERATORS = { + '=': (Equals, True), + '==': (Equals, True), + '!=': (Equals, False), + '>': (Greater, True), + '>=': (GreaterOrEqual, True), + '<=': (Greater, False), + '<': (GreaterOrEqual, False), + 'or': (Or, True), + 'and': (And, True), + 'in': (In, True), +} +BOOL_OPERATORS = ('or', 'and') + + +class IfParser(object): + error_class = ValueError + + def __init__(self, tokens): + self.tokens = tokens + + def _get_tokens(self): + return self._tokens + + def _set_tokens(self, tokens): + self._tokens = tokens + self.len = len(tokens) + self.pos = 0 + + tokens = property(_get_tokens, _set_tokens) + + def parse(self): + if self.at_end(): + raise self.error_class('No variables provided.') + var1 = self.get_bool_var() + while not self.at_end(): + op, negate = self.get_operator() + var2 = self.get_bool_var() + var1 = op(var1, var2, negate=negate) + return var1 + + def get_token(self, eof_message=None, lookahead=False): + negate = True + token = None + pos = self.pos + while token is None or token == 'not': + if pos >= self.len: + if eof_message is None: + raise self.error_class() + raise self.error_class(eof_message) + token = self.tokens[pos] + negate = not negate + pos += 1 + if not lookahead: + self.pos = pos + return token, negate + + def at_end(self): + return self.pos >= self.len + + def create_var(self, value): + return TestVar(value) + + def get_bool_var(self): + """ + Returns either a variable by itself or a non-boolean operation (such as + ``x == 0`` or ``x < 0``). + + This is needed to keep correct precedence for boolean operations (i.e. + ``x or x == 0`` should be ``x or (x == 0)``, not ``(x or x) == 0``). + """ + var = self.get_var() + if not self.at_end(): + op_token = self.get_token(lookahead=True)[0] + if isinstance(op_token, basestring) and (op_token not in + BOOL_OPERATORS): + op, negate = self.get_operator() + return op(var, self.get_var(), negate=negate) + return var + + def get_var(self): + token, negate = self.get_token('Reached end of statement, still ' + 'expecting a variable.') + if isinstance(token, basestring) and token in OPERATORS: + raise self.error_class('Expected variable, got operator (%s).' % + token) + var = self.create_var(token) + if negate: + return Or(var, negate=True) + return var + + def get_operator(self): + token, negate = self.get_token('Reached end of statement, still ' + 'expecting an operator.') + if not isinstance(token, basestring) or token not in OPERATORS: + raise self.error_class('%s is not a valid operator.' % token) + if self.at_end(): + raise self.error_class('No variable provided after "%s".' % token) + op, true = OPERATORS[token] + if not true: + negate = not negate + return op, negate + + +#============================================================================== +# Actual templatetag code. +#============================================================================== + +class TemplateIfParser(IfParser): + error_class = template.TemplateSyntaxError + + def __init__(self, parser, *args, **kwargs): + self.template_parser = parser + return super(TemplateIfParser, self).__init__(*args, **kwargs) + + def create_var(self, value): + return self.template_parser.compile_filter(value) + + +class SmartIfNode(template.Node): + def __init__(self, var, nodelist_true, nodelist_false=None): + self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false + self.var = var + + def render(self, context): + if self.var.resolve(context): + return self.nodelist_true.render(context) + if self.nodelist_false: + return self.nodelist_false.render(context) + return '' + + def __repr__(self): + return "" + + def __iter__(self): + for node in self.nodelist_true: + yield node + if self.nodelist_false: + for node in self.nodelist_false: + yield node + + def get_nodes_by_type(self, nodetype): + nodes = [] + if isinstance(self, nodetype): + nodes.append(self) + nodes.extend(self.nodelist_true.get_nodes_by_type(nodetype)) + if self.nodelist_false: + nodes.extend(self.nodelist_false.get_nodes_by_type(nodetype)) + return nodes + + +def smart_if(parser, token): + """ + A smarter {% if %} tag for django templates. + + While retaining current Django functionality, it also handles equality, + greater than and less than operators. Some common case examples:: + + {% if articles|length >= 5 %}...{% endif %} + {% if "ifnotequal tag" != "beautiful" %}...{% endif %} + + Arguments and operators _must_ have a space between them, so + ``{% if 1>2 %}`` is not a valid smart if tag. + + All supported operators are: ``or``, ``and``, ``in``, ``=`` (or ``==``), + ``!=``, ``>``, ``>=``, ``<`` and ``<=``. + """ + bits = token.split_contents()[1:] + var = TemplateIfParser(parser, bits).parse() + nodelist_true = parser.parse(('else', 'endif')) + token = parser.next_token() + if token.contents == 'else': + nodelist_false = parser.parse(('endif',)) + parser.delete_first_token() + else: + nodelist_false = None + return SmartIfNode(var, nodelist_true, nodelist_false) + diff --git a/euscanwww/annoying/utils.py b/euscanwww/annoying/utils.py new file mode 100644 index 0000000..6bb8f06 --- /dev/null +++ b/euscanwww/annoying/utils.py @@ -0,0 +1,26 @@ +from django.http import HttpResponse +from django.utils.encoding import iri_to_uri + + +class HttpResponseReload(HttpResponse): + """ + Reload page and stay on the same page from where request was made. + + example: + + def simple_view(request): + if request.POST: + form = CommentForm(request.POST): + if form.is_valid(): + form.save() + return HttpResponseReload(request) + else: + form = CommentForm() + return render_to_response('some_template.html', {'form': form}) + """ + status_code = 302 + + def __init__(self, request): + HttpResponse.__init__(self) + referer = request.META.get('HTTP_REFERER') + self['Location'] = iri_to_uri(referer or "/") diff --git a/euscanwww/euscan/__init__.py b/euscanwww/euscan/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/euscanwww/euscan/__init__.pyc b/euscanwww/euscan/__init__.pyc new file mode 100644 index 0000000..6c1ec8b Binary files /dev/null and b/euscanwww/euscan/__init__.pyc differ diff --git a/euscanwww/euscan/admin.py b/euscanwww/euscan/admin.py new file mode 100644 index 0000000..6629839 --- /dev/null +++ b/euscanwww/euscan/admin.py @@ -0,0 +1,5 @@ +"""from polls.models import Package +from django.contrib import admin + +admin.site.register(Package) +""" diff --git a/euscanwww/euscan/admin.pyc b/euscanwww/euscan/admin.pyc new file mode 100644 index 0000000..451e331 Binary files /dev/null and b/euscanwww/euscan/admin.pyc differ diff --git a/euscanwww/euscan/models.py b/euscanwww/euscan/models.py new file mode 100644 index 0000000..d486ca3 --- /dev/null +++ b/euscanwww/euscan/models.py @@ -0,0 +1,31 @@ +from django.db import models +""" +class Package(models.Model): + category + package + description + homepage + herds + maintainers + +class Herd(models.Model): + herd + +class Maintainer(models.Model): + name + email + +class Version(models.Model): + package + slot + revision + version + packaged + overlay + urls + +class EuscanResult(models.Model): + package + datetime + result +""" diff --git a/euscanwww/euscan/models.pyc b/euscanwww/euscan/models.pyc new file mode 100644 index 0000000..9dc5723 Binary files /dev/null and b/euscanwww/euscan/models.pyc differ diff --git a/euscanwww/euscan/tests.py b/euscanwww/euscan/tests.py new file mode 100644 index 0000000..2247054 --- /dev/null +++ b/euscanwww/euscan/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/euscanwww/euscan/urls.py b/euscanwww/euscan/urls.py new file mode 100644 index 0000000..23e9529 --- /dev/null +++ b/euscanwww/euscan/urls.py @@ -0,0 +1,13 @@ +from django.conf.urls.defaults import * + +urlpatterns = patterns('euscan.views', + (r'^$', 'index'), + (r'^logs/$', 'logs'), + (r'^categories/$', 'categories'), + (r'^category/(?P\w+)/packages/$', 'category'), + (r'^herds/$', 'herds'), + (r'^herd/(?P\w+)/packages/$', 'herd'), + (r'^maintainers/$', 'maintainers'), + (r'^maintainer/(?P\d+)/packages/$', 'maintainer'), + (r'^package/(?P\w+)/(?P\w+)/$', 'package'), +) diff --git a/euscanwww/euscan/urls.pyc b/euscanwww/euscan/urls.pyc new file mode 100644 index 0000000..e187d8d Binary files /dev/null and b/euscanwww/euscan/urls.pyc differ diff --git a/euscanwww/euscan/views.py b/euscanwww/euscan/views.py new file mode 100644 index 0000000..3fdf543 --- /dev/null +++ b/euscanwww/euscan/views.py @@ -0,0 +1,38 @@ +from annoying.decorators import render_to +from django.http import Http404 + +@render_to('euscan/index.html') +def index(request): + return {} + +@render_to('euscan/logs.html') +def logs(request): + return {} + +@render_to('euscan/categories.html') +def categories(request): + return {} + +@render_to('euscan/category.html') +def category(request, category): + return {} + +@render_to('euscan/herds.html') +def herds(request): + return {} + +@render_to('euscan/herd.html') +def herd(request, herd): + return {} + +@render_to('euscan/maintainers.html') +def maintainers(request): + return {} + +@render_to('euscan/maintainer.html') +def maintainer(request, maintainer_id): + return {} + +@render_to('euscan/package.html') +def package(request, category, package): + return {} diff --git a/euscanwww/euscan/views.pyc b/euscanwww/euscan/views.pyc new file mode 100644 index 0000000..862a5a9 Binary files /dev/null and b/euscanwww/euscan/views.pyc differ diff --git a/euscanwww/media/css/style.css b/euscanwww/media/css/style.css new file mode 100644 index 0000000..3826939 --- /dev/null +++ b/euscanwww/media/css/style.css @@ -0,0 +1,422 @@ +body +{ + margin: 0; + padding: 0; + font-size: 0.8em; + font-family: Dejavu, Verdana, "Bitstream Vera Sans", "Lucida Grande", "Trebuchet MS", sans-serif; + color: #535353; + background: #E3E3E2; + } + +img +{ + border: none; + } + +h1 +{ + margin-top: 0; + color: #369; + font-size: 1.6em; +} + +a:link, a:visited +{ + text-decoration: none; + font-weight: bold; + color: #ff8c00; + } + +a:hover, a:active +{ + font-weight: bold; + color: #ff4500; + text-decoration: underline; + } + +#header { + background: #ffffff; + width: 100%; + margin: 0; + padding: 0; +} + +#content { + background: #ffffff; + padding: 10px; + margin-top: 10px; +/* margin-right: auto; + margin-left: auto; +*/ + margin-left: 20%; + margin-right: 250px; + max-width: 60em; + + border: solid 1px #DBDBDA; + background: #FEFEFE; + + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; +} + +#menu { + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + +} + +#menu, #menu_dl { + width:100%; + border-bottom: 1px dotted #663300; + margin-top: 5px; + background: #252525; +} + +#menu a { + color: #fff; +} + +#menu li +{ + list-style-type: none; + } +#menus { + width: 200px; + position:absolute; + top:30px; + right:20px; + +/* + position: fixed; + right: 10px; + top: 2em; + width: 20%; +*/ +} + +/* +code, pre{ + background-color:transparent; + font-family:"Courier New",Courier,monospace; + font-size:small; +} +*/ + +a{ + color: #3F4C66; +} + +a:link, a:visited, a:active { + color: #3F4C66; + text-decoration: none; +} +a:hover { + color: #4C5C7B; + text-decoration: underline; +} + +abbr:hover { + text-decoration: underline; +} + +pre{ + border-left:5px solid; + padding:0.5em 1em; + margin-left:2em; +} + +dt { + font-weight: bold; +} + +dd { + border-left: 1px solid #ccc; + margin: 5px; + padding: 5px; +} + +table { + border:3px solid #55534E; + border-collapse:collapse; + width:90%; + margin:auto; +} + +thead, tfoot { + border:1px solid #55534E; +} + +tbody { + background-color:#FFFFFF; + border:1px solid #55534E; +} +tbody tr.even { + background-color: #eee; +} +tbody tr.odd { + background-color: #fff; +} +tbody tr:hover { + background: #DFD9CD; +} + + +th { + border:1px dotted #55534E; + padding:5px; + background-color: #DFD9CD; +} + +td { + border:1px solid #55534E; + padding:5px; + text-align:left; +} + +h1 { + width: 20em; + margin-left: auto; + margin-right: auto; +} + +.ok { + color:#15B100; +} +.bad { + color:#FFFFFF; +} +hr +{ + margin: 0.3em 1em 0.3em 1em; + height: 1px; + border: #bcbcbc dashed; + border-width: 0 0 1px 0; + } + + +table +{ + width: 80%; + border-collapse: collapse; + font-size: 1em; + margin-left: auto; + margin-right: auto; + background: #F5F5F5; + text-align: left; +} + +td +{ + vertical-align: top; + } + +th +{ + text-align: center; + border-bottom: 3px solid; + } + +#logos, #footer +{ + margin: 10px; + text-align: center; + background: #FFF; + font-size: 0.8em; + margin-right: auto; + margin-left:auto; + width: 60em; + padding: 10px; + + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + + } + +.err,.ok,.inf +{ + margin: 5px; + margin-left: auto; + margin-right: auto; + width: 70%; + font-weight:bold; + border: 1px dotted #5682AD; + } + +.err +{ + border-color: #F00; + color: #F00; + } + +.ok +{ + border-color: #262; + color: #262; + } + +.logo { + float: right; +} + +.clear { + clear: both; +} + +.download a { + color: #1c1c1c; +} + +.download { + background: url('download-bg.png') no-repeat; + color: #1c1c1c; + padding: 1em; + float: right; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + background-size: 100% 100%; + -moz-background-size: 100% 100%; + -webkit-background-size: 100% 100%; +} + +.ubuntu { + background: url('dev/img/ubuntu.png') no-repeat; + padding-left: 20px; +} + +.debian { + background: url('dev/img/debian.png') no-repeat; + padding-left: 20px; +} + +.gentoo { + background: url('dev/img/gentoo.png') no-repeat; + padding-left: 20px; +} + +.osx { + background: url('dev/img/osx.png') no-repeat; + padding-left: 20px; +} + +.win32 { + background: url('dev/img/win32.png') no-repeat; + padding-left: 20px; +} + +.maemo { + background: url('dev/img/maemo.png') no-repeat; + padding-left: 20px; +} + +.symbian { + background: url('dev/img/symbian.png') no-repeat; + padding-left: 20px; +} + +.os2 { + background: url('dev/img/os2.png') no-repeat; + padding-left: 20px; +} + + +pre code[class]:after { + content: 'highlight: ' attr(class); + display: block; text-align: right; + font-size: smaller; + color: #CCC; background: white; + border-top: solid 1px; + padding-top: 0.5em; +} + +pre code { + display: block; + background: #F0F0F0; +} + +pre code, +pre .ruby .subst, +pre .xml .title, +pre .lisp .title { + color: black; +} + +pre .string, +pre .title, +pre .parent, +pre .tag .attribute .value, +pre .rules .value, +pre .rules .value .number, +pre .preprocessor, +pre .ruby .symbol, +pre .instancevar, +pre .aggregate, +pre .template_tag, +pre .django .variable, +pre .smalltalk .class, +pre .addition, +pre .flow, +pre .stream, +pre .bash .variable, +pre .apache .tag, +pre .apache .cbracket { + color: #800; +} + +pre .comment, +pre .annotation, +pre .template_comment, +pre .diff .header, +pre .chunk { + color: #888; +} + +pre .number, +pre .date, +pre .regexp, +pre .literal, +pre .smalltalk .symbol, +pre .smalltalk .char, +pre .change { + color: #080; +} + +pre .label, +pre .javadoc, +pre .ruby .string, +pre .decorator, +pre .filter .argument, +pre .localvars, +pre .array, +pre .attr_selector, +pre .pseudo, +pre .pi, +pre .doctype, +pre .deletion, +pre .envvar, +pre .shebang, +pre .apache .sqbracket { + color: #88F; +} + +pre .keyword, +pre .id, +pre .phpdoc, +pre .title, +pre .built_in, +pre .aggregate, +pre .smalltalk .class, +pre .winutils, +pre .bash .variable, +pre .apache .tag { + font-weight: bold; +} + +pre .html .css, +pre .html .javascript, +pre .html .vbscript { + opacity: 0.5; +} diff --git a/euscanwww/media/img/gentoo.png b/euscanwww/media/img/gentoo.png new file mode 100644 index 0000000..d6533d7 Binary files /dev/null and b/euscanwww/media/img/gentoo.png differ diff --git a/euscanwww/media/img/linux.png b/euscanwww/media/img/linux.png new file mode 100644 index 0000000..2a4f2e4 Binary files /dev/null and b/euscanwww/media/img/linux.png differ diff --git a/euscanwww/settings.py b/euscanwww/settings.py index 81a9c57..e5454b5 100644 --- a/euscanwww/settings.py +++ b/euscanwww/settings.py @@ -1,18 +1,20 @@ # Django settings for euscanwww project. +import os.path + DEBUG = True TEMPLATE_DEBUG = DEBUG ADMINS = ( - # ('Your Name', 'your_email@domain.com'), + ('admin', 'admin@example.com'), ) MANAGERS = ADMINS DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. - 'NAME': '', # Or path to database file if using sqlite3. + 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. + 'NAME': os.path.join(os.path.dirname( __file__ ), 'euscan.db'), # 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. @@ -27,7 +29,7 @@ DATABASES = { # 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 = 'America/Chicago' +TIME_ZONE = 'Europe/Paris' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html @@ -45,20 +47,20 @@ USE_L10N = True # Absolute filesystem path to the directory that will hold user-uploaded files. # Example: "/home/media/media.lawrence.com/" -MEDIA_ROOT = '' +MEDIA_ROOT = os.path.join(os.path.dirname( __file__ ), 'media/') # 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 = '' +MEDIA_URL = 'media/' # 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/' +ADMIN_MEDIA_PREFIX = '/admin-media/' # Make this unique, and don't share it with anybody. -SECRET_KEY = 'h!@c5^bi%emv1malwhk(txwqo1(uxyzvp6@+^gn4zyyr2pu*1c' +SECRET_KEY = '7b7ea2ca45021661d623122e9e14c2b529f23054' # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = ( @@ -78,19 +80,20 @@ MIDDLEWARE_CLASSES = ( ROOT_URLCONF = 'euscanwww.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. + os.path.join(os.path.dirname( __file__ ), 'templates'), ) INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', - 'django.contrib.sites', + #'django.contrib.sites', 'django.contrib.messages', + 'south', + 'euscan', # Uncomment the next line to enable the admin: - # 'django.contrib.admin', + 'django.contrib.admin', # Uncomment the next line to enable admin documentation: # 'django.contrib.admindocs', ) + diff --git a/euscanwww/templates/_base.html b/euscanwww/templates/_base.html new file mode 100644 index 0000000..1aa06d2 --- /dev/null +++ b/euscanwww/templates/_base.html @@ -0,0 +1,43 @@ + + + + {% block title %}euscan{% endblock %} + + {% block css %} + + {% endblock %} + {% block javascript %} + {% endblock %} + + + +
+ {% block content %}{% endblock %} + + + + diff --git a/euscanwww/templates/euscan/_base.html b/euscanwww/templates/euscan/_base.html new file mode 100644 index 0000000..72dd2c0 --- /dev/null +++ b/euscanwww/templates/euscan/_base.html @@ -0,0 +1,43 @@ +?xml version="1.0" encoding="utf8"?> + + + {% block title %}euscan{% endblock %} + + {% block css %} + + {% endblock %} + {% block javascript %} + {% endblock %} + + + +
+ {% block content %}{% endblock %} + + + + diff --git a/euscanwww/templates/euscan/index.html b/euscanwww/templates/euscan/index.html new file mode 100644 index 0000000..a601da3 --- /dev/null +++ b/euscanwww/templates/euscan/index.html @@ -0,0 +1,5 @@ +{% extends "_base.html" %} + +{% block content %} +Hello world ! +{% endblock %} diff --git a/euscanwww/urls.py b/euscanwww/urls.py index 4e34182..680835a 100644 --- a/euscanwww/urls.py +++ b/euscanwww/urls.py @@ -1,8 +1,9 @@ +from django.conf import settings from django.conf.urls.defaults import * # Uncomment the next two lines to enable the admin: -# from django.contrib import admin -# admin.autodiscover() +from django.contrib import admin +admin.autodiscover() urlpatterns = patterns('', # Example: @@ -12,5 +13,16 @@ urlpatterns = patterns('', # (r'^admin/doc/', include('django.contrib.admindocs.urls')), # Uncomment the next line to enable the admin: - # (r'^admin/', include(admin.site.urls)), + (r'^admin/', include(admin.site.urls)), + + (r'^', include('euscan.urls')), ) + + +if settings.DEBUG: + urlpatterns += patterns('', + url(r'^media/(?P.*)$', 'django.views.static.serve', { + 'document_root': settings.MEDIA_ROOT, + }), + ) +