3 from pylons
import config
, request
, response
, session
, tmpl_context
as c
, h
4 from pylons
.controllers
.util
import abort
, redirect
6 from floof
.lib
.base
import BaseController
, render
8 log
= logging
.getLogger(__name__
)
10 from floof
.lib
import file_storage
as storage
11 from floof
.model
import Art
, Rating
, ArtUser
12 from floof
.model
.art
import ArtUserType
13 from floof
.model
.comments
import Discussion
14 from floof
.model
.users
import User
, UserRelationship
21 from sqlalchemy
import func
22 from sqlalchemy
.exceptions
import IntegrityError
23 from sqlalchemy
.orm
.exc
import NoResultFound
24 from wtforms
.validators
import ValidationError
28 class ArtUploadForm(Form
):
29 by
= TextField('Artists')
30 file = FileField('Upload')
31 url
= TextField('Link')
33 # TODO: make this general purpose
34 def validate_file(self
, field
):
36 raise ValidationError('File is required')
39 class ArtController(BaseController
):
40 def __before__(self
, id=None):
41 super(ArtController
, self
).__before__()
42 # Awesome refactoring!
44 c
.art
= h
.get_object_or_404(Art
, id=id)
48 c
.form
= ArtUploadForm()
49 return render("/art/new.mako")
51 # TODO: login required
53 c
.form
= ArtUploadForm(request
.params
)
54 if not c
.form
.validate():
55 ## TODO: JavaScript should be added to the upload form so that it is
56 ## impossible to submit the form when it contains any invalid users,
57 ## so this never happens. Only autocompled usernames should be allowed.
58 return render("/art/new.mako")
61 upload
= request
.params
['file']
62 hash = storage
.save_file('art/original', upload
.file)
64 # Create a thumbnail and a medium view
66 config
['app_conf']['static_root']
67 + storage
.get_path('art/original', hash)[1:]
69 for subdir
, config_size
in [('medium', config
['medium_size']),
70 ('thumbnail', config
['thumbnail_size'])]:
71 path
= config
['app_conf']['static_root'] + storage
.get_path("art/{0}".format(subdir
), hash)
73 dir, _
= os
.path
.split(path
)
74 if not os
.path
.exists(dir):
77 size
= int(config_size
)
78 shrunken_img
= img
.copy()
79 shrunken_img
.thumbnail((size
, size
), PIL
.Image
.ANTIALIAS
)
80 shrunken_img
.save(path
, img
.format
)
82 #magicker = magic.Magic(mime=True)
83 buffer = upload
.file.read(64)
85 mimetype
= 'image/unknown' #magickery.from_buffer(buffer)
87 # XXX Ensure we can actually handle the mimetype
92 original_filename
=upload
.filename
,
96 c
.art
.discussion
= Discussion(count
=0)
98 # For the moment, cheerfully assume that people are uploading their own
100 ArtUser(art
=c
.art
, user
=c
.user
, type=ArtUserType
.BY
)
104 elixir
.session
.commit()
105 redirect(url('show_art', id=c
.art
.id))
106 except IntegrityError
:
107 # XXX Check this as early as possible, and clean up the filesystem!
108 # Right now this replaces the original file!
110 elixir
.session
.rollback()
111 duplicate_art
= Art
.get_by(hash=hash)
112 h
.flash("We already have that one.")
113 redirect(url('show_art', id=duplicate_art
.id))
118 # c.art = h.get_object_or_404(Art, id=id)
120 c
.your_score
= c
.art
.user_score(c
.user
)
121 return render("/art/show.mako")
124 # TODO: login required
126 # c.art = h.get_object_or_404(Art, id=id)
127 score
= request
.params
.get("score")
128 if score
and score
.isnumeric():
131 score
= Rating
.reverse_options
.get(score
)
133 c
.art
.rate(score
, c
.user
)
134 elixir
.session
.commit()
136 redirect(url('show_art', id=c
.art
.id))
139 def watchstream(self
, name
):
140 """Watchstream for a certain user."""
142 c
.watching_user
= User
.query
.filter(func
.lower(User
.name
) == name
) \
144 except NoResultFound
:
147 # This user has watches which are users which have art
148 # XXX use artist, not uploader
149 c
.artwork
= Art
.query
.join(Art
.uploader
,
150 User
.target_of_relationships
) \
151 .filter(UserRelationship
.user_id
== c
.watching_user
.id)
153 return render('/index.mako')