From 28047277f1fb0679c3b94bb5a14d2384a94cc27f Mon Sep 17 00:00:00 2001
From: expo <expo@expobox.potato.hut>
Date: Sun, 12 Aug 2012 19:10:23 +0200
Subject: [PATCH] Started removing foreignkeys to caves, to achieve greater
 flexability.  Some log book entries stuff may be broken.  Add ability to make
 new caves and entrances via website.

---
 core/admin.py                 |  3 +--
 core/forms.py                 | 17 +++++++++++++----
 core/models.py                | 27 ++++++++++++++++++++-------
 core/views_caves.py           | 29 ++++++++++++++++++++++++-----
 databaseReset.py              | 10 ++++++++++
 flatpages/views.py            |  5 +++--
 templates/base.html           |  2 +-
 templates/cave_entrances.html |  2 ++
 templates/caveindex.html      |  2 ++
 urls.py                       |  3 +++
 10 files changed, 79 insertions(+), 21 deletions(-)

diff --git a/core/admin.py b/core/admin.py
index fc43f23..0192807 100644
--- a/core/admin.py
+++ b/core/admin.py
@@ -55,8 +55,7 @@ class PersonTripInline(admin.TabularInline):
 
 #class LogbookEntryAdmin(VersionAdmin):
 class LogbookEntryAdmin(TroggleModelAdmin):
-    prepopulated_fields = {'slug':("title",)}
-    raw_id_fields = ('cave',)    
+    prepopulated_fields = {'slug':("title",)} 
     search_fields = ('title','expedition__year')
     date_heirarchy = ('date')
     inlines = (PersonTripInline, PhotoInline, QMsFoundInline)
diff --git a/core/forms.py b/core/forms.py
index e0654fb..da16d79 100644
--- a/core/forms.py
+++ b/core/forms.py
@@ -16,8 +16,11 @@ class CaveForm(ModelForm):
     underground_centre_line = forms.CharField(required = False, widget=forms.Textarea())
     notes = forms.CharField(required = False, widget=forms.Textarea())
     references = forms.CharField(required = False, widget=forms.Textarea())
+    slug = forms.CharField(required = True) 
+    url = forms.CharField(required = True) 
     class Meta:
         model = Cave
+        exclude = ("filename",)
 
 class VersionControlCommentForm(forms.Form):
     description_of_change = forms.CharField(required = True, widget=forms.Textarea())
@@ -32,15 +35,21 @@ class EntranceForm(ModelForm):
     #underground_centre_line = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10}))
     #notes = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10}))
     #references = forms.CharField(required = False, widget=TinyMCE(attrs={'cols': 80, 'rows': 10}))
+    other_station = forms.CharField(required=False) # Trying to change this to a singl;e line entry
+    tag_station = forms.CharField(required=False) # Trying to change this to a singl;e line entry
+    exact_station = forms.CharField(required=False) # Trying to change this to a singl;e line entry
+    northing = forms.CharField(required=False) # Trying to change this to a singl;e line entry
+    easting = forms.CharField(required=False) # Trying to change this to a singl;e line entry
+    alt = forms.CharField(required=False) # Trying to change this to a singl;e line entry
+    slug = forms.CharField() 
     class Meta:
         model = Entrance
+        exclude = ("cached_primary_slug", "filename",)
+
+
 
 CaveAndEntranceFormSet = modelformset_factory(CaveAndEntrance, exclude=('cave'))
 
-class EntranceForm(ModelForm):
-    class Meta:
-        model = Entrance
-
 #class PersonForm(ModelForm):
 #    class Meta:
 #        model = Person
diff --git a/core/models.py b/core/models.py
index ca4556e..1c86dd5 100644
--- a/core/models.py
+++ b/core/models.py
@@ -23,7 +23,8 @@ def get_related_by_wikilinks(wiki_text):
     for wikilink in found:
         qmdict={'urlroot':settings.URL_ROOT,'cave':wikilink[2],'year':wikilink[1],'number':wikilink[3]}
         try:
