User Tools

Site Tools


Writing /var/lib/dokuwiki/data/meta/teaching/ie0117/proyectos/2013/i/way_to_shop/serverimplementation.meta failed
teaching:ie0117:proyectos:2013:i:way_to_shop:serverimplementation

Way To Shop server implementation

The following files are the source code for the server that supports Way To Shop. For more information about multi-process servers visit Writing a multi-process server with python. Also if you want to see a simple implementation of the server working with the data base you can check the principal project page Way to Shop

DBmethods.py

This program supports the interaction with mysql server. You can get more information about the developing of this program here Databases in MYSQL and here Database implementation

#Connection import
import MySQLdb
 
#Creating the connection
db = MySQLdb.connect(host='localhost', user='guillermo', passwd='olaquease', db='wtsdatabase')
 
#Creting a cursor
cursor = db.cursor()
 
 
#------------------------------------Users table methods------------------------------------#	
 
 
#Retrieving the password of an user: 
def get_password(username):
	try:
		cursor.execute("select password from Users where username='%s';" % username)
		return  cursor.fetchone() [0]
	except:
		return "None/*/"
 
#Registering a new user:
def write_user(username, password, name, email):
	try:
		result = cursor.execute("INSERT INTO `Users` (`username`, `password`,  `name`, `mail`) VALUES ( '%s' , '%s', '%s', '%s');" % (username, password , name,  email))
		db.commit()
	except: result = 0
	return result
 
 
 
#Changing the privileges of a user:
def modify_privileges(username, privileges):
	result = cursor.execute("UPDATE Users SET privileges=%s WHERE username = '%s';" % (privileges, username))
	db.commit()
	return result
 
 
#Changing the password of an user
def change_password(username, password):
	result = cursor.execute("UPDATE Users SET password='%s' WHERE username = '%s';" % (password, username))
	db.commit()
	return result
 
 
#Retrieving the privileges of an user
def get_privileges(username):
	cursor.execute("SELECT privileges FROM Users WHERE username= '%s';" % username)
	return cursor.fetchone()[0]
 
 
#Retrieving the email of an user
def get_email(username):
	cursor.execute("SELECT mail FROM Users WHERE username= '%s';" % username)
	return cursor.fetchone()[0]
 
 
#Adding a submit to an user
def add_submit(username):
	try:
		result = cursor.execute("UPDATE Users SET submits = submits + 1 WHERE username = '%s';" % username)
		db.commit()
	except: result = 0
	return result
 
#Retrieving the times an user has submitted something
def get_submits(username):
	cursor.execute("SELECT submits FROM Users WHERE username= '%s';" % username)
	return cursor.fetchone()[0]
 
 
#------------------------------------Items table methods------------------------------------#
 
 
#Registering a new item
def write_item(barcode, name, brand, quantity, description, image):
	try:
		result= cursor.execute("INSERT INTO Items (barcode, name, brand, quantity, description, image) VALUES (%s, '%s', '%s', '%s', '%s', '%s');" % (barcode, name, brand, quantity, description, image))
		db.commit()
	except: result = 0
	return result
 
#Modifying an item
def modify_item(barcode, name, brand, quantity, description, image):
	try:
		result = cursor.execute("UPDATE Items SET name = '%s', brand = '%s', quantity = '%s', description = '%s', image = '%s' WHERE barcode= %s;" % (name, brand, quantity, description, image, barcode))
		db.commit()
	except: result = 0
	return result
 
 
#Retrieving the information of an item
def get_item(barcode):
	cursor.execute("SELECT * FROM Items WHERE barcode = %s;" % barcode)
	return cursor.fetchone()
 
 
#------------------------------------Stores table methods------------------------------------#
 
 
#Registering a new store
def write_store(name, location, latitude, longitude):
	try:
		result = cursor.execute("INSERT INTO Stores (name, location, latitude, longitude) VALUES ( '%s', '%s', %s, %s);" % (name, location, latitude, longitude))
		db.commit()
	except: result = 0
	return result
 
 
