gridftp: handle paths beginning with `~`
authorMaciej Tronowski <mtro@man.poznan.pl>
Mon, 20 Apr 2015 15:12:05 +0000 (17:12 +0200)
committerMaciej Tronowski <mtro@man.poznan.pl>
Mon, 20 Apr 2015 15:12:05 +0000 (17:12 +0200)
filex/forms.py
filex/migrations/0003_auto_20150420_1646.py [new file with mode: 0644]
filex/models.py
filex/static/filex/filex.js
filex/templates/filex/source.js.html
filex/templatetags/filex.py
filex/uploadhandler.py
filex/views.py

index 26ca737..e9b866f 100644 (file)
@@ -12,12 +12,12 @@ from filex.models import Favorite
 msg = u'Invalid value'
 host_validator = RegexValidator(r'^(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+'
                                 r'(?:[a-zA-Z]{2,6}\.?|[a-zA-Z0-9-]{2,}(?<!-)\.?))(?::\d+)?$', msg)
-path_validator = RegexValidator(r'^/(?:[^/\0]+/?)*$', msg)
+path_validator = RegexValidator(r'^~?(?:/[^/\0]*)*$', msg)
 name_validator = RegexValidator(r'^[^/\0]+$', msg)
 
 
 def clean_path(path):
-    return urlquote(os.path.normpath(path))
+    return urlquote(os.path.normpath(path), safe='/~')
 
 
 class FavoriteForm(forms.ModelForm):
diff --git a/filex/migrations/0003_auto_20150420_1646.py b/filex/migrations/0003_auto_20150420_1646.py
new file mode 100644 (file)
index 0000000..710676d
--- /dev/null
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('filex', '0002_auto_20150415_1744'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='favorite',
+            name='path',
+            field=models.CharField(default=b'~', max_length=1024, verbose_name='\u015acie\u017cka'),
+            preserve_default=True,
+        ),
+    ]
index e7e8247..d2d3792 100644 (file)
@@ -6,7 +6,7 @@ from django.db import models
 class Favorite(models.Model):
     owner = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u"Właściciel", related_name='favorites')
     host = models.CharField(u"Host", max_length=256)
-    path = models.CharField(u"Ścieżka", max_length=1024, default='/')
+    path = models.CharField(u"Ścieżka", max_length=1024, default='~')
 
     created = models.DateTimeField(u"Utworzono", auto_now_add=True)
     updated = models.DateTimeField(u"Uaktualniono", auto_now=True)
index 7eabdd2..6785d74 100644 (file)
@@ -107,7 +107,7 @@ $(function(){
         },
 
         full: function() {
-            return this.pluck('path').join('/') || '/';
+            return this.pluck('name').join('/').replace(/^\/+/, '/');
         }
     });
 
