Commits

Christian Scholz  committed ae51425

added profile picture field to form and started to add it to the controller.
Implemented a new validator for image uploads, checking file size and file type.

  • Participants
  • Parent commits d2c9862

Comments (0)

Files changed (2)

File adhocracy/controllers/user.py

 from pylons.i18n import _
 from babel import Locale
 
+import quantumcore.contenttypes.registry
+import quantumcore.storages
+
 import adhocracy.lib.text as text
 from adhocracy.lib.base import *
 import adhocracy.forms as forms
     chained_validators = [validators.FieldsMatch(
          'password', 'password_confirm')]
 
+class ImageValidator(formencode.FancyValidator):                                                                                                                                                
+
+    messages = {
+        'too_big': 'The file exceeds the maximum file size of %(max_size)i KB ',
+        'wrong_filetype': 'The uploaded file has the wrong file type',
+        }
+    
+    def validate_python(self, value, state):
+        # check file size
+        if len(value.value)/1024>self.max_size:
+            raise formencode.Invalid(self.message("too_big", state,
+                                       max_size=self.max_size),
+                          value, state)
+        # check file type
+        mr = quantumcore.contenttypes.registry.MIMETypesRegistry()
+        content_type = mr.classify(value.filename, value.value, default="application/octet-stream")
+        if content_type not in self.allowed_types:
+            raise formencode.Invalid(self.message("wrong_filetype", state),
+                          value, state)
+        return value
+    
          
 class UserUpdateForm(formencode.Schema):
     allow_extra_fields = True
     page_size =  validators.Int(min=1, max=100, not_empty=False, if_empty=10, if_missing=10)
     email_priority = validators.Int(min=0, max=6, not_empty=False, if_missing=3)
     twitter_priority = validators.Int(min=0, max=6, not_empty=False, if_missing=3)
+    profilepic = ImageValidator(max_size=1024, allowed_types=['image/png', 'image/jpeg', 'image/jpg', 'image/x-png'])
 
     
 class UserCodeForm(formencode.Schema):
     def update(self, id):
         c.page_user = get_entity_or_abort(model.User, id, instance_filter=False)
         require.user.edit(c.page_user)
+        if request.POST.get("profilepic",u'')!=u'':
+            f=request.POST["profilepic"]
+            fs = quantumcore.storages.FileSystemStorage("/tmp")
         if self.form_result.get("password_change"):
             c.page_user.password = self.form_result.get("password_change")
         c.page_user.display_name = self.form_result.get("display_name")

File adhocracy/templates/user/edit.html

 <%def name="title()">${_("Settings: %s") % c.page_user.name}</%def>
 
 <%def name="breadcrumbs()">
-	${h.user.breadcrumbs(c.page_user)|n} &raquo; ${_("Edit")}
+    ${h.user.breadcrumbs(c.page_user)|n} &raquo; ${_("Edit")}
 </%def>
 
 
-<form name="settings" class="inplace" method="POST" action="/user/${c.page_user.user_name}">
-	${h.field_token()|n}
-	<input type="hidden" name="_method" value="PUT" />
-	<div class="page_title">
-		<label for="display_name" class="armhint">${c.page_user.name}</label>
-		<input tabindex="1" class="title armlabel" name="display_name"
-	 		value="${c.page_user.display_name}"/>
-	 </div>
+<form name="settings" class="inplace" method="POST" action="/user/${c.page_user.user_name}"
+        enctype="multipart/form-data">
+    ${h.field_token()|n}
+    <input type="hidden" name="_method" value="PUT" />
+    <div class="page_title">
+        <label for="display_name" class="armhint">${c.page_user.name}</label>
+        <input tabindex="1" class="title armlabel" name="display_name"
+            value="${c.page_user.display_name}"/>
+     </div>
 
