diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6018d6995..aaf582aac 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,6 +36,6 @@ Currently, our most pressing issues are: * Some way to donate would be also nice (PayPal, gittip.com, Flattr,...?) * Bug triaging. We have about [200 open issues](https://github.com/thinkle/gourmet/issues), and some of them are a couple of years old and have already been fixed. Some help in tagging, commenting, and ideally closing bugs is very welcome! (Note that to close a bug, you should really be sure it's okay to do so because you have tested Gourmet to work under the same conditions the bug reporter did.) -Make sure to also check out our upcoming [milestones](https://github.com/thinkle/gourmet/issues/milestones). +Make sure to also check out our upcoming [milestones](https://github.com/thinkle/gourmet/milestones). More nifty ideas can be found via the [gsoc-idea label](https://github.com/thinkle/gourmet/issues?labels=gsoc-idea&page=1&state=open). diff --git a/INSTALL.md b/INSTALL.md index 16fbb2a27..0d6e03b6d 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -31,7 +31,27 @@ for those options. Mac OS X -------- -### Using MacPorts +### Installing with "Automatic Installation" +#### Using MacPorts +This guide will assume that the user does not already have any of the required packages installed. First, complete the following list of instructions to install MacPorts. These steps are reproduced from [MacPorts official instructions](https://www.macports.org/install.php). + +1. Install Xcode and the Xcode Command Line Tools, accept the license. + 1. Download Xcode from the App Store: [Link to download](https://itunes.apple.com/us/app/xcode/id497799835) + 2. Run the following commands in Terminal + + xcode-select --install + sudo xcodebuild -license +2. Install MacPorts for your version of the Mac operating system: + * [macOS High Sierra v10.13](https://distfiles.macports.org/MacPorts/MacPorts-2.5.3-10.13-HighSierra.pkg) + * [macOS Sierra v10.12](https://distfiles.macports.org/MacPorts/MacPorts-2.5.3-10.12-Sierra.pkg) + * [OS X El Capitan v10.11](https://distfiles.macports.org/MacPorts/MacPorts-2.5.3-10.11-ElCapitan.pkg) + * [Older OS? See here.](https://www.macports.org/install.php#installing) + +With MacPorts installed, the command to install Gourmet is + + sudo port install gourmet +### Installing From Source +#### Using MacPorts To build gourmet from source, install the required dependencies as listed in the MacPorts column of the table below by running `sudo port install `. @@ -44,7 +64,7 @@ You should then be able to launch gourmet by running /opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin/gourmet -### Using Fink +#### Using Fink The following instructions all assume you have fink installed and that you have a terminal set up with the proper paths to run executables in the fink directories (/sw/bin/, etc.). diff --git a/README.md b/README.md index 6a57e1521..f980d12d7 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ See [INSTALL.md](INSTALL.md). Warning ======= -No warantee, etc. Please inform me of bugs/problems/feature +No warranty, etc. Please inform me of bugs/problems/feature requests and I'll respond as quickly as I can. I can be reached at Thomas_Hinkle@alumni.brown.edu diff --git a/gourmet/OptionParser.py b/gourmet/OptionParser.py index 90bde424d..23f265215 100644 --- a/gourmet/OptionParser.py +++ b/gourmet/OptionParser.py @@ -31,17 +31,29 @@ group = parser.add_mutually_exclusive_group() group.add_argument('-q',action='store_const',const=-1,dest='debug',help='Don\'t print gourmet error messages') -group.add_argument('-v',action='count',dest='debug',help='Be verbose (extra v\'s will increase the verbosity level') +group.add_argument('-v',action='count',dest='debug',help='Be verbose (extra v\'s will increase the verbosity level)') if has_argcomplete: argcomplete.autocomplete(parser) try: args = parser.parse_args() -except: - print 'Maybe using django?' - print 'Then you can ignore this :)' + print 'args1 = %s' % args +except SystemExit as e: import sys - sys.argv = ['gourmet'] - args = parser.parse_args() + exc = sys.exc_info()[1] + if e.code is 0: + # Normal system exit + exit(e.code) + else: + print "Exception code: ", exc + argv = str(sys.argv[0]) + + if argv == "manage.py": + print 'Ignore the error message. Launching gourmetweb Django server ...' + sys.argv = ['gourmet'] + args = parser.parse_args() + else: + # unrecognized argument + exit(e.code) diff --git a/gourmet/exporters/exporter.py b/gourmet/exporters/exporter.py index 6de2a8ade..fdb2de519 100644 --- a/gourmet/exporters/exporter.py +++ b/gourmet/exporters/exporter.py @@ -464,30 +464,33 @@ class ExporterMultirec (SuspendableThread, Pluggable): name = 'Exporter' - def __init__ (self, rd, recipes, out, one_file=True, open_files = True, - ext='txt', - conv=None, - imgcount=1, - exporter=exporter, - exporter_kwargs={}, - padding=None): + def __init__(self, rd, recipes, out, one_file=True, create_file=True, + ext='txt', + conv=None, + imgcount=1, + exporter=exporter, + exporter_kwargs={}, + padding=None): """Output all recipes in recipes into a document or multiple documents. if one_file, then everything is in one file. Otherwise, we treat 'out' as a directory and put individual recipe files within it. - @param one_file If True works in one_file mode. For this the class will + @param out: The name of the output file or directory + + @param one_file: If True works in one_file mode. For this the class will create the file which is accessible by self.ofi If this is set to False a directory will be created and the name of the directory will be passed via self.outdir and self.ofi - @param open_files If this parameter is True the files will be created + @param create_file: If this parameter is True the files will be created otherwise to create the file is up to the user. """ self.timer=TimeAction('exporterMultirec.__init__()') self.rd = rd self.recipes = recipes self.out = out + self.outdir = out self.padding=padding self.one_file = one_file Pluggable.__init__(self,[BaseExporterMultiRecPlugin]) @@ -499,7 +502,7 @@ def __init__ (self, rd, recipes, out, one_file=True, open_files = True, convert.FRACTIONS_ASCII) self.DEFAULT_ENCODING = self.exporter.DEFAULT_ENCODING self.one_file = one_file - self.open_files = open_files + self.create_file = create_file def _grab_attr_ (self, obj, attr): if attr=='category': @@ -550,8 +553,9 @@ def do_run (self): self.outdir=self.unique_name(self.outdir) os.makedirs(self.outdir) else: os.makedirs(self.outdir) - oneFileOpenByMyself = self.one_file and type(self.out) not in [str,unicode] and self.open_files - if oneFileOpenByMyself: + create_one_file = self.one_file and type(self.out) in [str, unicode] and self.create_file + create_multi_file = not self.one_file and type(self.out) in [str, unicode] + if create_one_file: self.ofi=open(self.out,'wb') else: self.ofi = self.out self.write_header() @@ -564,7 +568,7 @@ def do_run (self): msg = _("Exported %(number)s of %(total)s recipes")%{'number':self.rcount,'total':self.rlen} self.emit('progress',float(self.rcount)/float(self.rlen), msg) fn=None - if multiFileOpenByMyself: + if create_multi_file: fn=self.generate_filename(r,self.ext,add_id=True) self.ofi=open(fn,'wb') if self.padding and not first: @@ -573,12 +577,12 @@ def do_run (self): self.connect_subthread(e) e.do_run() self.recipe_hook(r,fn,e) - if multiFileOpenByMyself: + if create_multi_file: self.ofi.close() self.rcount += 1 first = False self.write_footer() - if oneFileOpenByMyself: + if create_one_file: self.ofi.close() self.timer.end() self.emit('progress',1,_("Export complete.")) diff --git a/gourmet/plugins/import_export/epub_plugin/epub_exporter.py b/gourmet/plugins/import_export/epub_plugin/epub_exporter.py index bd07ed3d7..7cc471b5b 100644 --- a/gourmet/plugins/import_export/epub_plugin/epub_exporter.py +++ b/gourmet/plugins/import_export/epub_plugin/epub_exporter.py @@ -287,7 +287,7 @@ def __init__ (self, rd, recipe_table, out, conv=None, ext='epub', copy_css=True, self.exportargs['conv']=conv ExporterMultirec.__init__(self, rd, recipe_table, out, one_file=True, - open_files=False, + create_file=False, ext=self.ext, exporter=epub_exporter, exporter_kwargs=self.exportargs) diff --git a/gourmet/plugins/web_plugin/gourmetweb/recview/views.py b/gourmet/plugins/web_plugin/gourmetweb/recview/views.py index 21951527d..88381b0ab 100644 --- a/gourmet/plugins/web_plugin/gourmetweb/recview/views.py +++ b/gourmet/plugins/web_plugin/gourmetweb/recview/views.py @@ -2,13 +2,15 @@ from django.http import HttpResponse, HttpResponseRedirect from django import forms from django.shortcuts import render_to_response -from django.template import Context, loader import sys +sys.path.append('../../../') import re import gourmet.backends.db import gourmet.shopping import gourmet.recipeManager -from django.utils import simplejson +import json + +from django.shortcuts import render class MultiplierForm (forms.Form): @@ -81,6 +83,12 @@ def do_search (request): else: print 'Not a post!' + +def about(request): + return render(request, 'about.html') + + + def search (request, term, template='index.html'): vw = rd.search_recipes( [{'column':'deleted','operator':'=','search':False}, @@ -169,8 +177,8 @@ def multiply_rec (request, xhr=None): 'ingredients':get_ings(recid,multiplier), 'multiplier':multiplier} return HttpResponse( - simplejson.dumps(d), - mimetype='application/javascript' + json.dumps(d), + content_type='application/javascript' ) else: return HttpResponseRedirect('/rec/%s/%s'%(recid,multiplier)) @@ -216,10 +224,10 @@ def shop_to_list (request): def thumb (request, rec_id): return HttpResponse(rd.get_rec(rec_id).thumb, - mimetype='image/jpeg' + content_type = 'image/jpeg' ) def img (request, rec_id): return HttpResponse(rd.get_rec(rec_id).image, - mimetype='image/jpeg' + content_type = 'image/jpeg' ) diff --git a/gourmet/plugins/web_plugin/gourmetweb/settings.py b/gourmet/plugins/web_plugin/gourmetweb/settings.py index 408f611f4..aa7aa514c 100644 --- a/gourmet/plugins/web_plugin/gourmetweb/settings.py +++ b/gourmet/plugins/web_plugin/gourmetweb/settings.py @@ -1,82 +1,122 @@ -# Django settings for gourmetweb project. +""" +Django settings for gourmetweb project. -import os.path +Generated by 'django-admin startproject' using Django 1.11.16. -DEBUG = True -TEMPLATE_DEBUG = DEBUG - -ADMINS = ( - # ('Your Name', 'your_email@domain.com'), -) - -MANAGERS = ADMINS - -DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. -DATABASE_NAME = '' # Or path to database file if using sqlite3. -DATABASE_USER = '' # Not used with sqlite3. -DATABASE_PASSWORD = '' # Not used with sqlite3. -DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. -DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. - -# Local time zone for this installation. Choices can be found here: -# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name -# although not all choices may be available on all operating systems. -# If running in a Windows environment this must be set to the same as your -# system time zone. -TIME_ZONE = 'America/Chicago' - -# Language code for this installation. All choices can be found here: -# http://www.i18nguy.com/unicode/language-identifiers.html -LANGUAGE_CODE = 'en-us' +For more information on this file, see +https://docs.djangoproject.com/en/1.11/topics/settings/ -SITE_ID = 1 +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.11/ref/settings/ +""" -# If you set this to False, Django will make some optimizations so as not -# to load the internationalization machinery. -USE_I18N = True +import os -# Absolute path to the directory that holds media. -# Example: "/home/media/media.lawrence.com/" -MEDIA_ROOT = '' +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +TEMPLATE_PATH = os.path.join(BASE_DIR, 'gourmetweb/templates/') -# URL that handles the media served from MEDIA_ROOT. Make sure to use a -# trailing slash if there is a path component (optional in other cases). -# Examples: "http://media.lawrence.com", "http://example.com/media/" -MEDIA_URL = '' -# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a -# trailing slash. -# Examples: "http://foo.com/media/", "/media/". -ADMIN_MEDIA_PREFIX = '/media/' +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ -# Make this unique, and don't share it with anybody. -SECRET_KEY = '79ko3mh^6v!kgn_*!@d8f5yk=v@v-^3(b4+&3-ihcpj1)pxfaw' +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '8vuzo^76+3#a!0^i&mbac@z8g3pz2w(u9d=+8hce276sb9a3x2' -# List of callables that know how to import templates from various sources. -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.load_template_source', - 'django.template.loaders.app_directories.load_template_source', -# 'django.template.loaders.eggs.load_template_source', -) +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True -MIDDLEWARE_CLASSES = ( - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', -) +ALLOWED_HOSTS = [] -ROOT_URLCONF = 'gourmetweb.urls' -TEMPLATE_DIRS = ( - # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. - os.path.join(os.path.realpath(os.path.split(__file__)[0]),'templates'), -) +# Application definition -INSTALLED_APPS = ( +INSTALLED_APPS = [ + 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', - 'django.contrib.sites', -) + 'django.contrib.messages', + 'django.contrib.staticfiles', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + # 'django.middleware.csrf.CsrfViewMiddleware', # uncomment to activate Cross-Site Request Forgery (CSRF) + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'gourmetweb.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [TEMPLATE_PATH], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'gourmetweb.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.11/ref/settings/#databases + +DATABASES = { + # 'default': {} # Empty dictionary + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/1.11/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.11/howto/static-files/ + +STATIC_URL = '/static/' diff --git a/gourmet/plugins/web_plugin/gourmetweb/templates/about.html b/gourmet/plugins/web_plugin/gourmetweb/templates/about.html new file mode 100644 index 000000000..00be7bcf9 --- /dev/null +++ b/gourmet/plugins/web_plugin/gourmetweb/templates/about.html @@ -0,0 +1,36 @@ + + + + + About: Gourmet Recipe Manager - Web View + + + + + + {%include "menu.html"%} +
+

Gourmet Recipe Manager - Web View

+

Recipe viewer and shopping list generator

+

Copyright (c) 2004-2014 Thomas M. Hinkle. GNU GPL v2

+ http://thinkle.github.io/gourmet/ +

This is an experimental implementation of a Django-based Gourmet Recipe Manager web application.

+

Even though the implementation is still experimental and not complete, the web app is usable.

+

This web app provides:

+ +

Notes:

+ + + diff --git a/gourmet/plugins/web_plugin/gourmetweb/templates/detect_screensize.js b/gourmet/plugins/web_plugin/gourmetweb/templates/detect_screensize.js index 29c83976d..aed138d50 100644 --- a/gourmet/plugins/web_plugin/gourmetweb/templates/detect_screensize.js +++ b/gourmet/plugins/web_plugin/gourmetweb/templates/detect_screensize.js @@ -10,5 +10,4 @@ $(document).ready(function() { if ($(window).width()<=600) { $("body").attr("class","tiny"); } - } - ); +}); diff --git a/gourmet/plugins/web_plugin/gourmetweb/templates/index.html b/gourmet/plugins/web_plugin/gourmetweb/templates/index.html index 5acea6e8c..e252a98dd 100644 --- a/gourmet/plugins/web_plugin/gourmetweb/templates/index.html +++ b/gourmet/plugins/web_plugin/gourmetweb/templates/index.html @@ -1,51 +1,53 @@ - - - - - - + + - - {%include "menu.html"%} -
-
{{form.as_p}} - -
-
{%include "list.html" %}
-
- + + + + {%include "menu.html"%} +
+
{{form.as_p}} + +
+
{%include "list.html" %}
+
+ diff --git a/gourmet/plugins/web_plugin/gourmetweb/templates/list.html b/gourmet/plugins/web_plugin/gourmetweb/templates/list.html index 0f5257fbd..af635f32b 100644 --- a/gourmet/plugins/web_plugin/gourmetweb/templates/list.html +++ b/gourmet/plugins/web_plugin/gourmetweb/templates/list.html @@ -1,21 +1,27 @@ - - {% for r, cats in recs %} - - - - - - - - {% endfor %} -
TitleCuisineCategory
{% if r.thumb %} - - {%endif%} - {{ r.title }}{{ r.cuisine }} - - - {% for c in cats %} - {{c}} - - - {% endfor %} - (add to shopping list)
+ + + Title + Cuisine + Category + + + {% for r, cats in recs %} + + {% if r.thumb %} + + {%endif%} + + {{ r.title }} + {{ r.cuisine }} + + - + {% for c in cats %} + {{c}} + - + {% endfor %} + + (add to shopping list) + + {% endfor %} + diff --git a/gourmet/plugins/web_plugin/gourmetweb/templates/menu.html b/gourmet/plugins/web_plugin/gourmetweb/templates/menu.html index 30f0709fe..13dd30a38 100644 --- a/gourmet/plugins/web_plugin/gourmetweb/templates/menu.html +++ b/gourmet/plugins/web_plugin/gourmetweb/templates/menu.html @@ -1,8 +1,9 @@ - - - - - - + + + + + + + diff --git a/gourmet/plugins/web_plugin/gourmetweb/templates/rec.html b/gourmet/plugins/web_plugin/gourmetweb/templates/rec.html index fddc9d512..8b42e735d 100644 --- a/gourmet/plugins/web_plugin/gourmetweb/templates/rec.html +++ b/gourmet/plugins/web_plugin/gourmetweb/templates/rec.html @@ -1,125 +1,124 @@ - - - - + - - - {%include "menu.html"%} - -
-

