Commit 08d8d2ed3e8269028ee23806e33dd35ce84fc60a

Authored by Luan
2 parents ff53d32c 03fd3b9f

Merge branch 'master' of github.com:TracyWebTech/colab

src/accounts/forms.py
... ... @@ -5,11 +5,24 @@ from django.contrib.auth import get_user_model
5 5 from django.utils.translation import ugettext_lazy as _
6 6  
7 7 from super_archives.models import MailingList
8   -
  8 +from .utils.validators import validate_social_account
9 9  
10 10 User = get_user_model()
11 11  
12 12  
  13 +class SocialAccountField(forms.Field):
  14 + def __init__(self, *args, **kwargs):
  15 + self.url = kwargs.pop('url', None)
  16 + super(SocialAccountField, self).__init__(*args, **kwargs)
  17 +
  18 + def validate(self, value):
  19 + super(SocialAccountField, self).validate(value)
  20 +
  21 + if value and not validate_social_account(value, self.url):
  22 + raise forms.ValidationError(_('Social account does not exist'),
  23 + code='social-account-doesnot-exist')
  24 +
  25 +
13 26 class UserForm(forms.ModelForm):
14 27 required = ('first_name', 'last_name', 'email', 'username')
15 28  
... ... @@ -34,12 +47,16 @@ class UserCreationForm(UserForm):
34 47  
35 48  
36 49 class UserUpdateForm(UserForm):
  50 +
37 51 class Meta:
38 52 model = User
39 53 fields = ('username', 'first_name', 'last_name',
40 54 'institution', 'role', 'twitter', 'facebook',
41 55 'google_talk', 'webpage')
42 56  
  57 + twitter = SocialAccountField(url='https://twitter.com/', required=False)
  58 + facebook = SocialAccountField(url='https://graph.facebook.com/', required=False)
  59 +
43 60  
44 61 class ListsForm(forms.Form):
45 62 LISTS_NAMES = ((list.name, list.name) for list in MailingList.objects.all())
... ...
src/accounts/migrations/0005_remove_host_from_social_accounts.py 0 → 100644
... ... @@ -0,0 +1,67 @@
  1 +# -*- coding: utf-8 -*-
  2 +import datetime
  3 +from south.db import db
  4 +from south.v2 import DataMigration
  5 +from django.db import models
  6 +
  7 +class Migration(DataMigration):
  8 +
  9 + def forwards(self, orm):
  10 + for user in orm.User.objects.iterator():
  11 + if user.twitter:
  12 + user.twitter = user.twitter.split('/')[-1]
  13 + if user.facebook:
  14 + user.facebook = user.facebook.split('/')[-1]
  15 + user.save()
  16 +
  17 + def backwards(self, orm):
  18 + "Write your backwards methods here."
  19 +
  20 + models = {
  21 + u'accounts.user': {
  22 + 'Meta': {'object_name': 'User'},
  23 + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
  24 + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75', 'blank': 'True'}),
  25 + 'facebook': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
  26 + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
  27 + 'google_talk': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
  28 + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
  29 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  30 + 'institution': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
  31 + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
  32 + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
  33 + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
  34 + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
  35 + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
  36 + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
  37 + 'role': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
  38 + 'twitter': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
  39 + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
  40 + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
  41 + 'verification_hash': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
  42 + 'webpage': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'})
  43 + },
  44 + u'auth.group': {
  45 + 'Meta': {'object_name': 'Group'},
  46 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  47 + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
  48 + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
  49 + },
  50 + u'auth.permission': {
  51 + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
  52 + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
  53 + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
  54 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  55 + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
  56 + },
  57 + u'contenttypes.contenttype': {
  58 + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
  59 + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
  60 + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
  61 + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
  62 + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
  63 + }
  64 + }
  65 +
  66 + complete_apps = ['accounts']
  67 + symmetrical = True
... ...
src/accounts/models.py
1 1  
  2 +import urlparse
  3 +