#Modifying a store
def modify_store(storeid, name, location, latitude, longitude):
	try:
		result = cursor.execute("UPDATE Stores SET name = '%s', location = '%s', latitude = %s, longitude = %s WHERE storeid= %s;"% (name, location, latitude, longitude, storeid))
		db.commit()
	except: result = 0
	return result
 
 
#Retrieving the coordinates from a store
def get_coordinates(storeid):
	cursor.execute("SELECT latitude, longitude FROM Stores WHERE storeid= %s;" % storeid)
	return cursor.fetchone()
 
#Retrieving storeid
def get_storeid(latitude, longitude):
	cursor.execute("SELECT storeid FROM Stores WHERE latitude = %s AND longitude = %s;" %(latitude, longitude))
	return cursor.fetchone()
 
#Retrieving store name and location
def get_storename(storeid):
	cursor.execute("SELECT name, location FROM Stores WHERE storeid= %s;" %storeid)
	return cursor.fetchone()
 
 
#Retrieving the stores inside a given radius
def get_stores(latitude, longitude, radius):
	cursor.execute("SELECT storeid, location, name FROM Stores WHERE (latitude > %s) AND (latitude < %s) AND (longitude > %s) AND (longitude < %s);" % ((latitude-radius), (latitude+radius), (longitude-radius), (longitude+radius)))
	return cursor.fetchall()
 
 
#------------------------------------Lists_users table methods------------------------------------#
 
 
#Creating a new list for an user
def write_list_user(listname,username):
	try:
		result = cursor.execute("INSERT INTO Lists_users (listname , username) VALUES ('%s', '%s');" % (listname,username))
		db.commit()
	except: result = 0
	return result
 
 
#Retrieving the lists of an user
def get_lists(username):
	cursor.execute("SELECT listid, listname FROM Lists_users WHERE username = '%s';" % username)
	return cursor.fetchall()
 
#Retrieving the list id
def get_listid(username, listname):
	cursor.execute("SELECT listid FROM Lists_users WHERE username ='%s' AND listname = '%s';"%(username, listname))
	return cursor.fetchone()[0]
 
#Deleting a list (also affects Lists_items)
def delete_list(listid):
	try:
		result1 = cursor.execute("DELETE FROM Lists_items WHERE listid = %s;" % (listid))
		result2 = cursor.execute("DELETE FROM Lists_users WHERE listid = %s;" % (listid))
		result = [result1,result2]
		db.commit()
	except: result = [0,0]
	return result
 
 
#------------------------------------Lists_items table methods------------------------------------#
 
 
#Adding an item to a list
def write_list_item(listid,barcode):
	try:
		result = cursor.execute("INSERT INTO Lists_items (listid,barcode) VALUES (%s, %s);" % (listid,barcode))
		db.commit()
	except: result = 0
	return result
 
 
#Deleting an item from a list
def delete_item(listid,barcode):
	try:
		result = cursor.execute("DELETE FROM Lists_items WHERE listid = %s AND barcode = %s;" % (listid,barcode))
		db.commit()
	except: result = 0
	return result
 
 
#Retrieving all items on a list
def get_all_items(listid):
	cursor.execute("SELECT * FROM Lists_items WHERE listid= %s;" % listid)
	return cursor.fetchall()
 
 
#------------------------------------Items_stores table methods------------------------------------#
 
 
#Adding an item to a store
def write_item_store(barcode,storeid,price):
	try:
		result = cursor.execute("INSERT INTO Items_stores (barcode,storeid,price) VALUES (%s,%s,%s);" % (barcode,storeid,price))
		db.commit()
	except: result = 0
	return result
 
#Get storeid where barcode exist
def get_storeid_barcode(barcode):	
	cursor.execute("SELECT storeid FROM Items_stores WHERE barcode = %s;" % barcode)
	return cursor.fetchall()
 