{{ r.title }}

Add to Shopping List - {% if r.image %} {% endif %} -
-

- {% if r.cuisine %}
Cuisine: {{ r.cuisine }} {% endif %} - {% if r.link %}
Original Link: {{ r.link }} {% endif %} - {% if r.rating %}
Rating: {{ r.rating }} {% endif %} - {% if cats %}
Categories: {{ cats }}{% endif %} - {% if r.yields %}
Yields: {{yields}} {{r.yield_unit}} {% endif %} - {% if is_adjusted %} - (x{{mult}}) - {% endif %} - (Edit) -

-
- {% if r.instructions %} -

Instructions

-

{{ instructions|safe }}

- {% endif %} - {% if r.modifications %} -

Notes

-

{{ notes|safe }}

- {% endif %} -
- -
-

Ingredients

-
-
    - {% for group, items in ings %} - - {% if group %} -
  • - - {{ group }} -
      - {% endif %} - {% for item in items %} -
    • {{ item }}
    • - {% endfor %} - {% if group %} -
    -
  • - {% endif %} - {% endfor %} -
-
-
-
- + + + + {%include "menu.html"%} +
+

{{ r.title }}

+ Add to Shopping List + {% if r.image %} {% endif %} +
+

+ + {% if r.cuisine %}
Cuisine: {{ r.cuisine }} {% endif %} + {% if r.link %}
Original Link: {{ r.link }} {% endif %} + {% if r.rating %}
Rating: {{ r.rating }} {% endif %} + {% if cats %}
Categories: {{ cats }}{% endif %} + {% if r.yields %}
Yields: {{yields}} {{r.yield_unit}} {% endif %} + {% if is_adjusted %} + (x{{mult}}) + {% endif %} + (Edit) +

