From 482e54cfce6892286543387314c0116adc6dca99 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Wed, 13 Apr 2011 08:50:24 +0200 Subject: [PATCH] euscanwww: import new website Signed-off-by: Corentin Chary --- BUGS | 4 - euscanwww/annoying/__init__.py | 0 euscanwww/annoying/__init__.pyc | Bin 0 -> 141 bytes euscanwww/annoying/decorators.py | 194 +++++++++ euscanwww/annoying/decorators.pyc | Bin 0 -> 8396 bytes euscanwww/annoying/exceptions.py | 5 + euscanwww/annoying/fields.py | 69 ++++ euscanwww/annoying/functions.py | 32 ++ euscanwww/annoying/middlewares.py | 32 ++ euscanwww/annoying/templatetags/__init__.py | 0 euscanwww/annoying/templatetags/annoying.py | 14 + euscanwww/annoying/templatetags/smart_if.py | 240 +++++++++++ euscanwww/annoying/utils.py | 26 ++ euscanwww/euscan/__init__.py | 0 euscanwww/euscan/__init__.pyc | Bin 0 -> 139 bytes euscanwww/euscan/admin.py | 5 + euscanwww/euscan/admin.pyc | Bin 0 -> 255 bytes euscanwww/euscan/models.py | 31 ++ euscanwww/euscan/models.pyc | Bin 0 -> 195 bytes euscanwww/euscan/tests.py | 23 ++ euscanwww/euscan/urls.py | 13 + euscanwww/euscan/urls.pyc | Bin 0 -> 1019 bytes euscanwww/euscan/views.py | 38 ++ euscanwww/euscan/views.pyc | Bin 0 -> 1691 bytes euscanwww/media/css/style.css | 422 ++++++++++++++++++++ euscanwww/media/img/gentoo.png | Bin 0 -> 2295 bytes euscanwww/media/img/linux.png | Bin 0 -> 2090 bytes euscanwww/settings.py | 29 +- euscanwww/templates/_base.html | 43 ++ euscanwww/templates/euscan/_base.html | 43 ++ euscanwww/templates/euscan/index.html | 5 + euscanwww/urls.py | 18 +- 32 files changed, 1266 insertions(+), 20 deletions(-) delete mode 100644 BUGS create mode 100644 euscanwww/annoying/__init__.py create mode 100644 euscanwww/annoying/__init__.pyc create mode 100644 euscanwww/annoying/decorators.py create mode 100644 euscanwww/annoying/decorators.pyc create mode 100644 euscanwww/annoying/exceptions.py create mode 100644 euscanwww/annoying/fields.py create mode 100644 euscanwww/annoying/functions.py create mode 100644 euscanwww/annoying/middlewares.py create mode 100644 euscanwww/annoying/templatetags/__init__.py create mode 100644 euscanwww/annoying/templatetags/annoying.py create mode 100644 euscanwww/annoying/templatetags/smart_if.py create mode 100644 euscanwww/annoying/utils.py create mode 100644 euscanwww/euscan/__init__.py create mode 100644 euscanwww/euscan/__init__.pyc create mode 100644 euscanwww/euscan/admin.py create mode 100644 euscanwww/euscan/admin.pyc create mode 100644 euscanwww/euscan/models.py create mode 100644 euscanwww/euscan/models.pyc create mode 100644 euscanwww/euscan/tests.py create mode 100644 euscanwww/euscan/urls.py create mode 100644 euscanwww/euscan/urls.pyc create mode 100644 euscanwww/euscan/views.py create mode 100644 euscanwww/euscan/views.pyc create mode 100644 euscanwww/media/css/style.css create mode 100644 euscanwww/media/img/gentoo.png create mode 100644 euscanwww/media/img/linux.png create mode 100644 euscanwww/templates/_base.html create mode 100644 euscanwww/templates/euscan/_base.html create mode 100644 euscanwww/templates/euscan/index.html 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 0000000000000000000000000000000000000000..6915190058d2e87378b2a9edab1709ea80dbc5ca GIT binary patch literal 141 zcmcckiI?k^<5J&b1}I1X8Urs`*A7bj+> z=@%Cz>!+3$Cnx4Xsq*r2{lvVy{L0L{bp81F%)HE!_;|g7$`THsR-4@Xl+v73JCFs% HK+FID!YUvr literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..2ed3c22908ec02ff37f04a22ba2e9ac17b09ecc0 GIT binary patch literal 8396 zcmcIpTa(nr6>iP!owb2AU}Kl7>T0d-`gOHAp^{0pHtG5k zYI8~@(`s$T^(WQltV-t8+MMf8sm((wnOAG`=ufL?Mn$tKnp5owwf2hIJtmtTQk$=; zX}lXuN_n781L4wEAHoH`1oM>xQb4&vvxv7uglHrTynMX7Q_+%2Y(HSL=_8Y za+5|T4~i_vjqPQrHEwJYV;foCwXXXry1sebH@3KurG?ok-1BKXw{bfSlXBub9(+<1 zJ%7(?b26>lOUxsS*JsfkZ0y(3EBIdcDBJ-VvWv_K`$cApJnju?+RnqCEx29~bhD_R zm>?)-q??9ac1ThXL|JPv5XG$`2wL1{0vCUI*^_9V*VJ=QJqNROYRETAJ*}%JbqK45 z(Ulej#XD~C8ZH~6*;!OCJazNIyXvW@3Z|v{-#MpVD9mig zOs|}Y32|*Wzk_3~t7lNl$LH03EVe5At~5k4B4Sg7MUe|{?ecyKg!Fq+SQsHy#weYh z$qTZ{7ltdinURPpv^+8sjl2>y@P@Jhy5?-WX~THqtj$|zP2aY{wEWrL-aZ?q zX|@}u?X!_-WqDX+xo!4#3#v?RdfHr21??oa@z!A7mp0i0v4)B*cfFgB<0ce7$w!!q>E zM`7B|^j2)Ptu8uYp)G95>f99l9MaWPJ6&XWu;0YAEVt25TSc6u%{l4bGq4YwrluZi zNL;TQJ&>^Og*l!VCfC^e-mN=#KfQMEmW~V4)p0u9RF>k-SUAjgn_BNRTOB6b;jYzT z6oJIh>XtKSEMki=ZJDO5aC<`-(@|z@x>%I!mn?NmIzpI@LHBMs!|JSG^!i1~)7^?_ zdr_9vA7~IPY+fAPIffyqzBSdXZVX;`d*-5}FNGk{qckaG$FXx)x?@6kFzbYPYbT_a zDYrYV&o}j6xk6Sik!kt%)xl9U7ArcNouZp8E;+fH4IF*eD1FpY$rMy$J{XDw<)EG?uhGXzGsB3jNh0W-eaj{HKoM(;5yB?vuP7&?W;ehCY2CJIh1DNZiZ+ zMrr+CFO;ejRH}4&uj&oNwlr6$R*QAv)k7&nB)nOS% zTbOp1?~W)&rAC2R^<}+y#yXACX9m*;jC@x~mi1yK4`|Jv#h%J*(wrWskaVNHYI15V7g-C1Rh!4TAIwL|KXSjQ6!+yvIXCafI#Bkk44g!22#P z`xzR%?V>#5!XNNPUE)4k3HLofMuG-5i0l9oKmv&JPbX9XI59y)0lbO0j76|vR40IV zR;#T_JY12mTpe`5__^PfWJcu`8zfIaP;4t>lbBD(j}4XTWj!B1%4d{w)5%T+t^^fpl+=2WrDCuR~_s*{(vJzk7HiZwsMWeEaRZNWR@O?nI7 zyeBY7LbyO2{}hIO&URhW;-6-hC{0GkB1HIdN^bIBU`YoWy!U2=Ns)%^CsOc#z@2gJ zr)De~e4Ypyb9*-z<^-j!I*i@ocKjp5*KygOp)r8^&?&T{dSBy4)QvY2)HU8rs%S!P zrc^X3H`B^rZE!pL4YWi&2e3U{XAGaGODHK&XFJO`f%o)wTy#p@vuJgR`*j0=Busa8 z29KM|GDHN1o--s2L0sp{mayj9-P=ngHYh{2&NeV1Y@3T0%dh|=KFzS7B91!z)Q&BH z5AcfHQue^Ct0e`^93sU>3A*XxEsHn(|qcd<18u%G*BhR{K39Nwx7n~6607s02EIM4zw#;Bp z$h2Z}a8vQSZ{-7L`F1Mj*$OQI=tfL1TR8ye0ODwFx*

19n-|0-nRY1PQl|Ezh{o zTGAKJo%={%OTZ?NMz3Z`wzZpWE$h^5>+7pG^`~*mAnz1*#e36%P2jpg-3-ul#QEZG z=T~&N@USuRCFWIE)R*wG@W+yP#n5)RRZq=l@4+F%CTi+YU1i76L2fchQ19|H@9{}w zTPM~1h}jl5Tq)=(ku%aFR>j=JIK(NGM`|Tab;s+HPoGr=$yI^GfhJ7XC8xmBd0}ZU z#bM0YuNvG?ysS0J1~`HfmUhee6ZFT-#b&TV03a44@y)mzGiK$@){m(9+B=>kLFAW& z+`wg-j8R6em3Vj(f~+!8&UKO~4bvy3&JBOSF`gG8&OtG72(Za-A5(kG=8eUCZ5_d%PTXC3%3V)IirWXtD!LmK36JYf-}{~DKIz^Ri{-t6pbeRgVgQe5sYQ8lb8 ziY?5NKZ@x(F8ex~mtr8`8y=|r5{-nH(aI!3n?>M>!n8mL>%^@N!Wv6A_$f;Zf_EN1 zL`^M;k=p^woMrv;;X_>^aaS!FxKrYCIataEIR~6N&K8M)O9}wZ5uzA@Bs2k;JySK- zqN_B37#%*R0CWG_Ze{x@_W3N@xkKVJDZ@qmZqM%X&ZrcI!y_B-w5Sq) zBmoq!@?25xC2BL=?*LSUe16MKX-`x2DX&EhAO*B1UY0IoG}U9-T#C97_-K-6Kf|>MWJR8ZAccnaE)0Y%RlgNT&}_2AY)^f@rM- zfqh@jqzvjt`9TD=Po$?|60{N%rsLa?pvOx|*jy^Q6yyR4 zf@2^cGXFcClp#qZ;8>#_6%0=6NN5A6nEw0dJC{S^B!e3$mCuyT=kg8Op%m0wiIoH( z_~QHnd9Z1A{hxD``J!7?Dsplw)m}j^uIoMu_}4j~z)A=clHHl%(U@*z1}prHtB`DU z_zu3g&3m)8}B;Ul26jz^D`@Bl+ajw9x0G z)i11+7)1bX#1~modgaWjNGN5<(IukwCK70qSo!+vFL4JRQTbknUy$h#MTX_Wei387 zU>rxUBr0-rQk}>$49kIWrQ6*esJxZuXt~l#mKrIp3BBckoWX#@Ph8Qb5QhgMcjKuj r7rf*u1y?8=dkW1F)Hln2wS{^eC-kaU_m0jTzI5WpvlAy~XHWbWg-g!D literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..6c1ec8bc03ae486774fd3b3b3dca697227ce52f8 GIT binary patch literal 139 zcmcckiI=N1Zi#O)0~9a_ui>ls1ZH!?K)yc- ze@Nb+1>L=#dqIYXP`8*s5t5KIG9ssB(#MNhh)_!IJy|D{Rx7Gb+_3 jaGj^%MXDMQ+z!&V?Kt?|svlvFTWkEdsnlkQHDHo2`O`)1 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..9dc57238f7cb64f07321af92747be105d9e55249 GIT binary patch literal 195 zcmcckiI;2f<|V$#3{b!fq#b~`SOiF<01+cYHUmQrBSRD;17ivkL$C%&Mdp7X&|n0z zO4xuzZhlH?PO+Z`6G(s)NTg&X=B4NBr6dIbISd-8M6nT&ub+{ho2s9gU7VPire9o? pte;w1oSc{krOM08VFD1d^$IFWIDp!0fZWoYR6CH>#USeh>> 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 0000000000000000000000000000000000000000..e187d8d5edc09fd2be4c628093a0a4d7892aa3ff GIT binary patch literal 1019 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 RwQK+Y002ovPDHLkV1iBEq^1A> literal 0 HcmV?d00001 diff --git a/euscanwww/media/img/linux.png b/euscanwww/media/img/linux.png new file mode 100644 index 0000000000000000000000000000000000000000..2a4f2e475660b01a505c5804c4b14e8817a2d46b GIT binary patch literal 2090 zcmV+_2-WwAP)q+fV=i2e(N? zK~z}7%~x$uROc0b?tAZrWfx%=7g$_S5Q8FWw0Ey{%)~60$TwH7&2pnL<7$5eWoxRLHQon4ZhGk{t002=GU@*jn-ixA$ zu_-A?N-}}5K6g%M)ALWA000<`qjCIr5mv5T3C0+-+9(the2C)WKV$ReO(6oUt*v+l z1Q@cjvr$=j2^%+VfIc<`vu4i3tXV(6ulM{0IXSN&Daix?kR%DMt*s+E2f|3hDC(3o@djo%sB3e?fV9IVvkFk(4wBO-;?;>1>UdfL?DvRaF&!xAS#O z)gDLs3Jy}x3tl*l==(a%of3;Z^>rb8yWReD37AZY5buABEOs5~<2f)LLy~?hc-Db! zn-z3AbCI6tL#?CFzPh^R=@OVUX;Qr)0D^`fYIs1S1xIbTT0{Cq@-ln z{lJeDys4@ACr+o+@{3&`!XrgNYHov1Ndh-+14dq6b*sI=U`yk!A)kwl)>w4nE%8W zno6}bH53T+lBxzN5b#kj=qFVThP0>W9^Jj$LUwyKRa8`v(U?G{L=#0uY6xJY(P(KT zT@jL!k`ilVq=sT+^>paaK~j`J7~q34Jg%}FpvFcA?cBMOG#U+=&E`-x)~$PUz#r9X*RE1>ax$4rCNdi131Bo~LI#bPz~sqOC@wCJ4j%lp zpY!f+@2~`9IY22XV+mjsAD<993rCI|wGKN8*R5M;z1!M?Kp==!t9~5z8xcWKXX<6vYT|90yf>NZ9A|4V?kI-40Cz(A;zzM&sxK z2q1Lz8cw`k38Ui-kmVp^Vn%`Ic{DXSZ9}f(qJ4|;Ty!y9_X2q5(=s$PTt`O6b73|d zH*^Mqo_Z+WQUpC$;Ocbu0SQ55O`eDZV@&ygA9Xffu(s5kwqE;e3VF}!=zgh|st#)? zBi&4;rRN?w-G1_VJwtYY``^3B`<0e{x+EfW`gvZU*A_;Rr*>IbD>9eklBMow21#En z%j>Dxm}iV}fEW90veFo~{K$pn%X9G2M}L5-5*TBMj@Atty~iWL)hWT(NtkLPL<#`o zfak{%@;0alIIF^ML_Y6ri%x7pd;$k>93Ic^`Wzl7{vN=N9lKFeQ;Wlg4?z$Hzec#- zUGRDX7{v%V^Ek{LFF*m1n!;hMnFq%L=(6v&8m50>1ppRfnu36z`)_UgJJfK%{$B|Y z1)!+t1S-lahOECv6N&bA38VsJk{L25F-)7xkZk6`3jkvT^=?s~=i5Rn0B`_McTh*E zX#{SNz+?ve_K!fL?`3@Q$pOU2#}7*2z=4m^dT|f7uO`IAGJxdKqzX2K4s&aO1`eeEH=+aNxklXlrW+V?dOM{)i8z zs0?&_HSkBywPQK)o~ydaNbtY*i49s5HW6?8Oh1X{kq}KomRLzn$h0XiT=vXHh0B4&DDRLT8 z=lv{y+xFZ+|9HAxZ435odEr9V=-Y^o9-~7F8pz;ph(;cmrKNaL! zVhy9;z2ED*IB&_C{J9I3+J@T!Xa8DcsjK`v&uECY1ZBlGW&Vo%`HNq(;r~(o13!0N U>+tKN=Kufz07*qoM6N<$f_RJHasU7T literal 0 HcmV?d00001 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, + }), + ) +