-	<div style="clear:both;"></div>
-	<h3>${_("User Details")}</h3>
-	<div class="sidebar">
-		<div class="infobox">
-			${_("Configure your user icon at <a href='http://www.gravatar.com'>Gravatar</a>")|n} 
-		</div>
-	</div>
-	<div class="mainbar">
-		<label for="locale">${_("Language:")}</label>
-		<ul>
-			%for locale in c.locales:
-				<li style="list-style-type: none;"><input type="radio" name="locale" value="${str(locale)}" 
-					%if locale == c.page_user.locale:
-						checked="checked"
-					%endif
-					/> ${locale.display_name}</li>
-			%endfor
-		</ul>
-	</div>
-	
-	<h3> </h3>
-	<div class="sidebar">
-		<div class="infobox">
-			${_("Select a new password or leave the fields blank to keep your old one.")}
-		</div>
-	</div>
-	
-	<div class="mainbar">	
-		<label for="password_change">${_("Password:")}</label>
-		<input type="password" name="password_change">
+    <div style="clear:both;"></div>
+    <h3>${_("User Details")}</h3>
+    <div class="sidebar">
+        <div class="infobox">
+            ${_("Configure your user icon at <a href='http://www.gravatar.com'>Gravatar</a>")|n} 
+        </div>
+    </div>
+    <div class="mainbar">
+        <label for="locale">${_("Language:")}</label>
+        <ul>
+            %for locale in c.locales:
+                <li style="list-style-type: none;"><input type="radio" name="locale" value="${str(locale)}" 
+                    %if locale == c.page_user.locale:
+                        checked="checked"
+                    %endif
+                    /> ${locale.display_name}</li>
+            %endfor
+        </ul>
+    </div>
 
