from django.conf.urls import patterns, url, include
from django.contrib.auth import views as auth_views
from django.core.urlresolvers import reverse_lazy

from oscar.core.application import Application
from oscar.apps.catalogue.app import application as catalogue_app
from oscar.apps.customer.app import application as customer_app
from oscar.apps.basket.app import application as basket_app
from oscar.apps.checkout.app import application as checkout_app
from oscar.apps.promotions.app import application as promotions_app
from oscar.apps.search.app import application as search_app
from oscar.apps.offer.app import application as offer_app
from oscar.apps.dashboard.app import application as dashboard_app

from oscar.apps.customer import forms
from oscar.views.decorators import login_forbidden


class Shop(Application):
    name = None

    catalogue_app = catalogue_app
    customer_app = customer_app
    basket_app = basket_app
    checkout_app = checkout_app
    promotions_app = promotions_app
    search_app = search_app
    dashboard_app = dashboard_app
    offer_app = offer_app

    def get_urls(self):
        urlpatterns = patterns('',
            (r'^i18n/', include('django.conf.urls.i18n')),
            (r'^catalogue/', include(self.catalogue_app.urls)),
            (r'^basket/', include(self.basket_app.urls)),
            (r'^checkout/', include(self.checkout_app.urls)),
            (r'^accounts/', include(self.customer_app.urls)),
            (r'^search/', include(self.search_app.urls)),
            (r'^dashboard/', include(self.dashboard_app.urls)),
            (r'^offers/', include(self.offer_app.urls)),

            # Password reset - as we're using Django's default view funtions,
            # we can't namespace these urls as that prevents
            # the reverse function from working.
            url(r'^password-reset/$',
                login_forbidden(auth_views.password_reset),
                {'password_reset_form': forms.PasswordResetForm,
                 'post_reset_redirect': reverse_lazy('password-reset-done')},
                name='password-reset'),
            url(r'^password-reset/done/$',
                login_forbidden(auth_views.password_reset_done),
                name='password-reset-done'),
            url(r'^password-reset/confirm/(?P<uidb36>[0-9A-Za-z]{1,13})-(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
                login_forbidden(auth_views.password_reset_confirm),
                {'post_reset_redirect': reverse_lazy('password-reset-complete')},
                name='password-reset-confirm'),
            url(r'^password-reset/complete/$',
                login_forbidden(auth_views.password_reset_complete),
                name='password-reset-complete'),
            (r'', include(self.promotions_app.urls)),
        )
        return urlpatterns


# 'shop' kept for legacy projects - 'application' is a better name
shop = application = Shop()

@@ -195,16 +195,17 @@
 ication%0A
+%0A
 from osc
@@ -217,116 +217,214 @@
 ps.c
-atalogue.app import application as catalogue_app%0Afrom oscar.apps.customer.app import application as 
+ustomer import forms%0Afrom oscar.core.loading import get_class%0Afrom oscar.views.decorators import login_forbidden%0A%0ACATALOGUE_APP = get_class('catalogue.app', 'application')%0ACUSTOMER_APP = get_class('
 customer
 _app
@@ -419,37 +419,62 @@
 customer
-_app%0Afrom oscar.apps.
+.app', 'application')%0ABASKET_APP = get_class('
 basket.a
@@ -471,32 +471,28 @@
 ('basket.app
- import 
+', '
 application 
@@ -494,39 +494,37 @@
 tion
- as basket_app%0Afrom oscar.apps.
+')%0ACHECKOUT_APP = get_class('
 chec
@@ -527,32 +527,28 @@
 checkout.app
- import 
+', '
 application 
@@ -550,41 +550,39 @@
 tion
- as checkout_app%0Afrom oscar.apps.
+')%0APROMOTIONS_APP = get_class('
 prom
@@ -587,32 +587,28 @@
 omotions.app
- import 
+', '
 application 
@@ -610,43 +610,35 @@
 tion
- as promotions_app%0Afrom oscar.apps.
+')%0ASEARCH_APP = get_class('
 sear
@@ -639,32 +639,28 @@
 ('search.app
- import 
+', '
 application 
@@ -662,39 +662,34 @@
 tion
- as search_app%0Afrom oscar.apps.
+')%0AOFFER_APP = get_class('
 offe
@@ -689,32 +689,28 @@
 s('offer.app
- import 
+', '
 application 
@@ -712,38 +712,38 @@
 tion
- as offer_app%0Afrom oscar.apps.
+')%0ADASHBOARD_APP = get_class('
 dash
@@ -751,24 +751,20 @@
 oard.app
- import 
+', '
 applicat
@@ -770,115 +770,10 @@
 tion
- as dashboard_app%0A%0Afrom oscar.apps.customer import forms%0Afrom oscar.views.decorators import login_forbidden
+')
 %0A%0A%0Ac
@@ -833,29 +833,29 @@
 e_app = 
-catalogue_app
+CATALOGUE_APP
 %0A    cus
@@ -866,28 +866,28 @@
 r_app = 
-customer_app
+CUSTOMER_APP
 %0A    bas
@@ -896,26 +896,26 @@
 t_app = 
-basket_app
+BASKET_APP
 %0A    che
@@ -926,28 +926,28 @@
 t_app = 
-checkout_app
+CHECKOUT_APP
 %0A    pro
@@ -960,30 +960,30 @@
 s_app = 
-promotions_app
+PROMOTIONS_APP
 %0A    sea
@@ -992,26 +992,26 @@
 h_app = 
-search_app
+SEARCH_APP
 %0A    das
@@ -1023,29 +1023,29 @@
 d_app = 
-dashboard_app
+DASHBOARD_APP
 %0A    off
@@ -1053,25 +1053,25 @@
 r_app = 
-offer_app
+OFFER_APP
 %0A%0A    de

Load Oscar applications dynamically