So I've heard that it's an incredibly bad idea to host media on the same server as your Django/Apache web framework. So to solve this problem with my iOS app and greatly improve server side performance in the long run would be to upload the images to the Django server and then right after that, transfer the newly uploaded image to a separate server dedicated to hosting user profile images.
So using Paramiko I can send files directly to the directory of my choosing, but this does not seem to be working in my Django view.
Here's an incredible simple python script using Paramiko that allows you to upload files to a remote server via 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()
So this script works perfectly fine when I run the script on my remote server which successfully transfers the jpeg image to another remote server I own. So I'd like to just cut and paste this script into my Django view which will transfer all freshly uploaded images to a different server, here's how this looks:
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))
Ultimately though, adding the simple Python script has not worked due to a strange error:
AttributeError at /upload_profile/ 'str' object has no attribute 'get_name'
Exception Location: /usr/local/lib/python2.7/dist-packages/paramiko-1.14.0-py2.7.egg/paramiko/transport.py in connect, line 873
/srv/www/django/chatfeed/views.py in profile_picture t.connect(username=username, password=password, hostkey=hostkey)
I don't understand what's causing this... is this related to directory permission denied??
authorized_keysinstead. - abarnert