Esempio n. 1
0
class sockServer:

	PORT              = 5000  # Arbitrary non-privileged port
	MESSAGE_SIGNATURE = 'cachemoney'

	BUFF_SIZE     = 512
	MIN_PIC_LINES = 50

	OUTPUT_DIR      = 'outputFiles'
	UNPROCESSED_DIR = os.path.join( OUTPUT_DIR, 'Unprocessed' )
	PROCESSED_DIR   = os.path.join( OUTPUT_DIR, 'Processed' )
	PROCESSING_DIR  = os.path.join( OUTPUT_DIR, 'Processing' )
	OUTPUT_EXT      = 'jpg'

	numReceived = 0

	def __init__(self, debug=False):
		self.debug  = debug
		if self.debug:
			logLevel = logging.DEBUG
		else:
			logLevel = logging.INFO
		logging.basicConfig(format='%(levelname)s: %(message)s', level=logLevel)

		if not os.path.isdir(self.OUTPUT_DIR):
		 	os.mkdir(self.OUTPUT_DIR)
		if not os.path.isdir(self.UNPROCESSED_DIR):
		 	os.mkdir(self.UNPROCESSED_DIR)
		if not os.path.isdir(self.PROCESSED_DIR):
		 	os.mkdir(self.PROCESSED_DIR)
		if not os.path.isdir(self.PROCESSING_DIR):
		 	os.mkdir(self.PROCESSING_DIR)
		self.db = DB(debug = self.debug)
		self.rsync = rsync( self.debug )

		if socket.gethostname() == 'cet-sif':
			self.OnServer = True
			# self.host = socket.gethostbyname( 'cet-research.colorado.edu' )
			self.host = '128.138.248.205'
		else:
			self.OnServer = False
			self.host = socket.gethostbyname(socket.gethostname())
		# self.host = socket.gethostbyname(socket.gethostname())

	def runNonBlockingSocket(self):
		listener = eventlet.listen( (self.host, self.PORT)  )
		print 'Recieving on %s, %s'%(self.host, self.PORT)
		eventlet.serve(listener, self.recieveData)

	def recieveData(self, client_sock, client_addr):
		'''Callback function for every time a client connects to the nonblocking socket'''

		print "client connected", client_addr
		first = True
		lines = []
		while 1:
			line = client_sock.recv( self.BUFF_SIZE )
			if first:
				tic = time.time()
				first = False
			if not line:
				break
			lines.append(line)

		if len(lines) == 0:
			logging.info('No message provided. Ignoring client.')
			return
		# Check signature and get image file name
		if len(lines[0].split('\n')) < 2:
			logging.info('Incoming message is not the required format. Ignoring client.')
			return # ignore this message
		signature, imageName = tuple( lines[0].split('\n')[0:2] )
		if self.MESSAGE_SIGNATURE != signature:
			logging.info('Illegal message recieved with signature:\n%s' % lines[0])
			return # ignore this message
		lines[0] = ''.join( lines[0].split('%s\n' % imageName)[1:] )
		#print "imageName: ", imageName
		logging.info(imageName)
		cameraID, timeTaken, lat, lon, powerData = tuple( imageName.split('_') )
		groupID = self.numReceived%2
		self.numReceived += 1

		if len(lines) > self.MIN_PIC_LINES:
			lat = float( lat.replace(',','.') )
			lon = float( lon.replace(',','.') )
			timeTaken = time.strptime( timeTaken, '%H%M%S')
			groupID = self.timeToGroupID( timeTaken )
			self.db.setCameraGeoTag(cameraID, lat, lon)

			imPath = self.saveImg(lines, groupID, cameraID)
			if self.OnServer:
				self.rsync.sendPhotoToCETResearch( os.path.dirname(imPath), verbose=False )
			logging.debug('Image added to queue')
		else:
			self.db.writePowerData( lines[0], 'TEST_GEOTAG', datetime.datetime.now() )
			logging.debug('Power data written to database')
			self.db.syncPowerWithCETResearch(verbose=False)
			logging.debug( 'Total time taken = %f' % (time.time()-tic) )

	def groupIDtoDatetime( self, groupID ):
		today    = datetime.date.today()
		midnight = datetime.datetime(year=today.year, month=today.month, day=today.day,
								  hour=0, minute=0, second=0)
		thirtySec = datetime.timedelta(seconds=30)
		return midnight + (groupID * thirtySec)

	def timeToGroupID( self, t ):
		return int( 120 * t.tm_hour + 2 * t.tm_min + floor(t.tm_sec/30) )

	def saveImg(self, dataLines, groupID, sensorID):
		idealDateTimeTaken = self.groupIDtoDatetime( groupID )
		timeStr = idealDateTimeTaken.strftime("%h%d_%Y-%H_%M_%S")
		now = datetime.datetime.now()
		nowStr = now.strftime("%h%d_%Y %H_%M_%S")

		outputFileDir = os.path.join( self.UNPROCESSED_DIR,
												'%i-%s' % (groupID, timeStr) )
		if os.path.isdir(outputFileDir) is False:
			os.mkdir( outputFileDir )
		outputFilePath = os.path.join( outputFileDir,
												 '%i_%s_%s.%s' % (groupID, sensorID,timeStr,self.OUTPUT_EXT) )
		f = open(outputFilePath, 'w')
		for line in dataLines:
			f.write( line )
		f.close()

		logging.info('%s written successfully' % outputFilePath)

		return outputFilePath

	'''
	==============================================================================
	=============================== OLD CODE BELOW ===============================
	==============================================================================
	'''

	def runSocket(self,customHostPort=None):
		if customHostPort:
			host, port = customHostPort
		else:
			host, port = self.host, self.PORT
		self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		self.sock.bind((host, port))
		self.sock.listen(1)
		self.conn, self.addr = self.sock.accept()

		logging.debug( 'Connected by %s' % (self.addr,) )

	def recieveOne(self):
		self.runSocket()
		lines = []
		first = True
		while 1:
			line = self.conn.recv( self.BUFF_SIZE )
			if first:
				tic = time.time()
				first = False
			lines.append( line )
			if not line:
				break
		self.saveImg(lines)
		print 'Total time taken = %f' % (time.time()-tic)
		self.conn.close()
		exit()

	def reciveFileName(self):
	   filename = self.conn.recv( self.BUFF_SIZE )
	   return filename


	def recieveArray(self):
		self.runSocket()
		line = self.conn.recv( self.BUFF_SIZE )
		logging.debug(line)
		self.conn.close()
		exit()

	def keepRecievingStrs(self):
		lines = []
		while 1:
			self.runSocket()
			try:
				while 1:
					line = self.conn.recv( self.BUFF_SIZE )
					if not line:
						break
					lines.append(line)
			except socket.error, e:
				print e
			if len(lines) == 1:
				logging.debug(lines[0])
			else:
				logging.debug('%d lines received' % len(lines))
				# print lines[:50]
			self.conn.close()
			self.runSocket()