+
+
+ {% if r.instructions %} +

Instructions

+

{{ instructions|safe }}

+ {% endif %} + {% if r.modifications %} +

Notes

+

{{ notes|safe }}

+ {% endif %} +
+
+

Ingredients

+
+
    + {% for group, items in ings %} + {% if group %} +
  • + {{ group }} +
      + {% endif %} + {% for item in items %} +
    • {{ item }}
    • + {% endfor %} + {% if group %} +
    +
  • + {% endif %} + {% endfor %} +
+
+
+
+ diff --git a/gourmet/plugins/web_plugin/gourmetweb/templates/shop.html b/gourmet/plugins/web_plugin/gourmetweb/templates/shop.html index 846092c2d..13410a7b6 100644 --- a/gourmet/plugins/web_plugin/gourmetweb/templates/shop.html +++ b/gourmet/plugins/web_plugin/gourmetweb/templates/shop.html @@ -1,58 +1,56 @@ - - - - - - - {%include "menu.html"%} -
-
-

Shopping list for...

- {% for rec, mult in recs %} -
{{rec.title}} x{{mult}} (remove) - {% endfor %} -
- - - - - -
-
-

Shopping List

- - - {% for group, lst in data %} -

{{group}}

- {% for item, amt in lst %} - {{item}} {{amount}}
- {% endfor %} - {% endfor %} -
-
-
-

