Server-side refactor.
authorŁukasz Rekucki <lrekucki@gmail.com>
Wed, 26 Aug 2009 11:42:42 +0000 (13:42 +0200)
committerŁukasz Rekucki <lrekucki@gmail.com>
Wed, 26 Aug 2009 11:42:42 +0000 (13:42 +0200)
Brute-force refresh of HTMLEditor.

apps/explorer/forms.py
apps/explorer/views.py
lib/hg.py
project/static/js/editor.js
project/templates/explorer/editor.html [new file with mode: 0644]
project/templates/explorer/file_list.html
project/templates/explorer/file_xml.html [deleted file]
project/templates/explorer/panels/xmleditor.html
project/urls.py

index e648aa5..f7fcf07 100644 (file)
@@ -5,11 +5,9 @@ from librarian import dcparser
 
 from explorer import models
 
-
 class BookForm(forms.Form):
-    text = forms.CharField(widget=forms.Textarea)
-    commit_message = forms.CharField()
-    user = forms.CharField()
+    content = forms.CharField(widget=forms.Textarea)
+    message = forms.CharField(required=False)
 
 class ImageFoldersForm(forms.Form):
     folders = forms.ChoiceField(required=False)
index ffe5973..197e6f5 100644 (file)
@@ -1,5 +1,5 @@
 from librarian import html
-import hg, urllib2
+import hg, urllib2, time
 from django.utils import simplejson as json
 
 from django.views.generic.simple import direct_to_template
@@ -17,54 +17,62 @@ def file_list(request):
         'objects': repo.all_files(),
     })
 
+
+#
+# Edit the file
+#
 def file_xml(request, path):
     if request.method == 'POST':
         form = forms.BookForm(request.POST)
         if form.is_valid():
-            # save the changes to a local branch
-#           repo.write_lock()
-            print request.user
-#            repo.switch_to_branch(request.user.name)           
-#            repo.add_file(path, form.cleaned_data['text'])
-            
-            # add references to comment
-            issues = _get_issues_for_file(path)
-            commit_message = _add_references(form.cleaned_data['commit_message'], issues)
-            print 'Commiting with: ' + commit_message
-
-#            repo.commit(message=commit_message, user=form.cleaned_data['user'])
-        return HttpResponse( json.dumps({'message': commit_message}) )
+            print 'Saving whole text.', request.user.username
+            def save_action():
+                repo.add_file(path, form.cleaned_data['content'])
+                repo.commit(message='Local save at %s' % time.ctime(), user=request.user.username)
+
+            repo.in_branch('local_'+request.user.username, save_action);
+            return HttpResponse( json.dumps({'result': 'ok', 'errors': []}) );
     else:
         form = forms.BookForm()
