~marcosvanetta/+junk/finop

« back to all changes in this revision

Viewing changes to temp.py

  • Committer: Marcos Vanetta
  • Date: 2010-04-21 21:57:06 UTC
  • Revision ID: marcosvanetta@gmail.com-20100421215706-046jx16am69j802e
starting refactoring

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env python
2
 
#-*- coding:utf-8 -*-
3
 
 
4
 
import os
5
 
from storm.locals import *
6
 
 
7
 
# FIXME: tengo que hacer más consistentes los nombres
8
 
# de los métodos.
9
 
 
10
 
class Atajo(object):
11
 
    '''Representa una relación slug <=> URL
12
 
 
13
 
    Miembros:
14
 
 
15
 
    id     = Único, creciente, entero (primary key)
16
 
    url    = la URL original
17
 
    test   = un test de validez de la URL
18
 
    user   = el dueño del atajo
19
 
    activo = Si este atajo está activo o no.
20
 
    Nunca hay que borrarlos, sino el ID puede volver
21
 
    atrás y se "recicla" una URL. ¡Malo, malo, malo!
22
 
    status = Resultado del último test (bien/mal)
23
 
    ultimo = Fecha/hora del último test
24
 
    '''
25
 
 
26
 
    # Hacer que los datos se guarden via Storm
27
 
    __storm_table__ = "atajo"
28
 
    id     = Int(primary=True)
29
 
    url    = Unicode()
30
 
    test   = Unicode()
31
 
    user   = Unicode()
32
 
    activo = Bool()
33
 
    status = Bool()
34
 
    ultimo = DateTime()
35
 
 
36
 
    def __init__(self, url, user, test=''):
37
 
        '''Exigimos la URL y el usuario, test es opcional,
38
 
        _id es automático.'''
39
 
 
40
 
        # Hace falta crear esto?
41
 
        r = self.store.find(Atajo, user = user, url = url)
42
 
        self.url = url
43
 
        self.user = user
44
 
        self.activo = True
45
 
        # Test por default, verifica que la página exista.
46
 
        self.test = u'code 200'
47
 
        if r.count():
48
 
            # FIXME: esto creo que es una race condition
49
 
            # Existe la misma URL para el mismo usuario,
50
 
            # reciclamos el id y el test, pero activa.
51
 
            viejo = r.one()
52
 
            Atajo.store.remove(viejo)
53
 
            self.id = viejo.id
54
 
            self.test = viejo.test
55
 
        self.store.add(self)
56
 
        # Autosave/flush/commit a la base de datos
57
 
        self.save()
58
 
 
59
 
    def save(self):
60
 
        '''Método de conveniencia'''
61
 
        Atajo.store.flush()
62
 
        Atajo.store.commit()
63
 
 
64
 
    @classmethod
65
 
    def initDB(cls):
66
 
        # Creamos una base SQLite
67
 
        if not os.path.exists('pyurl.sqlite'):
68
 
            cls.database = create_database("sqlite:///pyurl.sqlite")
69
 
            cls.store = Store (cls.database)
70
 
            try:
71
 
                # Creamos la tabla
72
 
                cls.store.execute ('''
73
 
                    CREATE TABLE atajo (
74
 
                    id INTEGER PRIMARY KEY,
75
 
                    url VARCHAR,
76
 
                    test VARCHAR,
77
 
                    user VARCHAR,
78
 
                    activo TINYINT,
79
 
                    status TINYINT,
80
 
                    ultimo TIMESTAMP
81
 
                    ) ''' )
82
 
                cls.store.flush()
83
 
                cls.store.commit()
84
 
            except:
85
 
                pass
86
 
        else:
87
 
            cls.database = create_database("sqlite:///pyurl.sqlite")
88
 
            cls.store = Store (cls.database)
89
 
    # Caracteres válidos en un atajo de URL
90
 
    #validos = string.letters + string.digits
91
 
 
92
 
    def slug(self):
93
 
        '''Devuelve el slug correspondiente al
94
 
        ID de este atajo
95
 
 
96
 
        Básicamente un slug es un número en base 62,
97
 
        representado usando a-zA-Z0-9 como "dígitos",
98
 
        y dado vuelta:
99
 
 
100
 
        Más significativo a la derecha.
101
 
 
102
 
        Ejemplo:
103
 
 
104
 
        100000 => '4aA'
105
 
        100001 => '5aA'
106
 
 
107
 
        '''
108
 
        s = ''
109
 
#        n = self.id
110
 
#        while n:
111
 
#            s += self.validos[n%62]
112
 
#            n = n // 62
113
 
        return "estoesunslug"
114
 
 
115
 
    @classmethod
116
 
    # FIXME: no estoy feliz con esta API
117
 
    def get(cls, slug = None, user = None, url = None):
118
 
        ''' Dado un slug, devuelve el atajo correspondiente.
119
 
        Dado un usuario:
120
 
        Si url es None, devuelve la lista de sus atajos
121
 
        Si url no es None , devuelve *ese* atajo
122
 
        '''
123
 
 
124
 
        if slug is not None:
125
 
            i = 0
126
 
            for p,l in enumerate(slug):
127
 
                i += 62 ** p * cls.validos.index(l)
128
 
            return cls.store.find(cls, id = i, activo = True).one()
129
 
 
130
 
        if user is not None:
131
 
            if url is None:
132
 
                return cls.store.find(cls, user = user, activo = True)
133
 
        else:
134
 
            return cls.store.find(cls, user = user, url = url, activo = True).one()
135
 
 
136
 
    def delete(self):
137
 
        '''Eliminar este objeto de la base de datos'''
138
 
        self.activo=False
139
 
        self.save()
140
 
 
141
 
    def run_test(self):
142
 
        '''Correr el test con minitwill y almacenar
143
 
        el resultado'''
144
 
        self.status = minitwill(self.url, self.test)
145
 
        self.ultimo = datetime.datetime.now()
146
 
        self.save()
147
 
 
148
 
Atajo.initDB()
149
 
a1 = Atajo(u'http://nomuerde.netmanagers.com.ar', u'unnombredeusuario')
150
 
print a1.slug()
151
 
a1 = Atajo(u'http://www.python.org', u'unnombredeusuario')
152
 
print a1.slug()
153
 
print Atajo.get(slug='b').url
154
 
#$[print x.url for x in Atajo.get(user=u'unnombredeusuario')]
155