Pantry List

- - {% for group, lst in pantry %} -

{{group}}

- {% for item, amt in lst %} - {{item}} {{amount}}
- {% endfor %} - {% endfor %} -
-
- + + + Shopping List: Gourmet Recipe Manager - Web View + + + + + + {%include "menu.html"%} +
+
+

Shopping list for...

+ {% for rec, mult in recs %} +
{{rec.title}} x{{mult}} (remove) + {% endfor %} +
+ + + + + +
+ +

Shopping List

+ + {% for group, lst in data %} +

{{group}}

+ {% for item, amt in lst %} + {{item}} {{amount}}
+ {% endfor %} + {% endfor %} + +
+
+

Pantry List

+ + {% for group, lst in pantry %} +

{{group}}

+ {% for item, amt in lst %} + {{item}} {{amount}}
+ {% endfor %} + {% endfor %} +
+
+
+ diff --git a/gourmet/plugins/web_plugin/gourmetweb/urls.py b/gourmet/plugins/web_plugin/gourmetweb/urls.py index 5986af468..b8ba61f7f 100644 --- a/gourmet/plugins/web_plugin/gourmetweb/urls.py +++ b/gourmet/plugins/web_plugin/gourmetweb/urls.py @@ -1,32 +1,35 @@ -from django.conf.urls import patterns +from django.conf.urls import url +import django.views.static +from recview import views as rv_views +from django.conf import settings # Uncomment the next two lines to enable the admin: # from django.contrib import admin # admin.autodiscover() -urlpatterns = patterns( - '', - (r'^$','gourmetweb.recview.views.index'), - (r'^sort/(?P.*)/','gourmetweb.recview.views.sort'), - (r'^search/(?P.*)','gourmetweb.recview.views.search'), - (r'^rec/do_search/','gourmetweb.recview.views.do_search'), - (r'^rec/do_search_xhr/','gourmetweb.recview.views.do_search_xhr'), - (r'^regexp/(?P.*)','gourmetweb.recview.views.regexp'), - (r'^rec/$','gourmetweb.recview.views.index'), - (r'^rec/(?P\d*)/$','gourmetweb.recview.views.rec'), - (r'^rec/(?P\d*)/(?P[\d.]*)$','gourmetweb.recview.views.rec'), - (r'^shop/$','gourmetweb.recview.views.shop'), - (r'^shop/(?P\d*)/$','gourmetweb.recview.views.shop'), - (r'^shop/(?P\d*)/(?P[\d.]*)$','gourmetweb.recview.views.shop'), - (r'^shop/remove/(?P\d*)/$','gourmetweb.recview.views.shop_remove'), - (r'^shop/to_pantry/','gourmetweb.recview.views.shop_to_pantry'), - (r'^shop/to_list/','gourmetweb.recview.views.shop_to_list'), - (r'^rec/multiply/','gourmetweb.recview.views.multiply_rec'), - (r'^img/(?P\d*)/$','gourmetweb.recview.views.img'), - (r'^thumb/(?P\d*)/$','gourmetweb.recview.views.thumb'), - (r'^rec/multiply_xhr/','gourmetweb.recview.views.multiply_rec_xhr'), - (r'^js/(?P.*)$','django.views.static.serve',{'document_root':'/home/tom/Projects/grecipe-manager/src/lib/plugins/web_plugin/gourmetweb/templates/'}), - #(r'^shop/(?P\d*)/(?P\d)/$','gourmetweb.recview.views.shop'), +urlpatterns = [ + url(r'^$', rv_views.index, name='index'), + url(r'^sort/(?P.*)/', rv_views.sort), + url(r'^search/(?P.*)', rv_views.search), + url(r'^rec/do_search/', rv_views.do_search), + url(r'^rec/do_search_xhr/', rv_views.do_search_xhr), + # url(r'^regexp/(?P.*)', rv_views.regexp), # regexp is not implemented in recview.views.regexp + url(r'^rec/$', rv_views.index), + url(r'^rec/(?P\d*)/$', rv_views.rec), + url(r'^rec/(?P\d*)/(?P[\d.]*)$', rv_views.rec), + url(r'^shop/$', rv_views.shop), + url(r'^shop/(?P\d*)/$', rv_views.shop), + url(r'^shop/(?P\d*)/(?P[\d.]*)$', rv_views.shop), + url(r'^shop/remove/(?P\d*)/$', rv_views.shop_remove), + url(r'^shop/to_pantry/', rv_views.shop_to_pantry), + url(r'^shop/to_list/', rv_views.shop_to_list), + url(r'^rec/multiply/', rv_views.multiply_rec), + url(r'^img/(?P\d*)/$', rv_views.img), + url(r'^thumb/(?P\d*)/$', rv_views.thumb), + url(r'^rec/multiply_xhr/', rv_views.multiply_rec_xhr), + url(r'^js/(?P.*)$', django.views.static.serve, {'document_root': settings.TEMPLATE_PATH}), + # url(r'^shop/(?P\d*)/(?P\d)/$', rv_views.shop), + url(r'^about/$', rv_views.about), # Example: # (r'^gourmet/', include('gourmet.foo.urls')), @@ -36,4 +39,4 @@ # Uncomment the next line to enable the admin: # (r'^admin/', include(admin.site.urls)), -) +] diff --git a/gourmet/plugins/web_plugin/gourmetweb/wsgi.py b/gourmet/plugins/web_plugin/gourmetweb/wsgi.py new file mode 100644 index 000000000..355cecec6 --- /dev/null +++ b/gourmet/plugins/web_plugin/gourmetweb/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for gourmetweb project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gourmetweb.settings") + +application = get_wsgi_application() diff --git a/gourmet/plugins/web_plugin/manage.py b/gourmet/plugins/web_plugin/manage.py index 45ad3bce2..8790c4102 100755 --- a/gourmet/plugins/web_plugin/manage.py +++ b/gourmet/plugins/web_plugin/manage.py @@ -1,9 +1,22 @@ #!/usr/bin/env python -import os, sys +import os +import sys if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gourmetweb.settings") - - from django.core.management import execute_from_command_line - + try: + from django.core.management import execute_from_command_line + except ImportError: + # The above import may fail for some other reason. Ensure that the + # issue is really that Django is missing to avoid masking other + # exceptions on Python 2. + try: + import django + except ImportError: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) + raise execute_from_command_line(sys.argv) diff --git a/po/nl.po b/po/nl.po index 40babd255..cf6042c24 100644 --- a/po/nl.po +++ b/po/nl.po @@ -463,7 +463,7 @@ msgstr "Notities" #: ../ui/recCardDisplay.ui.h:16 msgid "Edit _notes" -msgstr "_Notiities bewerken" +msgstr "_Notities bewerken" #: ../ui/recCardDisplay.ui.h:17 ../gourmet/exporters/exporter.py:615 #: ../gourmet/plugins/duplicate_finder/recipeMerger.py:488 @@ -1132,7 +1132,7 @@ msgstr "Recept %s is verwijderd" #: ../gourmet/GourmetRecipeManager.py:1328 msgid "See Trash Now" -msgstr "" +msgstr "Prullenbak openen" #: ../gourmet/GourmetRecipeManager.py:1367 msgid "Done!"