-        form.fields['text'].initial = repo.get_file(path).data()
-    
-    return direct_to_template(request, 'explorer/file_xml.html', extra_context={
-        'hash': path,
+        form.fields['content'].initial = repo.get_file(path).data()
+
+    return direct_to_template(request, 'explorer/edit_text.html', extra_context={
         'form': form,
-        'image_folders_form': forms.ImageFoldersForm(),
     })
 
+def file_dc(request, path):
+    return HttpResponse("N/A")
+
+# Display the main editor view
+def display_editor(request, path):
+    return direct_to_template(request, 'explorer/editor.html', extra_context={
+        'hash': path,
+    })
 
 # ===============
 # = Panel views =
 # ===============
+
 def xmleditor_panel(request, path):
     form = forms.BookForm()
     text = repo.get_file(path).data()
     
     return direct_to_template(request, 'explorer/panels/xmleditor.html', extra_context={
+        'fpath': path,
         'text': text,
     })
     
 
 def gallery_panel(request, path):
     return direct_to_template(request, 'explorer/panels/gallery.html', extra_context={
+        'fpath': path,
         'form': forms.ImageFoldersForm(),
     })
 
 
 def htmleditor_panel(request, path):
     return direct_to_template(request, 'explorer/panels/htmleditor.html', extra_context={
+        'fpath': path,
         'html': html.transform(repo.get_file(path).data(), is_file=False),
     })
  
@@ -80,6 +88,7 @@ def dceditor_panel(request, path):
         form = forms.DublinCoreForm(text=text)       
 
     return direct_to_template(request, 'explorer/panels/dceditor.html', extra_context={
+        'fpath': path,
         'form': form,
     })
 
index e785b37..2b885b3 100644 (file)
--- a/lib/hg.py
+++ b/lib/hg.py
@@ -108,4 +108,22 @@ class Repository(object):
             # reread keys
             # self._keys = self.get_persisted_objects_keys()
             # return node.hex(rev)
+
+    def in_branch(self, branch_name, action):
+        wlock = self.repo.wlock()
+        try:
+            current_branch = self.repo[None].branch()
+            self.repo.dirstate.setbranch(branch_name)
+            try:
+                # do some stuff
+                action()
+            finally:
+                self.repo.dirstate.setbranch(current_branch)
+        finally:
+            wlock.release()
+
+    def write_lock(self):
+        """Returns w write lock to the repository."""
+        return self.repo.wlock()
+
             
index 234a436..4e867b7 100644 (file)
@@ -13,7 +13,7 @@ function Panel(panelWrap) {
                if(self != data) 
                        self.otherPanelChanged(event.target);
                else 
-                       self.changed();
+                       self.markChanged();
 
                return false;           
        });
@@ -24,7 +24,7 @@ Panel.prototype.callHook = function(hookName) {
        {       
 //             arguments.shift();
                $.log('calling hook: ', hookName, 'with args: ', arguments);
-               this.hooks[hookName].apply(this, arguments);
+               return this.hooks[hookName].apply(this, arguments);
        }
 }
 
@@ -32,6 +32,7 @@ Panel.prototype.load = function (url) {
     $.log('preparing xhr load: ', this.wrap);
     $(document).trigger('panel:unload', this);
        var self = this;
+       self.current_url = url;
 
     $.ajax({
         url: url,
@@ -61,14 +62,30 @@ Panel.prototype.unload = function(event, data) {
     };
 }
 
+Panel.prototype.refresh = function(event, data) {
+       $('.change-notification', this.wrap).fadeOut();
+       $.log('refreshing view for panel ', this.current_url);
+       this.load(this.current_url);
+//     if( this.callHook('refresh') )
+} 
+
 Panel.prototype.otherPanelChanged = function(other) {
        $.log('panel ', other, ' changed.');
        $('.change-notification', this.wrap).fadeIn();
        this.callHook('dirty');
 }      
 
+Panel.prototype.markChanged = function () {
+       if(!this.wrap.hasClass('changed') ) // TODO: is this needed ?
+               this.wrap.addClass('changed');
+}
+
 Panel.prototype.changed = function () {
-       this.wrap.addClass('changed');
+       return this.wrap.hasClass('changed');
+}
+
+Panel.prototype.unmarkChanged = function () {
+       this.wrap.removeClass('changed');
 }
 
 Panel.prototype.saveInfo = function() {
@@ -87,6 +104,7 @@ Editor.prototype.setupUI = function() {
        // set up the UI visually and attach callbacks
        var self = this;
        var panelRoot = $('#panels');
+       self.rootDiv = panelRoot;
 
        panelRoot.makeHorizPanel({}); // TODO: this probably doesn't belong into jQuery
     panelRoot.css('top', ($('#header').outerHeight() ) + 'px');
@@ -112,6 +130,7 @@ Editor.prototype.loadConfig = function() {
 
 Editor.prototype.saveToBranch = function() {
        var changed_panel = $('.panel-wrap.changed');
+       var self = this;
        $.log('Saving to local branch - panel:', changed_panel);
 
        if( changed_panel.length == 0) {
@@ -127,19 +146,36 @@ Editor.prototype.saveToBranch = function() {
        saveInfo = changed_panel.data('ctrl').saveInfo();
 
        $.ajax({
-               url: location.href + (saveInfo.part || ''),
-               dataType: (saveInfo.dataType || 'text'),
+               url: saveInfo.url,
+               dataType: 'json',
                success: function(data, textStatus) {
-                       $.log('Success:', data);
+                       if (data.result != 'ok')
+                               $.log('save errors: ', data.errors)
+                       else 
+                               self.refreshPanels(changed_panel);
                },
                error: function(rq, tstat, err) {
                        $.log('save error', rq, tstat, err);
                },
                type: 'POST',
-               data: (saveInfo.content || '')
+               data: saveInfo.postData
        });
 };
 
+Editor.prototype.refreshPanels = function(goodPanel) {
+       var self = this;
+       var panels = $('#' + self.rootDiv.attr('id') +' > *.panel-wrap', self.rootDiv.parent());
+
+       panels.each(function() {
+               var panel = $(this).data('ctrl');
+               $.log(this, panel);
+               if ( panel.changed() )
+                       panel.unmarkChanged();
+               else 
+                       panel.refresh();
+       });
+};             
+
 $(function() {
        editor = new Editor();
 
diff --git a/project/templates/explorer/editor.html b/project/templates/explorer/editor.html
new file mode 100644 (file)
index 0000000..805f59c
--- /dev/null
@@ -0,0 +1,47 @@
+{% extends "base.html" %}
+
+{% block extrahead %}
+    <script src="/static/js/jquery.lazyload.js" type="text/javascript" charset="utf-8"></script>
+    <script src="/static/js/codemirror/codemirror.js" type="text/javascript" charset="utf-8"></script>
+    <script src="/static/js/jquery.autoscroll.js" type="text/javascript" charset="utf-8"></script>
+    <script src="/static/js/jquery.wtooltip.js" type="text/javascript" charset="utf-8"></script>
+    <script src="/static/js/jquery.hpanel.js" type="text/javascript" charset="utf-8"></script>
+    <script src="/static/js/editor.js" type="text/javascript" charset="utf-8"></script>
+{% endblock extrahead %}
+
+{% block breadcrumbs %}<a href="{% url file_list %}">Platforma Redakcyjna</a> ❯ plik {{ hash }}{% endblock breadcrumbs %}
+
+{% block header-toolbar %}
+       <button type="button" class="toolbar-button" id="toolbar-button-save">Zapisz</button>
+{% endblock %}
+{% block maincontent %}
+        <div id="panels">
+            <div id="left-panel-wrap" class="panel-wrap">
+               <div id="left-panel-toolbar" class="panel-toolbar">
+                    <label for="select-left-panel">Lewy panel:</label>
+                    <select name="select-left-panel" id="select-left-panel">
+                        <option value="{% url xmleditor_panel hash %}">Edytor XML</option>
+                        <option value="{% url htmleditor_panel hash %}">Edytor HTML</option>
+                        <option value="{% url gallery_panel hash %}">Galeria skanów</option>
+                        <option value="{% url dceditor_panel hash %}">Edytor DublinCore</option>
+                    </select>
+                    <strong class="change-notification" style="display: none">Widok nieaktualny!</strong>
+               </div>
+               <div id="left-panel-content" class="panel-content"></div>
+               <button type="button" class="panel-slider" id="slider01">&nbsp;</button>
+            </div>
+            <div id="right-panel-wrap" class="panel-wrap last-panel">
+                <div id="right-panel-toolbar" class="panel-toolbar">
+                    <label for="select-right-panel">Prawy panel:</label>
+                    <select name="select-right-panel" id="select-right-panel">
+                        <option value="{% url xmleditor_panel hash %}">Edytor XML</option>
+                        <option value="{% url htmleditor_panel hash %}">Edytor HTML</option>
+                        <option value="{% url gallery_panel hash %}">Galeria skanów</option>
+                        <option value="{% url dceditor_panel hash %}">Edytor DublinCore</option>
+                    </select>
+                    <strong class="change-notification" style="display: none">Widok nieaktualny!</strong>
+                 </div>
+                 <div id="right-panel-content" class="panel-content"></div>
+            </div>
+        </div>
+{% endblock maincontent %}    
index 7063d29..bfbafe1 100644 (file)
@@ -3,7 +3,7 @@
 {% block maincontent %}
 <ul>
 {% for blob in objects %}
-    <li><a href="{% url file_xml blob %}">{{ blob }}</a></li>
+    <li><a href="{% url editor_view blob %}">{{ blob }}</a></li>
 {% endfor %}
 </ul>
 {% endblock maincontent %}
diff --git a/project/templates/explorer/file_xml.html b/project/templates/explorer/file_xml.html
deleted file mode 100644 (file)
index 805f59c..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-{% extends "base.html" %}
-
-{% block extrahead %}
-    <script src="/static/js/jquery.lazyload.js" type="text/javascript" charset="utf-8"></script>
-    <script src="/static/js/codemirror/codemirror.js" type="text/javascript" charset="utf-8"></script>
-    <script src="/static/js/jquery.autoscroll.js" type="text/javascript" charset="utf-8"></script>
-    <script src="/static/js/jquery.wtooltip.js" type="text/javascript" charset="utf-8"></script>
-    <script src="/static/js/jquery.hpanel.js" type="text/javascript" charset="utf-8"></script>
-    <script src="/static/js/editor.js" type="text/javascript" charset="utf-8"></script>
-{% endblock extrahead %}
-
-{% block breadcrumbs %}<a href="{% url file_list %}">Platforma Redakcyjna</a> ❯ plik {{ hash }}{% endblock breadcrumbs %}
-
-{% block header-toolbar %}
-       <button type="button" class="toolbar-button" id="toolbar-button-save">Zapisz</button>
-{% endblock %}
-{% block maincontent %}
-        <div id="panels">
-            <div id="left-panel-wrap" class="panel-wrap">
-               <div id="left-panel-toolbar" class="panel-toolbar">
-                    <label for="select-left-panel">Lewy panel:</label>
-                    <select name="select-left-panel" id="select-left-panel">
-                        <option value="{% url xmleditor_panel hash %}">Edytor XML</option>
-                        <option value="{% url htmleditor_panel hash %}">Edytor HTML</option>
-                        <option value="{% url gallery_panel hash %}">Galeria skanów</option>
-                        <option value="{% url dceditor_panel hash %}">Edytor DublinCore</option>
-                    </select>
-                    <strong class="change-notification" style="display: none">Widok nieaktualny!</strong>
-               </div>
-               <div id="left-panel-content" class="panel-content"></div>
-               <button type="button" class="panel-slider" id="slider01">&nbsp;</button>
-            </div>
-            <div id="right-panel-wrap" class="panel-wrap last-panel">
-                <div id="right-panel-toolbar" class="panel-toolbar">
-                    <label for="select-right-panel">Prawy panel:</label>
-                    <select name="select-right-panel" id="select-right-panel">
-                        <option value="{% url xmleditor_panel hash %}">Edytor XML</option>
-                        <option value="{% url htmleditor_panel hash %}">Edytor HTML</option>
-                        <option value="{% url gallery_panel hash %}">Galeria skanów</option>
-                        <option value="{% url dceditor_panel hash %}">Edytor DublinCore</option>
-                    </select>
-                    <strong class="change-notification" style="display: none">Widok nieaktualny!</strong>
-                 </div>
-                 <div id="right-panel-content" class="panel-content"></div>
-            </div>
-        </div>
-{% endblock maincontent %}    
index 9186f04..fe1870e 100644 (file)
@@ -81,8 +81,19 @@ panel_hooks = {
                this.texteditor = null;
        },
 
+
+       refresh: function(hn) {
+               // TODO
+               return true;
+       },
+
        saveInfo: function(hn, saveInfo) {
-               var myInfo = {content: this.texteditor.getCode(), dataType: 'xml'};
+               var myInfo = {
+                       url: "{% url file_xml fpath %}", 
+                       postData: {
+                               content: this.texteditor.getCode()
+                       } 
+               };
                $.extend(saveInfo, myInfo);
        }               
 };
index 05fe1b4..4e672f3 100644 (file)
@@ -2,23 +2,26 @@ from django.conf.urls.defaults import *
 from django.contrib import admin
 from django.conf import settings
 
-
 admin.autodiscover()
-
+PATH_END = r"(?P<path>[^/]+)$"
 
 urlpatterns = patterns('',
     # Explorer:
     url(r'^$', 'explorer.views.file_list', name='file_list'),
-    url(r'^file/(?P<path>[^/]+)/$', 'explorer.views.file_xml', name='file_xml'),
+    
+    url(r'^file/text/'+PATH_END, 'explorer.views.file_xml', name='file_xml'),
+    url(r'^file/dc/'+PATH_END, 'explorer.views.file_dc', name='file_dc'),
+
     url(r'^images/(?P<folder>[^/]+)/$', 'explorer.views.folder_images', name='folder_image'),
     url(r'^images/$', 'explorer.views.folder_images', {'folder': '.'}, name='folder_image_ajax'),
     
     # Editor panels
-    url(r'^editor/(?P<path>[^/]+)/panels/xmleditor/$', 'explorer.views.xmleditor_panel', name='xmleditor_panel'),
-    url(r'^editor/(?P<path>[^/]+)/panels/gallery/$', 'explorer.views.gallery_panel', name='gallery_panel'),
-    url(r'^editor/(?P<path>[^/]+)/panels/htmleditor/$', 'explorer.views.htmleditor_panel', name='htmleditor_panel'),
-    url(r'^editor/(?P<path>[^/]+)/panels/dceditor/$', 'explorer.views.dceditor_panel', name='dceditor_panel'),
-    
+    url(r'^editor/panel/xmleditor/'+PATH_END, 'explorer.views.xmleditor_panel', name='xmleditor_panel'),
+    url(r'^editor/panel/gallery/'+PATH_END, 'explorer.views.gallery_panel', name='gallery_panel'),
+    url(r'^editor/panel/htmleditor/'+PATH_END, 'explorer.views.htmleditor_panel', name='htmleditor_panel'),
+    url(r'^editor/panel/dceditor/'+PATH_END, 'explorer.views.dceditor_panel', name='dceditor_panel'),
+    url(r'^editor/'+PATH_END, 'explorer.views.display_editor', name='editor_view'),
+
     # Admin panel
     url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
     url(r'^admin/(.*)', admin.site.root),