view visualclient/visclient.py @ 21:92903c908539

added colors from Matthias to visual client
author gyorgyf
date Fri, 22 Jun 2012 16:02:14 +0100
parents 3bc0521eff28
children 858fc44a17c1
line wrap: on
line source
#!/usr/bin/env python
# encoding: utf-8
"""
visclient.py

Created by George Fazekas on 2012-06-17.
Copyright (c) 2012 . All rights reserved.
"""

import sys,os,math,time,copy
import pygame as pg
from pygame.locals import *
import httplib as ht

import gradients
from gradients import genericFxyGradient

# from pytagcloud import create_tag_image, make_tags
# from pytagcloud.lang.counter import get_tag_counts

# YOUR_TEXT = "A tag cloud is a visual representation for text data, typically\
# used to depict keyword metadata on websites, or to visualize free form text."
# 
# tags = make_tags(get_tag_counts(YOUR_TEXT), maxsize=120)
# 
# create_tag_image(tags, 'cloud_large.png', size=(900, 600), fontname='Lobster')

scol   = (0,255,0,255)
ecol   = (0,0,0,255)

# X,Y=1140,900
X,Y = 600,400
NBLOBS = 15
BLOBSIZE = 20
G=110
FADE = 40

class Blob(object):
	
	def __init__(self,bg,x,y,color=(255,255,255),mood=None):
		self.x = x
		self.y = y
		self.xs = x * X
		self.ys = Y - (y * Y)
		self.bg = bg
		self.size = BLOBSIZE
		self.time = time.time()
		self.alpha = 255
		self.c = color
		self.count = 1
		self.visible = True
		if mood and mood.color :
			self.c = mood.color
				
	def __cmp__(self,other):
		d = math.sqrt( math.pow((self.x-other.x),2) + math.pow((self.y-other.y),2) )
		if d < 0.03 : 
			return 0
		else :
			return -1
		
	def draw(self):
		d=int(self.size)
		self.bg.blit(gradients.radial(self.size, (self.c[0],self.c[1],self.c[2],self.alpha), (0,0,0,self.alpha)), (self.xs-d,self.ys-d))
		self.alpha = 255 - int(self.age()*FADE) 
		if self.alpha < 5 : 
			self.alpha = 1
			self.visible = False
				
	def age(self):
		return time.time() - self.time
		
	def increment(self,count):
		self.time = time.time()
		self.count = count
		self.size = int(BLOBSIZE * int(self.count/1.5))
		
	def get_distance(self,x,y):
		return math.sqrt( math.pow((self.x-x),2) + math.pow((self.y-y),2) )




class Mood():
	def __init__(self,word,x,y):
		self.word = word
		self.x = float(x)
		self.y = float(y)
		self.color = []
		
	def get_distance(self,x,y):
		return math.sqrt( math.pow((self.x-x),2) + math.pow((self.y-y),2) )
	


class VisualClient(object):
	
	def __init__(self):
		# self.conn = ht.HTTPConnection("192.168.2.184:8030")
		self.conn = ht.HTTPConnection("138.37.95.215")
		
		pg.init()
		
		# fontObj = pg.font.Font("freesansbold.ttf",18)
		white = ( 255, 255, 255)
		black = ( 0,0,0)
		
		self.fpsClock = pg.time.Clock()
		self.screen = pg.display.set_mode((X, Y))
		pg.display.set_caption('Mood Conductor')
		self.bg = pg.Surface(self.screen.get_size())
		self.bg = self.bg.convert()
		self.bg.fill((0,0,0))
		
		
		self.scol   = (0,255,0,255)
		self.ecol   = (0,0,0,255)
		coordstxt = "test"
		
		self.blobs = []
		self.moods = []
		self.read_mood_data()
		# pg.quit()
		# sys.exit(-1)
		
		pass
		
	def read_mood_data(self):
		
		with open('moods.csv') as mf:
			data = mf.readlines()[1:]
			for line in data :
				l = line.split(',')
				mood = Mood(l[0],l[1],l[2])
				self.moods.append(mood)
		with open('feelings.txt') as ff:
			data = ff.readlines()
			data = map(lambda x: x.split('\t'),data)
			for mood in self.moods :
				for colors in data :
					if mood.word == colors[0] :
						mood.color = colors[2]
		pass
		for mood in self.moods:
			if mood.color :
				mood.color = map(lambda x: '0x'+str(x).strip(),[mood.color[0:2],mood.color[2:4],mood.color[4:]])
				mood.color = tuple(map(lambda x: int(eval(x)),mood.color))
				# print mood.color
		
		
	def update(self):
		
		# delete invisibles
		for blob in self.blobs :
			if not blob.visible :
				self.blobs.remove(blob)
				
		# get new coordinates from the server
		self.conn.putrequest("GET","/moodconductor/result", skip_host=True)
		self.conn.putheader("Host", "www.isophonics.net")
		self.conn.endheaders()
		res = self.conn.getresponse()
		data = res.read()
		data = eval(data)
		if not data : 
			self.conn.close()
			return False
		for d in data :
			# coordstxt = "x:%s y:%s c:%s" %d
			x,y,c = d
			
			cmood = None
			d = cd = sys.float_info.max
			for mood in self.moods :
				d = mood.get_distance(x,y)
				if d < cd :
					cd = d
					cmood = mood

			new = Blob(self.bg,x,y,mood=cmood)
			if not new in self.blobs :
				self.blobs.insert(0,new)
			elif c > self.blobs[self.blobs.index(new)].count:
				self.blobs[self.blobs.index(new)].increment(c)

		self.conn.close()
		self.blobs = self.blobs[:NBLOBS]
		return True

		
	def draw(self):
		self.bg.fill((0,0,0))			
		# self.bg.blit(gradients.radial(19, self.scol, self.ecol), (rect_x,rect_y))
		l = copy.copy(self.blobs)
		l.reverse()
		for blob in l :
			blob.draw()

		# axis
		pg.draw.line(self.bg, (G,G,G), (int(X/2.0),0),(int(X/2.0),Y), 1)
		pg.draw.line(self.bg, (G,G,G), (0,int(Y/2.0)),(X,int(Y/2.0)), 1)
		

				
	def run(self):
		# conn = ht.HTTPConnection("192.168.2.184:8030")
		self.conn = ht.HTTPConnection("138.37.95.215")
		
		rect_x,rect_y = 0,0
		counter = 0
		
		# main loop
		while True :
			# pg.draw.circle(screen, pg.Color(255,0,0), (300,50),20,0)
			# screen.blit(gradients.radial(99, scol, ecol), (401, 1))

			for event in pg.event.get() :
				if event.type == QUIT:
					self.conn.close()				
					pg.quit()
					sys.exit()
				elif event.type == KEYDOWN :
					if event.key == K_ESCAPE :
						pg.event.post(pg.event.Event(QUIT))


			# Draw 
			self.draw()


			# update from the server
			counter += 1
			if counter % 12 :
				counter = 0
				try :
					self.update()
				except:
					pass
			# update display
			self.screen.blit(self.bg, (0, 0))
			pg.display.flip()
			self.fpsClock.tick(50)
		pass


