Skip to content

Instantly share code, notes, and snippets.

@richard-to
Created April 26, 2014 07:45
Show Gist options
  • Save richard-to/11314272 to your computer and use it in GitHub Desktop.
Save richard-to/11314272 to your computer and use it in GitHub Desktop.
Random code for a class project
import logging
import socket
import SocketServer
import sys
import time
import threading
from ftplib import FTP
from os import listdir, remove, rename, stat
from os.path import isfile, join, splitext, isfile
from random import randint
from pydub import AudioSegment
# Module Client Settings
MODULE_HOST = '255.255.255.255'
MODULE_FTP_HOST = '255.255.255.255'
MODULE_PORT = 20000
HOSTS_FILENAME = 'hosts.txt'
UPLOAD_FILENAME = 'sound.mp3'
MODULE_UPLOAD_DIR = '/upload'
MODULE_READY_DIR = '/ready'
MODULE_LOCAL_FTP_DIR = 'ftpserver/res/home'
MODULE_LOCAL_FTP_UPLOAD_DIR = ''.join([MODULE_LOCAL_FTP_DIR, MODULE_UPLOAD_DIR])
MODULE_LOCAL_FTP_READY_DIR = ''.join([MODULE_LOCAL_FTP_DIR, MODULE_READY_DIR])
SOUND_PATH = 'sounds'
SERVER_PORT = 20000
FTP_PORT = 2021
OUTPUT_FILENAME = 'output{}.mp3'
SOUND_DURATION = 2000
DELAY = 5
# General Settings
LOG_FILE = 'sb16.log'
LOG_LEVEL = logging.INFO
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
# Setup Logger
logging.basicConfig(level=LOG_LEVEL, format=LOG_FORMAT)
logger = logging.getLogger()
file_log_handler = logging.FileHandler(LOG_FILE)
logger.addHandler(file_log_handler)
formatter = logging.Formatter(LOG_FORMAT)
file_log_handler.setFormatter(formatter)
# Shared Variables
iteration = 0
has_file = True
class FTPThread(threading.Thread):
def __init__(self, ip, path):
threading.Thread.__init__(self)
self.ip = ip
self.path = path
def run(self):
# Open FTP connection
print self.ip
print FTP_PORT
logger.info('Connecting to FTP server at {}:{}.'.format(self.ip.strip(), FTP_PORT))
ftp = FTP()
ftp.connect(self.ip.strip(), FTP_PORT)
ftp.login()
# Send MP3 File to Client
file_path = join(self.path, UPLOAD_FILENAME)
ftp.storbinary('STOR ' + file_path, open(UPLOAD_FILENAME, 'rb'))
ftp.quit()
remove(UPLOAD_FILENAME)
class RequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
global has_file
logger.info('Client request received from {}.'.format(self.client_address[0]))
# TODO(richard-to): Add timeout logic
received = self.request.recv(1024).strip()
print received
data = received.split('\n')
if isfile(UPLOAD_FILENAME) and (len(data) == 3 or len(data) == 5):
if len(data) == 3:
thread = FTPThread(data[0], data[2])
else:
thread = FTPThread(data[1], data[3])
thread.start()
class ClientThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.kill_received = False
def run(self):
global iteration
global has_file
# Get the list of host computers
logger.info('Retrieving list of hosts.')
hosts = [line.strip() for line in open(HOSTS_FILENAME, 'r')]
# Get the list of sounds to add to file
logger.info('Retrieving list of sound files.')
sounds = []
for mp3_file in listdir(SOUND_PATH):
if isfile(join(SOUND_PATH, mp3_file)):
filename, ext = splitext(mp3_file)
if ext == ".mp3":
sounds.append(join(SOUND_PATH, mp3_file))
# Start Client Process
while True:
for host in hosts:
if self.kill_received:
logger.info('Kill received. Stopping client thread.')
return
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# Connect to next host in list
logger.info('Connecting to server at {}:{}.'.format(host, SERVER_PORT))
sock.settimeout(5)
sock.connect((host, SERVER_PORT))
sock.settimeout(None)
# Send request information to server
logger.info('Sending FTP info to server at {}:{}.'.format(host, SERVER_PORT))
request = "{}\n{}\n{}".format(MODULE_HOST, host, '/upload/')
sock.send(request)
except Exception:
logger.error('Could not connect to host {}:{}.'.format(host, SERVER_PORT))
finally:
logger.info('Closing connection to host {}:{}.'.format(host, SERVER_PORT))
# Remember to close socket
sock.close()
# Check for an mp3 file
mp3_file_path = None
for mp3_file in listdir(MODULE_LOCAL_FTP_UPLOAD_DIR):
if isfile(join(MODULE_LOCAL_FTP_UPLOAD_DIR, mp3_file)):
filename, ext = splitext(mp3_file)
if ext == ".mp3":
logger.info('Found mp3 file in upload dir: {}.'.format(mp3_file))
mp3_file_path = join(MODULE_LOCAL_FTP_UPLOAD_DIR, mp3_file)
break
# If we have an mp3 file, process the mp3 with out modifications
if mp3_file_path is not None:
file_done = False
prev_size = -1
while file_done is False:
statinfo = stat(mp3_file_path)
if statinfo.st_size == prev_size:
# Append random sound fragment to downloaded sound
rand_sound = sounds[randint(0, len(sounds) - 1)]
logger.info('Adding two seconds of sound from {}.'.format(rand_sound))
sound1 = AudioSegment.from_mp3(mp3_file_path)
sound2 = AudioSegment.from_mp3(rand_sound)
sound3 = sound2.set_frame_rate(sound1.frame_rate)
output = sound1 + sound3
# Save new sound to our FTP path
output_filename = OUTPUT_FILENAME.format(iteration)
output.export(join(MODULE_LOCAL_FTP_DIR, output_filename), format="mp3", bitrate=str(output.frame_rate))
rename(join(MODULE_LOCAL_FTP_DIR, output_filename), UPLOAD_FILENAME)
output.export(join(MODULE_LOCAL_FTP_DIR, output_filename), format="mp3", bitrate=str(output.frame_rate))
remove(mp3_file_path)
logger.info('Saving new sound file as ready.'.format(UPLOAD_FILENAME))
# Increment iteration
iteration += 1
logger.info('Incrementing iteration to {}.'.format(iteration))
prev_size = -1
file_done = True
else:
prev_size = statinfo.st_size
time.sleep(2)
logger.info('Finished contacting all hosts. Waiting {} seconds before trying again.'.format(DELAY))
# Wait X seconds after connecting to all hosts
time.sleep(DELAY)
# Start Client Thread
try:
thread = ClientThread()
thread.start()
except:
sys.exit()
try:
logger.info('Starting TCP Server on port {}'.format(MODULE_PORT))
server = SocketServer.TCPServer((MODULE_HOST, MODULE_PORT), RequestHandler)
server.serve_forever()
except KeyboardInterrupt:
logger.info('Ctrl+C detected. Please wait. Shutting down client thread')
thread.kill_received = True
import logging
import socket
import SocketServer
import sys
import time
import threading
from ftplib import FTP
from os import listdir, remove
from os.path import isfile, join, splitext
from random import randint
from pydub import AudioSegment
# Module Server Settings
MODULE_PORT = 20000
MODULE_HOST = '255.255.255.255'
MODULE_FTP_HOST = '255.255.255.255'
MODULE_FTP_DIR = 'ftpserver/res/home'
MODULE_INITIAL_FILE = 'test.mp3'
MODULE_INITIAL_HAS_FILE = False
# Module Client Settings
HOSTS_FILENAME = 'hosts.txt'
SOUND_PATH = 'sounds'
SERVER_PORT = 20000
FTP_PORT = 2121
TEMP_FILENAME = 'temp.mp3'
OUTPUT_FILENAME = 'output{}.mp3'
SOUND_DURATION = 2000
DELAY = 5
# General Settings
LOG_FILE = 'soundblaster16.log'
LOG_LEVEL = logging.INFO
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s'
# Setup Logger
logging.basicConfig(level=LOG_LEVEL, format=LOG_FORMAT)
logger = logging.getLogger()
file_log_handler = logging.FileHandler(LOG_FILE)
logger.addHandler(file_log_handler)
formatter = logging.Formatter(LOG_FORMAT)
file_log_handler.setFormatter(formatter)
# Shared Variables
iteration = 0
output_filename = MODULE_INITIAL_FILE
has_file = MODULE_INITIAL_HAS_FILE
class RequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
global has_file
logger.info('Client request received from {}.'.format(self.client_address[0]))
if has_file:
logger.info('Sending FTP info to client at {}.'.format(self.client_address[0]))
response = "{}\n{}\n{}".format(MODULE_HOST, MODULE_FTP_HOST, output_filename)
self.request.sendall(response)
has_file = False
class ClientThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.kill_received = False
def run(self):
global iteration
global output_filename
global has_file
# Get the list of host computers
logger.info('Retrieving list of hosts.')
hosts = [line.strip() for line in open(HOSTS_FILENAME, 'r')]
# Get the list of sounds to add to file
logger.info('Retrieving list of sound files.')
sounds = []
for mp3_file in listdir(SOUND_PATH):
if isfile(join(SOUND_PATH, mp3_file)):
filename, ext = splitext(mp3_file)
if ext == ".mp3":
sounds.append(join(SOUND_PATH, mp3_file))
# Start Client Process
while True:
for host in hosts:
if self.kill_received:
logger.info('Kill received. Stopping client thread.')
return
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# Connect to next host in list
logger.info('Connecting to server at {}:{}.'.format(host, SERVER_PORT))
sock.connect((host, SERVER_PORT))
received = sock.recv(1024)
data = received.split('\n')
# Make sure we received 3 lines of data
# Probably should check that data is in correct format
if len(data) == 3:
# Open FTP connection
logger.info('Connecting to FTP server at {}:{}.'.format(data[1], FTP_PORT))
ftp = FTP()
ftp.connect(data[1], FTP_PORT)
ftp.login()
ftp.cwd('.')
temp_mp3_file = open(TEMP_FILENAME, 'wb')
# Download the sound from FTP server
logger.info('Downloading {} from FTP server.'.format(data[2]))
ftp.retrbinary('RETR %s' % data[2], temp_mp3_file.write)
ftp.quit()
# Append random sound fragment to downloaded sound
rand_sound = sounds[randint(0, len(sounds) - 1)]
logger.info('Adding two seconds of sound from {}.'.format(rand_sound))
sound1 = AudioSegment.from_mp3(TEMP_FILENAME)
sound2 = AudioSegment.from_mp3(rand_sound)
sound3 = sound2.set_frame_rate(sound1.frame_rate)
output = sound1 + sound3[-SOUND_DURATION:]
output_filename = OUTPUT_FILENAME.format(iteration)
# Save new sound to our FTP path
logger.info('Saving new sound file to FTP folder as {}.'.format(output_filename))
output.export(join(MODULE_FTP_DIR, output_filename), format="mp3", bitrate=str(output.frame_rate))
# Clean up temp file
logger.info('Deleting temporary file')
remove(TEMP_FILENAME)
# Increment iteration
iteration += 1
logger.info('Incrementing iteration to {}.'.format(iteration))
# Notify our server process that we have the file to pass on
logger.info('Notifying server process that we are in possession of the file.')
has_file = True
except Exception:
logger.error('Could not connect to host {}:{}.'.format(host, SERVER_PORT))
finally:
logger.info('Closing connection to host {}:{}.'.format(host, SERVER_PORT))
# Remember to close socket
sock.close()
logger.info('Finished contacting all hosts. Waiting {} seconds before trying again.'.format(DELAY))
# Wait X seconds after connecting to all hosts
time.sleep(DELAY)
# Start Client Thread
thread = ClientThread()
thread.start()
try:
logger.info('Starting TCP Server on port {}'.format(MODULE_PORT))
server = SocketServer.TCPServer((MODULE_HOST, MODULE_PORT), RequestHandler)
server.serve_forever()
except KeyboardInterrupt:
logger.info('Ctrl+C detected. Please wait. Shutting down client thread')
thread.kill_received = True
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment