Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ngns-io committed May 9, 2014
0 parents commit 7f980a1
Show file tree
Hide file tree
Showing 18 changed files with 727 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
*.pyc
*.pyo
*.db
.DS_Store
.coverage
local_settings.py
/static
/dist
*.egg-info
23 changes: 23 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Copyright (c) Doug Evenhouse, Evenhouse Consulting, Inc. and individual contributors.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5 changes: 5 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include LICENSE
include README.md
recursive-include mezzanine_people/templates *
recursive-include mezzanine_people/templatetags *
recursive-include mezzanine_people/migrations *
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
Overview
========
This pluggable app provides a "Person" model to categorize and list people on your Mezzanine sites.


Requirements
============
Required
- [Mezzanine CMS] [1]


Installation
============
1. Add mezzanine_people to your virtualenv or clone the repository :
```bash
pip install mezzanine_people
```

2. Add "people" to INSTALLED_APPS:
```python
INSTALLED_APPS = (
"...",
"mezzanine_people",
)
```

3. Set values for some settings (Optional):
```python
PEOPLE_PER_PAGE = 5 # the default is 10
```

4. Include the people URLconf in your project urls.py like this:
```python
url(r'^people/', include('mezzanine_people.urls')),
```

5. Run `python manage.py createdb` or `python manage.py syncdb && python manage.py migrate`.


Template Tag Usage
==================
1. Include people_tags in the template:

{% load ... people_tags %}

2. Insert tag anywhere in the template:

{% get_random_people 10 as featured_people_list %}


Version 0.1
-----------
- Initial Release

[1]: http://mezzanine.jupo.org "Mezzanine CMS"
1 change: 1 addition & 0 deletions mezzanine_people/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "0.1"
54 changes: 54 additions & 0 deletions mezzanine_people/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@

from copy import deepcopy

from django.contrib import admin

from .models import Person, PersonLink, PersonCategory
from mezzanine.conf import settings
from mezzanine.core.admin import DisplayableAdmin


person_fieldsets = deepcopy(DisplayableAdmin.fieldsets)
person_fieldsets[0][1]["fields"].insert(1, "categories")
person_list_display = ["title", "status", "admin_link"]
person_fieldsets[0][1]["fields"].extend(["first_name", "last_name", "job_title",
"mugshot", "mugshot_credit", "bio", "email",
"order"])
person_list_display.insert(0, "admin_thumb")


class PersonLinkInline(admin.TabularInline):
model = PersonLink

class PersonAdmin(DisplayableAdmin):
"""
Admin class for people.
"""

fieldsets = person_fieldsets
list_display = person_list_display
filter_horizontal = ("categories",)
inlines = [
PersonLinkInline,
]

class PersonCategoryAdmin(admin.ModelAdmin):
"""
Admin class for people categories. Hides itself from the admin menu
unless explicitly specified.
"""

fieldsets = ((None, {"fields": ("title",)}),)

def in_menu(self):
"""
Hide from the admin menu unless explicitly set in ``ADMIN_MENU_ORDER``.
"""
for (name, items) in settings.ADMIN_MENU_ORDER:
if "people.PersonCategory" in items:
return True
return False