#Modifying an item price
def set_item_price(barcode,storeid,price):
	try:
		result = cursor.execute("UPDATE Items_stores SET price = %s WHERE barcode= %s AND storeid= %s;"% (price, barcode, storeid))
		db.commit()
	except: result = 0
	return result	
 
#Retrieving the lowest price of an item
def get_lowest_price(barcode):
	cursor.execute("SELECT storeid, price FROM Items_stores WHERE barcode = %s ORDER BY price ASC ;" % barcode)
	return cursor.fetchone()
 
 
#Retrieving the different prices for an item and its corresponding store
def get_prices_stores(barcode):
	cursor.execute("SELECT storeid, price FROM Items_stores WHERE barcode = %s ORDER BY price ASC;" % barcode)
	return cursor.fetchall()
 
 
#Retrieving the average price of an item
def get_avgprice(barcode):
	cursor.execute("SELECT AVG(price) FROM Items_stores WHERE barcode = %s;" % barcode)
	return cursor.fetchone()
 
 
#Retrieving the lowest price of an item between certain coordinates (Due to a radius)
def get_nearlowestprice(barcode, latitude, longitude, radius):
	cursor.execute("SELECT storeid FROM Stores WHERE (latitude > %s) AND (latitude < %s) AND (longitude > %s) AND (longitude < %s);" % ((latitude-radius), (latitude+radius), (longitude-radius), (longitude+radius)))
	storelist = cursor.fetchall()
	cursor.execute("SELECT storeid, price FROM Items_stores WHERE barcode = %s ORDER BY price ;" % barcode)
	pricelist = cursor.fetchall()	
	i = 0
	j = 0
	result = ''
	while i < len(pricelist):
		while j < len(storelist):			
			if storelist[j][0] == pricelist[i][0]:
				return [str(pricelist[i][1]), str(storelist[j][0])]
			j += 1
		i += 1
		j = 0	


The next files: server.py, client_server.py and client.py has a similar function to the one exposed in the main project page. Remember that the idea of client file is to test the functioning of the components. The final goal is to support an android app.

server.py

import socket, os
import client_server
from client_server import Client_server
 
def socket_setup():
	server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	server_address = ('localhost', 10100)
	server.bind(server_address)
	server.listen(1)
	print "server created and configured"
	return server
 
def wait_connection(server):
	wait_connection = True
	while wait_connection:	
	  print "Online and waiting for new requests"	
	  client_socket, client_address = server.accept()  
	  newproc = os.fork()  
	  if newproc == 0:	
		wait_connection = False
		client_sver = Client_server(client_socket)
		client_sver.decide()	
		client_sver = None
		print 'lost connection'
		os._exit(1)		
 
def main():
	server = socket_setup()
	wait_connection(server)
 
if __name__== "__main__":
	main()

client_server

import socket
import DBmethods as dbm
 
