Added MIT license.
[zzz-floof.git] / floof / model / art.py
1 #
2 # floof/floof/model/art.py
3 #
4 # Copyright (c) 2009 Scribblr
5 #
6
7 # from elixir import Entity, Field, Integer, Unicode
8 from elixir import *
9 import elixir
10
11 from pylons import config
12
13 from floof.lib.file_storage import get_path, save_file
14 from floof.lib.dbhelpers import find_or_create, update_or_create
15 import floof.model.comments
16
17 class Art(Entity):
18 title = Field(Unicode(120))
19 original_filename = Field(Unicode(120))
20 hash = Field(String, unique=True, required=True)
21
22 uploader = ManyToOne('User', required=True)
23 tags = OneToMany('Tag')
24 discussion = ManyToOne('Discussion')
25
26 def set_file(self, file):
27 self.hash = save_file("art", file)
28 self.original_filename = file.filename
29
30 file = property(get_path, set_file)
31
32 def get_path(self):
33 if self.hash:
34 return get_path("art", self.hash)
35
36
37 def add_tags(self, tags, user):
38 for text in tags.split():
39 if text[0] == '-':
40 # Nega-tags
41 tagtext = TagText.get_by(text=text[1:])
42 if tagtext:
43 tag = Tag.get_by(art=self, tagger=user, tagtext=tagtext)
44 if tag:
45 elixir.session.delete(tag)
46
47 else:
48 if len(text) > 50:
49 raise "Long Tag!" # can we handle this more gracefully?
50 # sqlite seems happy to store strings much longer than the supplied limit...
51
52 # elixir should really have its own find_or_create.
53 tagtext = find_or_create(TagText, text=text)
54 tag = find_or_create(Tag, art=self, tagger=user, tagtext=tagtext)
55
56
57
58
59 def rate(self, score, user):
60 return update_or_create(Rating, {"rater":user, "art":self}, {"score":score})
61
62 def user_score(self, user):
63 rating = Rating.get_by(rater=user, art=self)
64 if rating:
65 return rating.score
66 return Rating.default
67
68 def __unicode__(self):
69 return self.get_path()
70
71
72 class Tag(Entity):
73 # look into how ondelete works. This just sets a database property.
74 art = ManyToOne('Art', ondelete='cascade')
75 tagger = ManyToOne('User', ondelete='cascade')
76 tagtext = ManyToOne('TagText')
77
78 def __unicode__(self):
79 if not self.tagtext:
80 return "(broken)"
81 return unicode(self.tagtext)
82
83
84 class TagText(Entity):
85 text = Field(Unicode(50)) # gotta enforce this somehow
86 tags = OneToMany('Tag')
87
88 def __unicode__(self):
89 return self.text
90
91
92 class Rating(Entity):
93 art = ManyToOne('Art', ondelete='cascade')
94 rater = ManyToOne('User', ondelete='cascade')
95 score = Field(Integer)
96
97 options = {-1:"sucks", 0:"undecided", 1:"good", 2:"great"}
98 default = 0
99
100
101 Rating.reverse_options = dict (zip(Rating.options.values(), Rating.options.keys()))