Skip to content

Commit

Permalink
factored course discovery into separate app
Browse files Browse the repository at this point in the history
  • Loading branch information
dirkcuys committed Aug 15, 2012
1 parent e5de40d commit e8822c3
Show file tree
Hide file tree
Showing 22 changed files with 628 additions and 266 deletions.
46 changes: 46 additions & 0 deletions lernanta/apps/discover/forms.py
@@ -0,0 +1,46 @@
import logging

from django import forms
from django.conf import settings
from django.utils.translation import ugettext as _
from django.contrib.sites.models import Site
from django.template.loader import render_to_string
from django.db.models import Count

from schools.models import School

from discover.models import get_active_languages

log = logging.getLogger(__name__)

class ProjectsFilterForm(forms.Form):
# Not Listed by Default
archived = forms.BooleanField(required=False, widget=forms.HiddenInput)
under_development = forms.BooleanField(required=False, widget=forms.HiddenInput)
closed_signup = forms.BooleanField(required=False, widget=forms.HiddenInput)
# Filter Links
COMMUNITY = 'community'
SHOWCASE = 'showcase'
FRESH = 'fresh'
POPULAR = 'popular'
UPDATED = 'updated'
FEATURED_CHOICES = (
(COMMUNITY, _('Community Picks')),
(SHOWCASE, _('Showcase')),
(FRESH, _('Fresh Additions')),
(POPULAR, _('Popular')),
(UPDATED, _('Last Updated'))
)
featured = forms.ChoiceField(required=False, widget=forms.HiddenInput,
choices=FEATURED_CHOICES)
school = forms.ModelChoiceField(required=False, queryset=School.objects.all(),
widget=forms.HiddenInput)
tag = forms.CharField(required=False, widget=forms.HiddenInput)
# Filter Form
language = forms.ChoiceField(required=False, choices=[('all', 'All')] + get_active_languages())
reviewed = forms.BooleanField(required=False)


class SearchPreferenceForm(forms.Form):
search_language = forms.ChoiceField(required=False, choices=[('all', 'All')] + get_active_languages())
reviewed = forms.BooleanField(required=False)
75 changes: 75 additions & 0 deletions lernanta/apps/discover/models.py
@@ -0,0 +1,75 @@
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db.models import Count

from tags.models import GeneralTaggedItem
from projects.models import Project


def get_active_languages():
""" Return a list of the active language currently in use """
language_list = Project.objects.all().values_list('language').distinct('language')
language_dict = dict(settings.LANGUAGES)
languages = [(l[0], language_dict[l[0]],) for l in language_list]
return languages


def search(keyword, limit = 10):
""" a simple 1 word search for courses, will match partial name
or any tag.
"""
results = []
results += Project.objects.filter(name__icontains=keyword)[:limit]
results += get_tagged_projects(keyword)[:limit]
return list(set(results))[:limit]


def get_listed_projects():
""" return all the projects that should be listed """
listed = Project.objects.filter(
not_listed=False,
deleted=False,
archived=False,
under_development=False,
test=False)
return listed


def get_popular_tags(max_count=10):
ct = ContentType.objects.get_for_model(Project)
listed = list(get_listed_projects().values_list('id', flat=True))
return GeneralTaggedItem.objects.filter(
content_type=ct, object_id__in=listed).values(
'tag__name').annotate(tagged_count=Count('object_id')).order_by(
'-tagged_count')[:max_count]


def get_weighted_tags(min_count=2, min_weight=1.0, max_weight=7.0):
ct = ContentType.objects.get_for_model(Project)
listed = get_listed_projects().values('id')
tags = GeneralTaggedItem.objects.filter(
content_type=ct, object_id__in=listed).values(
'tag__name').annotate(tagged_count=Count('object_id')).filter(
tagged_count__gte=min_count)
if tags.count():
min_tagged_count = tags.order_by('tagged_count')[0]['tagged_count']
max_tagged_count = tags.order_by('-tagged_count')[0]['tagged_count']
if min_tagged_count == max_tagged_count:
factor = 1.0
else:
factor = float(max_weight - min_weight) / float(max_tagged_count - min_tagged_count)
tags = tags.order_by('tag__name')
for tag in tags:
tag['weight'] = max_weight - (max_tagged_count - tag['tagged_count']) * factor
return tags


def get_tagged_projects(tag_name, projects=None):
ct = ContentType.objects.get_for_model(Project)
items = GeneralTaggedItem.objects.filter(
content_type=ct, tag__name=tag_name).values(
'object_id')
if not projects:
projects = Project.objects
return projects.filter(id__in=items)

52 changes: 52 additions & 0 deletions lernanta/apps/discover/tests.py
@@ -0,0 +1,52 @@
from django.test import Client
from django.contrib.auth.models import User

from users.models import create_profile
from projects.models import Project

from test_utils import TestCase


class ProjectTests(TestCase):

test_username = 'testuser'
test_email = 'test@mozillafoundation.org'
test_password = 'testpass'

def setUp(self):
self.client = Client()
self.locale = 'en'
django_user = User(
username=self.test_username,
email=self.test_email,
)
self.user = create_profile(django_user)
self.user.set_password(self.test_password)
self.user.save()

def test_get_listed_projects(self):
deleted_project = Project(deleted=True, test=False)
deleted_project.save()

not_listed_project = Project(not_listed=True, test=False)
not_listed_project.save()

under_dev_project = Project(name="under_dev:default", test=False)
under_dev_project.save()

archived_project = Project(under_development=False, archived=True)
archived_project.save()

test_project = Project(under_development=False, test=True)
test_project.save()

project = Project(name="listed", under_development=False, test=False)
project.save()

listed_projects = Project.get_listed_projects()

self.assertFalse(deleted_project in listed_projects)
self.assertFalse(not_listed_project in listed_projects)
self.assertFalse(under_dev_project in listed_projects)
self.assertFalse(test_project in listed_projects)

18 changes: 18 additions & 0 deletions lernanta/apps/discover/urls.py
@@ -0,0 +1,18 @@
from django.conf.urls.defaults import patterns, url, include

urlpatterns = patterns('',
url(r'^$', 'discover.views.learn',
name='discover_learn'),

url(r'^schools/(?P<school_slug>[\w-]+)/', 'discover.views.schools',
name='discover_schools'),

url(r'^featured/(?P<feature>[\w-]+)/', 'discover.views.featured',
name='discover_featured'),

url(r'^find/$', 'discover.views.find',
name='discover_find'),

url(r'^tags/$', 'discover.views.learn_tags',
name='discover_learn_tags'),
)

0 comments on commit e8822c3

Please sign in to comment.