class Client_server:
 
	def __init__(self, client_socket):
		self.client_socket = client_socket
		self.ratio = 0.03
		self.username = ""		
 
	def __del__(self):
		del self.client_socket
 
	def decide(self):
		self.client_socket.settimeout(900)	
		while True:
			try:
				msg = self.client_socket.recv(4096) 
			except socket.timeout:				
				self.client_socket.close()
				break
			instruction = []		
			instruction = msg.split('<>')
			command = instruction[0]
			#choose a function		
			if command == 'printf':
				self.printf(instruction)		
			elif command == 'login':
				self.login(instruction)
			elif command == 'signup':
				self.signup(instruction)
			elif command == 'storeinratio':
				self.storeinratio(instruction)
			elif command == 'addstore':
				self.addstore(instruction)
			elif command == 'submititem':
				self.submititem(instruction)
			elif command == 'edititem':
				self.edititem(instruction)
			elif command == 'newlist':
				self.newlist(instruction)
			elif command == 'delist':
				self.delist(instruction)
			elif command == 'requestlists':
				self.requestlists()
			elif command == 'addtolist':
				self.addtolist(instruction)
			elif command == 'delfromlist':
				self.delfromlist(instruction)
			elif command == 'seekitem':
				self.seekitem(instruction)
 
	def answer(self, answer):				
		self.client_socket.sendall(answer)
 
	def printf(self, msg_list):	
		print msg_list[1]
		self.answer("Success")
 
	def login(self, msg_list):
		# login<>username<>password
		if msg_list[2] == dbm.get_password(msg_list[1]):
			self.answer("login<>success")
			self.username = msg_list[1]
		else:
			self.answer("login<>invalid username/password combination") 
 
	def signup(self, msg_list):
		# write_user(username, password, real name, email)
		status = dbm.write_user(msg_list[1], msg_list[2], msg_list[3],msg_list[4])
		if status:
			self.answer("signup<>success")
		else:
			self.answer("signup<>invalid username")
 
	def storeinratio(self, msg_list):
		coordinates = msg_list[1].split("%/")
		#get_stores(latitude, longitude, radius)
		data = dbm.get_stores(float(coordinates[0]), float(coordinates[1]), self.ratio)
		i = 0
		answer = ""
		while len(data) > i:
			answer += '<>'			
			answer += data[i][1]+', '+data[i][2]+'%/'+str(data[i][0])
			j = 1
			i += 1
		answer = 'storeinratio' + answer
		self.answer(answer)
 
	def addstore(self, msg_list):
		#write_store(name, location, latitude, longitude)
		coordinates = msg_list[3].split('%/')
		status = dbm.write_store(msg_list[1], msg_list[2], float(coordinates[0]), float(coordinates[1]))
		storeid = float(dbm.get_storeid(float(coordinates[0]), float(coordinates[1]))[0])
		if status:
			self.answer('addstore<>success<>'+str(storeid))
		else:
			self.answer('addstore<>data base error')
 
	def submititem(self, msg_list):
		# according to communication protocol submititem<>barcode<>name<>brand<>quantity<>descripton<>image<>price<>storeid
 
		# write_item(barcode, name, brand, quantity, description, image):
		dbm.write_item(msg_list[1], msg_list[2], msg_list[3], msg_list[4], msg_list[5], msg_list[6])
		# write_item_store(barcode,storeid,price)
		dbm.write_item_store(msg_list[1], msg_list[8], msg_list[7])
		self.answer('submititem<>success')	
 
	def edititem(self, msg_list):
		# modify_item(barcode, name, brand, quantity, description, image)
		dbm.modify_item(msg_list[1], msg_list[2], msg_list[3], msg_list[4], msg_list[5], msg_list[6])
 
		ids = dbm.get_storeid_barcode(msg_list[1])		
		isnew = True
		i = 0
 
		while i < len(ids):
			if int(ids[i][0])== int(msg_list[8]):
				isnew = False
			i+=1			 
 
		if isnew:
			dbm.write_item_store(msg_list[1], msg_list[8], msg_list[7])
		else: 			
			# set_item_price(barcode,storeid,price)		
			dbm.set_item_price(msg_list[1], msg_list[8], msg_list[7])			
		self.answer('submititem<>success')		
 
	def newlist(self, msg_list):
		#write_list_user(listname,username)
		dbm.write_list_user(msg_list[1], self.username)
		self.answer('newlist<>succesful')
 
	def delist(self, msg_list):
		#get_listid(username, listname)
		listid = dbm.get_listid(self.username, msg_list[1])
		#def delete_list(listid)
		dbm.delete_list(listid)
		self.answer('delist<>succesful')
 
	def requestlists(self):
		#get_lists(username)
		lists = dbm.get_lists(self.username)
		data = ''
		i = 0
		while i < len(lists):			
			data += lists[i][1]
			if i != (len(lists)-1):
				data += '%/'
			i += 1
		message = 'requestlists<>'+data
		self.answer(message)
 
	def addtolist(self, msg_list):
		#get_listid(username, listname)
		listid = dbm.get_listid(self.username, msg_list[1])
		#write_list_item(listid,barcode)
		dbm.write_list_item(listid, msg_list[2])
		self.answer('addtolist<>succesful')
 
	def delfromlist(self, msg_list):
		#get_listid(username, listname)
		listid = dbm.get_listid(self.username, msg_list[1])
		#delete_item(listid,barcode)
		dbm.delete_item(listid, msg_list[2])
		self.answer('delfromlist<>succesful')
 
	def seekitem(self, msg_list):
		#get item information
		#get_item(barcode)
		infolist = dbm.get_item(msg_list[1])
		iteminfo = ''
		if infolist == None:
			self.answer('seekitem<>notfound')
			return 
		else:
			i = 1
			while i < len(infolist):
				iteminfo += '<>'+infolist[i]
				i+=1
 
		#get lowest price and store
		lowestprice = str(dbm.get_lowest_price(msg_list[1])[1])
		storeid = int(dbm.get_lowest_price(msg_list[1])[0])
		lowestprice_store = dbm.get_storename(storeid)[0]+', '+dbm.get_storename(storeid)[1] 				
 
		#get closest lower price and store
		#def get_nearlowestprice(barcode, latitude, longitude, radius)
		coordinates = msg_list[2].split('%/')
		closest_price = dbm.get_nearlowestprice(msg_list[1], float(coordinates[0]), float(coordinates[1]), self.ratio)
		closest_store = dbm.get_storename(closest_price[1])[0]+', '+dbm.get_storename(closest_price[1])[1]
		closest_lower = closest_price[0]+'<>'+closest_store
 
		self.answer('seekitem'+iteminfo+'<>'+lowestprice+'<>'+lowestprice_store+'<>'+closest_lower)

