Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # imports
- import sys
- import socket
- import datetime
- import threading
- import signal
- import json
- import MySQLdb
- import S3
- import os.path
- import os
- import mimetypes
- import Image
- # configuration
- LISTEN_HOST = ''
- LISTEN_PORT = 49494
- LISTEN_ADDR = (LISTEN_HOST,LISTEN_PORT)
- BUFSIZE = 4096
- LOG_PATH = 'logs/'
- ACCESS_LOG = 'access_log'
- ERROR_LOG = 'error_log'
- MYSQL_HOST = "localhost"
- MYSQL_PORT = 3306
- MYSQL_USER = "root"
- MYSQL_PASS = ""
- MYSQL_DB = "mydb"
- ITEM_TABLE = "attachment"
- S3_ACCESS_KEY = ''
- S3_SECRET_KEY = ''
- S3_BUCKET = "mybucket"
- S3_NEWFILE_PATH = "uploaded/"
- S3_IMAGE_PATH = "media/images/"
- S3_VIDEO_PATH = "media/images/"
- LOCALTMP_PATH = 'tmp/'
- IMAGE_RESOLUTION = {"small":"320x240","medium":"800x600","large":"1024x768"}
- IMAGE_EXTENSION = ".jpg"
- IMAGE_MIME_TYPE = "image/jpg"
- MAX_FIBO = 4000000 # this var is used for the max length of the fibonacci rule to calculate securekey
- # variables
- threads = []
- # time handling
- def current_time(string=False):
- time = datetime.datetime.now()
- if string:
- time = time.replace(microsecond=0)
- return str(time)
- else:
- return time
- # log file handling
- def log_error(msg):
- time = current_time(True)
- msg = msg + '\n'
- f = open(LOG_PATH + ERROR_LOG, 'a')
- f.write('%s: %s' % (time, msg))
- f.close()
- def log_access(msg):
- time = current_time(True)
- msg = msg + '\n'
- f = open(LOG_PATH + ACCESS_LOG, 'a')
- f.write('%s: %s' % (time, msg))
- f.close()
- # listen tcp server
- try:
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- except socket.error, msg:
- log_error(msg(1))
- sys.exit(1)
- # init mimetypes
- mimetypes.init()
- # cleans up when sigint or when script ends
- def cleanup(*args):
- print 'Exiting'
- global threads
- global s
- # Close the server socket
- s.close()
- s = None
- # Wait for all threads
- for t in threads:
- t.join()
- sys.exit(0)
- def getFileExtension(file):
- ext = os.path.splitext(file)[1]
- return ext
- # handles the socket connections
- class ConnectionHandler(threading.Thread):
- def __init__(self,(conn,addr)):
- self.conn = conn
- self.addr = addr
- self.s3conn = ''
- self.secretkey = ''
- self.articleid = ''
- self.nrimg = ''
- self.itemlist = ''
- self.authenticated = False
- # connect mysql server
- try:
- self.db = MySQLdb.connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB)
- self.dbcursor = self.db.cursor()
- except Exception, e:
- raise e
- threading.Thread.__init__(self)
- def run(self):
- log_access('Connection from ' + str(self.addr))
- while self.conn:
- data = self.conn.recv(BUFSIZE)
- if data:
- # encode json data received and validate it
- try:
- data = json.loads(data)
- except ValueError, msg:
- log_error(str(self.addr) + ": " + str(msg))
- break
- for key,value in data.iteritems():
- log_access('Received: ' + str(key) + " -> " + str(value))
- if key == "articleid":
- self.articleid = value
- elif key == "nrimg":
- self.nrimg = value
- elif key == "secretkey":
- self.secretkey = value
- else:
- pass
- # check that articleid and nrimg got data
- if self.articleid and self.nrimg:
- newkey = self.checkKey()
- else:
- log_error(str(self.addr) + ": could not generate secretkey")
- break
- if newkey == self.secretkey:
- log_access(str(self.addr) + " authentication successful")
- self.authenticated = True
- else:
- log_error("Error Authenticating " + str(self.addr) + ". Key was " + str(self.secretkey) + " but needs to be " + str(newkey))
- break
- if self.authenticated:
- # query DB for image items
- # connect to database and receive media info
- try:
- self.itemlist = self.queryItems(self.articleid)
- except Exception, e:
- raise e
- if self.itemlist:
- print str(self.itemlist)
- # connect to S3 and get images
- self.connectS3()
- else:
- log_error("Imagelist is empty!")
- # convert them
- # update DB
- # close connections
- self.dbcursor.close()
- self.db.close()
- pass
- else:
- log_access('Connection closed by ' + str(self.addr))
- break
- self.conn.close()
- self.conn = None
- def queryItems(self, id):
- itemlist = []
- rows = ''
- try:
- self.dbcursor.execute("SELECT * from " + ITEM_TABLE)
- rows = self.dbcursor.fetchall()
- except MySQLdb.ProgrammingError, e:
- log_error(str(e))
- if rows:
- for row in rows:
- itemlist.append(row[1])
- else:
- log_error("Database result for current query is empty!")
- return itemlist
- def checkKey(self):
- z = [self.articleid,self.nrimg]
- while z[-1] < MAX_FIBO:
- z.append(z[-1] + z[-2])
- return sum([x for x in z if x % 2 == 0])
- def connectS3(self):
- self.s3conn = S3.AWSAuthConnection(S3_ACCESS_KEY, S3_SECRET_KEY)
- # get bucket list
- if (self.s3conn.check_bucket_exists(S3_BUCKET).status == 200):
- print '---- bucket status OK ----'
- for item in self.itemlist:
- log_access('--- handling item %s ---' % item)
- self.handleS3Item(item)
- else:
- print '---- bucket doesnt exist ----'
- def handleS3Item(self,item):
- itempath = S3_NEWFILE_PATH + item
- localitem = LOCALTMP_PATH + item
- itemext = getFileExtension(item)
- try:
- self.getS3Item(itempath,localitem)
- except Exception, e:
- log_error(str(e))
- try:
- filetype = self.handleItemType(itemext)
- except Exception, e:
- log_error(str(e))
- if filetype:
- if filetype == "image":
- self.handleImage(localitem)
- elif filetype == "video":
- self.handleVideo()
- os.unlink(localitem)
- def getS3Item(self,remoteitem,localitem):
- try:
- itemdata = self.s3conn.get(S3_BUCKET, remoteitem).object.data
- except Exception, e:
- log_error(str(e))
- if itemdata:
- f = open(localitem, 'wb+')
- f.write(itemdata)
- f.close()
- else:
- log_error("S3 Object doesnt have data!")
- log_access('--- done getting item %s ---' % localitem)
- def handleItemType(self,itemext):
- try:
- mime = mimetypes.types_map[itemext]
- except Exception, e:
- log_error(str(e))
- if "image" in mime:
- return "image"
- elif "video" in mime:
- return "video"
- else:
- pass
- def handleImage(self, imagefile):
- log_access('--- opened image %s ---' % imagefile)
- try:
- self.convertImage(imagefile)
- except Exception, e:
- raise e
- def convertImage(self, imagefile):
- imagedata = Image.open(imagefile)
- for k,v in IMAGE_RESOLUTION.iteritems():
- resizename = k
- resolution = v.split('x')
- width = int(resolution[0])
- height = int(resolution[1])
- try:
- log_access('--- resizing image %s ---' % imagefile)
- img = imagedata.resize((width,height), Image.NEAREST)
- except Exception, e:
- log_error(e)
- newname = self.generateNewImageName(imagefile, resizename)
- try:
- log_access('--- trying to save new image %s ---' % newname)
- img.save(newname)
- except Exception, e:
- log_error(e)
- log_access('--- new image created %s ---' % newname)
- try:
- self.putS3Item(newname,IMAGE_MIME_TYPE)
- except Exception, e:
- log_error(e)
- def generateNewImageName(self,imgfile,addname):
- path, ext = os.path.splitext(imgfile)
- newname = path + "_" + addname + ext
- return newname
- def handleVideo(self):
- pass
- def putS3Item(self, item, contenttype):
- itemreplace = item.replace(LOCALTMP_PATH,'')
- s3itempath = S3_IMAGE_PATH + itemreplace
- itemdata = open(item, 'rb').read()
- try:
- log_access('--- trying to upload %s ---' % itemreplace)
- self.s3conn.put(S3_BUCKET,s3itempath, S3.S3Object(itemdata),
- {'x-amz-acl': 'public-read', 'Content-Type': contenttype})
- except Exception, e:
- log_error(e)
- self.delTmpItem(item)
- def delTmpItem(self,item):
- try:
- os.unlink(item)
- except Exception, e:
- raise e
- log_access("deleted temp file %s " % item)
- # runs the actual tcp server
- try:
- s.bind((LISTEN_HOST, LISTEN_PORT))
- s.listen(5)
- log_access('Server started!')
- except socket.error, e:
- s.close()
- if s is None:
- log_error('could not open socket')
- sys.exit(1)
- # Catch some signals
- signal.signal(signal.SIGINT, cleanup)
- signal.signal(signal.SIGTERM, cleanup)
- # builds up the single client connections
- # handle incoming connections
- while s:
- print "Threads:", len(threads)
- ch = ConnectionHandler(s.accept())
- ch.daemon = True
- ch.start()
- threads.append(ch)
- cleanup()
Add Comment
Please, Sign In to add comment