def main():
	
	v = VisualClient()
	v.run()
	
	# conn = ht.HTTPConnection("192.168.2.184:8030")	
	# 
	# pg.init()
	# fontObj = pg.font.Font("freesansbold.ttf",18)
	# 
	# white = ( 255, 255, 255)
	# black = ( 0,0,0)
	# fpsClock = pg.time.Clock()
	# screen = pg.display.set_mode((1024, 768))
	# rect_x,rect_y=50,50
	# rect_xp,rect_yp=50,50	
	# rect_change_x,rect_change_y=5,5
	# counter = 0
	# scol   = (0,255,0,255)
	# # ecol   = (100,0,50,255)
	# ecol   = (0,0,0,255)
	# coordstxt = "test"
	# 
	# while True :
	# 	pg.draw.circle(screen, pg.Color(255,0,0), (300,50),20,0)
	# 	# screen.blit(gradients.radial(99, scol, ecol), (401, 1))
	# 
	# 	for event in pg.event.get() :
	# 		if event.type == QUIT:
	# 			conn.close()				
	# 			pg.quit()
	# 			sys.exit()
	# 		elif event.type == KEYDOWN :
	# 			if event.key == K_ESCAPE :
	# 				pg.event.post(pg.event.Event(QUIT))
	# 				
	# 	# put text
	# 	# txtObj = fontObj.render(coordstxt,True,pg.Color(254,254,254))
	# 	# rectObj = txtObj.get_rect()
	# 	# rectObj.topleft = (10,20)
	# 	# # rectObj.fill(pg.Color(254,254,254))
	# 	# screen.blit(txtObj,rectObj)
	# 	
	# 	
	# 	# Draw the rectangle		
	# 	# pg.draw.rect(screen,black,[rect_xp,rect_yp,50,50])
	# 	screen.blit(gradients.radial(19, ecol, ecol), (rect_xp,rect_yp))
	# 	
	# 	rect_xp,rect_yp = rect_x,rect_y
	# 	# pg.draw.rect(screen,white,[rect_x,rect_y,50,50])
	# 	screen.blit(gradients.radial(19, scol, ecol), (rect_x,rect_y))
	# 	
	# 	
	# 	# Move the rectangle starting point
	# 	# rect_x += rect_change_x
	# 	# rect_y += rect_change_y
	# 	counter += 1
	# 	if counter % 12 :
	# 		counter = 0
	# 		try :
	# 			conn.request("GET","/moodconductor/result")
	# 			res = conn.getresponse()
	# 			data = eval(res.read())
	# 			coordstxt = "x:%s y:%s" %data
	# 			rect_x = data[0] * 300
	# 			rect_y = data[1] * 1000
	# 			conn.close()
	# 		except :
	# 			pass
	# 		
	# 	
	# 
	# 	# Bounce the ball if needed
	# 	if rect_y > 450 or rect_y < 0:
	# 		rect_change_y = rect_change_y * -1
	# 	if rect_x > 650 or rect_x < 0:
	# 		rect_change_x = rect_change_x * -1
	# 	
	# 	# pg.display.update()
	# 	pg.display.flip()
	# 	fpsClock.tick(50)
	# 	
	# 
	# # if raw_input("quit?") in ['y'] :
	# # 	pg.quit()
	# 
	# pass


if __name__ == '__main__':
	pass
	main()