admin.site.register(Person, PersonAdmin)
admin.site.register(PersonCategory, PersonCategoryAdmin)
24 changes: 24 additions & 0 deletions mezzanine_people/defaults.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""
Default settings for the ``mezzanine_people`` app. Each of these can be
overridden in your project's settings module, just like regular
Django settings. The ``editable`` argument for each controls whether
the setting is editable via Django's admin.
Thought should be given to how a setting is actually used before
making it editable, as it may be inappropriate - for example settings
that are only read during startup shouldn't be editable, since changing
them would require an application reload.
"""

from django.utils.translation import ugettext_lazy as _

from mezzanine.conf import register_setting


register_setting(
name="PEOPLE_PER_PAGE",
label=_("People per page"),
description=_("Max number of people shown on a people listing page."),
editable=True,
default=10,
)
133 changes: 133 additions & 0 deletions mezzanine_people/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

def forwards(self, orm):
# Adding model 'Person'
db.create_table(u'mezzanine_people_person', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
(u'keywords_string', self.gf('django.db.models.fields.CharField')(max_length=500, blank=True)),
('site', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['sites.Site'])),
('title', self.gf('django.db.models.fields.CharField')(max_length=500)),
('slug', self.gf('django.db.models.fields.CharField')(max_length=2000, null=True, blank=True)),
('_meta_title', self.gf('django.db.models.fields.CharField')(max_length=500, null=True, blank=True)),
('description', self.gf('django.db.models.fields.TextField')(blank=True)),
('gen_description', self.gf('django.db.models.fields.BooleanField')(default=True)),
('created', self.gf('django.db.models.fields.DateTimeField')(null=True)),
('updated', self.gf('django.db.models.fields.DateTimeField')(null=True)),
('status', self.gf('django.db.models.fields.IntegerField')(default=2)),
('publish_date', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
('expiry_date', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
('short_url', self.gf('django.db.models.fields.URLField')(max_length=200, null=True, blank=True)),
('in_sitemap', self.gf('django.db.models.fields.BooleanField')(default=True)),
('content', self.gf('mezzanine.core.fields.RichTextField')()),
('first_name', self.gf('django.db.models.fields.CharField')(max_length=100, blank=True)),
('last_name', self.gf('django.db.models.fields.CharField')(max_length=100, blank=True)),
('mugshot', self.gf('mezzanine.core.fields.FileField')(max_length=255, null=True, blank=True)),
('mugshot_credit', self.gf('django.db.models.fields.CharField')(max_length=200, blank=True)),
('email', self.gf('django.db.models.fields.EmailField')(max_length=75, blank=True)),
('bio', self.gf('mezzanine.core.fields.RichTextField')(default='', blank=True)),
('job_title', self.gf('django.db.models.fields.CharField')(max_length=60, blank=True)),
('order', self.gf('django.db.models.fields.PositiveSmallIntegerField')(default=0)),
))
db.send_create_signal(u'mezzanine_people', ['Person'])

# Adding M2M table for field categories on 'Person'
m2m_table_name = db.shorten_name(u'mezzanine_people_person_categories')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('person', models.ForeignKey(orm[u'mezzanine_people.person'], null=False)),
('personcategory', models.ForeignKey(orm[u'mezzanine_people.personcategory'], null=False))
))
db.create_unique(m2m_table_name, ['person_id', 'personcategory_id'])

# Adding model 'PersonLink'
db.create_table(u'mezzanine_people_personlink', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=50)),
('url', self.gf('django.db.models.fields.URLField')(max_length=200)),
('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['mezzanine_people.Person'])),
))
db.send_create_signal(u'mezzanine_people', ['PersonLink'])

# Adding model 'PersonCategory'
db.create_table(u'mezzanine_people_personcategory', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('site', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['sites.Site'])),
('title', self.gf('django.db.models.fields.CharField')(max_length=500)),
('slug', self.gf('django.db.models.fields.CharField')(max_length=2000, null=True, blank=True)),
))
db.send_create_signal(u'mezzanine_people', ['PersonCategory'])


def backwards(self, orm):
# Deleting model 'Person'
db.delete_table(u'mezzanine_people_person')

# Removing M2M table for field categories on 'Person'
db.delete_table(db.shorten_name(u'mezzanine_people_person_categories'))

# Deleting model 'PersonLink'
db.delete_table(u'mezzanine_people_personlink')

# Deleting model 'PersonCategory'
db.delete_table(u'mezzanine_people_personcategory')


models = {
u'mezzanine_people.person': {
'Meta': {'ordering': "('order', 'last_name', 'first_name')", 'object_name': 'Person'},
'_meta_title': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}),
'bio': ('mezzanine.core.fields.RichTextField', [], {'default': "''", 'blank': 'True'}),
'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'people'", 'blank': 'True', 'to': u"orm['mezzanine_people.PersonCategory']"}),
'content': ('mezzanine.core.fields.RichTextField', [], {}),
'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'expiry_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'gen_description': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'in_sitemap': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'job_title': ('django.db.models.fields.CharField', [], {'max_length': '60', 'blank': 'True'}),
u'keywords_string': ('django.db.models.fields.CharField', [], {'max_length': '500', 'blank': 'True'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'mugshot': ('mezzanine.core.fields.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'mugshot_credit': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'}),
'publish_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'short_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'site': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['sites.Site']"}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '2000', 'null': 'True', 'blank': 'True'}),
'status': ('django.db.models.fields.IntegerField', [], {'default': '2'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
'updated': ('django.db.models.fields.DateTimeField', [], {'null': 'True'})
},
u'mezzanine_people.personcategory': {
'Meta': {'object_name': 'PersonCategory'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'site': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['sites.Site']"}),
'slug': ('django.db.models.fields.CharField', [], {'max_length': '2000', 'null': 'True', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '500'})
},
u'mezzanine_people.personlink': {
'Meta': {'ordering': "('name',)", 'object_name': 'PersonLink'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['mezzanine_people.Person']"}),
'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
},
u'sites.site': {
'Meta': {'ordering': "(u'domain',)", 'object_name': 'Site', 'db_table': "u'django_site'"},
'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
}
}

complete_apps = ['mezzanine_people']
Empty file.
68 changes: 68 additions & 0 deletions mezzanine_people/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _

from mezzanine.conf import settings
from mezzanine.core.fields import RichTextField, FileField
from mezzanine.core.models import Displayable, RichText, Slugged
from mezzanine.utils.models import AdminThumbMixin


class Person(Displayable, RichText, AdminThumbMixin):
"""
A person.
"""

categories = models.ManyToManyField("PersonCategory",
verbose_name=_("Categories"),
blank=True, related_name="people")
first_name = models.CharField(_("first name"), blank=True, max_length=100)
last_name = models.CharField(_("last name"), blank=True, max_length=100)
mugshot = FileField(verbose_name=_("Profile photo"),
upload_to="people", format="Image",
max_length=255, null=True, blank=True)
mugshot_credit = models.CharField(_("Profile photo credit"), blank=True, max_length=200)
email = models.EmailField(_("e-mail address"), blank=True)
bio = RichTextField(_("biography"),
help_text=_("This field can contain HTML and should contain a few paragraphs describing the background of the person."),
default="", blank=True)
job_title = models.CharField(_("job title"), max_length=60, blank=True, help_text=_("Example: First Grade Teacher"))
order = models.PositiveSmallIntegerField(default=0)
admin_thumb_field = "mugshot"
search_fields = {"first_name", "last_name", "bio", "job_title",}

class Meta:
verbose_name = _("Person")
verbose_name_plural = _("People")
ordering = ("order", "last_name", "first_name",)

@property
def full_name(self):
return u'%s %s' % (self.first_name, self.last_name)

@models.permalink
def get_absolute_url(self):
return ("person_detail", (), {"slug": self.slug})

class PersonLink(models.Model):
"""
A link to a person's interesting URLs, such as Twitter or Facebook
"""
name = models.CharField(_("link name"), max_length=50, help_text=_("Friendly name of the link. E.g. Twitter"))
url = models.URLField(_("URL"))
person = models.ForeignKey(Person)

class Meta:
ordering = ('name',)

class PersonCategory(Slugged):
"""
A category for grouping people.
"""

class Meta:
verbose_name = _("Person Category")
verbose_name_plural = _("Person Categories")

@models.permalink
def get_absolute_url(self):
return ("person_list_category", (), {"slug": self.slug})
Loading

0 comments on commit 7f980a1

Please sign in to comment.