@@ -192,12 +192,12 @@ $(function(){
 
         render: function() {
             if (this.model.get('active')) {
-                this.$el.text(this.model.get('text'));
+                this.$el.text(this.model.get('name'));
             }
             else {
                 this.$el.html($('<a/>', {
                     href: '#',
-                    text: this.model.get('text')
+                    text: this.model.get('name')
                 }));
             }
             this.$el.toggleClass('active', this.model.get('active'));
@@ -261,13 +261,13 @@ $(function(){
                 lockOptgroupOrder: true,
                 create: function(input, callback) {
                     var $form = $('#favorite-form'),
-                        parts = input.split('/', 1),
+                        parts = input.split('/'),
                         callback_called = false;
 
-                    $form.find('#id_host').val(parts[0]);
+                    $form.find('#id_host').val(parts.shift());
 
-                    if (parts.length > 1)
-                        $form.find('#id_path').val(parts[1]);
+                    if (parts.length)
+                        $form.find('#id_path').val(parts.join('/'));
 
                     $form.on('submit', function(e) {
                         var $this = $(this),
@@ -326,13 +326,15 @@ $(function(){
         },
 
         load: function(location) {
-            var path = location.replace(/(^\/+|\/+$)/g, '').split('/'),
-                host = path.shift(),
-                pathBits = [new Filex.PathBit({'text': '/', 'path': ''})].concat(_.map(path, function(name) {
-                    return new Filex.PathBit({'text': name, 'path': name});
-                }));
-
-            this.host = host;
+            var hostRootPath = location.split(/\/(\/|~)(.*)/),
+                pathBits = [new Filex.PathBit({'name': hostRootPath[1]})].concat(
+                    _.chain(hostRootPath[2].split('/'))
+                        .filter(_.identity)
+                        .map(function(name) { return new Filex.PathBit({'name': name}) })
+                        .value()
+                );
+
+            this.host = hostRootPath[0];
             this.path.reset(pathBits);
 
             this.$host.text(this.host);
@@ -393,7 +395,7 @@ $(function(){
         },
 
         selectedDir: function(dir) {
-            this.path.add({'text': dir.get('name'), 'path': dir.get('name')});
+            this.path.add({'name': dir.get('name')});
         },
 
         selectedPath: function(bit) {
@@ -459,20 +461,13 @@ $(function(){
 
             $btn.button('loading');
 
-            $.post(url, data, 'json').done(function () {
+            $.post(url, data, 'json').done(function (response) {
                 $btn.button('reset');
 
-                if (is_active) {
-                    locations.removeOption(data.host + data.path);
-                }
-                else {
-                    locations.addOption({
-                        group: 'usr',
-                        host: data.host,
-                        path: data.path,
-                        value: data.host + data.path
-                    });
-                }
+                if (is_active)
+                    locations.removeOption(data.host + '/' + data.path);
+                else
+                    locations.addOption(response);
             }).fail(function() {
                 $btn.button('reset');
                 $btn.button('toggle');
@@ -495,7 +490,7 @@ $(function(){
         },
 
         updateFavorites: function() {
-            var loc = this.host + this.path.full(),
+            var loc = this.host + '/' + this.path.full(),
                 favorites = this.hostSelectize.options;
 
             if (favorites.hasOwnProperty(loc)) {
index 311acb7..0623fde 100644 (file)
     });
 </script>
 
-<script type="text/template" id="path-bit-template">
-    <a href="#"><%= name %></a>
-</script>
-
 <script type="text/template" id="dir-template">
     <td class="text-center">
         <label for="dir-<%= cid %>" class="sr-only">Zaznacz katalog <%= name %></label>
index e854e49..f9022b9 100644 (file)
@@ -27,7 +27,7 @@ def locations(context):
         result.append(item)
 
     for item in result:
-        item['value'] = item['host'] + item['path']
+        item['value'] = item['host'] + '/' + item['path']
 
     return json.dumps(result)
 
index c2414ee..600524f 100644 (file)
@@ -25,7 +25,8 @@ class FtpUploadHandler(FileUploadHandler):
         if self.ftp is None:
             self.ftp = FTPOperation(self.request.session['proxy'], self.chunk_size)
 
-        self.url = 'gsiftp://' + form.cleaned_data['host'] + os.path.join(form.cleaned_data['path'], self.file_name)
+        self.url = 'gsiftp://{}/{}'.format(form.cleaned_data['host'],
+                                           os.path.join(form.cleaned_data['path'], self.file_name))
         self.tmp_url = self.url + '.part'
 
         self.ftp.put(self.tmp_url)
index 8ef9d5b..e3a2ca2 100644 (file)
@@ -168,7 +168,7 @@ class ExtractView(FTPView):
 
 
 def make_url(params, *parts):
-    return 'gsiftp://' + params['host'] + (os.path.join(*[params[part] for part in parts]) if parts else '')
+    return 'gsiftp://{}/{}'.format(params['host'], os.path.join(*[params[part] for part in parts]) if parts else '')
 
 
 @require_POST
@@ -190,7 +190,7 @@ def fav_add(request):
         instance = form.save()
 
         return JsonResponse({'group': 'usr', 'host': instance.host, 'path': instance.path,
-                             'value': instance.host + instance.path})
+                             'value': instance.host + '/' + instance.path})
 
     return JsonResponse({'error': form.errors}, status=400)