client.py

import socket
 
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 10100)
print "socket created"
client.connect(server_address)
print "connection established, write a command"
 
def ask_info():
	info = raw_input()
	return info
	print '/n'
 
exit = False
while not exit:
	command = ask_info()		
	if command == "exit":
		exit = True
#secret command print
	elif command == 'print':
		info = ask_info()
		message = 'printf<>'+info
		client.sendall(message)
		print client.recv(100)
#signup		
	elif command == "signup":
		tmplist = ['username', 'password', 'name', 'mail']
		j = 0
		for i in tmplist:
			print i,
			tmplist[j] = ask_info()	
			j += 1
		info = reduce(lambda x,y: x+'<>'+y, tmplist)
		message = command+'<>'+info
		client.sendall(message)
		print client.recv(100) # check if the operation succeded
#login		
	elif command == "login":
		tmplist = ['username', 'password']
		j = 0
		for i in tmplist:
			print i,
			tmplist[j] = ask_info()	
			j += 1
		info = reduce(lambda x,y: x+'<>'+y, tmplist)
		message = command+'<>'+info
		client.sendall(message)
		print client.recv(100)
#storeinratio
	elif command == "storeinratio":
		print 'latitude'
		latitude = ask_info()
		print 'longitude'
		longitude = ask_info()
		message = command+'<>'+latitude+'%/'+longitude
		client.sendall(message)
		print client.recv(100)
#addstore
	elif command == 'addstore':
		print 'name'
		name = ask_info()
		print 'location'
		location = ask_info()
		print 'latitude'
		latitude = ask_info()
		print 'longitude'
		longitude = ask_info()
		message = command+'<>'+name+'<>'+location+'<>'+latitude+'%/'+longitude
		client.sendall(message)
		print client.recv(100)
#submit item
	elif command == 'submititem':
		print 'introduce: barcode<>name<>brand<>quantity<>descripton<>image<>price<>storeid'
		data = ask_info()
		message = 'submititem<>'+data
		client.sendall(message)
		print client.recv(100)
#edit item
	elif command == 'edititem':
		print 'introduce: barcode<>name<>brand<>quantity<>descripton<>image<>price<>storeid'
		data = ask_info()
		message = 'edititem<>'+data
		client.sendall(message)
		print client.recv(100)
