aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvolpino <fox91@anche.no>2012-11-02 17:33:00 +0100
committervolpino <fox91@anche.no>2012-11-02 20:15:51 +0100
commitc31076ddb4cc790fc69dde45f89aeaee3cb583ef (patch)
tree53d108c87e39a48a2bd3d7cfcbbe0846ca5dfdc7 /euscanwww
parenteuscanwww: removed useless 'print' (diff)
downloadeuscan-c31076ddb4cc790fc69dde45f89aeaee3cb583ef.tar.gz
euscan-c31076ddb4cc790fc69dde45f89aeaee3cb583ef.tar.bz2
euscan-c31076ddb4cc790fc69dde45f89aeaee3cb583ef.zip
euscanwww: Moving all account related stuff to a separate app
Note: This commit could break things, the userprofile model has been moved so the db layout must change (some alter table commands are needed to don't lose data) Signed-off-by: volpino <fox91@anche.no>
Diffstat (limited to 'euscanwww')
-rw-r--r--euscanwww/djeuscan/admin.py4
-rw-r--r--euscanwww/djeuscan/feeds.py27
-rw-r--r--euscanwww/djeuscan/forms.py39
-rw-r--r--euscanwww/djeuscan/helpers.py86
-rw-r--r--euscanwww/djeuscan/models.py31
-rw-r--r--euscanwww/djeuscan/tasks.py7
-rw-r--r--euscanwww/djeuscan/tests/test_views.py2
-rw-r--r--euscanwww/djeuscan/urls.py54
-rw-r--r--euscanwww/djeuscan/views.py226
-rw-r--r--euscanwww/euscan_accounts/__init__.py0
-rw-r--r--euscanwww/euscan_accounts/admin.py4
-rw-r--r--euscanwww/euscan_accounts/feeds.py26
-rw-r--r--euscanwww/euscan_accounts/forms.py38
-rw-r--r--euscanwww/euscan_accounts/helpers.py81
-rw-r--r--euscanwww/euscan_accounts/migrations/0001_initial.py204
-rw-r--r--euscanwww/euscan_accounts/migrations/__init__.py0
-rw-r--r--euscanwww/euscan_accounts/models.py35
-rw-r--r--euscanwww/euscan_accounts/templates/euscan/accounts/categories.html (renamed from euscanwww/djeuscan/templates/euscan/accounts/categories.html)0
-rw-r--r--euscanwww/euscan_accounts/templates/euscan/accounts/euscan_email.txt (renamed from euscanwww/djeuscan/templates/euscan/accounts/euscan_email.txt)0
-rw-r--r--euscanwww/euscan_accounts/templates/euscan/accounts/herds.html (renamed from euscanwww/djeuscan/templates/euscan/accounts/herds.html)0
-rw-r--r--euscanwww/euscan_accounts/templates/euscan/accounts/index.html (renamed from euscanwww/djeuscan/templates/euscan/accounts/index.html)0
-rw-r--r--euscanwww/euscan_accounts/templates/euscan/accounts/maintainers.html (renamed from euscanwww/djeuscan/templates/euscan/accounts/maintainers.html)0
-rw-r--r--euscanwww/euscan_accounts/templates/euscan/accounts/overlays.html (renamed from euscanwww/djeuscan/templates/euscan/accounts/overlays.html)0
-rw-r--r--euscanwww/euscan_accounts/templates/euscan/accounts/packages.html (renamed from euscanwww/djeuscan/templates/euscan/accounts/packages.html)0
-rw-r--r--euscanwww/euscan_accounts/templates/euscan/accounts/preferences.html (renamed from euscanwww/djeuscan/templates/euscan/accounts/preferences.html)0
-rw-r--r--euscanwww/euscan_accounts/tests.py16
-rw-r--r--euscanwww/euscan_accounts/urls.py26
-rw-r--r--euscanwww/euscan_accounts/views.py221
-rw-r--r--euscanwww/euscanwww/settings.py3
-rw-r--r--euscanwww/euscanwww/urls.py1
-rw-r--r--euscanwww/runtests.py4
31 files changed, 696 insertions, 439 deletions
diff --git a/euscanwww/djeuscan/admin.py b/euscanwww/djeuscan/admin.py
index 800fefc..5ecc512 100644
--- a/euscanwww/djeuscan/admin.py
+++ b/euscanwww/djeuscan/admin.py
@@ -1,6 +1,6 @@
from djeuscan.models import Package, Version, VersionLog, EuscanResult, \
Log, WorldLog, CategoryLog, HerdLog, MaintainerLog, Herd, Maintainer, \
- RefreshPackageQuery, Category, Overlay, ProblemReport, UserProfile
+ RefreshPackageQuery, Category, Overlay, ProblemReport
from django.contrib import admin
@@ -37,8 +37,6 @@ class ProblemReportAdmin(admin.ModelAdmin):
ordering = ["-datetime"]
-admin.site.register(UserProfile)
-
admin.site.register(Package, PackageAdmin)
admin.site.register(Herd, HerdAdmin)
diff --git a/euscanwww/djeuscan/feeds.py b/euscanwww/djeuscan/feeds.py
index f1e2094..59b8e05 100644
--- a/euscanwww/djeuscan/feeds.py
+++ b/euscanwww/djeuscan/feeds.py
@@ -9,7 +9,8 @@ from django.db.models import Q
from euscan.version import gentoo_unstable
from djeuscan.models import Package, Herd, Maintainer, VersionLog
-from djeuscan.helpers import get_profile, get_account_versionlogs
+
+from euscan_accounts.helpers import get_profile
class BaseFeed(Feed):
@@ -217,30 +218,6 @@ class CategoryFeed(BaseFeed):
return VersionLog.objects.for_category(data["obj"]), 100
-class UserFeed(BaseFeed):
- link = "/"
-
- def description(self, data):
- return "%s - last euscan changes" % data["user"]
-
- def title(self, data):
- return "%s - watched packages" % data["user"]
-
- def get_object(self, request):
- return {
- "user": request.user,
- "options": request.GET,
- }
-
- def _items(self, data):
- user = data["user"]
-
- profile = get_profile(user)
- vlogs = get_account_versionlogs(profile)
-
- return vlogs, 100
-
-
class WorldScanFeed(BaseFeed):
link = "/"
diff --git a/euscanwww/djeuscan/forms.py b/euscanwww/djeuscan/forms.py
index 95f4717..a1c6f65 100644
--- a/euscanwww/djeuscan/forms.py
+++ b/euscanwww/djeuscan/forms.py
@@ -1,6 +1,5 @@
from django import forms
-
-from djeuscan.models import Version, ProblemReport, UserProfile
+from djeuscan.models import Version, ProblemReport
class WorldForm(forms.Form):
@@ -27,39 +26,3 @@ class ProblemReportForm(forms.ModelForm):
class Meta:
model = ProblemReport
fields = ('version', 'subject', 'message')
-
-
-class PreferencesForm(forms.Form):
- first_name = forms.CharField(max_length=30, required=False)
- last_name = forms.CharField(max_length=30, required=False)
- email = forms.EmailField()
-
- feed_upstream_info = forms.BooleanField(required=False,
- label="Upstream info")
- feed_portage_info = forms.BooleanField(required=False,
- label="Portage info")
- feed_show_adds = forms.BooleanField(required=False,
- label="Show version bumps")
- feed_show_removals = forms.BooleanField(required=False,
- label="Show version removals")
- feed_ignore_pre = forms.BooleanField(required=False,
- label="Ignore unstable releases")
- feed_ignore_pre_if_stable = forms.BooleanField(
- required=False,
- label="Ignore unstable releases if current version is stable"
- )
-
- email_activated = forms.BooleanField(
- required=False, label="Receive euscan emails"
- )
- email_every = forms.ChoiceField(
- choices=UserProfile.EMAIL_OPTS,
- label="Send email",
- )
- email_ignore_pre = forms.BooleanField(
- required=False, label="Ignore unstable releases"
- )
- email_ignore_pre_if_stable = forms.BooleanField(
- required=False,
- label="Ignore unstable releases if current version is stable"
- )
diff --git a/euscanwww/djeuscan/helpers.py b/euscanwww/djeuscan/helpers.py
index d46fcaf..d5426eb 100644
--- a/euscanwww/djeuscan/helpers.py
+++ b/euscanwww/djeuscan/helpers.py
@@ -3,7 +3,7 @@ djeuscan.helpers
"""
from distutils.version import StrictVersion, LooseVersion
-from django.db.models import Q
+from django.shortcuts import get_object_or_404
def xint(i):
@@ -77,81 +77,9 @@ class catch_and_return(object):
return wrapper
-def get_profile(user):
- from djeuscan.models import UserProfile
- try:
- return user.get_profile()
- except UserProfile.DoesNotExist:
- UserProfile.objects.create(user=user)
- return user.get_profile()
-
-
-def get_account_categories(user):
- from djeuscan.models import Package
- # TODO: This is quite ugly
- category_names = [obj.name for obj in get_profile(user).categories.all()]
- return [c for c in Package.objects.categories()
- if c["category"] in category_names]
-
-
-def get_account_herds(user):
- from djeuscan.models import Package
-
- ids = [herd.pk for herd in get_profile(user).herds.all()]
- return Package.objects.herds(ids=ids)
-
-
-def get_account_maintainers(user):
- from djeuscan.models import Package
-
- ids = [obj.pk for obj in get_profile(user).maintainers.all()]
- return Package.objects.maintainers(ids=ids)
-
-
-def get_account_versionlogs(profile):
- """
- Returns all watched packages
- """
- from djeuscan.models import Package, VersionLog
-
- q_categories = Q(category__in=[
- category.name for category in profile.categories.all()])
- q_herds = Q(herds__in=profile.herds.all())
- q_maintainers = Q(maintainers__in=profile.maintainers.all())
- packages = list(profile.packages.all()) + list(Package.objects.filter(
- q_categories | q_herds | q_maintainers))
-
- overlays = [o.name for o in profile.overlays.all()]
-
- return VersionLog.objects.filter(
- Q(package__in=packages) | Q(overlay__in=overlays)
- )
-
-
-def get_user_fav_infos(user):
- upstream_k = lambda c: c["n_versions"] - c["n_packaged"] - c["n_overlay"]
-
- categories = sorted(get_account_categories(user),
- key=upstream_k, reverse=True)
- c_upstream = sum([upstream_k(c) for c in categories])
- herds = sorted(get_account_herds(user),
- key=upstream_k, reverse=True)
- h_upstream = sum([upstream_k(c) for c in herds])
- maintainers = sorted(get_account_maintainers(user),
- key=upstream_k, reverse=True)
- m_upstream = sum([upstream_k(c) for c in maintainers])
- packages = sorted(
- get_profile(user).packages.all(),
- key=lambda p: p.n_versions - p.n_packaged - p.n_overlay,
- reverse=True
- )
- p_upstream = sum(
- [c.n_versions - c.n_packaged - c.n_overlay for c in packages]
- )
-
- return {
- "categories": categories, "categories_upstream": c_upstream,
- "herds": herds, "herds_upstream": h_upstream,
- "maintainers": maintainers, "maintainers_upstream": m_upstream,
- "packages": packages, "packages_upstream": p_upstream,
- }
+def get_maintainer_or_404(id=None, email=None):
+ from djeuscan.models import Maintainer
+ if id:
+ return get_object_or_404(Maintainer, pk=id)
+ else:
+ return get_object_or_404(Maintainer, email=email)
diff --git a/euscanwww/djeuscan/models.py b/euscanwww/djeuscan/models.py
index a328522..a09c3e3 100644
--- a/euscanwww/djeuscan/models.py
+++ b/euscanwww/djeuscan/models.py
@@ -265,37 +265,6 @@ class Overlay(models.Model):
return self.name
-class UserProfile(models.Model):
- EMAIL_SCAN = 1
- EMAIL_WEEKLY = 2
- EMAIL_MONTHLY = 3
- EMAIL_OPTS = (
- (EMAIL_SCAN, 'On updates'),
- (EMAIL_WEEKLY, 'Weekly'),
- (EMAIL_MONTHLY, 'Monthly')
- )
-
- user = models.OneToOneField(User)
- herds = models.ManyToManyField(Herd)
- maintainers = models.ManyToManyField(Maintainer)
- packages = models.ManyToManyField(Package)
- categories = models.ManyToManyField(Category)
- overlays = models.ManyToManyField(Overlay)
-
- feed_upstream_info = models.BooleanField(default=True)
- feed_portage_info = models.BooleanField(default=False)
- feed_show_adds = models.BooleanField(default=True)
- feed_show_removals = models.BooleanField(default=True)
- feed_ignore_pre = models.BooleanField(default=False)
- feed_ignore_pre_if_stable = models.BooleanField(default=False)
-
- email_activated = models.BooleanField(default=True)
- email_every = models.IntegerField(choices=EMAIL_OPTS, default=EMAIL_SCAN)
- email_ignore_pre = models.BooleanField(default=False)
- email_ignore_pre_if_stable = models.BooleanField(default=False)
- last_email = models.DateTimeField(auto_now_add=True)
-
-
class Log(models.Model):
"""
Model used for keeping data for charts
diff --git a/euscanwww/djeuscan/tasks.py b/euscanwww/djeuscan/tasks.py
index 769e4af..b0b4413 100644
--- a/euscanwww/djeuscan/tasks.py
+++ b/euscanwww/djeuscan/tasks.py
@@ -15,10 +15,11 @@ from django.db.models import Q
from euscan.version import gentoo_unstable
-from djeuscan.models import Package, RefreshPackageQuery, UserProfile, \
- VersionLog
+from djeuscan.models import Package, RefreshPackageQuery, VersionLog
from djeuscan.processing import scan, misc
-from djeuscan.helpers import get_account_versionlogs, get_user_fav_infos
+
+from euscan_accounts.helpers import get_account_versionlogs, get_user_fav_infos
+from euscan_accounts.models import UserProfile
class TaskFailedException(Exception):
diff --git a/euscanwww/djeuscan/tests/test_views.py b/euscanwww/djeuscan/tests/test_views.py
index 5cf55c2..4917d9d 100644
--- a/euscanwww/djeuscan/tests/test_views.py
+++ b/euscanwww/djeuscan/tests/test_views.py
@@ -5,7 +5,7 @@ try:
except ImportError:
from bs4 import BeautifulSoup
-from djeuscan.helpers import get_profile
+from euscan_accounts.helpers import get_profile
from djeuscan.tests import SystemTestCase
from djeuscan.tests.euscan_factory import PackageFactory, setup_maintainers, \
diff --git a/euscanwww/djeuscan/urls.py b/euscanwww/djeuscan/urls.py
index a9add71..ded690f 100644
--- a/euscanwww/djeuscan/urls.py
+++ b/euscanwww/djeuscan/urls.py
@@ -1,14 +1,16 @@
from django.conf.urls.defaults import url, patterns, include
from django.contrib.auth.decorators import user_passes_test
-from django.contrib.auth.views import logout
-from django.views.generic import RedirectView
-from django.contrib.auth.decorators import login_required
from djcelery.views import apply as apply_task
from djeuscan.views import registered_tasks
+from euscan_accounts.views import favourite_package, unfavourite_package, \
+ favourite_category, unfavourite_category, favourite_herd, \
+ unfavourite_herd, favourite_maintainer, unfavourite_maintainer, \
+ favourite_overlay, unfavourite_overlay, favourite_world, unfavourite_world
+
from djeuscan.feeds import PackageFeed, CategoryFeed, HerdFeed, \
- MaintainerFeed, GlobalFeed, UserFeed, WorldScanFeed
+ MaintainerFeed, GlobalFeed, WorldScanFeed
admin_required = user_passes_test(lambda u: u.is_superuser)
@@ -17,8 +19,8 @@ admin_required = user_passes_test(lambda u: u.is_superuser)
package_patterns = patterns('djeuscan.views',
url(r'^$', 'package', name="package"),
url(r'^feed/$', PackageFeed(), name='package_feed'),
- url(r'^favourite/$', 'favourite_package', name="favourite_package"),
- url(r'^unfavourite/$', 'unfavourite_package', name="unfavourite_package"),
+ url(r'^favourite/$', favourite_package, name="favourite_package"),
+ url(r'^unfavourite/$', unfavourite_package, name="unfavourite_package"),
url(r'^refresh$', "refresh_package", name="refresh_package"),
url(r'^problem$', 'problem', name="problem"),
)
@@ -28,8 +30,8 @@ categories_patterns = patterns('djeuscan.views',
url(r'^feed/$', CategoryFeed(), name='category_feed'),
url(r'^charts/(?P<chart>[\w\-]+).png$', 'chart_category',
name="chart_category"),
- url(r'^favourite/$', 'favourite_category', name="favourite_category"),
- url(r'^unfavourite/$', 'unfavourite_category',
+ url(r'^favourite/$', favourite_category, name="favourite_category"),
+ url(r'^unfavourite/$', unfavourite_category,
name="unfavourite_category"),
)
@@ -37,8 +39,8 @@ herds_patterns = patterns('djeuscan.views',
url(r'^(?:view/)?$', 'herd', name="herd"),
url(r'^feed/$', HerdFeed(), name='herd_feed'),
url(r'^charts/(?P<chart>[\w\-]+).png$', 'chart_herd', name="chart_herd"),
- url(r'^favourite/$', 'favourite_herd', name="favourite_herd"),
- url(r'^unfavourite/$', 'unfavourite_herd', name="unfavourite_herd"),
+ url(r'^favourite/$', favourite_herd, name="favourite_herd"),
+ url(r'^unfavourite/$', unfavourite_herd, name="unfavourite_herd"),
)
maintainers_patterns = patterns('djeuscan.views',
@@ -46,15 +48,15 @@ maintainers_patterns = patterns('djeuscan.views',
url(r'^feed/$', MaintainerFeed(), name='maintainer_feed'),
url(r'^charts/(?P<chart>[\w\-]+).png$', 'chart_maintainer',
name="chart_maintainer"),
- url(r'^favourite/$', 'favourite_maintainer', name="favourite_maintainer"),
- url(r'^unfavourite/$', 'unfavourite_maintainer',
+ url(r'^favourite/$', favourite_maintainer, name="favourite_maintainer"),
+ url(r'^unfavourite/$', unfavourite_maintainer,
name="unfavourite_maintainer"),
)
overlays_patterns = patterns('djeuscan.views',
url(r'^(?:view/)?$', 'overlay', name="overlay"),
- url(r'^favourite/$', 'favourite_overlay', name="favourite_overlay"),
- url(r'^unfavourite/$', 'unfavourite_overlay', name="unfavourite_overlay"),
+ url(r'^favourite/$', favourite_overlay, name="favourite_overlay"),
+ url(r'^unfavourite/$', unfavourite_overlay, name="unfavourite_overlay"),
)
tasks_patterns = patterns('djeuscan.views',
@@ -64,25 +66,6 @@ tasks_patterns = patterns('djeuscan.views',
name="apply_task"),
)
-accounts_patterns = patterns('djeuscan.views',
- url(r'^profile/$', 'accounts_index', name="accounts_index"),
- url(r'^profile/preferences/$', 'accounts_preferences',
- name="accounts_preferences"),
- url(r'^categories/$', 'accounts_categories', name="accounts_categories"),
- url(r'^herds/$', 'accounts_herds', name="accounts_herds"),
- url(r'^maintainers/$', 'accounts_maintainers',
- name="accounts_maintainers"),
- url(r'^packages/$', 'accounts_packages', name="accounts_packages"),
- url(r'^overlays/$', 'accounts_overlays', name="accounts_overlays"),
-
- url(r'^feed/$', login_required(UserFeed()), name='user_feed'),
-
- url(r'^logout/$', logout, {'next_page': '/'}),
-
- url(r'^password/change/done/$',
- RedirectView.as_view(url="../../../profile/")),
-)
-
urlpatterns = patterns('djeuscan.views',
# Global stuff
@@ -99,8 +82,8 @@ urlpatterns = patterns('djeuscan.views',
url(r'^world/$', 'world', name="world"),
url(r'^world/scan/$', 'world_scan', name="world_scan"),
url(r'^world/scan/feed$', WorldScanFeed(), name="world_scan_feed"),
- url(r'^world/favourite/$', 'favourite_world', name="favourite_world"),
- url(r'^world/unfavourite/$', 'unfavourite_world',
+ url(r'^world/favourite/$', favourite_world, name="favourite_world"),
+ url(r'^world/unfavourite/$', unfavourite_world,
name="unfavourite_world"),
# Real data
@@ -124,5 +107,4 @@ urlpatterns = patterns('djeuscan.views',
include(package_patterns)),
url(r'^tasks/', include(tasks_patterns)),
- url(r'^accounts/', include(accounts_patterns)),
)
diff --git a/euscanwww/djeuscan/views.py b/euscanwww/djeuscan/views.py
index 05c8c21..3a7df88 100644
--- a/euscanwww/djeuscan/views.py
+++ b/euscanwww/djeuscan/views.py
@@ -8,17 +8,16 @@ from django.shortcuts import get_object_or_404
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_POST
-from djeuscan.helpers import version_key, packages_from_names, get_profile, \
- get_account_categories, get_account_herds, get_account_maintainers, \
- get_user_fav_infos
-from djeuscan.feeds import UserFeed
+from djeuscan.helpers import version_key, packages_from_names, \
+ get_maintainer_or_404
from djeuscan.models import Version, Package, Herd, Maintainer, EuscanResult, \
VersionLog, RefreshPackageQuery, ProblemReport, Category, Overlay
-from djeuscan.forms import WorldForm, PackagesForm, ProblemReportForm, \
- PreferencesForm
+from djeuscan.forms import WorldForm, PackagesForm, ProblemReportForm
from djeuscan.tasks import admin_tasks
from djeuscan import charts
+from euscan_accounts.helpers import get_profile
+
@render_to('euscan/index.html')
def index(request):
@@ -122,13 +121,6 @@ def maintainers(request):
return {'maintainers': maintainers, 'last_scan': last_scan}
-def get_maintainer_or_404(id=None, email=None):
- if id:
- return get_object_or_404(Maintainer, pk=id)
- else:
- return get_object_or_404(Maintainer, email=email)
-
-
@render_to('euscan/maintainer.html')
def maintainer(request, maintainer_id=None, maintainer_email=None):
maintainer = get_maintainer_or_404(maintainer_id, maintainer_email)
@@ -422,211 +414,3 @@ def refresh_package(request, category, package):
from djeuscan.tasks import consume_refresh_queue
consume_refresh_queue.delay()
return {"result": "success", "position": obj.position}
-
-
-@login_required
-@render_to('euscan/accounts/index.html')
-def accounts_index(request):
- user = request.user
-
- infos = get_user_fav_infos(user)
- infos['vlog'] = UserFeed().items({'user': user, 'options': {}})
-
- return infos
-
-
-@login_required
-@render_to('euscan/accounts/preferences.html')
-def accounts_preferences(request):
- user = request.user
- prof = get_profile(user)
-
- updated = False
- if request.method == "POST":
- form = PreferencesForm(request.POST)
- if form.is_valid():
- user.first_name = form.cleaned_data["first_name"]
- user.last_name = form.cleaned_data["last_name"]
- user.email = form.cleaned_data["email"]
- user.save(force_update=True)
-
- prof.feed_upstream_info = form.cleaned_data["feed_upstream_info"]
- prof.feed_portage_info = form.cleaned_data["feed_portage_info"]
- prof.feed_show_adds = form.cleaned_data["feed_show_adds"]
- prof.feed_show_removals = form.cleaned_data["feed_show_removals"]
- prof.feed_ignore_pre = form.cleaned_data["feed_ignore_pre"]
- prof.feed_ignore_pre_if_stable = \
- form.cleaned_data["feed_ignore_pre_if_stable"]
-
- prof.email_activated = form.cleaned_data["email_activated"]
- prof.email_every = form.cleaned_data["email_every"]
- prof.email_ignore_pre = form.cleaned_data["email_ignore_pre"]
- prof.email_ignore_pre_if_stable = \
- form.cleaned_data["email_ignore_pre_if_stable"]
-
- prof.save(force_update=True)
-
- updated = True
- else:
- initial_data = {
- "first_name": user.first_name,
- "last_name": user.last_name,
- "email": user.email,
- "feed_upstream_info": prof.feed_upstream_info,
- "feed_portage_info": prof.feed_portage_info,
- "feed_show_adds": prof.feed_show_adds,
- "feed_show_removals": prof.feed_show_removals,
- "feed_ignore_pre": prof.feed_ignore_pre,
- "feed_ignore_pre_if_stable": prof.feed_ignore_pre_if_stable,
- "email_activated": prof.email_activated,
- "email_every": prof.email_every,
- "email_ignore_pre": prof.email_ignore_pre,
- "email_ignore_pre_if_stable": prof.email_ignore_pre_if_stable,
- }
- form = PreferencesForm(initial_data)
- return {"form": form, "updated": updated}
-
-
-@login_required
-@render_to('euscan/accounts/categories.html')
-def accounts_categories(request):
- return {"categories": get_account_categories(request.user)}
-
-
-@login_required
-@render_to('euscan/accounts/herds.html')
-def accounts_herds(request):
- return {"herds": get_account_herds(request.user)}
-
-
-@login_required
-@render_to('euscan/accounts/maintainers.html')
-def accounts_maintainers(request):
- return {"maintainers": get_account_maintainers(request.user)}
-
-
-@login_required
-@render_to('euscan/accounts/packages.html')
-def accounts_packages(request):
- return {"packages": get_profile(request.user).packages.all()}
-
-
-@login_required
-@render_to('euscan/accounts/overlays.html')
-def accounts_overlays(request):
- overlays = [obj.name for obj in get_profile(request.user).overlays.all()]
- return {"overlays": overlays}
-
-
-@login_required
-@require_POST
-@ajax_request
-def favourite_package(request, category, package):
- obj = get_object_or_404(Package, category=category, name=package)
- get_profile(request.user).packages.add(obj)
- return {"success": True}
-
-
-@login_required
-@require_POST
-@ajax_request
-def unfavourite_package(request, category, package):
- package = get_object_or_404(Package, category=category, name=package)
- get_profile(request.user).packages.remove(package)
- return {"success": True}
-
-
-@login_required
-@require_POST
-@ajax_request
-def favourite_herd(request, herd):
- obj = get_object_or_404(Herd, herd=herd)
- get_profile(request.user).herds.add(obj)
- return {"success": True}
-
-
-@login_required
-@require_POST
-@ajax_request
-def unfavourite_herd(request, herd):
- herd = get_object_or_404(Herd, herd=herd)
- get_profile(request.user).herds.remove(herd)
- return {"success": True}
-
-
-@login_required
-@require_POST
-@ajax_request
-def favourite_maintainer(request, maintainer_id=None, maintainer_email=None):
- obj = get_maintainer_or_404(maintainer_id, maintainer_email)
- get_profile(request.user).maintainers.add(obj)
- return {"success": True}
-
-
-@login_required
-@require_POST
-@ajax_request
-def unfavourite_maintainer(request, maintainer_id=None, maintainer_email=None):
- obj = get_maintainer_or_404(maintainer_id, maintainer_email)
- get_profile(request.user).maintainers.remove(obj)
- return {"success": True}
-
-
-@login_required
-@require_POST
-@ajax_request
-def favourite_category(request, category):
- obj = Category.objects.get(name=category)
- get_profile(request.user).categories.add(obj)
- return {"success": True}
-
-
-@login_required
-@require_POST
-@ajax_request
-def unfavourite_category(request, category):
- obj = Category.objects.get(name=category)
- get_profile(request.user).categories.remove(obj)
- return {"success": True}
-
-
-@login_required
-@require_POST
-@ajax_request
-def favourite_overlay(request, overlay):
- obj = Overlay.objects.get(name=overlay)
- get_profile(request.user).overlays.add(obj)
- return {"success": True}
-
-
-@login_required
-@require_POST
-@ajax_request
-def unfavourite_overlay(request, overlay):
- obj = Overlay.objects.get(name=overlay)
- get_profile(request.user).overlays.remove(obj)
- return {"success": True}
-
-
-@login_required
-@require_POST
-@ajax_request
-def favourite_world(request):
- if not "packages[]" in request.POST:
- return {"success": False}
- packages = request.POST.getlist("packages[]")
- objs = Package.objects.filter(id__in=packages)
- get_profile(request.user).packages.add(*objs)
- return {"success": True}
-
-
-@login_required
-@require_POST
-@ajax_request
-def unfavourite_world(request):
- if not "packages[]" in request.POST:
- return {"success": False}
- packages = request.POST.getlist("packages[]")
- objs = Package.objects.filter(id__in=packages)
- get_profile(request.user).packages.remove(*objs)
- return {"success": True}
diff --git a/euscanwww/euscan_accounts/__init__.py b/euscanwww/euscan_accounts/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/euscanwww/euscan_accounts/__init__.py
diff --git a/euscanwww/euscan_accounts/admin.py b/euscanwww/euscan_accounts/admin.py
new file mode 100644
index 0000000..453650a
--- /dev/null
+++ b/euscanwww/euscan_accounts/admin.py
@@ -0,0 +1,4 @@
+from django.contrib import admin
+from euscan_accounts.models import UserProfile
+
+admin.site.register(UserProfile)
diff --git a/euscanwww/euscan_accounts/feeds.py b/euscanwww/euscan_accounts/feeds.py
new file mode 100644
index 0000000..9a70b80
--- /dev/null
+++ b/euscanwww/euscan_accounts/feeds.py
@@ -0,0 +1,26 @@
+from djeuscan.feeds import BaseFeed
+from euscan_accounts.helpers import get_profile, get_account_versionlogs
+
+
+class UserFeed(BaseFeed):
+ link = "/"
+
+ def description(self, data):
+ return "%s - last euscan changes" % data["user"]
+
+ def title(self, data):
+ return "%s - watched packages" % data["user"]
+
+ def get_object(self, request):
+ return {
+ "user": request.user,
+ "options": request.GET,
+ }
+
+ def _items(self, data):
+ user = data["user"]
+
+ profile = get_profile(user)
+ vlogs = get_account_versionlogs(profile)
+
+ return vlogs, 100
diff --git a/euscanwww/euscan_accounts/forms.py b/euscanwww/euscan_accounts/forms.py
new file mode 100644
index 0000000..620448d
--- /dev/null
+++ b/euscanwww/euscan_accounts/forms.py
@@ -0,0 +1,38 @@
+from django import forms
+from euscan_accounts.models import UserProfile
+
+
+class PreferencesForm(forms.Form):
+ first_name = forms.CharField(max_length=30, required=False)
+ last_name = forms.CharField(max_length=30, required=False)
+ email = forms.EmailField()
+
+ feed_upstream_info = forms.BooleanField(required=False,
+ label="Upstream info")
+ feed_portage_info = forms.BooleanField(required=False,
+ label="Portage info")
+ feed_show_adds = forms.BooleanField(required=False,
+ label="Show version bumps")
+ feed_show_removals = forms.BooleanField(required=False,
+ label="Show version removals")
+ feed_ignore_pre = forms.BooleanField(required=False,
+ label="Ignore unstable releases")
+ feed_ignore_pre_if_stable = forms.BooleanField(
+ required=False,
+ label="Ignore unstable releases if current version is stable"
+ )
+
+ email_activated = forms.BooleanField(
+ required=False, label="Receive euscan emails"
+ )
+ email_every = forms.ChoiceField(
+ choices=UserProfile.EMAIL_OPTS,
+ label="Send email",
+ )
+ email_ignore_pre = forms.BooleanField(
+ required=False, label="Ignore unstable releases"
+ )
+ email_ignore_pre_if_stable = forms.BooleanField(
+ required=False,
+ label="Ignore unstable releases if current version is stable"
+ )
diff --git a/euscanwww/euscan_accounts/helpers.py b/euscanwww/euscan_accounts/helpers.py
new file mode 100644
index 0000000..7422ab9
--- /dev/null
+++ b/euscanwww/euscan_accounts/helpers.py
@@ -0,0 +1,81 @@
+from django.db.models import Q
+
+
+def get_profile(user):
+ from euscan_accounts.models import UserProfile
+ try:
+ return user.get_profile()
+ except UserProfile.DoesNotExist:
+ UserProfile.objects.create(user=user)
+ return user.get_profile()
+
+
+def get_account_categories(user):
+ from djeuscan.models import Package
+ # TODO: This is quite ugly
+ category_names = [obj.name for obj in get_profile(user).categories.all()]
+ return [c for c in Package.objects.categories()
+ if c["category"] in category_names]
+
+
+def get_account_herds(user):
+ from djeuscan.models import Package
+
+ ids = [herd.pk for herd in get_profile(user).herds.all()]
+ return Package.objects.herds(ids=ids)
+
+
+def get_account_maintainers(user):
+ from djeuscan.models import Package
+
+ ids = [obj.pk for obj in get_profile(user).maintainers.all()]
+ return Package.objects.maintainers(ids=ids)
+
+
+def get_account_versionlogs(profile):
+ """
+ Returns all watched packages
+ """
+ from djeuscan.models import Package, VersionLog
+
+ q_categories = Q(category__in=[
+ category.name for category in profile.categories.all()])
+ q_herds = Q(herds__in=profile.herds.all())
+ q_maintainers = Q(maintainers__in=profile.maintainers.all())
+ packages = list(profile.packages.all()) + list(Package.objects.filter(
+ q_categories | q_herds | q_maintainers))
+
+ overlays = [o.name for o in profile.overlays.all()]
+
+ return VersionLog.objects.filter(
+ Q(package__in=packages) | Q(overlay__in=overlays)
+ )
+
+
+def get_user_fav_infos(user):
+ upstream_k = lambda c: c["n_versions"] - c["n_packaged"] - c["n_overlay"]
+
+ categories = sorted(get_account_categories(user),
+ key=upstream_k, reverse=True)
+ c_upstream = sum([upstream_k(c) for c in categories])
+ herds = sorted(get_account_herds(user),
+ key=upstream_k, reverse=True)
+ h_upstream = sum([upstream_k(c) for c in herds])
+ maintainers = sorted(get_account_maintainers(user),
+ key=upstream_k, reverse=True)
+ m_upstream = sum([upstream_k(c) for c in maintainers])
+ packages = sorted(
+ get_profile(user).packages.all(),
+ key=lambda p: p.n_versions - p.n_packaged - p.n_overlay,
+ reverse=True
+ )
+ p_upstream = sum(
+ [c.n_versions - c.n_packaged - c.n_overlay for c in packages]
+ )
+
+ return {
+ "categories": categories, "categories_upstream": c_upstream,
+ "herds": herds, "herds_upstream": h_upstream,
+ "maintainers": maintainers, "maintainers_upstream": m_upstream,
+ "packages": packages, "packages_upstream": p_upstream,
+ }
diff --git a/euscanwww/euscan_accounts/migrations/0001_initial.py b/euscanwww/euscan_accounts/migrations/0001_initial.py
new file mode 100644
index 0000000..dd7ab8c
--- /dev/null
+++ b/euscanwww/euscan_accounts/migrations/0001_initial.py
@@ -0,0 +1,204 @@
+# -*- coding: utf-8 -*-
+import 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 'UserProfile'
+ db.create_table('euscan_accounts_userprofile', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('user', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['auth.User'], unique=True)),
+ ('feed_upstream_info', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ('feed_portage_info', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('feed_show_adds', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ('feed_show_removals', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ('feed_ignore_pre', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('feed_ignore_pre_if_stable', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('email_activated', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ('email_every', self.gf('django.db.models.fields.IntegerField')(default=1)),
+ ('email_ignore_pre', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('email_ignore_pre_if_stable', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('last_email', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
+ ))
+ db.send_create_signal('euscan_accounts', ['UserProfile'])
+
+ # Adding M2M table for field herds on 'UserProfile'
+ db.create_table('euscan_accounts_userprofile_herds', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('userprofile', models.ForeignKey(orm['euscan_accounts.userprofile'], null=False)),
+ ('herd', models.ForeignKey(orm['djeuscan.herd'], null=False))
+ ))
+ db.create_unique('euscan_accounts_userprofile_herds', ['userprofile_id', 'herd_id'])
+
+ # Adding M2M table for field maintainers on 'UserProfile'
+ db.create_table('euscan_accounts_userprofile_maintainers', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('userprofile', models.ForeignKey(orm['euscan_accounts.userprofile'], null=False)),
+ ('maintainer', models.ForeignKey(orm['djeuscan.maintainer'], null=False))
+ ))
+ db.create_unique('euscan_accounts_userprofile_maintainers', ['userprofile_id', 'maintainer_id'])
+
+ # Adding M2M table for field packages on 'UserProfile'
+ db.create_table('euscan_accounts_userprofile_packages', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('userprofile', models.ForeignKey(orm['euscan_accounts.userprofile'], null=False)),
+ ('package', models.ForeignKey(orm['djeuscan.package'], null=False))
+ ))
+ db.create_unique('euscan_accounts_userprofile_packages', ['userprofile_id', 'package_id'])
+
+ # Adding M2M table for field categories on 'UserProfile'
+ db.create_table('euscan_accounts_userprofile_categories', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('userprofile', models.ForeignKey(orm['euscan_accounts.userprofile'], null=False)),
+ ('category', models.ForeignKey(orm['djeuscan.category'], null=False))
+ ))
+ db.create_unique('euscan_accounts_userprofile_categories', ['userprofile_id', 'category_id'])
+
+ # Adding M2M table for field overlays on 'UserProfile'
+ db.create_table('euscan_accounts_userprofile_overlays', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('userprofile', models.ForeignKey(orm['euscan_accounts.userprofile'], null=False)),
+ ('overlay', models.ForeignKey(orm['djeuscan.overlay'], null=False))
+ ))
+ db.create_unique('euscan_accounts_userprofile_overlays', ['userprofile_id', 'overlay_id'])
+
+ def backwards(self, orm):
+ # Deleting model 'UserProfile'
+ db.delete_table('euscan_accounts_userprofile')
+
+ # Removing M2M table for field herds on 'UserProfile'
+ db.delete_table('euscan_accounts_userprofile_herds')
+
+ # Removing M2M table for field maintainers on 'UserProfile'
+ db.delete_table('euscan_accounts_userprofile_maintainers')
+
+ # Removing M2M table for field packages on 'UserProfile'
+ db.delete_table('euscan_accounts_userprofile_packages')
+
+ # Removing M2M table for field categories on 'UserProfile'
+ db.delete_table('euscan_accounts_userprofile_categories')
+
+ # Removing M2M table for field overlays on 'UserProfile'
+ db.delete_table('euscan_accounts_userprofile_overlays')
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'djeuscan.category': {
+ 'Meta': {'object_name': 'Category'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'})
+ },
+ 'djeuscan.herd': {
+ 'Meta': {'object_name': 'Herd'},
+ 'email': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
+ 'herd': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'maintainers': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['djeuscan.Maintainer']", 'symmetrical': 'False'})
+ },
+ 'djeuscan.maintainer': {
+ 'Meta': {'object_name': 'Maintainer'},
+ 'email': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
+ },
+ 'djeuscan.overlay': {
+ 'Meta': {'object_name': 'Overlay'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'})
+ },
+ 'djeuscan.package': {
+ 'Meta': {'unique_together': "(['category', 'name'],)", 'object_name': 'Package'},
+ 'category': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'herds': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['djeuscan.Herd']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'homepage': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_version_gentoo': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'last_version_gentoo'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['djeuscan.Version']"}),
+ 'last_version_overlay': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'last_version_overlay'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['djeuscan.Version']"}),
+ 'last_version_upstream': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'last_version_upstream'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['djeuscan.Version']"}),
+ 'maintainers': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['djeuscan.Maintainer']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'n_overlay': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'n_packaged': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'n_versions': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'})
+ },
+ 'djeuscan.version': {
+ 'Meta': {'unique_together': "(['package', 'slot', 'revision', 'version', 'overlay'],)", 'object_name': 'Version'},
+ 'alive': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}),
+ 'confidence': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'ebuild_path': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
+ 'handler': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'metadata_path': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
+ 'overlay': ('django.db.models.fields.CharField', [], {'default': "'gentoo'", 'max_length': '128', 'db_index': 'True', 'blank': 'True'}),
+ 'package': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djeuscan.Package']"}),
+ 'packaged': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'slot': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
+ 'urls': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'version': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'vtype': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'})
+ },
+ 'euscan_accounts.userprofile': {
+ 'Meta': {'object_name': 'UserProfile'},
+ 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['djeuscan.Category']", 'symmetrical': 'False'}),
+ 'email_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'email_every': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'email_ignore_pre': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'email_ignore_pre_if_stable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'feed_ignore_pre': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'feed_ignore_pre_if_stable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'feed_portage_info': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'feed_show_adds': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'feed_show_removals': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'feed_upstream_info': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'herds': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['djeuscan.Herd']", 'symmetrical': 'False'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_email': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'maintainers': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['djeuscan.Maintainer']", 'symmetrical': 'False'}),
+ 'overlays': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['djeuscan.Overlay']", 'symmetrical': 'False'}),
+ 'packages': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['djeuscan.Package']", 'symmetrical': 'False'}),
+ 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
+ }
+ }
+
+ complete_apps = ['euscan_accounts'] \ No newline at end of file
diff --git a/euscanwww/euscan_accounts/migrations/__init__.py b/euscanwww/euscan_accounts/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/euscanwww/euscan_accounts/migrations/__init__.py
diff --git a/euscanwww/euscan_accounts/models.py b/euscanwww/euscan_accounts/models.py
new file mode 100644
index 0000000..0d83e15
--- /dev/null
+++ b/euscanwww/euscan_accounts/models.py
@@ -0,0 +1,35 @@
+from django.db import models
+from django.contrib.auth.models import User
+
+from djeuscan.models import Herd, Maintainer, Package, Category, Overlay
+
+
+class UserProfile(models.Model):
+ EMAIL_SCAN = 1
+ EMAIL_WEEKLY = 2
+ EMAIL_MONTHLY = 3
+ EMAIL_OPTS = (
+ (EMAIL_SCAN, 'On updates'),
+ (EMAIL_WEEKLY, 'Weekly'),
+ (EMAIL_MONTHLY, 'Monthly')
+ )
+
+ user = models.OneToOneField(User)
+ herds = models.ManyToManyField(Herd)
+ maintainers = models.ManyToManyField(Maintainer)
+ packages = models.ManyToManyField(Package)
+ categories = models.ManyToManyField(Category)
+ overlays = models.ManyToManyField(Overlay)
+
+ feed_upstream_info = models.BooleanField(default=True)
+ feed_portage_info = models.BooleanField(default=False)
+ feed_show_adds = models.BooleanField(default=True)
+ feed_show_removals = models.BooleanField(default=True)
+ feed_ignore_pre = models.BooleanField(default=False)
+ feed_ignore_pre_if_stable = models.BooleanField(default=False)
+
+ email_activated = models.BooleanField(default=True)
+ email_every = models.IntegerField(choices=EMAIL_OPTS, default=EMAIL_SCAN)
+ email_ignore_pre = models.BooleanField(default=False)
+ email_ignore_pre_if_stable = models.BooleanField(default=False)
+ last_email = models.DateTimeField(auto_now_add=True)
diff --git a/euscanwww/djeuscan/templates/euscan/accounts/categories.html b/euscanwww/euscan_accounts/templates/euscan/accounts/categories.html
index 0caa1a6..0caa1a6 100644
--- a/euscanwww/djeuscan/templates/euscan/accounts/categories.html
+++ b/euscanwww/euscan_accounts/templates/euscan/accounts/categories.html
diff --git a/euscanwww/djeuscan/templates/euscan/accounts/euscan_email.txt b/euscanwww/euscan_accounts/templates/euscan/accounts/euscan_email.txt
index baf396b..baf396b 100644
--- a/euscanwww/djeuscan/templates/euscan/accounts/euscan_email.txt
+++ b/euscanwww/euscan_accounts/templates/euscan/accounts/euscan_email.txt
diff --git a/euscanwww/djeuscan/templates/euscan/accounts/herds.html b/euscanwww/euscan_accounts/templates/euscan/accounts/herds.html
index b9d3f50..b9d3f50 100644
--- a/euscanwww/djeuscan/templates/euscan/accounts/herds.html
+++ b/euscanwww/euscan_accounts/templates/euscan/accounts/herds.html
diff --git a/euscanwww/djeuscan/templates/euscan/accounts/index.html b/euscanwww/euscan_accounts/templates/euscan/accounts/index.html
index 0e61ed6..0e61ed6 100644
--- a/euscanwww/djeuscan/templates/euscan/accounts/index.html
+++ b/euscanwww/euscan_accounts/templates/euscan/accounts/index.html
diff --git a/euscanwww/djeuscan/templates/euscan/accounts/maintainers.html b/euscanwww/euscan_accounts/templates/euscan/accounts/maintainers.html
index cc8eefe..cc8eefe 100644
--- a/euscanwww/djeuscan/templates/euscan/accounts/maintainers.html
+++ b/euscanwww/euscan_accounts/templates/euscan/accounts/maintainers.html
diff --git a/euscanwww/djeuscan/templates/euscan/accounts/overlays.html b/euscanwww/euscan_accounts/templates/euscan/accounts/overlays.html
index 946b61e..946b61e 100644
--- a/euscanwww/djeuscan/templates/euscan/accounts/overlays.html
+++ b/euscanwww/euscan_accounts/templates/euscan/accounts/overlays.html
diff --git a/euscanwww/djeuscan/templates/euscan/accounts/packages.html b/euscanwww/euscan_accounts/templates/euscan/accounts/packages.html
index 46e674b..46e674b 100644
--- a/euscanwww/djeuscan/templates/euscan/accounts/packages.html
+++ b/euscanwww/euscan_accounts/templates/euscan/accounts/packages.html
diff --git a/euscanwww/djeuscan/templates/euscan/accounts/preferences.html b/euscanwww/euscan_accounts/templates/euscan/accounts/preferences.html
index 8df632a..8df632a 100644
--- a/euscanwww/djeuscan/templates/euscan/accounts/preferences.html
+++ b/euscanwww/euscan_accounts/templates/euscan/accounts/preferences.html
diff --git a/euscanwww/euscan_accounts/tests.py b/euscanwww/euscan_accounts/tests.py
new file mode 100644
index 0000000..501deb7
--- /dev/null
+++ b/euscanwww/euscan_accounts/tests.py
@@ -0,0 +1,16 @@
+"""
+This file demonstrates writing tests using the unittest module. These will pass
+when you run "manage.py test".
+
+Replace this with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+
+class SimpleTest(TestCase):
+ def test_basic_addition(self):
+ """
+ Tests that 1 + 1 always equals 2.
+ """
+ self.assertEqual(1 + 1, 2)
diff --git a/euscanwww/euscan_accounts/urls.py b/euscanwww/euscan_accounts/urls.py
new file mode 100644
index 0000000..0a798cb
--- /dev/null
+++ b/euscanwww/euscan_accounts/urls.py
@@ -0,0 +1,26 @@
+from django.conf.urls import patterns, url
+from django.contrib.auth.views import logout
+from django.views.generic import RedirectView
+from django.contrib.auth.decorators import login_required
+
+from euscan_accounts.feeds import UserFeed
+
+
+urlpatterns = patterns('euscan_accounts.views',
+ url(r'^profile/$', 'accounts_index', name="accounts_index"),
+ url(r'^profile/preferences/$', 'accounts_preferences',
+ name="accounts_preferences"),
+ url(r'^categories/$', 'accounts_categories', name="accounts_categories"),
+ url(r'^herds/$', 'accounts_herds', name="accounts_herds"),
+ url(r'^maintainers/$', 'accounts_maintainers',
+ name="accounts_maintainers"),
+ url(r'^packages/$', 'accounts_packages', name="accounts_packages"),
+ url(r'^overlays/$', 'accounts_overlays', name="accounts_overlays"),
+
+ url(r'^feed/$', login_required(UserFeed()), name='user_feed'),
+
+ url(r'^logout/$', logout, {'next_page': '/'}),
+
+ url(r'^password/change/done/$',
+ RedirectView.as_view(url="../../../profile/")),
+)
diff --git a/euscanwww/euscan_accounts/views.py b/euscanwww/euscan_accounts/views.py
new file mode 100644
index 0000000..e80bc04
--- /dev/null
+++ b/euscanwww/euscan_accounts/views.py
@@ -0,0 +1,221 @@
+from annoying.decorators import render_to, ajax_request
+
+from django.shortcuts import get_object_or_404
+from django.contrib.auth.decorators import login_required
+from django.views.decorators.http import require_POST
+
+from djeuscan.models import Package, Category, Herd, Overlay
+from djeuscan.helpers import get_maintainer_or_404
+
+from euscan_accounts.feeds import UserFeed
+from euscan_accounts.forms import PreferencesForm
+from euscan_accounts.helpers import get_user_fav_infos, get_profile, \
+ get_account_categories, get_account_herds, get_account_maintainers
+
+
+@login_required
+@render_to('euscan/accounts/index.html')
+def accounts_index(request):
+ user = request.user
+
+ infos = get_user_fav_infos(user)
+ infos['vlog'] = UserFeed().items({'user': user, 'options': {}})
+
+ return infos
+
+
+@login_required
+@render_to('euscan/accounts/preferences.html')
+def accounts_preferences(request):
+ user = request.user
+ prof = get_profile(user)
+
+ updated = False
+ if request.method == "POST":
+ form = PreferencesForm(request.POST)
+ if form.is_valid():
+ user.first_name = form.cleaned_data["first_name"]
+ user.last_name = form.cleaned_data["last_name"]
+ user.email = form.cleaned_data["email"]
+ user.save(force_update=True)
+
+ prof.feed_upstream_info = form.cleaned_data["feed_upstream_info"]
+ prof.feed_portage_info = form.cleaned_data["feed_portage_info"]
+ prof.feed_show_adds = form.cleaned_data["feed_show_adds"]
+ prof.feed_show_removals = form.cleaned_data["feed_show_removals"]
+ prof.feed_ignore_pre = form.cleaned_data["feed_ignore_pre"]
+ prof.feed_ignore_pre_if_stable = \
+ form.cleaned_data["feed_ignore_pre_if_stable"]
+
+ prof.email_activated = form.cleaned_data["email_activated"]
+ prof.email_every = form.cleaned_data["email_every"]
+ prof.email_ignore_pre = form.cleaned_data["email_ignore_pre"]
+ prof.email_ignore_pre_if_stable = \
+ form.cleaned_data["email_ignore_pre_if_stable"]
+
+ prof.save(force_update=True)
+
+ updated = True
+ else:
+ initial_data = {
+ "first_name": user.first_name,
+ "last_name": user.last_name,
+ "email": user.email,
+ "feed_upstream_info": prof.feed_upstream_info,
+ "feed_portage_info": prof.feed_portage_info,
+ "feed_show_adds": prof.feed_show_adds,
+ "feed_show_removals": prof.feed_show_removals,
+ "feed_ignore_pre": prof.feed_ignore_pre,
+ "feed_ignore_pre_if_stable": prof.feed_ignore_pre_if_stable,
+ "email_activated": prof.email_activated,
+ "email_every": prof.email_every,
+ "email_ignore_pre": prof.email_ignore_pre,
+ "email_ignore_pre_if_stable": prof.email_ignore_pre_if_stable,
+ }
+ form = PreferencesForm(initial_data)
+ return {"form": form, "updated": updated}
+
+
+@login_required
+@render_to('euscan/accounts/categories.html')
+def accounts_categories(request):
+ return {"categories": get_account_categories(request.user)}
+
+
+@login_required
+@render_to('euscan/accounts/herds.html')
+def accounts_herds(request):
+ return {"herds": get_account_herds(request.user)}
+
+
+@login_required
+@render_to('euscan/accounts/maintainers.html')
+def accounts_maintainers(request):
+ return {"maintainers": get_account_maintainers(request.user)}
+
+
+@login_required
+@render_to('euscan/accounts/packages.html')
+def accounts_packages(request):
+ return {"packages": get_profile(request.user).packages.all()}
+
+
+@login_required
+@render_to('euscan/accounts/overlays.html')
+def accounts_overlays(request):
+ overlays = [obj.name for obj in get_profile(request.user).overlays.all()]
+ return {"overlays": overlays}
+
+
+@login_required
+@require_POST
+@ajax_request
+def favourite_package(request, category, package):
+ obj = get_object_or_404(Package, category=category, name=package)
+ get_profile(request.user).packages.add(obj)
+ return {"success": True}
+
+
+@login_required
+@require_POST
+@ajax_request
+def unfavourite_package(request, category, package):
+ package = get_object_or_404(Package, category=category, name=package)
+ get_profile(request.user).packages.remove(package)
+ return {"success": True}
+
+
+@login_required
+@require_POST
+@ajax_request
+def favourite_herd(request, herd):
+ obj = get_object_or_404(Herd, herd=herd)
+ get_profile(request.user).herds.add(obj)
+ return {"success": True}
+
+
+@login_required
+@require_POST
+@ajax_request
+def unfavourite_herd(request, herd):
+ herd = get_object_or_404(Herd, herd=herd)
+ get_profile(request.user).herds.remove(herd)
+ return {"success": True}
+
+
+@login_required
+@require_POST
+@ajax_request
+def favourite_maintainer(request, maintainer_id=None, maintainer_email=None):
+ obj = get_maintainer_or_404(maintainer_id, maintainer_email)
+ get_profile(request.user).maintainers.add(obj)
+ return {"success": True}
+
+
+@login_required
+@require_POST
+@ajax_request
+def unfavourite_maintainer(request, maintainer_id=None, maintainer_email=None):
+ obj = get_maintainer_or_404(maintainer_id, maintainer_email)
+ get_profile(request.user).maintainers.remove(obj)
+ return {"success": True}
+
+
+@login_required
+@require_POST
+@ajax_request
+def favourite_category(request, category):
+ obj = Category.objects.get(name=category)
+ get_profile(request.user).categories.add(obj)
+ return {"success": True}
+
+
+@login_required
+@require_POST
+@ajax_request
+def unfavourite_category(request, category):
+ obj = Category.objects.get(name=category)
+ get_profile(request.user).categories.remove(obj)
+ return {"success": True}
+
+
+@login_required
+@require_POST
+@ajax_request
+def favourite_overlay(request, overlay):
+ obj = Overlay.objects.get(name=overlay)
+ get_profile(request.user).overlays.add(obj)
+ return {"success": True}
+
+
+@login_required
+@require_POST
+@ajax_request
+def unfavourite_overlay(request, overlay):
+ obj = Overlay.objects.get(name=overlay)
+ get_profile(request.user).overlays.remove(obj)
+ return {"success": True}
+
+
+@login_required
+@require_POST
+@ajax_request
+def favourite_world(request):
+ if not "packages[]" in request.POST:
+ return {"success": False}
+ packages = request.POST.getlist("packages[]")
+ objs = Package.objects.filter(id__in=packages)
+ get_profile(request.user).packages.add(*objs)
+ return {"success": True}
+
+
+@login_required
+@require_POST
+@ajax_request
+def unfavourite_world(request):
+ if not "packages[]" in request.POST:
+ return {"success": False}
+ packages = request.POST.getlist("packages[]")
+ objs = Package.objects.filter(id__in=packages)
+ get_profile(request.user).packages.remove(*objs)
+ return {"success": True}
diff --git a/euscanwww/euscanwww/settings.py b/euscanwww/euscanwww/settings.py
index 5705c3b..d14b968 100644
--- a/euscanwww/euscanwww/settings.py
+++ b/euscanwww/euscanwww/settings.py
@@ -159,6 +159,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
INSTALLED_APPS = (
'euscanwww',
'djeuscan',
+ 'euscan_accounts',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
@@ -253,7 +254,7 @@ AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
-AUTH_PROFILE_MODULE = 'djeuscan.UserProfile'
+AUTH_PROFILE_MODULE = 'euscan_accounts.UserProfile'
try:
from local_settings import *
diff --git a/euscanwww/euscanwww/urls.py b/euscanwww/euscanwww/urls.py
index a93c3e8..524fe5e 100644
--- a/euscanwww/euscanwww/urls.py
+++ b/euscanwww/euscanwww/urls.py
@@ -8,6 +8,7 @@ urlpatterns = patterns('',
url(r'^', include('djeuscan.urls')),
url(r'^admin/', include(admin.site.urls)),
+ url(r'^accounts/', include('euscan_accounts.urls')),
url(r'^accounts/', include('euscan_captcha.urls')),
url(r'^accounts/', include('registration.backends.default.urls')),
)
diff --git a/euscanwww/runtests.py b/euscanwww/runtests.py
index 417fd1d..b22d209 100644
--- a/euscanwww/runtests.py
+++ b/euscanwww/runtests.py
@@ -16,6 +16,8 @@ settings.configure(
INSTALLED_APPS=[
'euscanwww.euscanwww',
'djeuscan',
+ 'euscan_accounts',
+ 'euscan_captcha',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.admin',
@@ -29,7 +31,7 @@ settings.configure(
USE_TZ=True,
TASKS_CONCURRENTLY=8,
TASKS_SUBTASK_PACKAGES=32,
- AUTH_PROFILE_MODULE="djeuscan.UserProfile",
+ AUTH_PROFILE_MODULE="euscan_accounts.UserProfile",
RECAPTCHA_PUBLIC_KEY="",
RECAPTCHA_PRIVATE_KEY="",
)