-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmodel_v1.py
151 lines (140 loc) · 4.72 KB
/
model_v1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import sqlite3
import re
from os import path
import minijson
class DataStoreV1(object):
'''
OBSOLETE: Represents a loaded set of cards in the old format.
Construct with a filename. Creates the file if it doesn't exist
Also includes config
'''
def __init__(self, conn):
'''
Initialize the data store. If the file doesn't exist, adds the
infrastructure, and optionally the sample data.
'''
self.conn = conn
# load cards into self.cards
self.cards = []
for hsh, data in self.conn.execute("select * from cards"):
self.cards.append(Card(self, hash=hsh, data=data))
def get_cards(self):
return self.cards
class InvalidCard(Exception):
pass
class Card(object):
'''
A single card. All properties, when written, write to the
data store. For now, that means it hits sqlite which (I think)
hits the disk. Someday we'll do something more intelligent.
Probably after a rewrite.
members:
* hash: the current id as supplied by the data store
* _x, _y, _w, _h: position and dimensions of card
* _text: text of the card
* x, y, w, h, text: properties that save when modified
'''
def __init__(self, datastore, *args, **kwargs):
'''
Creates a representation of a card object. Must be called in one
of two ways
Card(datastore, hash=<hash>, data=<data>)
Card(datastore, x, y, w, h)
The first form is for loading a card from the store. The second is
for creating new cards. I'm not going to do much checking, so be
careful.
'''
self.datastore = datastore
# there should either be args or kwargs, but not both. just assume it:
if kwargs:
# loading
self.hash = kwargs['hash']
self.unpack(kwargs['data']) # let errors out
else:
# new card, with no hash yet
assert len(args) == 4
self._x = args[0]
self._y = args[1]
self._w = args[2]
self._h = args[3]
self._text = ''
# save it and keep id
self.hash = self.datastore.create_card(str(self))
def get_x(self): return self._x
def get_y(self): return self._y
def get_w(self): return self._w
def get_h(self): return self._h
def get_text(self): return self._text
def save(self):
# write self in standard format
# send command to datastore
self.hash = self.datastore.modify_card(self.hash, str(self))
def set_pos(self, x, y):
self._x = x
self._y = y
self.save()
def set_dimensions(self, w, h):
self._w = w
self._h = h
self.save()
def set_x(self, x):
self._x = x
self.save()
def set_y(self, y):
self._y = y
self.save()
def set_w(self, w):
self._w = w
self.save()
def set_h(self, h):
self._h = h
self.save()
def set_text(self, text):
self._text = text
self.save()
x = property(get_x, set_x)
y = property(get_y, set_y)
w = property(get_w, set_w)
h = property(get_h, set_h)
text = property(get_text, set_text)
def __str__(self):
return minijson.encode({
'objtype': 'card',
'x': int(self._x),
'y': int(self._y),
'w': int(self._w),
'h': int(self._h),
'text': self._text,
})
def unpack(self, string):
old_regex = re.compile(
r'''{(?P<x>-?\d+),(?P<y>-?\d+),(?P<w>-?\d+),(?P<h>-?\d+)}(?P<text>.*)''',
flags = re.MULTILINE | re.DOTALL # must match multiple lines of text
)
match = old_regex.match(string)
if match:
# this is an old-format card
self._x = int(match.group('x'))
self._y = int(match.group('y'))
self._w = int(match.group('w'))
self._h = int(match.group('h'))
self._text = match.group('text')
else:
try:
data = minijson.decode(string)
self._x = data['x']
self._y = data['y']
self._w = data['w']
self._h = data['h']
self._text = data['text']
except ValueError:
raise InvalidCard("Could not parse card at all!")
except KeyError:
raise InvalidCard("Card data did not contain all required fields!")
# make sure w and h are valid
if self._w <= 0:
raise InvalidCard('Card width must be > 0!')
if self._h <= 0:
raise InvalidCard('Card height must be > 0!')
def delete(self):
self.datastore.delete_card(self.hash)