Esempio n. 2
0
class sockServer:

   # Constants
   PORT              = 5000  # Arbitrary non-privileged port
   # 'Shared secret' code at the beginning of each message for a crude attempt at security
   MESSAGE_SIGNATURE = 'cachemoney'

   BUFF_SIZE     = 512
   MIN_PIC_LINES = 50

   '''The various directories which comprise our file system based processing queue.'''
   OUTPUT_DIR      = 'outputFiles'
   UNPROCESSED_DIR = os.path.join( OUTPUT_DIR, 'Unprocessed' )
   PROCESSED_DIR   = os.path.join( OUTPUT_DIR, 'Processed' )
   PROCESSING_DIR  = os.path.join( OUTPUT_DIR, 'Processing' )

   OUTPUT_EXT      = 'jpg'

   def __init__(self, debug=False):
      self.debug  = debug # Set debug mode
      if self.debug:
         logLevel = logging.DEBUG
      else:
         logLevel = logging.INFO
      # Set logging level
      logging.basicConfig(format='%(levelname)s: %(message)s', level=logLevel)

      if not os.path.isdir(self.OUTPUT_DIR):
         os.mkdir(self.OUTPUT_DIR)
      if not os.path.isdir(self.UNPROCESSED_DIR):
         os.mkdir(self.UNPROCESSED_DIR)
      if not os.path.isdir(self.PROCESSED_DIR):
         os.mkdir(self.PROCESSED_DIR)
      if not os.path.isdir(self.PROCESSING_DIR):
         os.mkdir(self.PROCESSING_DIR)
      self.db = DB(debug = self.debug)
      self.rsync = rsync( self.debug )

      if socket.gethostname() == 'cet-sif':
         self.OnServer = True
         self.host     = '128.138.248.205' # Static ip resolution of cet-sif.colorado.edu
      else:
         self.OnServer = False
         self.host     = socket.gethostbyname(socket.gethostname()) # Set to localhost

   def runNonBlockingSocket(self):
      '''Run the nonblocking socket server. Any time a client connects to
      (self.host, self.PORT), recieveData is called to handle the request.'''

      listener = eventlet.listen( (self.host, self.PORT)  )
      logging.info( 'Recieving on %s, %s' % (self.host, self.PORT) )
      eventlet.serve(listener, self.recieveData)

   def recieveData(self, client_sock, client_addr):
      '''Callback function for every time a client connects to the nonblocking socket'''

      logging.info( "client connected", client_addr )
      first = True
      lines = []

      '''Collect all of the incoming data lines, each of size <BUFF_SIZE>.'''
      while 1:
         line = client_sock.recv( self.BUFF_SIZE )
         if first:
            tic = time.time()
            first = False
         if not line:
            break
         lines.append(line)

      '''Check the validity of the message. Message cannot be empty, and must contain
      <MESSAGE_SIGNATURE> in the correct place for us to process the information
      contained within the received lines'''
      if len(lines) == 0:
         logging.info('No message provided. Ignoring client.')
         return
      # Check signature and get image file name
      if len(lines[0].split('\n')) < 2:
         logging.info('Incoming message is not the required format. Ignoring client.')
         return # ignore this message
      signature, imageName = tuple( lines[0].split('\n')[0:2] )
      if self.MESSAGE_SIGNATURE != signature:
         logging.info('Illegal message recieved with signature:\n%s' % lines[0])
         return # ignore this message
      lines[0] = ''.join( lines[0].split('%s\n' % imageName)[1:] )
      cameraID, timeTaken, lat, lon, powerData = tuple( imageName.split('_') )

      # Detect datatype of message, and process accordingly.
      if len(lines) > self.MIN_PIC_LINES:
         # Message is a picture
         lat       = float( lat.replace(',','.') )
         lon       = float( lon.replace(',','.') )
         timeTaken = time.strptime( timeTaken, '%H%M%S')
         groupID   = self.timeToGroupID( timeTaken )

         self.db.setCameraGeoTag(cameraID, lat, lon)

         imPath = self.saveImg(lines, groupID)
         if self.OnServer:
            self.rsync.sendPhotoToCETResearch( os.path.dirname(imPath), verbose=False )
         logging.debug('Image added to queue')
      else:
         # Message is a power reading
         temp  = hexlify(lines[0][0])+hexlify(lines[0][1])+hexlify(lines[0][2])
         temp  = int(temp,16)<<1
         value = float(temp)/((2**24) -1)
         value = (value/0.36)*60
         logging.debug( 'Power=%f retrieved' % value )
         self.db.writePowerData( value, 'TEST_GEOTAG', datetime.datetime.now() )
         logging.debug('Power data written to database')
         self.db.syncPowerWithCETResearch(verbose=False)
      logging.debug( 'Total time taken = %f' % (time.time()-tic) )

   def groupIDtoDatetime( self, groupID ):
      '''Convert a groupID to datetime. Note that groupID's are incremented
      every 30 seconds, starting at midnight (groupID = 0)'''

      today    = datetime.date.today()
      midnight = datetime.datetime(year=today.year, month=today.month, day=today.day,
                          hour=0, minute=0, second=0)
      thirtySec = datetime.timedelta(seconds=30)
      return midnight + (groupID * thirtySec)

   def timeToGroupID( self, t ):
      '''Convert a datetime to groupID. Note that groupID's are incremented
      every 30 seconds, starting at midnight (groupID = 0)'''
      return int( 120 * t.tm_hour + 2 * t.tm_min + floor(t.tm_sec/30) )

   def saveImg(self, dataLines, groupID):
      '''Save an image and place it at back of queue (Unprocessed directory).'''
      idealDateTimeTaken = self.groupIDtoDatetime( groupID )
      timeStr            = idealDateTimeTaken.strftime("%h%d_%Y-%H_%M_%S")
      now                = datetime.datetime.now()
      nowStr             = now.strftime("%h%d_%Y %H_%M_%S")

      outputFileDir = os.path.join( self.UNPROCESSED_DIR,
                                    '%i-%s' % (groupID,timeStr) )
      if os.path.isdir(outputFileDir) is False:
         os.mkdir( outputFileDir )
      outputFilePath = os.path.join( outputFileDir,
                                     '%s.%s' % (nowStr,self.OUTPUT_EXT) )
      f = open(outputFilePath, 'w')
      for line in dataLines:
         f.write( line )
      f.close()

      logging.info('%s written successfully' % outputFilePath)

      return outputFilePath

   def runSocket(self,customHostPort=None):
      '''Run a socket. This implementation is blocking.'''

      if customHostPort:
         host, port = customHostPort
      else:
         host, port = self.host, self.PORT
      self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      self.sock.bind((host, port))
      self.sock.listen(1)
      self.conn, self.addr = self.sock.accept()

      logging.debug( 'Connected by %s' % (self.addr,) )

   def recieveOne(self):
      '''Recieve one image, and save it using saveImg. Then we close the program'''
      self.runSocket()
      lines = []
      first = True
      while 1:
         line = self.conn.recv( self.BUFF_SIZE )
         if first:
            tic = time.time()
            first = False
         lines.append( line )
         if not line:
            break
      self.saveImg(lines)
      logging.info( 'Total time taken = %f' % (time.time()-tic) )
      self.conn.close()
      exit()

   def keepRecievingStrs(self):
      '''Keep recieving strings, and keep incrementing the lines array'''
      lines = []
      while 1:
         self.runSocket()
         try:
            while 1:
               line = self.conn.recv( self.BUFF_SIZE )
               if not line:
                  break
               lines.append(line)
         except socket.error, e:
            logging.error( e )
         if len(lines) == 1:
            logging.debug(lines[0])
         else:
            logging.debug('%d lines received' % len(lines))
         self.conn.close()
         self.runSocket()