text: '''
  Created on 14/01/2016
  
  Controller for the catalog server containing helper functions and rest API to perform CRUD operations
  on the composer database. Route to the app index is forwarded to angular.js framework routing.
  
  @author: Jessica
  '''
  
  import os
  import json
  
  from flask import send_file, jsonify, request
  from catalog import app, client_path
  from catalog.authentication.controllers import login_required, getUser
  from catalog.models import Composer, MusicItem, MusicFile
  from catalog.core import db
  from werkzeug import secure_filename
  
  #Helper functions
  def createMusicFile(musicItem, filename):
      musicFile = MusicFile(path=filename)
      musicFile.music_item = musicItem
      db.session.add(musicFile)
      db.session.commit()
      
  def createMusicItem(user_id, name, number, key, dateOfComposition, dateAdded, composer):
      musicItem = MusicItem(user_id=user_id, name=name, number=number, key=key, dateOfComposition=dateOfComposition, dateAdded=dateAdded)
      musicItem.composer = composer
      db.session.add(musicItem)
      db.session.commit()
      return musicItem
  
  def uploadFileToServer(uploadFile, musicItem):
      filename = secure_filename(uploadFile.filename)
      uploadFile.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
      return filename
  
  #API Routes
  @app.route('/')
  def index():
      #forward to angular routing
      return send_file(os.path.join(client_path, 'index.html'))
  
  
  @app.route('/api/catalog/uploadfile', methods=['POST'])
  @login_required
  def uploadFileToMusicItem():
      uploadFile = request.files['file']
      
      if uploadFile:
          
          musicItem = MusicItem.query.filter_by(id=request.form['id']).first()
          
          if not musicItem:
              response = jsonify(message="Couldn't find music item")
              response.status_code = 401
              return response
          
          try:
              filename = uploadFileToServer(uploadFile, musicItem)
              createMusicFile(musicItem, filename)
              response = jsonify(message="File has been saved %s"% filename)
              response.status_code = 200
          except Exception, e:
              response = jsonify(message="Failed to upload file %s"% str(e))
              response.status_code = 500
          return response
           
      response = jsonify(message="File could not be saved")
      response.status_code = 500
      return response
  
  '''
  Return composer data in JSON format for the current logged in user
  '''
  @app.route('/api/catalog/composers/JSON')
  @login_required
  def allComposersJSON():
      user = getUser()
      composers = Composer.query.filter_by(user_id=user.id).order_by(Composer.name).all()
      return jsonify(composers=[c.to_json() for c in composers])
  
  '''
  Return music item data for a particular composer in JSON format for the current logged in user
  '''
  @app.route('/api/catalog/composer/<int:composer_id>/musicitems/JSON')
  @login_required
  def composerMusicItemsJSON(composer_id):
      user = getUser()
      composer = Composer.query.filter_by(id=composer_id, user_id=user.id).first()
      return jsonify(musicItems=[i.to_json() for i in composer.musicItems])
  
  '''
  Update a composer, passing in JSON parameters containing the new model
  '''
  @app.route('/api/catalog/updatecomposer', methods=['POST'])
  @login_required
  def updateComposer():
      composer = Composer.query.filter_by(id=request.json['id']).first()
  
      if not composer:
          response = jsonify(message="Couldn't find composer")
          response.status_code = 401
          return response
      
      composer.name = request.json['name']
      composer.dateOfBirth = request.json['dateOfBirth']
      composer.dateOfDeath = request.json['dateOfDeath']
      db.session.commit()
      
      response = jsonify(message="Composer %s updated"%composer.name)
      response.status_code = 200
      return response
  
  '''
  Update a music item, passing in JSON parameters containing the new model
  '''
  @app.route('/api/catalog/updatemusicitem', methods=['POST'])
  @login_required
  def updateMusicItem():
      musicItem = MusicItem.query.filter_by(id=request.json['id']).first()
   
      if not musicItem:
          response = jsonify(message="Couldn't find music item")
          response.status_code = 401
          return response
       
      musicItem.name = request.json['name']
      musicItem.dateAdded = request.json['dateAdded']
      musicItem.dateOfComposition = request.json['dateOfComposition']
      musicItem.number = request.json['number'] 
      musicItem.key = request.json['key']
      db.session.commit()
  
      response = jsonify(message="Music item %s updated"% musicItem.name)
      response.status_code = 200
      return response
  
  '''
  Add a composer, passing in JSON parameters containing the new model
  '''
  @app.route('/api/catalog/addcomposer', methods=['POST'])
  @login_required
  def addComposer():
      user = getUser()
      composer = Composer(user_id=user.id, name=request.json['name'], dateOfBirth=request.json['dateOfBirth'], dateOfDeath=request.json['dateOfDeath'])
      db.session.add(composer)
      db.session.commit()
     
      response = jsonify(message="Added composer %s"%composer.name)
      response.status_code = 200
      return response
  
  '''
  Add a music item, passing in JSON parameters containing the new model
  '''
  @app.route('/api/catalog/addmusicitem', methods=['POST'])
  @login_required
  def addMusicItem():
      
      user = getUser()
      composer_id = request.form['composer_id']
      musicItemData = json.loads(request.form['music_item'])
      
      composer = Composer.query.filter_by(id=composer_id, user_id=user.id).first()
      
      if not composer:
          response = jsonify(message="Couldn't find composer")
          response.status_code = 401
          return response
      
      musicItem = createMusicItem(user_id=user.id, name=musicItemData['name'], number=musicItemData['number'], key=musicItemData['key'], dateOfComposition=musicItemData['dateOfComposition'], dateAdded=musicItemData['dateAdded'], composer=composer)
    
      if 'file' in request.files:
          uploadFile = request.files['file']
          print "uploading a file"
          try:
              filepath = uploadFileToServer(uploadFile, musicItem)
              createMusicFile(musicItem, filepath)
              response = jsonify(message="Added music item %s"%musicItem.name)
              response.status_code = 200
          except Exception, e:
              response = jsonify(message="Failed to upload file %s"% str(e))
              response.status_code = 500
      else:
          print "no file to upload"
          response = jsonify(message="Added music item %s"%musicItem.name)
          response.status_code = 200
  
      return response
  
  '''
  Delete a composer, passing in JSON parameters containing the id
  '''
  @app.route('/api/catalog/deletecomposer', methods=['POST'])
  @login_required
  def deleteComposer():
      composer = Composer.query.filter_by(id=request.json['id']).first()
  
      if not composer:
          response = jsonify(message="Couldn't find composer")
          response.status_code = 401
          return response
      
      db.session.delete(composer)
      db.session.commit()
     
      response = jsonify(message="Deleted composer %s"%composer.name)
      response.status_code = 200
      return response
  
  '''
  Delete a music item, passing in JSON parameters containing the id
  '''
  @app.route('/api/catalog/deletemusicitem', methods=['POST'])
  @login_required
  def deleteMusicItem():
      musicItem = MusicItem.query.filter_by(id=request.json['id']).first()
  
      if not musicItem:
          response = jsonify(message="Couldn't find music item")
          response.status_code = 401
          return response
      
      db.session.delete(musicItem)
      db.session.commit()
     
      response = jsonify(message="Deleted music item %s"%musicItem.name)
      response.status_code = 200
      return response
  
  '''
  Delete a music file, passing in JSON parameters containing the id
  '''
  @app.route('/api/catalog/deletemusicfile', methods=['POST'])
  @login_required
  def deleteMusicFile():
      musicFile = MusicFile.query.filter_by(id=request.json['id']).first()
  
      if not musicFile:
          response = jsonify(message="Couldn't find music file")
          response.status_code = 401
          return response
  
      db.session.delete(musicFile)
      db.session.commit()
     
      response = jsonify(message="Deleted music file %s"%musicFile.path)
      response.status_code = 200
      return response
  
  
      
  