Created
April 26, 2014 07:45
-
-
Save richard-to/11314272 to your computer and use it in GitHub Desktop.
Random code for a class project
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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