Django中的python paramiko错误:' str'对象没有属性' get_name'

时间:2014-08-11 01:35:32

标签: python django ssh smtp paramiko

所以我听说在与Django / Apache Web框架相同的服务器上托管媒体是一个非常糟糕的主意。因此,使用我的iOS应用程序来解决这个问题并从长远来看大大提高服务器端性能将是将图像上传到Django服务器然后在此之后,将新上传的图像传输到专用于托管用户配置文件图像的单独服务器

所以使用Paramiko我可以直接将文件发送到我选择的目录,但这似乎不适用于我的Django视图。

这是一个使用Paramiko的令人难以置信的简单python脚本,允许您通过SMTP将文件上传到远程服务器:

import base64
import getpass
import os
import socket
import sys
import traceback

import paramiko
#from paramiko.py3compat import input


# setup logging
#paramiko.util.log_to_file('demo_sftp.log')
port = 22
hostname = '198.199.101.115'
password = 'XXXXXXXXX'
username = 'root'
hostkeytype = 'ecdsa-sha2-nistp256'
hostkey = 'XXXXXXXXX'


try:
    host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
except IOError:
    try:
        # try ~/ssh/ too, because windows can't have a folder named ~/.ssh/
        host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts'))
    except IOError:
        print('*** Unable to open host keys file')
        host_keys = {}

if hostname in host_keys:
    hostkeytype = host_keys[hostname].keys()[0]
    hostkey = host_keys[hostname][hostkeytype]
    print('Using host key of type %s' % hostkeytype)


# now, connect and use paramiko Transport to negotiate SSH2 across the connection
t = paramiko.Transport((hostname, port))
t.connect(username=username, password=password, hostkey=hostkey)
sftp = paramiko.SFTPClient.from_transport(t)

    # dirlist on remote host
dirlist = sftp.listdir('.')
print("Dirlist: %s" % dirlist)

    # copy this demo onto the server
target_directory = '3COOL'

sftp.put('test_image.jpg', target_directory+'/test_image.jpg')

t.close()

因此,当我在远程服务器上运行脚本并成功将jpeg映像传输到我拥有的另一台远程服务器时,此脚本运行正常。因此,我想将此脚本剪切并粘贴到我的Django视图中,该视图会将所有新上传的图像传输到其他服务器,这里的内容如下:

def profile_picture(request):
    if request.POST:
        form = UserProfileForm(request.POST, request.FILES)
        obj = form.save(commit=False)
        obj.user_id = request.user.id
        obj.profile_picture = obj.profile_picture

        check = UserProfile.objects.filter(user_id=request.user.id)
        if check:
            oldup = UserProfile.objects.get(user_id=request.user.id)
            oldup.delete()
        obj.save()
        formNew = UserProfileForm()
        args = {}
        args.update(csrf(request))
        args['uid'] = request.user.id
        args['form'] = formNew

        # CONVERT THE IMAGE TO A SMALLER SIZE
        basewidth = 256
        img = Image.open('var/www/bitcraft/static/'+str(obj.profile_picture))
        wpercent = (basewidth/float(img.size[0]))
        hsize = int((float(img.size[1])*float(wpercent)))
        img = img.resize((basewidth,hsize), PIL.Image.ANTIALIAS)
        img.save('var/www/bitcraft/static/'+str(obj.profile_picture))

        import getpass
        import os
        import socket
        import sys
        import traceback
        import paramiko
        from paramiko.py3compat import input

        # TRANSFER THIS IMAGE TO MEDIA HOSTING SERVER  
        port = 22
        hostname = '198.199.101.115'
        password = 'pcorysatqwrw'
        username = 'root'
        hostkeytype = 'ecdsa-sha2-nistp256'
        hostkey = 'pcorysatqwrw'
        try:
            host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
        except IOError:
            try:
                host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts'))
            except IOError:
                print('*** Unable to open host keys file')
                host_keys = {}
        if hostname in host_keys:
            hostkeytype = host_keys[hostname].keys()[0]
            hostkey = host_keys[hostname][hostkeytype]
            print('Using host key of type %s' % hostkeytype)
        t = paramiko.Transport((hostname, port))
        t.connect(username=username, password=password, hostkey=hostkey)
        sftp = paramiko.SFTPClient.from_transport(t)
        dirlist = sftp.listdir('.')
        print("Dirlist: %s" % dirlist)
        target_directory = '3COOL'
        sftp.put('var/www/bitcraft/static/'+str(obj.profile_picture), target_directory+str(obj.profile_picture))
        t.close()    
        return render_to_response('profile.html', args, RequestContext(request))

    else:
        formNew = UserProfileForm()
        args = {}
        args.update(csrf(request))
        args['uid'] = request.user.id
        args['form'] = formNew
        return render_to_response('profile.html', args, RequestContext(request))

最终,由于一个奇怪的错误,添加简单的Python脚本无效:

  

/ upload_profile /' str'中的AttributeError对象没有属性' get_name'

     

例外位置:/usr/local/lib/python2.7/dist-packages/paramiko-1.14.0-py2.7.egg/paramiko/transport.py in connect,line 873

     profile_picture中的

/srv/www/django/chatfeed/views.py           t.connect(username = username,password = password,hostkey = hostkey)

我不明白造成这种情况的原因......这是否与目录权限相关?

2 个答案:

答案 0 :(得分:2)

问题是您要为hostkey传递字符串。正如the docs所示,这应该是PKey - 即包装私钥的对象。

如果您点击PKey,您会发现PKeyget_name方法。字符串显然不是。因此错误。


您有一些代码应该使用Paramiko从脚本顶部的hostkey加载~/.ssh/known_hosts。但是,如果hostname in host_keys为假,则它不会做任何事情,并且您最终会得到您在脚本顶部停留的默认值:

hostkeytype = 'ecdsa-sha2-nistp256'
hostkey = 'XXXXXXXXX'

我不知道您在实际代码中代替'XXXXXXXXX'所拥有的内容,但可能是字符串,因此不是有效hostkey


  

我不明白造成这种情况的原因......这是否与目录权限相关?

您必须告诉我们您正在谈论的内容。究竟是什么错误或警告或你得到什么,以及在哪里?如果服务器作为无法访问其自己~/.ssh的用户运行,那么您将看到"目录权限被拒绝"某种警告,你的主机密钥没有被加载,然后是的,这个问题与那个问题间接相关 - 如果主机实际上在known_keys,你解决了权限问题,这会掩盖代码中的错误,所以你不会注意到它。但是还有很多其他的东西你可能意味着答案是否定的,这与任何事都无关。

答案 1 :(得分:1)

:=

密钥文件不支持.ppk格式。