-            qm=QM.objects.get(found_by__cave__kataster_number = qmdict['cave'],
+            cave_slugs = CaveSlug.objects.filter(cave__kataster_number = qmdict['cave'])
+            qm=QM.objects.get(found_by__cave_slug__in = cave_slugs,
                               found_by__date__year = qmdict['year'],
                               number = qmdict['number'])
             res.append(qm)         
@@ -240,17 +241,29 @@ class LogbookEntry(TroggleModel):
     #author  = models.ForeignKey(PersonExpedition,blank=True,null=True)  # the person who writes it up doesn't have to have been on the trip.
     # Re: the above- so this field should be "typist" or something, not "author". - AC 15 jun 09
     #MJG wants to KILL THIS, as it is typically redundant with PersonTrip.is_logbook_entry_author, in the rare it was not redundanty and of actually interest it could be added to the text.
-    title   = models.CharField(max_length=settings.MAX_LOGBOOK_ENTRY_TITLE_LENGTH)
-    cave    = models.ForeignKey('Cave',blank=True,null=True)
-    place   = models.CharField(max_length=100,blank=True,null=True,help_text="Only use this if you haven't chosen a cave")
-    text    = models.TextField()
-    slug    = models.SlugField(max_length=50)
-    filename= models.CharField(max_length=200,null=True)
+    title     = models.CharField(max_length=settings.MAX_LOGBOOK_ENTRY_TITLE_LENGTH)
+    cave_slug = models.SlugField(max_length=50)
+    place     = models.CharField(max_length=100,blank=True,null=True,help_text="Only use this if you haven't chosen a cave")
+    text      = models.TextField()
+    slug      = models.SlugField(max_length=50)
+    filename  = models.CharField(max_length=200,null=True)
 
     class Meta:
 	verbose_name_plural = "Logbook Entries"
         # several PersonTrips point in to this object
         ordering = ('-date',)
+        
+    def __getattribute__(self, item):
+      if item == "cave":  #Allow a logbookentries cave to be directly accessed despite not having a proper foreignkey
+        return CaveSlug.objects.get(slug = self.cave_slug).cave
+      return super(LogbookEntry, self).__getattribute__(item)
+    
+    def __init__(self, *args, **kwargs):
+	  if "cave" in kwargs.keys():
+		 if kwargs["cave"] is not None:
+			 kwargs["cave_slug"] = CaveSlug.objects.get(cave = kwargs["cave"], primary = True).slug
+		 kwargs.pop("cave")
+	  return super(LogbookEntry, self).__init__(*args, **kwargs)
 
     def isLogbookEntry(self): # Function used in templates
         return True
diff --git a/core/views_caves.py b/core/views_caves.py
index ae5f46f..2590cf1 100644
--- a/core/views_caves.py
+++ b/core/views_caves.py
@@ -1,4 +1,4 @@
-from troggle.core.models import Cave, CaveAndEntrance, Survey, Expedition, QM, CaveDescription, Entrance, Area
+from troggle.core.models import CaveSlug, Cave, CaveAndEntrance, Survey, Expedition, QM, CaveDescription, EntranceSlug, Entrance, Area
 from troggle.core.forms import CaveForm, CaveAndEntranceFormSet, VersionControlCommentForm, EntranceForm
 import troggle.core.models as models
 import troggle.settings as settings
@@ -94,13 +94,22 @@ def caveSlug(request, slug):
 
 @login_required_if_public
 def edit_cave(request, slug=None):
-    cave = Cave.objects.get(caveslug__slug = slug)
+    if  slug is not None:
+        cave = Cave.objects.get(caveslug__slug = slug)
+    else:
+        cave = Cave()
     if request.POST:
         form = CaveForm(request.POST, instance=cave)
         ceFormSet = CaveAndEntranceFormSet(request.POST)
         versionControlForm = VersionControlCommentForm(request.POST)
         if form.is_valid() and ceFormSet.is_valid() and versionControlForm.is_valid():
-            cave = form.save()
+            cave = form.save(commit = False)
+            cave.filename = form.cleaned_data["slug"] + ".html"
+            cave.save()
+            form.save_m2m()
+            if slug is None:
+              cs = CaveSlug(cave = cave, slug = form.cleaned_data["slug"], primary = True)
+              cs.save()
             ceinsts = ceFormSet.save(commit=False)
             for ceinst in ceinsts:
                 ceinst.cave = cave
@@ -121,12 +130,22 @@ def edit_cave(request, slug=None):
 
 @login_required_if_public
 def editEntrance(request, slug=None):
-    entrance = Entrance.objects.get(entranceslug__slug = slug)
+    if  slug is not None:
+        entrance = Entrance.objects.get(entranceslug__slug = slug)
+    else:
+        entrance = Entrance()
     if request.POST:
         form = EntranceForm(request.POST, instance = entrance)
         versionControlForm = VersionControlCommentForm(request.POST)
         if form.is_valid() and versionControlForm.is_valid():
-            entrance = form.save()
+            entrance = form.save(commit = False)
+            entrance.filename = form.cleaned_data["slug"] + ".html"
+            if slug is None:
+              entrance.cached_primary_slug = form.cleaned_data["slug"]
+            entrance.save()
+            if slug is None:
+              es = EntranceSlug(entrance = entrance, slug = form.cleaned_data["slug"], primary = True)
+              es.save()
             entrance.writeDataFile()
             return HttpResponseRedirect("/" + entrance.url) 
     else:
diff --git a/databaseReset.py b/databaseReset.py
index 7f302d5..eb021d0 100644
--- a/databaseReset.py
+++ b/databaseReset.py
@@ -181,6 +181,16 @@ if __name__ == "__main__":
         import_tunnelfiles()
     elif "reset" in sys.argv:
         reset()
+    elif "resetend" in sys.argv:
+        #import_logbooks()
+        import_QMs()
+        try:
+            import_tunnelfiles()
+        except:
+            print "Tunnel files parser broken."
+        import_surveys()
+        import_descriptions()
+        parse_descriptions()
     elif "survex" in sys.argv:
         management.call_command('syncdb', interactive=False)  # this sets the path so that import settings works in import_survex
         import_survex()
diff --git a/flatpages/views.py b/flatpages/views.py
index 3a1bc40..cc1feef 100644
--- a/flatpages/views.py
+++ b/flatpages/views.py
@@ -128,7 +128,6 @@ def editflatpage(request, path):
     if request.method == 'POST': # If the form has been submitted...
         flatpageForm = FlatPageForm(request.POST) # A form bound to the POST data
         if flatpageForm.is_valid():# Form valid therefore write file
-            f = open(filepath, "w")
             if filefound:
                 headmatch =  re.match(r"(.*)<title>.*</title>(.*)", head, re.DOTALL + re.IGNORECASE)
                 if headmatch:
@@ -144,7 +143,9 @@ def editflatpage(request, path):
                 postbody = "</html>" 
             body = flatpageForm.cleaned_data["html"]
             body = body.replace("\r", "")
-            f.write("%s<head%s>%s</head>%s<body%s>\n%s</body>%s" % (preheader, headerargs, head, postheader, bodyargs, body, postbody))
+            result = u"%s<head%s>%s</head>%s<body%s>\n%s</body>%s" % (preheader, headerargs, head, postheader, bodyargs, body, postbody)
+            f = open(filepath, "w")
+            f.write(result)
             f.close()
             return HttpResponseRedirect(reverse('flatpage', args=[path])) # Redirect after POST
     else:
diff --git a/templates/base.html b/templates/base.html
index 3fa9245..b1e51e3 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -18,7 +18,7 @@
 <div id="header"> 
   <h1>CUCC Expeditions to Austria: 1976 - 2012</h1>
   <div id="editLinks"> {% block loginInfo %}
-    <a href="{{ settings.EXPOWEB_URL }}">Expoweb</a> |
+    <a href="{{settings.EXPOWEB_URL}}">Expoweb</a> |
     {% if user.username %}
     You are logged in as {{ user.username }} 
     	{% if user.person %}(<a href="{{ user.person.get_absolute_url }}">{{ user.person }}</a>)
diff --git a/templates/cave_entrances.html b/templates/cave_entrances.html
index 1364acf..6468ebc 100644
--- a/templates/cave_entrances.html
+++ b/templates/cave_entrances.html
@@ -65,5 +65,7 @@
       </li>
     {% endfor %}
     </ul>
+
 {% endif %}</p>
+<a href="{% url newentrance %}">New Entrance</a>
 	</div>
diff --git a/templates/caveindex.html b/templates/caveindex.html
index 42322d3..fe141ed 100644
--- a/templates/caveindex.html
+++ b/templates/caveindex.html
@@ -34,4 +34,6 @@
 {% endfor %}
 </ul>
 
+<a href="{% url newcave %}">New Cave</a>
+
 {% endblock %}
diff --git a/urls.py b/urls.py
index 1ff174d..35d8dad 100644
--- a/urls.py
+++ b/urls.py
@@ -43,6 +43,8 @@ actualurlpatterns = patterns('',
     url(r'^getPeople/(?P<expeditionslug>.*)', views_logbooks.get_people, name = "get_people"),
     url(r'^getLogBookEntries/(?P<expeditionslug>.*)', views_logbooks.get_logbook_entries, name = "get_logbook_entries"),
 
+    
+    url(r'^cave/new/$', edit_cave, name="newcave"),
     url(r'^cave/(?P<cave_id>[^/]+)/?$', views_caves.cave, name="cave"),
     url(r'^caveslug/([^/]+)/?$', views_caves.caveSlug, name="caveSlug"),
     url(r'^cave/entrance/([^/]+)/?$', views_caves.caveEntrance),
@@ -50,6 +52,7 @@ actualurlpatterns = patterns('',
     url(r'^cave/qms/([^/]+)/?$', views_caves.caveQMs),
     url(r'^cave/logbook/([^/]+)/?$', views_caves.caveLogbook),
     url(r'^entrance/(?P<slug>[^/]+)/edit/', views_caves.editEntrance, name = "editentrance"),
+    url(r'^entrance/new/', views_caves.editEntrance, name = "newentrance"),
     #url(r'^cavedescription/(?P<cavedescription_name>[^/]+)/?$', views_caves.cave_description, name="cavedescription"),
     #url(r'^cavedescription/?$', object_list, {'queryset':CaveDescription.objects.all(),'template_name':'object_list.html'}, name="cavedescriptions"),
     #url(r'^cavehref/(.+)$',     views_caves.cave,       name="cave"),url(r'cave'),