2 4 from django.db import models
3 5 from django.contrib.auth.models import AbstractUser
4   -
5 6 from django.core.urlresolvers import reverse
6 7  
7 8  
... ... @@ -17,6 +18,12 @@ class User(AbstractUser):
17 18 def get_absolute_url(self):
18 19 return reverse('user_profile', kwargs={'username': self.username})
19 20  
  21 + def twitter_link(self):
  22 + return urlparse.urljoin('https://twitter.com', self.twitter)
  23 +
  24 + def facebook_link(self):
  25 + return urlparse.urljoin('https://www.facebook.com', self.facebook)
  26 +
20 27 # We need to have `email` field set as unique but Django does not
21 28 # support field overriding (at least not until 1.6).
22 29 # The following workaroud allows to change email field to unique
... ...
src/accounts/templates/accounts/user_detail.html
... ... @@ -9,7 +9,7 @@
9 9 {% block main-content %}
10 10  
11 11 <div id="user-profile" class="row">
12   - <div class="vcard col-lg-3 col-md-3 col-sm-4">
  12 + <div class="vcard col-lg-4 col-md-4 col-sm-4">
13 13 <div class="thumbnail">
14 14 {% gravatar user_.email 200 %}
15 15 </div>
... ... @@ -43,23 +43,26 @@
43 43 </li>
44 44 {% endif %}
45 45 {% if request.user.is_active %}
  46 + <li>
46 47 {% if user_.twitter %}
47   - <li><span class="icon-twitter icon-fixed-width"></span> {{ user_.twitter }}</li>
  48 + <span class="icon-twitter icon-fixed-width"></span> <a target="_blank" href="{{ user_.twitter_link }}" title="{% trans 'Twitter account' %}">{{ user_.twitter }}</a>
48 49 {% endif %}
49 50 {% if user_.facebook %}
50   - <li><span class="icon-facebook icon-fixed-width"></span> {{ user_.facebook }}</li>
  51 + <span class="icon-facebook icon-fixed-width"></span> <a target="_blank" href="{{ user_.facebook_link }}" title="{% trans 'Facebook account' %}">{{ user_.facebook }}</a>
51 52 {% endif %}
  53 + </li>
  54 +
52 55 {% if user_.google_talk %}
53 56 <li><span class="icon-google-plus icon-fixed-width"></span> {{ user_.google_talk }}</li>
54 57 {% endif %}
55 58 {% if user_.webpage %}
56   - <li><span class="icon-link icon-fixed-width"></span> {{ user_.webpage }}</li>
  59 + <li><span class="icon-link icon-fixed-width"></span> <a target="_blank" href="{{ user_.webpage }}" title="{% trans 'Personal webpage' %}">{{ user_.webpage }}</a></li>
57 60 {% endif %}
58 61 {% endif %}
59 62 </ul>
60 63 </div>
61 64  
62   - <div class="col-lg-5 col-md-5 col-sm-8">
  65 + <div class="col-lg-4 col-md-4 col-sm-8">
63 66 <div class="panel panel-default">
64 67 <div class="panel-heading">
65 68 <h3 class="panel-title">{% trans "Contributions by Area" %}</h3>
... ...
src/accounts/utils/__init__.py 0 → 100644
src/accounts/utils/validators.py 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +
  2 +import urllib2
  3 +import urlparse
  4 +
  5 +
  6 +def validate_social_account(account, url):
  7 + """Verifies if a social account is valid.
  8 +
  9 + Examples:
  10 +
  11 + >>> validate_social_account('seocam', 'http://twitter.com')
  12 + True
  13 +
  14 + >>> validate_social_account('seocam-fake-should-fail', 'http://twitter.com')
  15 + False
  16 + """
  17 +
  18 + request = urllib2.Request(urlparse.urljoin(url, account))
  19 + request.get_method = lambda: 'HEAD'
  20 +
  21 + try:
  22 + response = urllib2.urlopen(request)
  23 + except urllib2.HTTPError:
  24 + return False
  25 +
  26 + return response.code == 200
... ...