text:
import json

from flask_api import status
import flask as fk

from corrdb.common import logAccess, logStat, logTraffic, crossdomain, get_or_create
from api import app, storage_manager, access_manager, API_URL, api_response, data_pop, merge_dicts
from corrdb.common.models import UserModel
from corrdb.common.models import AccessModel
from corrdb.common.models import TrafficModel
from corrdb.common.models import FileModel
from corrdb.common.models import ProfileModel
from corrdb.common.models import StatModel
from corrdb.common.models import ProjectModel
from corrdb.common.models import RecordModel
from corrdb.common.models import RecordBodyModel
from corrdb.common.models import DiffModel
from corrdb.common.models import ApplicationModel
from corrdb.common.models import CommentModel
from corrdb.common.models import MessageModel
from corrdb.common.models import EnvironmentModel
from corrdb.common.models import BundleModel
from corrdb.common.models import VersionModel

import mimetypes
import simplejson as json
import traceback
import datetime
import random
import string
import os
import _thread

@app.route(API_URL + '/public/api/status', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_api_status():
    logTraffic(API_URL, endpoint='/public/api/status')
    if fk.request.method == 'GET':
        # Maybe perform some sanity checks
        return api_response(200, 'API reached', 'This CoRR API instance is up and running')
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/app/show/<app_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_app_show(app_id):
    logTraffic(API_URL, endpoint='/public/app/show/<app_id>')
    if fk.request.method == 'GET':
        app = ApplicationModel.objects.with_id(app_id)
        if app == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this application.')
        else:
            return api_response(200, 'Application %s'%app.name, app.extended())
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/app/logo/<app_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_app_logo(app_id):
    logTraffic(API_URL, endpoint='/public/app/logo/<app_id>')
    if fk.request.method == 'GET':
        app = ApplicationModel.objects.with_id(app_id)
        if app != None:
            name = app.name if app.name != '' and app.name != None else 'unknown'
            logo = app.logo
            if logo.location == 'local' and ('http://' not in logo.storage and 'https://' not in logo.storage):
                logo_buffer = storage_manager.storage_get_file('logo', logo.storage)
                if logo_buffer == None:
                    return api_response(404, 'No logo found', 'We could not fetch the logo at [%s].'%logo.storage)
                else:
                    return fk.send_file(logo_buffer, attachment_filename=logo.name, mimetype=logo.mimetype)
            elif logo.location == 'remote':
                logo_buffer = storage_manager.web_get_file(logo.storage)
                if logo_buffer != None:
                    return fk.send_file(logo_buffer, attachment_filename=logo.name, mimetype=logo.mimetype)
                else:
                    logo_buffer = storage_manager.storage_get_file('logo', 'default-logo.png')
                    if logo_buffer == None:
                        return api_response(404, 'No logo found', 'We could not fetch the logo at %s.'%logo.storage)
                    else:
                        return fk.send_file(logo_buffer, attachment_filename=logo.name, mimetype=logo.mimetype)
            else:
                # solve the file situation and return the appropriate one.
                if 'http://' in logo.storage or 'https://' in logo.storage:
                    logo.location = 'remote'
                    logo.save()
                    logo_buffer = storage_manager.web_get_file(logo.storage)
                    if logo_buffer != None:
                        return fk.send_file(logo_buffer, attachment_filename=logo.name, mimetype=logo.mimetype)
                    else:
                        logo_buffer = storage_manager.storage_get_file('logo', 'default-logo.png')
                        if logo_buffer == None:
                            return api_response(404, 'No logo found', 'We could not fetch the logo at %s.'%logo.storage)
                        else:
                            return fk.send_file(logo_buffer, attachment_filename=logo.name, mimetype=logo.mimetype)
                else:
                    logo.location = 'local'
                    logo.save()
                    logo_buffer = storage_manager.storage_get_file('logo', logo.storage)
                    if logo_buffer == None:
                        return api_response(404, 'No logo found', 'We could not fetch the logo at %s.'%logo.storage)
                    else:
                        return fk.send_file(logo_buffer, attachment_filename=logo.name, mimetype=logo.mimetype)
        else:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this application.')
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/users', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_users():
    logTraffic(API_URL, endpoint='/public/users')
    if fk.request.method == 'GET':
        users = UserModel.objects
        users_dict = {'total_users':len(users), 'users':[]}
        for user in users:
            users_dict['users'].append(user.extended())
        return api_response(200, 'Users list', users_dict)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/user/show/<user_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_user_show(user_id):
    logTraffic(API_URL, endpoint='/public/user/show/<user_id>')
    if fk.request.method == 'GET':
        user = UserModel.objects.with_id(user_id)
        if user == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this user.')
        else:
            return api_response(200, 'User %s account'%user.email, user.extended())
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/user/profile/show/<user_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_user_profile_show(user_id):
    logTraffic(API_URL, endpoint='/public/user/profile/show/<user_id>')
    if fk.request.method == 'GET':
        user = UserModel.objects.with_id(user_id)
        if user == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this user.')
        else:
            profile = ProfileModel.objects(user=user).first()
            if profile == None:
                return api_response(404, 'User %s profile is empty'%user.email, 'You have to create a profile for this user.')
            else:
                return api_response(200, 'User %s profile'%user.email, profile.extended())
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/user/picture/<user_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_user_picture(user_id):
    logTraffic(API_URL, endpoint='/public/user/picture/<user_id>')
    if fk.request.method == 'GET':
        user = UserModel.objects.with_id(user_id)
        if user != None:
            profile = ProfileModel.objects(user=user).first()
            if profile == None:
                picture_buffer = storage_manager.storage_get_file('picture', 'default-picture.png')
                if picture_buffer == None:
                    return api_response(404, 'No picture found', 'We could not fetch the picture [default-picture.png].')
                else:
                    return fk.send_file(picture_buffer, attachment_filename='default-picture.png', mimetype='image/png')
            else:
                picture = profile.picture
                if picture == None:
                    picture_buffer = storage_manager.storage_get_file('picture', 'default-picture.png')
                    if picture_buffer == None:
                        return api_response(404, 'No picture found', 'We could not fetch the picture [default-picture.png].')
                    else:
                        return fk.send_file(picture_buffer, attachment_filename='default-picture.png', mimetype='image/png')
                elif picture.location == 'local' and ('http://' not in picture.storage and 'https://' not in picture.storage):
                    picture_buffer = storage_manager.storage_get_file('picture', picture.storage)
                    if picture_buffer == None:
                        return api_response(404, 'No picture found', 'We could not fetch the picture [%s].'%logo.storage)
                    else:
                        return fk.send_file(picture_buffer, attachment_filename=picture.name, mimetype=picture.mimetype)
                elif picture.location == 'remote':
                    picture_buffer = storage_manager.web_get_file(picture.storage)
                    if picture_buffer != None:
                        return fk.send_file(picture_buffer, attachment_filename=picture.name, mimetype=picture.mimetype)
                    else:
                        picture_buffer = storage_manager.storage_get_file('picture', 'default-picture.png')
                        if picture_buffer == None:
                            return api_response(404, 'No picture found', 'We could not fetch the picture [default-picture.png].')
                        else:
                            return fk.send_file(picture_buffer, attachment_filename=picture.name, mimetype=picture.mimetype)
                else:
                    # solve the file situation and return the appropriate one.
                    if 'http://' in picture.storage or 'https://' in picture.storage:
                        picture.location = 'remote'
                        picture.save()
                        picture_buffer = storage_manager.web_get_file(picture.storage)
                        if picture_buffer != None:
                            return fk.send_file(picture_buffer, attachment_filename=picture.name, mimetype=picture.mimetype)
                        else:
                            picture_buffer = storage_manager.storage_get_file('picture', 'default-picture.png')
                            if picture_buffer == None:
                                return api_response(404, 'No picture found', 'We could not fetch the picture [%s].'%picture.storage)
                            else:
                                return fk.send_file(picture_buffer, attachment_filename=picture.name, mimetype=picture.mimetype)
                    else:
                        picture.location = 'local'
                        picture.save()
                        picture_buffer = storage_manager.storage_get_file('picture', picture.storage)
                        if picture_buffer == None:
                            return api_response(404, 'No picture found', 'We could not fetch the picture [%s].'%picture.storage)
                        else:
                            return fk.send_file(picture_buffer, attachment_filename=picture.name, mimetype=picture.mimetype)
        else:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this user.')
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/user/projects/<user_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_user_projects(user_id):
    logTraffic(API_URL, endpoint='/public/user/projects')
    if fk.request.method == 'GET':
        user = UserModel.objects.with_id(user_id)
        if user == None:
            return api_response(404, 'No user found', 'We could not fetch the user with id:%s.'%user_id)
        projects = ProjectModel.objects(owner=user)
        projects_dict = {'total_projects':len(projects), 'projects':[]}
        for project in projects:
            projects_dict['projects'].append(project.extended())
        return api_response(200, 'Projects list', projects_dict)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/projects', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_projects():
    logTraffic(API_URL, endpoint='/public/projects')
    if fk.request.method == 'GET':
        projects = ProjectModel.objects
        projects_dict = {'total_projects':len(projects), 'projects':[]}
        for project in projects:
            if project.access == 'public':
                projects_dict['projects'].append(project.extended())
        return api_response(200, 'Projects list', projects_dict)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/project/comments/<project_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_project_comments(project_id):
    logTraffic(API_URL, endpoint='/public/project/comments/<project_id>')
    if fk.request.method == 'GET':
        project = ProjectModel.objects.with_id(project_id)
        if project == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this project.')
        else:
            comments = project._comments()
            comments_dict = {'total_comments':0, 'comments':[]}
            for comment_id in comments:
                comment = CommentModel.objects.with_id(comment_id)
                if comment != None:
                    comments_dict['comments'].append(comment.info())
            comments_dict['total_comments'] = len(comments_dict['comments'])
            return api_response(200, 'Project comment list', comments_dict)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/comment/show/<comment_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_comment_show(comment_id):
    logTraffic(API_URL, endpoint='/public/comment/show/<comment_id>')
    if fk.request.method == 'GET':
        comment = CommentModel.objects.with_id(comment_id)
        if comment == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this comment.')
        else:
            return api_response(200, 'Project %s info'%comment_id, comment.info())
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/project/records/<project_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_project_records(project_id):
    logTraffic(API_URL, endpoint='/public/project/records/<project_id>')
    if fk.request.method == 'GET':
        project = ProjectModel.objects.with_id(project_id)
        if project == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this project.')
        else:
            records = RecordModel.objects(project=project)
            records_dict = {'total_records':len(records), 'records':[]}
            for record in records:
                records_dict['records'].append(record.extended())
            return api_response(200, 'Project [%s] Records list'%project.name, records_dict)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/project/show/<project_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_project_show(project_id):
    logTraffic(API_URL, endpoint='/public/project/show/<project_id>')
    if fk.request.method == 'GET':
        project = ProjectModel.objects.with_id(project_id)
        if project == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this project.')
        else:
            return api_response(200, 'Project %s'%project.name, project.extended())
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/project/logo/<project_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_project_logo(project_id):
    logTraffic(API_URL, endpoint='/public/project/logo/<project_id>')
    if fk.request.method == 'GET':
        project = ProjectModel.objects.with_id(project_id)
        if project != None:
            logo = project.logo
            if logo.location == 'local' and 'http://' not in logo.storage and 'https://' not in logo.storage:
                logo_buffer = storage_manager.storage_get_file('logo', logo.storage)
                if logo_buffer == None:
                    return api_response(404, 'No logo found', 'We could not fetch the logo at [%s].'%logo.storage)
                else:
                    return fk.send_file(logo_buffer, attachment_filename=logo.name, mimetype=logo.mimetype)
            elif logo.location == 'remote':
                logo_buffer = storage_manager.web_get_file(logo.storage)
                if logo_buffer != None:
                    return fk.send_file(logo_buffer, attachment_filename=logo.name, mimetype=logo.mimetype)
                else:
                    logo_buffer = storage_manager.storage_get_file('logo', 'default-logo.png')
                    if logo_buffer == None:
                        return api_response(404, 'No logo found', 'We could not fetch the logo at %s.'%logo.storage)
                    else:
                        return fk.send_file(logo_buffer, attachment_filename=logo.name, mimetype=logo.mimetype)
            else:
                # solve the file situation and return the appropriate one.
                if 'http://' in logo.storage or 'https://' in logo.storage:
                    logo.location = 'remote'
                    logo.save()
                    logo_buffer = storage_manager.web_get_file(logo.storage)
                    if logo_buffer != None:
                        return fk.send_file(logo_buffer, attachment_filename=logo.name, mimetype=logo.mimetype)
                    else:
                        logo_buffer = storage_manager.storage_get_file('logo', 'default-logo.png')
                        if logo_buffer == None:
                            return api_response(404, 'No logo found', 'We could not fetch the logo at %s.'%logo.storage)
                        else:
                            return fk.send_file(logo_buffer, attachment_filename=logo.name, mimetype=logo.mimetype)
                else:
                    logo.location = 'local'
                    logo.save()
                    logo_buffer = storage_manager.storage_get_file('logo', logo.storage)
                    if logo_buffer == None:
                        return api_response(404, 'No logo found', 'We could not fetch the logo at %s.'%logo.storage)
                    else:
                        return fk.send_file(logo_buffer, attachment_filename=logo.name, mimetype=logo.mimetype)
        else:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this application.')
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/project/download/<project_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_project_download(project_id):
    logTraffic(API_URL, endpoint='/public/project/download/<project_id>')
    if fk.request.method == 'GET':
        project = ProjectModel.objects.with_id(project_id)
        if project == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this project.')
        else:
            prepared = storage_manager.prepare_project(project)
            if prepared[0] == None:
                return api_response(404, 'Request suggested an empty response', 'Unable to retrieve an environment to download.')
            else:
                return fk.send_file(prepared[0], as_attachment=True, attachment_filename=prepared[1], mimetype='application/zip')
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/project/history/<project_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_project_history(project_id):
    logTraffic(API_URL, endpoint='/public/project/envs/<project_id>')
    if fk.request.method == 'GET':
        project = ProjectModel.objects.with_id(project_id)
        if project == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this project.')
        else:
            history_dict = {'total_environments':0, 'environments':[]}
            for env_dict in project.history:
                env = EnvironmentModel.objects.with_id(env_dict)
                if env != None:
                    history_dict['environments'].append(env.info())
            history_dict['total_environments'] = len(history_dict['environments'])
            return api_response(200, 'Project %s environments'%project.name, history_dict)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/project/envs/head/<project_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_project_envs_head(project_id):
    logTraffic(API_URL, endpoint='/public/project/envs/head')
    if fk.request.method == 'GET':
        project = ProjectModel.objects.with_id(project_id)
        if project == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this project.')
        else:
            head = {}
            if len(project.history) > 0:
                head = project.history[-1]
            return api_response(200, 'Project %s environments head'%project.name, head)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/project/env/show/<project_id>/<env_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_project_env_show(project_id, env_id):
    logTraffic(API_URL, endpoint='/public/project/env/show/<project_id>/<env_id>')
    if fk.request.method == 'GET':
        project = ProjectModel.objects.with_id(project_id)
        if project == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this project.')
        else:
            if env_id not in project.history:
                return api_response(404, 'Request suggested an empty response', 'Unable to find this project environment.')
            else:
                env = EnvironmentModel.objects.with_id(env_id)
                if env == None:
                    return api_response(404, 'Request suggested an empty response', 'Unable to load this project environment.')
                else:
                    return api_response(200, 'Project %s environment %s'%(project.name, env_id), env.extended())
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/project/env/download/<project_id>/<env_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_project_env_download(project_id, env_id):
    logTraffic(API_URL, endpoint='/public/project/env/download/<project_id>/<env_id>')
    if fk.request.method == 'GET':
        project = ProjectModel.objects.with_id(project_id)
        if project == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this project.')
        else:
            if env_id not in project.history:
                return api_response(404, 'Request suggested an empty response', 'Unable to find this project environment.')
            else:
                env = EnvironmentModel.objects.with_id(env_id)
                if env == None:
                    return api_response(404, 'Request suggested an empty response', 'Unable to load this project environment.')
                else:
                    prepared = storage_manager.prepare_env(project, env)
                    if prepared[0] == None:
                        return api_response(404, 'Request suggested an empty response', 'Unable to retrieve an environment to download.')
                    else:
                        return fk.send_file(prepared[0], as_attachment=True, attachment_filename=prepared[1], mimetype='application/zip')
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/records', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_records():
    logTraffic(API_URL, endpoint='/public/records')
    if fk.request.method == 'GET':
        records = RecordModel.objects
        records_dict = {'total_records':len(records), 'records':[]}
        for record in records:
            records_dict['records'].append(record.extended())
        return api_response(200, 'Records list', records_dict)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/record/show/<record_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_record_show(record_id):
    logTraffic(API_URL, endpoint='/public/record/show/<record_id>')
    if fk.request.method == 'GET':
        record = RecordModel.objects.with_id(record_id)
        if record == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this record.')
        else:
            return api_response(200, 'Record info', record.extended())
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/record/download/<project_id>/<record_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_record_download(project_id, record_id):
    logTraffic(API_URL, endpoint='/public/record/download/<project_id>/<record_id>')
    if fk.request.method == 'GET':
        record = RecordModel.objects.with_id(record_id)
        if record == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this record.')
        else:
            if str(record.project.id) != project_id:
                return api_response(401, 'Unauthorized access to this record', 'This record is not part of the provided project.')
            else:
                prepared = storage_manager.prepare_record(record)
                if prepared[0] == None:
                    return api_response(404, 'Request suggested an empty response', 'Unable to retrieve a record to download.')
                else:
                    return fk.send_file(prepared[0], as_attachment=True, attachment_filename=prepared[1], mimetype='application/zip')
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/diffs', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_diffs():
    logTraffic(API_URL, endpoint='/public/diffs')
    if fk.request.method == 'GET':
        diffs = DiffModel.objects
        diffs_dict = {'total_diffs':len(diffs), 'diffs':[]}
        for diff in diffs:
            diffs_dict['diffs'].append(diff.extended())
        return api_response(200, 'Diffs list', diffs_dict)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/diff/show/<diff_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_diff_show(diff_id):
    logTraffic(API_URL, endpoint='/public/diff/show/<diff_id>')
    if fk.request.method == 'GET':
        diff = DiffModel.objects.with_id(diff_id)
        if diff == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this diff.')
        else:
            return api_response(200, 'Diff info', diff.extended())
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/files', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_files():
    logTraffic(API_URL, endpoint='/public/files')
    if fk.request.method == 'GET':
        files = FileModel.objects
        files_dict = {'total_files':len(files), 'files':[]}
        for _file in files:
            files_dict['files'].append(_file.extended())
        return api_response(200, 'Files list', files_dict)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/file/download/<file_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_file_download(file_id):
    logTraffic(API_URL, endpoint='/public/file/download/<file_id>')
    if fk.request.method == 'GET':
        file_meta = FileModel.objects.with_id(file_id)
        if file_meta == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this file.')
        else:
            file_obj = None
            if file_meta.location == 'remote':
                file_obj = storage_manager.web_get_file(file_meta.storage)
            elif file_meta.location == 'local':
                file_obj = storage_manager.storage_get_file(file_meta.group, file_meta.storage)

            if file_obj == None:
                return api_response(404, 'Request suggested an empty response', 'No content found for this file.')
            else:
                # return fk.send_file(
                #     file_obj,
                #     file_meta.mimetype,
                #     # as_attachment=True,
                #     attachment_filename=file_meta.name,
                # )
                if file_meta.group == 'logo' or file_meta.group == 'picture':
                    return fk.send_file(
                        file_obj,
                        file_meta.mimetype,
                        # as_attachment=True,
                        attachment_filename=file_meta.name,
                    )
                else:
                    if file_meta.name.split('.')[1] in ['jpg', 'pdf', 'txt']:
                        return fk.send_file(
                            file_obj,
                            file_meta.mimetype,
                            # as_attachment=True,
                            attachment_filename=file_meta.name,
                        )
                    else:
                        # Check the mimetype for media files to just provide them without attachment.
                        return fk.send_file(
                                file_obj,
                                file_meta.mimetype,
                                as_attachment=True,
                                attachment_filename=file_meta.name,
                            )

        if fk.request.data:
            data = json.loads(fk.request.data)
            encoding = data.get('developer', '')
            size = data.get('developer', 0)
            name = data.get('developer', '')
            path = data.get('developer', '')
            storage = data.get('developer', '')
            location = data.get('location', 'undefined')
            mimetype = data.get('developer', mimetypes.guess_type(location)[0])
            group = data.get('group', 'undefined')
            description = data.get('description', '')
            if storage == '' or name == '':
                return api_response(400, 'Missing mandatory fields', 'A file should have at least a name and a storage reference (s3 key or url).')
            else:
                _file, created = get_or_create(document=FileModel, encoding=encoding, name=name, mimetype=mimetype, size=size, path=path, storage=storage, location=location, group=group, description=description)
                if not created:
                    return api_response(200, 'File already exists', _file.info())
                else:
                    return api_response(201, 'File created', _file.info())
        else:
            return api_response(204, 'Nothing created', 'You must provide the file information.')
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/file/show/<file_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_file_show(file_id):
    logTraffic(API_URL, endpoint='/public/file/show/<file_id>')
    if fk.request.method == 'GET':
        _file = FileModel.objects.with_id(file_id)
        if _file == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this file.')
        else:
            return api_response(200, 'File %s'%_file.name, _file.extended())
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/messages', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_messages():
    logTraffic(API_URL, endpoint='/public/messages')
    if fk.request.method == 'GET':
        messages = MessageModel.objects
        messages_dict = {'total_messages':len(messages), 'messages':[]}
        for message in messages:
            messages_dict['messages'].append(message.extended())
        return api_response(200, 'Messages list', messages_dict)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/message/show/<message_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_message_show(message_id):
    logTraffic(API_URL, endpoint='/public/message/show/<message_id>')
    if fk.request.method == 'GET':
        message = MessageModel.objects.with_id(message_id)
        if message == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this message.')
        else:
            return api_response(200, 'Message %s'%str(message.id), message.extended())
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/search/<key_words>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_search(key_words):
    logTraffic(API_URL, endpoint='/public/search/<key_words>')
    if fk.request.method == 'GET':
        results = {'results':{}, 'total-results':0}
        results['results']['users'] = {'users-list':[], 'users-total':0}
        results['results']['apps'] = {'apps-list':[], 'apps-total':0}
        results['results']['projects'] = {'projects-list':[], 'projects-total':0}
        results['results']['records'] = {'records-list':[], 'records-total':0}
        results['results']['envs'] = {'envs-list':[], 'envs-total':0}
        results['results']['bundles'] = {'bundles-list':[], 'bundles-total':0}
        results['results']['files'] = {'files-list':[], 'files-total':0}
        results['results']['versions'] = {'versions-list':[], 'versions-total':0}

        words = key_words.split('-')

        for user in UserModel.objects:
            exists = [False for word in words]
            condition = [True for word in words]
            profile = ProfileModel.objects(user=user).first()
            index = 0
            for word in words:
                if word != '':
                    if profile != None:
                        try:
                            if word.lower() in user.email.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in profile.fname.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in profile.lname.lower():
                                exists[index] = True
                        except:
                            pass
                else:
                    exists[index] = True
                index += 1
            if exists == condition:
                results['results']['users']['users-list'].append({'user':user.info(), 'profile':profile.info()})
            results['results']['users']['users-total'] = len(results['results']['users']['users-list'])

        for app in ApplicationModel.objects:
            exists = [False for word in words]
            condition = [True for word in words]
            index = 0
            for word in words:
                if word != '':
                    try:
                        if word.lower() in app.possible_access.lower():
                            exists[index] = True
                    except:
                        pass
                    try:
                        if word.lower() in app.network.lower():
                            exists[index] = True
                    except:
                        pass
                    try:
                        if word.lower() in app.storage.lower():
                            exists[index] = True
                    except:
                        pass
                    try:
                        if word.lower() in app.about.lower():
                            exists[index] = True
                    except:
                        pass
                    try:
                        if word.lower() in app.name.lower():
                            exists[index] = True
                    except:
                        pass
                else:
                    exists[index] = True
                index += 1
            if exists == condition:
                results['results']['apps']['apps-list'].append(app.info())
            results['results']['apps']['apps-total'] = len(results['results']['apps']['apps-list'])

        for project in ProjectModel.objects:
            if project.access == "public":
                exists = [False for word in words]
                condition = [True for word in words]
                index = 0
                for word in words:
                    if word != '':
                        try:
                            if word.lower() in project.name.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in project.description.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in project.goals.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in str(project.tags).lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in project.access.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in project.group.lower():
                                exists[index] = True
                        except:
                            pass

                    else:
                        exists[index] = True
                    index += 1
                if exists == condition:
                    results['results']['projects']['projects-list'].append(project.info())
                results['results']['projects']['projects-total'] = len(results['results']['projects']['projects-list'])

        for record in RecordModel.objects:
            if record.access == "public":
                exists = [False for word in words]
                condition = [True for word in words]
                index = 0
                for word in words:
                    if word != '':
                        try:
                            if word.lower() in record.label.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in str(record.tags).lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in str(record.system).lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in str(record.execution).lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in str(record.preparation).lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in str(record.inputs).lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in str(record.outputs).lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in str(record.dependencies).lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in record.status.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in record.access.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in str(record.rationels).lower():
                                exists[index] = True
                        except:
                            pass
                    else:
                        exists[index] = True
                    index += 1
                if exists == condition:
                    results['results']['records']['records-list'].append(record.info())
                results['results']['records']['records-total'] = len(results['results']['records']['records-list'])

        for env in EnvironmentModel.objects:
            exists = [False for word in words]
            condition = [True for word in words]
            index = 0
            for word in words:
                if word != '':
                    try:
                        if word.lower() in env.group.lower():
                            exists[index] = True
                    except:
                        pass
                    try:
                        if word.lower() in env.system.lower():
                            exists[index] = True
                    except:
                        pass
                    try:
                        if word.lower() in str(env.specifics).lower():
                            exists[index] = True
                    except:
                        pass
                else:
                    exists[index] = True
                index += 1
            if exists == condition:
                results['results']['envs']['envs-list'].append(env.info())
            results['results']['envs']['envs-total'] = len(results['results']['envs']['envs-list'])

        for bundle in BundleModel.objects:
            exists = [False for word in words]
            condition = [True for word in words]
            index = 0
            for word in words:
                if word != '':
                    try:
                        if word.lower() in bundle.scope.lower():
                            exists[index] = True
                    except:
                        pass
                    try:
                        if word.lower() in bundle.location.lower():
                            exists[index] = True
                    except:
                        pass
                    try:
                        if word.lower() in bundle.mimetype.lower():
                            exists[index] = True
                    except:
                        pass
                else:
                    exists[index] = True
                index += 1
            if exists == condition:
                results['results']['bundles']['bundles-list'].append(bundle.info())
            results['results']['bundles']['bundles-total'] = len(results['results']['bundles']['bundles-list'])

        for file_ in FileModel.objects:
            if file_.owner == None:
                exists = [False for word in words]
                condition = [True for word in words]
                index = 0
                for word in words:
                    if word != '':
                        try:
                            if word.lower() in file_.mimetype.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in file_.name.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in file_.path.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in file_.storage.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in file_.location.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in file_.group.lower():
                                exists[index] = True
                        except:
                            pass
                        try:
                            if word.lower() in file_.description.lower():
                                exists[index] = True
                        except:
                            pass
                    else:
                        exists[index] = True
                    index += 1
                if exists == condition:
                    results['results']['files']['files-list'].append(file_.info())
                results['results']['files']['files-total'] = len(results['results']['files']['files-list'])

        for version in VersionModel.objects:
            exists = [False for word in words]
            condition = [True for word in words]
            index = 0
            for word in words:
                if word != '':
                    try:
                        if word.lower() in version.system.lower():
                            exists[index] = True
                    except:
                        pass
                    try:
                        if word.lower() in version.baseline.lower():
                            exists[index] = True
                    except:
                        pass
                    try:
                        if word.lower() in version.marker.lower():
                            exists[index] = True
                    except:
                        pass
                else:
                    exists[index] = True
                index += 1
            if exists == condition:
                results['results']['versions']['versions-list'].append(version.info())
            results['results']['versions']['versions-total'] = len(results['results']['versions']['versions-list'])

        results['total-results'] += results['results']['users']['users-total']
        results['total-results'] += results['results']['apps']['apps-total']
        results['total-results'] += results['results']['projects']['projects-total']
        results['total-results'] += results['results']['records']['records-total']
        results['total-results'] += results['results']['envs']['envs-total']
        results['total-results'] += results['results']['bundles']['bundles-total']
        results['total-results'] += results['results']['files']['files-total']
        results['total-results'] += results['results']['versions']['versions-total']

        return api_response(200, 'Search results for: [%s]'%key_words, results)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/app/search/<app_name>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_app_search(app_name):
    if fk.request.method == 'GET':
        apps = ApplicationModel.objects(name__icontains=app_name)
        apps_dict = {'total_apps':0, 'apps':[]}
        for application in apps:
            if application.developer == current_user:
                apps_dict['apps'].append(application.info())
            else:
                # Only visible apps from other researchers can be searched for.
                if application.visibile:
                    apps_dict['apps'].append(application.info())
        apps_dict['total_apps'] = len(apps_dict['apps'])
        return api_response(200, 'Search results for application with name: %s'%app_name, apps_dict)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/apps/<user_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_user_apps(user_id):
    current_user = UserModel.objects.with_id(user_id)
    if current_user is not None:
        if current_user.group == "developer":
            if fk.request.method == 'GET':
                apps = ApplicationModel.objects(developer=current_user)
                apps_json = {'total_apps':len(apps), 'apps':[]}
                for application in apps:
                    apps_json['apps'].append(application.extended())
                return api_response(200, 'Developer\'s applications', apps_json)
            else:
                return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')
        else:
            return api_response(404, 'Request suggested an empty response', 'This user is not allowed to create applications.')
    else:
        return api_response(404, 'Request suggested an empty response', 'Unable to find this user.')

@app.route(API_URL + '/public/apps', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_apps():
    if fk.request.method == 'GET':
        apps = ApplicationModel.objects
        apps_json = {'total_apps':len(apps), 'apps':[]}
        for application in apps:
            apps_json['apps'].append(application.extended())
        return api_response(200, 'Applications', apps_json)
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

@app.route(API_URL + '/public/resolve/<item_id>', methods=['GET','POST','PUT','UPDATE','DELETE','POST'])
@crossdomain(fk=fk, app=app, origin='*')
def public_resolve_item(item_id):
    logTraffic(API_URL, endpoint='/public/resolve/<item_id>')
    if fk.request.method == 'GET':
        resolution = {'class':'', 'endpoints':[]}
        if item_id == 'root':
            resolution['type'] = 'Public'
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['users', '--us'], 'endpoint':'/public/users'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['projects', '--pr'], 'endpoint':'/public/projects'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['files', '--fi'], 'endpoint':'/public/files'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['diffs', '--di'], 'endpoint':'/public/diffs'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['apps', '--ap'], 'endpoint':'/public/apps'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['token', '--tk'], 'endpoint':'/private/<credential.api_token>/<credential.app_token>/*'})
            resolution['endpoints'].append({'methods':['POST'], 'struct':{'email':'<credential.email>', 'password':'<credential.password>'}, 'meta':['login', '--lg'], 'endpoint':'/public/user/login'})
            return api_response(200, 'Public default resolution result', resolution)
        item = UserModel.objects.with_id(item_id)
        if item != None:
            resolution['type'] = 'User'
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['show', '--sh'], 'endpoint':'/public/user/show/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['picture', '--pc'], 'endpoint':'/public/user/picture/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['profile', '--pf'], 'endpoint':'/public/user/profile/show/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['projects', '--pj'], 'endpoint':'/public/user/projects/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['apps', '--ap'], 'endpoint':'/public/user/apps/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['token', '--tk'], 'endpoint':'/private/<credential.api_token>/<credential.app_token>/*'})
            resolution['endpoints'].append({'methods':['POST'], 'struct':{'email':'<credential.email>', 'password':'<credential.password>'}, 'meta':['login', '--lg'], 'endpoint':'/public/user/login'})
            return api_response(200, 'Item %s resolution results'%item_id, resolution)

        item = MessageModel.objects.with_id(item_id)
        if item != None:
            return api_response(404, 'Message items cannot be resolved in public', 'Please load your account API token.')

        item = CommentModel.objects.with_id(item_id)
        if item != None:
            resolution['type'] = 'Comment'
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['show', '--sh'], 'endpoint':'/public/comment/show/<selected.id>'})
            return api_response(200, 'Item %s resolution results'%item_id, resolution)

        item = ProjectModel.objects.with_id(item_id)
        if item != None:
            resolution['type'] = 'Project'
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['show', '--sh'], 'endpoint':'/public/project/show/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['history', '--hi'], 'endpoint':'/public/project/history/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['comments', '--co'], 'endpoint':'/public/project/comments/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['records', '--re'], 'endpoint':'/public/project/records/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['files', '--fi'], 'endpoint':'/public/project/files/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['download', '--do'], 'endpoint':'/public/project/download/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['logo', '--lo'], 'endpoint':'/public/project/logo/<selected.id>'})
            return api_response(200, 'Item %s resolution results'%item_id, resolution)

        item = RecordModel.objects.with_id(item_id)
        if item != None:
            resolution['type'] = 'Record'
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['show', '--sh'], 'endpoint':'/public/record/show/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['env', '--en'], 'endpoint':'/public/record/env/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['comments', '--co'], 'endpoint':'/public/record/comments/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['diffs', '--di'], 'endpoint':'/public/record/diffs/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['files', '--fi'], 'endpoint':'/public/record/files/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['download', '--do'], 'endpoint':'/public/record/download/<selected.id>'})
            return api_response(200, 'Item %s resolution results'%item_id, resolution)

        item = EnvironmentModel.objects.with_id(item_id)
        if item != None:
            resolution['type'] = 'Environment'
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['show', '--sh'], 'endpoint':'/public/env/show/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['download', '--do'], 'endpoint':'/public/env/download/<selected.id>'})
            return api_response(200, 'Item %s resolution results'%item_id, resolution)

        item = DiffModel.objects.with_id(item_id)
        if item != None:
            resolution['type'] = 'Diff'
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['show', '--sh'], 'endpoint':'/public/diff/show/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['comments', '--co'], 'endpoint':'/public/diff/comments/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['files', '--fi'], 'endpoint':'/public/diff/files/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['download', '--do'], 'endpoint':'/public/diff/download/<selected.id>'})
            return api_response(200, 'Item %s resolution results'%item_id, resolution)

        item = FileModel.objects.with_id(item_id)
        if item != None:
            resolution['type'] = 'File'
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['show', '--sh'], 'endpoint':'/public/file/show/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['download', '--do'], 'endpoint':'/public/file/download/<selected.id>'})
            return api_response(200, 'Item %s resolution results'%item_id, resolution)

        item = ApplicationModel.objects.with_id(item_id)
        if item != None:
            resolution['type'] = 'Application'
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['show', '--sh'], 'endpoint':'/public/app/show/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['search', '--se'], 'endpoint':'/public/app/search/<query>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['connectivity', '--co'], 'endpoint':'/public/app/connectivity/<selected.id>'})
            resolution['endpoints'].append({'methods':['GET','POST','PUT','UPDATE','DELETE','POST'], 'struct':{}, 'meta':['logo', '--lo'], 'endpoint':'/public/app/logo/<selected.id>'})
            return api_response(200, 'Item %s resolution results'%item_id, resolution)

        if item == None:
            return api_response(404, 'Request suggested an empty response', 'Unable to find this diff.')
    else:
        return api_response(405, 'Method not allowed', 'This endpoint supports only a GET method.')

redpajama_set_name: RedPajamaGithub


NVT is used to create professional rack layout diagrams and can export the bill of materials to an XLSX file for costing. V4.0 also includes 3D drawings of Nexans products for use in schematics or presentations. The Visio libraries of intelligent drawing shapes cover LANmark, LANsense, EMAC and now LANactive ranges. This useful support tool enables system designers, installers and integrators to create professional rack layout drawings and cabling schematics quickly and efficiently; thereby offering their customers much more comprehensive and professional documentation for Nexans solutions.
Centech Draw is a drawing program that is used to draw / design all kinds of panels, wall mounted and floor standing. It is based on switchgear supplied by FinelComp and the vast majority of board components Cenika stocks can be found in Centech Draw.


text:
@interface UIViewController (AMPAdditions)

- (BOOL)isRootViewController;

@end


text:
Mount Sopris Instrument Company
By Eric Peterson | Aug 04, 2015
Energy & Enviro Industrial & Equipment Colorado
Underground Detection Products
www.mountsopris.com
President Thom Mandl is bringing a Lean approach to the longtime maker of geophysical probes, winches, software, and other tools for seeing underground.
The history of Mount Sopris Instrument Company reads like a good novel, with lots of twists and turns.
After CSU grad student Fred Fowler started the company to make scintillation counters for Colorado's uranium industry on the Western Slope, it merged with a manufacturer that made respirators in the 1960s before going into making geophysical equipment borehole drillers. The company was acquired, moved to California, then moved back to the Front Range. In recent years, software has become an increasingly important product, and is often developed and marketed in tandem with Advanced Logic Technology in Luxembourg.
Uranium is still a part of the business, says Mandl, and Mount Sopris also supplies systems to groundwater, mining, geotechnical, environmental, energy, and research entities -- in other words, anyone who needs an accurate reading on what's going on below ground. The company's probes detect everything from gamma radiation to gas and water flows to magnetism, and they can even can sample fluid and record 3D images for posterity.
Mining, traditionally a stalwart market for Mount Sopris, is a bit off in 2015, but groundwater is the biggest, and growing strong, Mandl says. "That's a big market for us" -- about 60 percent of sales.
The customer base is worldwide: Mount Sopris ships to 120 countries and exports account for about two-thirds of all sales. "The business comes from all over the world," says Mandl.
Productivity is a focal point of late, and Mandl, whose C.V. lists stints at Procter & Gamble and Ford, joined the company in early 2014 to help implement a new approach. Mandl took over for owner John Stowell with a directive to "make the business smarter and make the business healthier."
Mandl says the company hit a bit of a wall in recent years, but is "starting to get traction" for sustained growth. "We have two Lean projects going on," he says. As of last year, the projects have been funded by a grant from Manufacturer's Edge. "It's great to see people embracing Lean and other new business processes. . . . The impact of Lean is going to have a dramatic impact on delivery, quality, and cost. It's going to serve the company very well."
Mount Sopris makes a good number of its printed circuit boards in-house and has a "modest" machine shop with two CNC milling machines and a lathe. "We manufacturer all of our products here and we source about 95 percent locally," says Mandl. "We're revamping our supply chain and bringing it up to best in class."
Challenges: The cyclical nature of mineral resource exploration is one. Another is "decreasing time to market," says Mandl. "Our goal is to grow by getting better at delivery of our products."
Opportunities: "Market share growth through more targeted sales strategies, new product introductions, and potential M&A," says Mandl. "We've started to look at potential acquisitions."
There's a reason for that. "We are fortunate not to be cash-strapped," he adds. "That's not the case here."
Needs: Operational excellence. Our current rallying cry is this: Lean transformation and implementation of best-in-class supply chain management practices," says Mandl.
He also cites the need for a more effective sales network. Mount Sopris has an industry-high 60 reps, but only 20 percent are active and many are retiring. "We're setting the bar much higher in terms of what is required to be a sales rep."
Connect with Mount Sopris Instrument Company on SCoP
Similar Industry
Humless
Aerospace & Electronics Built Environment Consumer & Lifestyle Energy & Enviro Utah
By Eric Peterson | Jan 06, 2021
Alphaeus Manufacturing
Aerospace & Electronics Consumer & Lifestyle Industrial & Equipment Supply Chain Utah
Quick Drive
Consumer & Lifestyle Industrial & Equipment Supply Chain Colorado
Editor's Picks: Top 10 Colorado Manufacturer Profiles for 2020
Aerospace & Electronics Brewing & Distilling Built Environment Consumer & Lifestyle Energy & Enviro Food & Beverage Industrial & Equipment Supply Chain Colorado
By Eric Peterson | Dec 08, 2020
Editor's Choice: Top 5 Utah Manufacturer Profiles for 2020
Aerospace & Electronics Brewing & Distilling Consumer & Lifestyle Industrial & Equipment Supply Chain Utah
Inside the Tesla supply chain: Hale Foote and Scandic
Aerospace & Electronics Bioscience & Medical Industrial & Equipment California
By Bart Taylor | Oct 11, 2020

redpajama_set_name: RedPajamaCommonCrawl


My Antarctica adventure is just a little over a month away, and I am looking very much forward to it. So todays image is another on from the high Arctic , at Svalbard, where I shot this image of a glacier at the East Coast of the main island, Spitsbergen. Looking forward to shooting images of Antarctic icebergs later this year.


text:
Ludwig A. Pongratz (* 1948 in Eiserfeld) ist ein deutscher Pädagoge. Er war von 1992 bis 2009 Professor für Allgemeine Pädagogik und Erwachsenenbildung an der Technischen Universität Darmstadt.

Leben
Ludwig A. Pongratz promovierte 1976 mit einer Dissertation zum Thema "Zur Kritik kybernetischer Methodologie in der Pädagogik" (Frankfurt/ Main u. a. 1978). Nach Referendariat und wissenschaftlicher Assistententätigkeit habilitierte er sich 1984 mit der Schrift "Bildung und Subjektivität. Historisch-systematische Studien zur Theorie der Bildung" (Weinheim 1986) an der Rheinisch-Westfälischen Technischen Hochschule Aachen. 1992 wurde er auf eine Professur für Allgemeine Pädagogik und Erwachsenenbildung an der Technischen Universität Darmstadt berufen, die er bis 2009 innehatte.

Pongratz ist Vater von vier Kindern, zwei davon, Tobias und Daniel, sind als Hip-Hopper unter den Namen Panik Panzer und Danger Dan als Mitglieder der Formation Antilopen Gang bekannt.

Forschungsschwerpunkte
Die Forschungsschwerpunkte von Ludwig A. Pongratz liegen im Feld der Erziehungs- und Bildungstheorie, der historischen und systematischen Pädagogik, der pädagogischen Methodologie sowie der Erwachsenen- und Weiterbildung. Ludwig A. Pongratz vertritt eine Kritische Bildungstheorie, die sowohl das Erbe der frühen Kritischen Theorie (vor allem Theodor W. Adornos) aufgreift wie auch an die bildungstheoretischen Entwürfen von Heinz-Joachim Heydorn und Gernot Koneffke anknüpft. Ludwig A. Pongratz gehört zudem zu den ersten deutschen Erziehungswissenschaftlern, die die Bedeutung der Diskurs- und Machtanalytik Michel Foucaults für die pädagogische Theoriegeschichte, Bildungsphilosophie und pädagogischen Methodologie aufzeigten.
Seit Ende der 1990er Jahre positioniert sich Ludwig A. Pongratz als profilierter Kritiker systemtheoretisch-konstruktivistischer Ansätze in der Pädagogik ("Untiefen im Mainstream", Paderborn 2009) sowie als Kritiker der neoliberal ausgerichteten Bildungsreform seit der Jahrtausendwende ("Das Bermuda-Dreieck der Bildung: Bologna – Lissabon – Berlin", Paderborn 2009; Sackgassen der Bildung. Pädagogik anders denken, Paderborn 2010).

Zahlreiche seiner Publikationen sind inzwischen frei zugänglich über die Technische Universität Darmstadt.

Funktionen
Ludwig A. Pongratz hatte zahlreiche Funktionen innerhalb und außerhalb der Hochschule inne: Er war Geschäftsführender Direktor des Instituts für Allgemeine Pädagogik und Berufspädagogik der TU Darmstadt, Dekan des Fachbereichs Humanwissenschaften der TU Darmstadt, Sprecher der Kommission Bildungs- und Erziehungsphilosophie und Vorstandsmitglied der Sektion Allgemeine Erziehungswissenschaft der DGfE (Deutsche Gesellschaft für Erziehungswissenschaft). 1985 hat er die Internationale Erich-Fromm-Gesellschaft mitbegründet. Darüber hinaus arbeitet Ludwig A. Pongratz seit 2007 als selbstständiger Supervisor (DGSv) und Coach mit eigener Praxis in Aachen.

Weblinks
 Liste der Publikationen
 http://www.ludwig-pongratz.de
 http://www.supervision-ludwig-pongratz.de

Einzelnachweise

Pädagoge
Hochschullehrer (Technische Universität Darmstadt)
Person (Aachen)
Deutscher
Geboren 1948
Mann

redpajama_set_name: RedPajamaWikipedia


A stunning necklace, handmade with gemstone beads, adorned with a delicate silver feather. With metallic silver tones, this stylish accessory will compliment any outfit, adding a touch of femininity to your look, whilst the sophisticated silver haematite beads make this necklace extremely versatile. Measures 34-52cm.


B Daddy and Pops took the Squirt up to Michigan for a long weekend of Mackinaw City fudge, expeditions on the Adventure IV and family time at the cabin with this view.
Last night I celebrated my single status by watching back to back episodes of Restaurant Impossible (there is seriously NO TV on during the summer months) and going to bed at 10:30. Tonight I'm upping the ante by having some girlfriends over after the kids are in bed and on Saturday I'm hosting a sleepover with my favorite 16 and 17 year old girls on the planet. So excited.
What are you up to this weekend?!
*Can some Michigander PLEASE explain Mackinaw/Mackinac to me? I'm utterly confused as to which is correct or if both are correct?


The process of accounting requires appropriate professionalism to conduct, and accounting professionals are commonly referred to as accountants. The field of accounting is large and is divided into different branches. Auditing is involved with verifying an institution financial books and statements. A business owners may find it overwhelming to carry out all transactions by themselves or with stuff. Some guidelines are important when selecting the perfect accounting agency.
One of the factors to consider when selecting the best accounting agency is the credibility of the agency. Before picking an accounting firm, enough research should be made of the certification of the firm. An accountant should be qualified according to the regulation set by the regulatory bodies. The credibility of an accounting agency also depends on standards of accounting in a particular region, country or state. The credibility of the agency enables the clients to have the confidence of the firm enabling them to fully disclose information to the agency. When dealing with a certified firm an individual can put the agency into account in cases of dissatisfaction with services rendered. An accountant should have gone through all required institutions and got the right training.
Secondly, when choosing an accountant, one should consider their experience. When looking for an accounting agency the reputation of the agency is very important. The history of the accounting firms gives a client a sneak view of the kind of services given by the accounting firm. If an accounting firm has a good history on customer care and service delivery the likeness of offering standard quality is very high.
Thirdly another factor to consider when choosing an accountant is their type of specialization. An accounting firm may have some specialities available and fail to have others. When picking an accountant a client should ensure that the accountant picked specializes in the type of accounting in question. Different firms specialize in different types of accounting thus a client should choose on the firm that others the specialities to get professional help hence satisfactory results.
When selecting an accounting agency one should check on the cost of hiring the agency. The cost of hiring a firm should be fair and within the clients' financial ability. An accounting firm should make sure to clearly state its charges and available premiums to their clients for them to clearly understand the terms and conditions. An accounting firm should offer favourable premiums to potential clients to improve their competitive ability to other firms offering the same services. Comparison of accountants enables a client to settle for the best qualified and affordable accountant. A client should give the relevant information to the agency for them to work efficiently.


text:
require 'QuantLib'
include QuantLib

SwaptionVols = [ # maturity,          length,             volatility
                 [Period.new(1, Years), Period.new(5, Years), 0.1148],
                 [Period.new(2, Years), Period.new(4, Years), 0.1108],
                 [Period.new(3, Years), Period.new(3, Years), 0.1070],
                 [Period.new(4, Years), Period.new(2, Years), 0.1021],
                 [Period.new(5, Years), Period.new(1, Years), 0.1000] ]

def formatVol(v, digits = 2)
  format = "%.#{digits}f %%"
  return sprintf(format, v*100)
end

def formatPrice(p, digits = 2)
  format = "%.#{digits}f"
  return sprintf(format, p)
end

def calibrate(model, helpers, l, name)

  format = '%12s |%12s |%12s |%12s |%12s'
  header = sprintf(format,'maturity','length','volatility','implied','error')
  rule = '-' * header.length
  dblrule = '=' * header.length

  puts
  puts dblrule
  puts name
  puts rule

  method = Simplex.new(l);
  model.calibrate!(helpers, method, EndCriteria.new(1000,250,1e-7,1e-7,1e-7))

  puts "Parameters: #{model.params}"
  puts rule

  puts header
  puts rule

  totalError = 0.0
  n = helpers.length

  (0...n).each do |i|
    maturity, length, vol = SwaptionVols[i]
    npv = helpers[i].modelValue
    implied = helpers[i].impliedVolatility(npv, 1.0e-4, 1000, 0.05, 0.50)
    error = implied - vol
    totalError += error.abs
    puts sprintf(format, maturity, length,
                 formatVol(vol,4), formatVol(implied,4),
                 formatVol(error,4))
  end

  averageError = totalError/helpers.length

  puts rule
  format = "%#{header.length}s"
  puts sprintf(format, "Average error: #{formatVol(averageError,4)}")
  puts dblrule
end

todaysDate = Date.new(15,February,2002)
Settings.instance.evaluationDate = todaysDate
calendar = TARGET.new
settlementDate = Date.new(19,February,2002);

# flat yield term structure impling 1x5 swap at 5%
rate = QuoteHandle.new(SimpleQuote.new(0.04875825))
termStructure = YieldTermStructureHandle.new(
                      FlatForward.new(settlementDate,rate,Actual365Fixed.new))

# define the ATM/OTM/ITM swaps

swapEngine = DiscountingSwapEngine.new(termStructure)

fixedLegFrequency = Annual
fixedLegTenor = Period.new(1,Years)
fixedLegConvention = Unadjusted
floatingLegConvention = ModifiedFollowing
fixedLegDayCounter = Thirty360.new(Thirty360::European)
floatingLegFrequency = Semiannual
floatingLegTenor = Period.new(6,Months)

payFixed = VanillaSwap::Payer
fixingDays = 2
index = Euribor6M.new(termStructure)
floatingLegDayCounter = index.dayCounter

swapStart = calendar.advance(settlementDate,1,Years,floatingLegConvention)
swapEnd = calendar.advance(swapStart,5,Years,floatingLegConvention)

fixedSchedule = Schedule.new(swapStart, swapEnd,
                             fixedLegTenor, calendar,
                             fixedLegConvention, fixedLegConvention,
                             DateGeneration::Forward, false)
floatingSchedule = Schedule.new(swapStart, swapEnd,
                                floatingLegTenor, calendar,
                                floatingLegConvention, floatingLegConvention,
                                DateGeneration::Forward, false)

dummy = VanillaSwap.new(payFixed, 100.0,
                        fixedSchedule, 0.0, fixedLegDayCounter,
                        floatingSchedule, index, 0.0,
                        floatingLegDayCounter)
dummy.pricingEngine = swapEngine
atmRate = dummy.fairRate

atmSwap = VanillaSwap.new(payFixed, 1000.0,
                          fixedSchedule, atmRate, fixedLegDayCounter,
                          floatingSchedule, index, 0.0,
                          floatingLegDayCounter)
otmSwap = VanillaSwap.new(payFixed, 1000.0,
                          fixedSchedule, atmRate*1.2, fixedLegDayCounter,
                          floatingSchedule, index, 0.0,
                          floatingLegDayCounter)
itmSwap = VanillaSwap.new(payFixed, 1000.0,
                          fixedSchedule, atmRate*0.8, fixedLegDayCounter,
                          floatingSchedule, index, 0.0,
                          floatingLegDayCounter)
atmSwap.pricingEngine = swapEngine
itmSwap.pricingEngine = swapEngine
otmSwap.pricingEngine = swapEngine

helpers = SwaptionVols.map { |maturity, length, vol|
  SwaptionHelper.new(maturity, length,
                     QuoteHandle.new(SimpleQuote.new(vol)),
                     index, index.tenor, index.dayCounter,
                     index.dayCounter, termStructure)
}

times = []
helpers.each { |h|
  times = times + h.times
}
times.sort!.uniq!

grid = TimeGrid.new(times, 30)

G2model = G2.new(termStructure)
HWmodel = HullWhite.new(termStructure)
HWmodel2 = HullWhite.new(termStructure)
BKmodel = BlackKarasinski.new(termStructure)

puts "Calibrating..."

helpers.each { |h|
  h.pricingEngine = G2SwaptionEngine.new(G2model,6.0,16)
}
calibrate(G2model, helpers, 0.05, "G2 (analytic formulae)")

helpers.each { |h|
  h.pricingEngine = JamshidianSwaptionEngine.new(HWmodel)
}
calibrate(HWmodel, helpers, 0.05, "Hull-White (analytic formulae)")

helpers.each { |h|
  h.pricingEngine = TreeSwaptionEngine.new(HWmodel2,grid)
}
calibrate(HWmodel2, helpers, 0.05, "Hull-White (numerical calibration)")

helpers.each { |h|
  h.pricingEngine = TreeSwaptionEngine.new(BKmodel,grid)
}
calibrate(BKmodel, helpers, 0.05, "Black-Karasinski (numerical calibration)")

# price Bermudan swaptions on defined swaps

bermudanDates = fixedSchedule.map { |d| d }
exercise = BermudanExercise.new(bermudanDates[0...-1])

format = '%17s |%17s |%17s |%17s'
header = sprintf(format,'model','in-the-money',
                 'at-the-money','out-of-the-money')
rule = '-' * header.length
dblrule = '=' * header.length

puts
puts dblrule
puts 'Pricing Bermudan swaptions...'
puts rule
puts header
puts rule

atmSwaption = Swaption.new(atmSwap, exercise)
otmSwaption = Swaption.new(otmSwap, exercise)
itmSwaption = Swaption.new(itmSwap, exercise)

atmSwaption.pricingEngine = TreeSwaptionEngine.new(G2model, 50)
otmSwaption.pricingEngine = TreeSwaptionEngine.new(G2model, 50)
itmSwaption.pricingEngine = TreeSwaptionEngine.new(G2model, 50)

puts sprintf(format,'G2 analytic', formatPrice(itmSwaption.NPV),
             formatPrice(atmSwaption.NPV), formatPrice(otmSwaption.NPV))

atmSwaption.pricingEngine = TreeSwaptionEngine.new(HWmodel, 50)
otmSwaption.pricingEngine = TreeSwaptionEngine.new(HWmodel, 50)
itmSwaption.pricingEngine = TreeSwaptionEngine.new(HWmodel, 50)

puts sprintf(format,'HW analytic', formatPrice(itmSwaption.NPV),
             formatPrice(atmSwaption.NPV), formatPrice(otmSwaption.NPV))

atmSwaption.pricingEngine = TreeSwaptionEngine.new(HWmodel2, 50)
otmSwaption.pricingEngine = TreeSwaptionEngine.new(HWmodel2, 50)
itmSwaption.pricingEngine = TreeSwaptionEngine.new(HWmodel2, 50)

puts sprintf(format,'HW numerical', formatPrice(itmSwaption.NPV),
             formatPrice(atmSwaption.NPV), formatPrice(otmSwaption.NPV))

atmSwaption.pricingEngine = TreeSwaptionEngine.new(BKmodel, 50)
otmSwaption.pricingEngine = TreeSwaptionEngine.new(BKmodel, 50)
itmSwaption.pricingEngine = TreeSwaptionEngine.new(BKmodel, 50)

puts sprintf(format,'BK numerical', formatPrice(itmSwaption.NPV),
             formatPrice(atmSwaption.NPV), formatPrice(otmSwaption.NPV))

puts dblrule


While it's always safer to get professional help for a medical condition than to self-treat, there are some remedies seniors can use at home to improve their discomfort or to help reduce their risk of disease. With the help of adult children and caregivers, many of these home remedies can be found in the kitchen.
Kiwi is a fruit full of antioxidants, and it offers anti-aging properties to seniors. Kiwi is known to lower the risk of cancer, cardiovascular disease, dementia and other aging symptoms. It can also help regulate blood sugar levels, support bone and connective tissue health, boost the immune system, enhance lung health and improve digestion.
A common herb, providers of Alzheimer's care in Phoenix will be interested to know sage also has antioxidant properties that research shows improves the signs of Alzheimer's disease. It contains cholinesterase inhibitors that reduce how quickly acetylcholine, a neurotransmitter, is broken down. This improves the interconnectivity of different areas of the brain, improving memory and cognition, and the rosmarinic and carnosic acids in sage combat the pathological processes of Alzheimer's. Sage is also known to help in the prevention of diabetes, reduce anxiety, fight infections, reduce inflammation and prevent cardiovascular disease.
Believe it or not, garlic is a natural remedy for the common cold because its allicin component kills viruses and bacteria. Garlic is also an immune system booster and can fight inflammation and cancer. Research shows that it improves heart health, stimulates the liver and rids the body of toxins.
Most people know that ginger is a natural remedy for nausea, but many do not realize that it can reduce dizziness and the feeling of imbalance, which are common problems that seniors deal with. It can also improve discomfort in the gastrointestinal tract after eating high-fiber foods that cause gas. Additionally, ginger can help the body maintain normal blood circulation, prevent colon and ovarian cancers, reduce inflammation and pain, and prevent the cold and flu.
Phoenix caregivers and adult children who need a way to soothe the chafed and chapped skin of seniors can use olive oil. All they need to do is rub it on the affected area. The monounsaturated fats in olive oil can lower bad cholesterol levels, protecting seniors against atherosclerosis. Other benefits include cancer prevention, lower blood pressure and improved cognitive function.
According to research, the antioxidant lycopene that tomatoes contain can significantly reduce the risk of stroke and help prevent prostate and stomach cancers. Vitamin B and potassium in tomatoes also help lower high cholesterol and blood pressure. Tomatoes contain plenty of vitamins A and C, which support eye health and boost the immune system. Studies show that they are full of chromium, a mineral that helps control blood sugar levels in diabetics.
Home remedies are great in a pinch and perfect if your loved one prefers trying all-natural measures before taking medicine. You can also help your loved one maintain a high quality of life with an hourly or live-in caregiver who can run errands, grocery shop, cook healthy meals, encourage physical activity, and provide mental stimulation. To learn more, reach out to Phoenix home care provider, Home Care Assistance. We offer both hourly and live-in care plans, as well as specialized care for seniors with Alzheimer's, dementia, or Parkinson's. Call a Care Manager today at (602) 388-1985 to schedule your complimentary no-obligation consolation.


The great thing about improving a small kitchen is that a few aesthetic changes can make a big impact. This means that there's loads of opportunity to upgrade a small kitchen with a low budget.
To start, it helps to think of your fitted cabinets as the starting point for all the accents and accessories that serve to make a kitchen homely. So, come with us to explore a few of the options! Finally, we're not all about looks here at homify, so we'll also include a few little tips to help just make your small kitchen a nicer place to work in as well. Enjoy!
Kitchen appliances are now available in cool retro designs and super bright colours. These appliances are meant to be shown off - not tucked away in a drawer. So consider investing in a new toaster or kettle. Perhaps you might even draw attention to the brightly coloured new appliance with some matching kitchen towels as well.
If you don't like the tiles on your walls or just want to add a little more interactive pizzazz to the small kitchen - install a large blackboard. If you have a rental kitchen, it could even just be propped up against the offending wall. A kitchen blackboard could turn into a spot for inspirational quotes, notes on your favourite recipes or even a place for a little old-fashioned communication between the householders.
Many small kitchens come with industrial standard style light fittings. They are often ugly and installed for purely pragmatic reasons. But it's easy enough to replace these. Perhaps you could consider adding some hanging retro lights like this. Another easy option is to attach cheap strip-lights to the underside of your kitchen cabinets. These are surprisingly cheap to buy in major outlets and they can easily be removed if you are worried about damaging a rental home. For power, all you need are some battery powered lights or an electrical outlet close by.
Switch plates or light switches are easily the most frequently touched spots in the home and get grubby and scratched very, very quickly. They are also one of the most overlooked items in a room. You don't need an electrician to replace them and the bright new switches will add a clean feel to the room. If you have a little more to invest, consider something a step up from the standard white plastic cover. Perhaps something like these silver switch plates from British company Focus SB might suit.
If you have never changed kitchen cupboard doors yourself, the whole prospect may seem a little overwhelming. But in fact, this is one of the easiest ways to completely change a small kitchen on a relatively small budget. And if you want an even cheaper approach, simply change the door handles and knobs.
Finally, if you are considering changing the cupboard doors, remember that most base kitchen cabinets come in standard sizes. This means that large home suppliers are very likely to have an exact door to match. There's a good chance the actual door fixtures will just slot into place as well. All you need is a screwdriver! Perhaps you could even spruce up your kitchen with some awesome mirrored kitchen cabinets like this!
Small kitchens often have limited countertop space. But this can actually be of benefit if you hate the material or colour. Changing your kitchen countertop is definitely not a low-budget option. But in a small kitchen, it's often possible to cover up most of an ugly countertop with a huge gorgeous chopping board. If you have a rental kitchen, this would even be another way to ensure that the original benchtop remains undamaged. This might turn into a permanent fixture in the kitchen and a perpetual solution!
Now there's nothing so annoying as a cluttered cupboard, so why not invest in some cheap drawer organisers like these by DesignStudio Speziell? If you are accustomed to rummaging through storage cabinets, a fresh and organised cupboard with everything easily at hand will make a radical difference. On the same note, look at refreshing or adding some drawer liners. They are available online these days in lovely, retro designs.
There are a huge amount of ugly dish racks marring otherwise perfectly lovely kitchens. So if you are a bit ho-hum about your dish take, look at investing in something a little more snazzy. If you love the one pictured here, it comes to us courtesy of Simple Human. But there are lots of other great options for wall mounted or even hanging dish racks that collect the water and free up precious bench space. Perhaps you might even find something to highlight some new colour accents in the room.
Fregadero de acero inoxidable bajo encimera de Corian.
We have all seen films in which a perplexed husband wrestled with a plumbing disaster in the kitchen—but don't fear! It's not actually that hard to replace a tap or faucet on your own. These can be bought relatively cheaply if you really hunt around online. The kitchen sink is a central hub in any kitchen, so this is one area to invest in.
Almost every kitchen could do with more storage. This is particularly true in small kitchens. Look again at all the hidden nooks and crannies in the kitchen and consider where you might install some cheap hooks or hanging baskets. Fine, aluminium storage items can look quite minimalist and chic in the right kitchen. If you have a rental kitchen, there are plenty of temporary options with suction cups that can be easily attached to the walls.
Finally, don't forget about houseplants! These are relatively cheap and will look fabulous hanging from the ceiling or placed on an open shelf.
If you are looking for more clever ways to improve a small home, you'll love How to Create Space in a Tiny Bathroom.
What do you think of theses low-budget kitchen ideas? Let us know if you have any tips for our readers!


One of the most renowned card magicians of all time, Richard Turner astounds audiences around the world with his legendary sleight of hand. What they may not even realize--and what makes his achievements all the more amazing--is that he is completely blind. Charting Turner's colorful life from his tumultuous childhood to the present, DEALT reveals how through determination and force of will, he overcame seemingly insurmountable obstacles to rise to the top of his profession. It's both a tantalizing, up-close look at the secretive world of magic and a candid, awe-inspiring portrait of a man who lives beyond his limitations.
"The card magician Richard Turner reveals that he has more than just a few tricks up his sleeve in Luke Korem's captivating documentary DEALT."
"It's well shot but never flashy, and it's well cut, making for a generally rounded film that disappears behind the larger than life personality at its core, a height few films manage to reach."
"He may have begun the years-long project to illustrate Turner's accomplishments, but Korem ended up with a richer profile of a perfectionist who realizes he still has things to learn."
"DEALT achieves the neat trick of giving its main subject a rewarding character arc."