-		<label for="password_confirm">${_("Password (confirm):")}</label>
-		<input type="password" name="password_confirm">
-	</div>
-	
-	<div style="clear:both;"></div>
-	<h3>${_("Notifications")}</h3>
-	<div class="sidebar">
-		<div class="infobox">
-			${_("Select how you would like to be notified of events.")}
-			<a target="_new" href="/static/notification_faq.html#howmany">${_("Help.")}</a>
-		</div>
-	</div>
-		
-	<div class="mainbar">
-		<table border="0" width="100%">
-			<tr>
-				<th width="50%">${_("Contact")}</th>
-				<th colspan="4">${_("fewer")}</th>
-				<th colspan="2">${_("more notifications")}</th>
-			</tr>
-			<tr>
-				<td>
-		<!-- label for="email">${_("E-Mail:")}</label -->
-					<input name="email" value="${c.page_user.email}"/>
-				</td>
-				%if c.page_user.is_email_activated():
-					<td><input type="radio" name="email_priority" value="6" 
-						${"checked='checked'" if c.page_user.email_priority==6 else ""} /></td>
-					<td><input type="radio" name="email_priority" value="4" 
-						${"checked='checked'" if c.page_user.email_priority==4 else ""} /></td>
-					<td><input type="radio" name="email_priority" value="3" 
-						${"checked='checked'" if c.page_user.email_priority==3 else ""} /></td>
-					<td><input type="radio" name="email_priority" value="2" 
-						${"checked='checked'" if c.page_user.email_priority==2 else ""} /></td>
-					<td><input type="radio" name="email_priority" value="1" 
-						${"checked='checked'" if c.page_user.email_priority==1 else ""} /></td>
-				%else:
-					<td colspan="5">${_("Not confirmed.")}
-						<a href="/user/${c.page_user.user_name}/resend?${h.url_token()}">${_("Re-send activation link")}</a></td>
-				%endif
-			</tr>
-			%if c.page_user.twitter:
-			<tr>
-				<td><img src="/img/twitter.png" /> ${_("Twitter: %s") % c.page_user.twitter.screen_name} &middot;
-					<a href="/twitter/revoke?${h.url_token()}">${_("remove")}</td>
-				<td><input type="radio" name="twitter_priority" value="6" 
-					${"checked='checked'" if c.page_user.twitter.priority==6 else ""} /></td>
-				<td><input type="radio" name="twitter_priority" value="4" 
-					${"checked='checked'" if c.page_user.twitter.priority==4 else ""} /></td>
-				<td><input type="radio" name="twitter_priority" value="3" 
-					${"checked='checked'" if c.page_user.twitter.priority==3 else ""} /></td>
-				<td><input type="radio" name="twitter_priority" value="2" 
-					${"checked='checked'" if c.page_user.twitter.priority==2 else ""} /></td>
-				<td><input type="radio" name="twitter_priority" value="1" 
-					${"checked='checked'" if c.page_user.twitter.priority==1 else ""} /></td>
-			</tr>
-			%endif
-		
-		
-		%if c.page_user == c.user and not c.page_user.twitter:
-		<tr>
-			<td colspan="5">
-				<a href="/twitter/init?${h.url_token()}"><img src="/img/twitter_signin.png" alt="${_("get twitter notifications")}" /></a>
-			</td>
-		</tr>
-		%endif
-			
-		</table>
-	</div>
-	
-	<div style="clear:both;"></div>
-	<h3><img src="/img/icons/openid_20.png" class="cd" /> ${_("OpenID")}</h3>
-	<div class="sidebar">
-		<div class="infobox">
-			${_("OpenID allows you to use a single login on many web sites.")}
-		</div>
-	</div>
-		
-	<div class="mainbar">
-		%if not len(c.page_user.openids):
-			<div class="infobox">
-				${_("There are no associated OpenIDs.")}
-			</div>
-		%else:
-		<table border="0" width="100%">
-			%for openid in c.page_user.openids:
-			<tr>
-				<td><code>${openid.identifier}</code></td>
-				<td><a href="/openid/revoke?id=${openid.id}&${h.url_token()}">${_("remove")}</a></td>
-			</tr>
-			%endfor
-		</table>
-		%endif 
-		<br/>
-		<a class="button add" href="/openid/connect">${_("new")}</a>
-	</div>
-	
-	<div style="clear:both;"></div>
-	<h3>${_("Short biography")}</h3>
-	<div class="sidebar">
-		<div class="infobox">
-			${_("A bio will allow others to learn about you and perhaps even get you a few delegations.")}
-		</div>
-	</div>
-		
-	<div class="mainbar">
-		<textarea tabindex="2" class="description" name="bio">${c.page_user.bio}</textarea>
-		${components.formatting()}
-	</div>
-	
-	<div style="clear: both;"></div>
-	<h3>${_("Advanced Settings")}</h3>
-	
-	<div class="sidebar">
-		<div class="infobox">
-			${_("The pre-set number of entries in listing pages.")}
-		</div>
-	</div>
-	<div class="mainbar">
-		<label for="page_size">${_("List size:")}</label>
-		<select name="page_size">
-			%for n in [10, 20, 30, 40, 50]:
-				<option value="${n}" ${"selected='selected'" if n == c.page_user.page_size else ''}>${n}</option>
-			%endfor
-		</select>
-	</div>
-	<div style="clear: both;"></div>
-	<div class="sidebar">
-		<div class="infobox">
-			${_("Disable help messages and links to the documentation.")}
-		</div>
-	</div>
-	<div class="mainbar">
-		<label for="page_size">${_("Hide help messages:")}</label>
-		<input type="checkbox" name="no_help" value="true" ${'checked="checked"' if c.page_user.no_help else ''} />
-	</div>
-	
-	<div style="clear:both;"></div>
-	${components.savebox("/user/%s" % c.page_user.user_name)}
-	
-</form>
+    <div style="clear:both;"></div>
+    <div class="sidebar">
+        <div class="infobox">
+            ${_("Please upload only JPEG, PNG or GIF images not bigge than 1MB")|n} 
+        </div>
+    </div>
+    <div class="mainbar">   
+        <label for="profilepic">${_("Profile Picture:")}</label>
+        <input type="file" name="profilepic">
+    </div>
+    
+    <h3> </h3>
+    <div class="sidebar">
+        <div class="infobox">
+            ${_("Select a new password or leave the fields blank to keep your old one.")}
+        </div>
+    </div>
+
+    
+    <div class="mainbar">   
+        <label for="password_change">${_("Password:")}</label>
+        <input type="password" name="password_change">
+
+        <label for="password_confirm">${_("Password (confirm):")}</label>
+        <input type="password" name="password_confirm">
+    </div>
+    
+    <div style="clear:both;"></div>
+    <h3>${_("Notifications")}</h3>
+    <div class="sidebar">
+        <div class="infobox">
+            ${_("Select how you would like to be notified of events.")}
+            <a target="_new" href="/static/notification_faq.html#howmany">${_("Help.")}</a>
+        </div>
+    </div>
+        
+    <div class="mainbar">
+        <table border="0" width="100%">
+            <tr>
+                <th width="50%">${_("Contact")}</th>
+                <th colspan="4">${_("fewer")}</th>
+                <th colspan="2">${_("more notifications")}</th>
+            </tr>
+            <tr>
+                <td>
+        <!-- label for="email">${_("E-Mail:")}</label -->
+                    <input name="email" value="${c.page_user.email}"/>
+                </td>
+                %if c.page_user.is_email_activated():
+                    <td><input type="radio" name="email_priority" value="6" 
+                        ${"checked='checked'" if c.page_user.email_priority==6 else ""} /></td>
+                    <td><input type="radio" name="email_priority" value="4" 
+                        ${"checked='checked'" if c.page_user.email_priority==4 else ""} /></td>
+                    <td><input type="radio" name="email_priority" value="3" 
+                        ${"checked='checked'" if c.page_user.email_priority==3 else ""} /></td>
+                    <td><input type="radio" name="email_priority" value="2" 
+                        ${"checked='checked'" if c.page_user.email_priority==2 else ""} /></td>
+                    <td><input type="radio" name="email_priority" value="1" 
+                        ${"checked='checked'" if c.page_user.email_priority==1 else ""} /></td>
+                %else:
+                    <td colspan="5">${_("Not confirmed.")}
+                        <a href="/user/${c.page_user.user_name}/resend?${h.url_token()}">${_("Re-send activation link")}</a></td>
+                %endif
+            </tr>
+            %if c.page_user.twitter:
+            <tr>
+                <td><img src="/img/twitter.png" /> ${_("Twitter: %s") % c.page_user.twitter.screen_name} &middot;
+                    <a href="/twitter/revoke?${h.url_token()}">${_("remove")}</td>
+                <td><input type="radio" name="twitter_priority" value="6" 
+                    ${"checked='checked'" if c.page_user.twitter.priority==6 else ""} /></td>
+                <td><input type="radio" name="twitter_priority" value="4" 
+                    ${"checked='checked'" if c.page_user.twitter.priority==4 else ""} /></td>
+                <td><input type="radio" name="twitter_priority" value="3" 
+                    ${"checked='checked'" if c.page_user.twitter.priority==3 else ""} /></td>
+                <td><input type="radio" name="twitter_priority" value="2" 
+                    ${"checked='checked'" if c.page_user.twitter.priority==2 else ""} /></td>
+                <td><input type="radio" name="twitter_priority" value="1" 
+                    ${"checked='checked'" if c.page_user.twitter.priority==1 else ""} /></td>
+            </tr>
+            %endif
+        
+        
+        %if c.page_user == c.user and not c.page_user.twitter:
+        <tr>
+            <td colspan="5">
+                <a href="/twitter/init?${h.url_token()}"><img src="/img/twitter_signin.png" alt="${_("get twitter notifications")}" /></a>
+            </td>
+        </tr>
+        %endif
+            
+        </table>
+    </div>
+    
+    <div style="clear:both;"></div>
+    <h3><img src="/img/icons/openid_20.png" class="cd" /> ${_("OpenID")}</h3>
+    <div class="sidebar">
+        <div class="infobox">
+            ${_("OpenID allows you to use a single login on many web sites.")}
+        </div>
+    </div>
+        
+    <div class="mainbar">
+        %if not len(c.page_user.openids):
+            <div class="infobox">
+                ${_("There are no associated OpenIDs.")}
+            </div>
+        %else:
+        <table border="0" width="100%">
+            %for openid in c.page_user.openids:
+            <tr>
+                <td><code>${openid.identifier}</code></td>
+                <td><a href="/openid/revoke?id=${openid.id}&${h.url_token()}">${_("remove")}</a></td>
+            </tr>
+            %endfor
+        </table>
+        %endif 
+        <br/>
+        <a class="button add" href="/openid/connect">${_("new")}</a>
+    </div>
+    
+    <div style="clear:both;"></div>
+    <h3>${_("Short biography")}</h3>
+    <div class="sidebar">
+        <div class="infobox">
+            ${_("A bio will allow others to learn about you and perhaps even get you a few delegations.")}
+        </div>
+    </div>
+        
+    <div class="mainbar">
+        <textarea tabindex="2" class="description" name="bio">${c.page_user.bio}</textarea>
+        ${components.formatting()}
+    </div>
+    
+    <div style="clear: both;"></div>
+    <h3>${_("Advanced Settings")}</h3>
+    
+    <div class="sidebar">
+        <div class="infobox">
+            ${_("The pre-set number of entries in listing pages.")}
+        </div>
+    </div>
+    <div class="mainbar">
+        <label for="page_size">${_("List size:")}</label>
+        <select name="page_size">
+            %for n in [10, 20, 30, 40, 50]:
+                <option value="${n}" ${"selected='selected'" if n == c.page_user.page_size else ''}>${n}</option>
+            %endfor
+        </select>
+    </div>
+    <div style="clear: both;"></div>
+    <div class="sidebar">
+        <div class="infobox">
+            ${_("Disable help messages and links to the documentation.")}
+        </div>
+    </div>
+    <div class="mainbar">
+        <label for="page_size">${_("Hide help messages:")}</label>
+        <input type="checkbox" name="no_help" value="true" ${'checked="checked"' if c.page_user.no_help else ''} />
+    </div>
+    
+    <div style="clear:both;"></div>
+    ${components.savebox("/user/%s" % c.page_user.user_name)}
+    
+</form>