#new list
	elif command == 'newlist':
		print 'introduce: list name'
		data = ask_info()
		message = 'newlist<>'+data
		client.sendall(message)
		print client.recv(100)
#delete list
	elif command == 'delist':
		print 'introduce: list name'
		data = ask_info()
		message = 'delist<>'+data
		client.sendall(message)
		print client.recv(100)
#request lists
	elif command == 'requestlists':		
		client.sendall('requestlists')
		print client.recv(100)
# add item to list
	elif command == 'addtolist':
		print 'introduce: listname<>barcode'
		data = ask_info()
		message = 'addtolist<>'+data
		client.sendall(message)
		print client.recv(100)
#delete item from list
	elif command == 'delfromlist':
		print 'introduce: listname<>barcode'
		data = ask_info()
		message = 'delfromlist<>'+data
		client.sendall(message)
		print client.recv(100)
#seek item
	elif command == 'seekitem':
		print 'introduce: barcode<>latitude%/logitude'
		data = ask_info()
		message = 'seekitem<>'+data
		client.sendall(message)
		print client.recv(4096)


Finally the next file present the Way to Shop function algorithms. The ones that allow the server to generate an optimized route for a shopping list.

wts_algorithms

#this is pseudo-code
#these are the route generation and optimization algorithms for Way To Shop 
 
#miscellaneous functions
 
#this function distributes the items between the stores, according with their position 
#in storelist
 
def assignitems(itemlist, storelist):
	storedic = {}
	for storeid in storelist:
		storedic[storeid] = 0		
	for storeid in storelist:
		temp = ''
		price = 0.0
		if len(itemlist) == 0:
			break
		for itemN in itemlist:
			if match(itemN, storeid):
				temp += name(itemN)
				price += price(storeid, itemN)
				itemlist.remove(itemN)
		storedic[storeid] = temp+str(price)
		return storedic
 
#this function sort the storeid according with nearest neighbour algorithm (http://en.wikipedia.org/wiki/Nearest_neighbour_algorithm)	
 
def sortdistance(initposition, storelist):
	improvedlist = []
	position = initposition
	while len(storelist) > 0:
		templist = []
		for storeid in storeidlist:
			dist = calcdist(position, position(storeid))
			templist.append((storeid, dist))
		templist = sorted(templist, key=lambda x:x[1])
		improvedlist.append(templist[0][0])
		storelist.remove(templist[0][0])
		position = position(templist[0][0])
	return improvedlist
 
#Function to organize the stores from cheaper to most expensive
 
def savemymoney(itemlist, storelist):
	storepoints = {}
	for storeid in storelist:
		storepoints[storeid] = 0
	for itemN in itemlist:
		lowest = (0, float('inf')
		for storeid in storelist:
			if match(itemN, storeid):
				newprice = price(itemN, storeid)
				if newprice < lowest[1]:
					lowest = (storeid, newprice)
		storepoints[lowest[0]) += 1
	templist = storepoints.items()
	templist = sorted(templist, key=lambda x:x[1])
	storelist = [storeid[0] for storeid in templist]
	assignedlist = assignitems(itemlist, storelist)
	storelist = sortdistance(initposition, assignedlist.keys())
	message = ''
	for storeid in storelist:
		message += name(storelist)+assignedlist[storeid]
 
#Function to organize the stores according with amount of item on it
 
def savemytime(itemlist, storelist):
	storepoints = []
	for storeid in storelist:
		points = 0
		for itemN in itemlist:
			if match(itemN, storeid):
				points += 1
		storepoints.append((storeid, points))
	storepoints = sorted(storepoints, key=lambda x:x[1])
	storelist = [storeid[0] for storeid in storepoints]
	assignedlist = assignitems(itemlist, storelist)
	storelist = sortdistance(initposition, assignedlist.keys()]
	message = ""
	for storeid in storelist:
		message += name(storeid) + assignedlist[storeid]
teaching/ie0117/proyectos/2013/i/way_to_shop/serverimplementation.txt · Last modified: 2022/09/20 00:08 (external edit)