Source code for problem_views

"""Module contains routes, used for problem table."""
import json
import hashlib
import time
import os
import PIL


from flask import request, jsonify, Response
from flask_login import current_user
from PIL import Image

from ecomap import validator
from ecomap.app import app, logger, auto
from ecomap.db import util as db


@app.route('/api/problems')
[docs]def problems(): """Handler for sending short data about all problem stored in db. Used by Google Map instance. :rtype: JSON :return: - If problems list not empty: ``[{"status": "Unsolved", "problem_type_Id": 2, "title": "problem 1","longitude": 25.9717, "date": 1450735578, "latitude": 50.2893, "problem_id": 75}, {"status": "Unsolved", "problem_type_Id": 3, "title": "problem 2", "longitude": 24.7852, "date": 1450738061, "latitude": 49.205, "problem_id": 76}]`` - If problem list is empty: ``{}`` :statuscode 200: no errors """ problem_tuple = db.get_all_problems() parsed_json = [] if problem_tuple: for problem in problem_tuple: parsed_json.append({ 'problem_id': problem[0], 'title': problem[1], 'latitude': problem[2], 'longitude': problem[3], 'problem_type_Id': problem[4], 'status': problem[5], 'date': problem[6]}) return Response(json.dumps(parsed_json), mimetype='application/json')
@app.route('/api/problem_detailed_info/<int:problem_id>', methods=['GET']) def detailed_problem(problem_id): """This method returns object with detailed problem data. :rtype: JSON :param problem_id: `{problem_id: 82}` :return: - If problem exists: ``[[{"content": "Text with situation", "status": "Unsolved", "date": 1450954447, "severity": "1", "title": "problem", "latitude": 52.7762, "proposal": "proposal how to solve", "problem_type_id": 3, "problem_id": 82, "longitude": 34.2114}], [{"activity_type": "Added", "user_id": 5, "problem_id": 82, "created_date": 1450954447}], [{"url": "/uploads/problems/82/0d0d3ef56a16bd069e.png", "user_id": 5, "description": "description to photo"}], [{"user_id": 5, "name": "User", "problem_id": 82, "content": "Comment", "created_date": 1450954929000, "id": 5}]]`` - If problem not exists: ``{"message": " resource not exists"}`` :statuscode 404: problem not exists :statuscode 200: problem displayed """ problem_data = db.get_problem_by_id(problem_id) activities_data = db.get_activity_by_problem_id(problem_id) photos_data = db.get_problem_photos(problem_id) comments_data = db.get_comments_by_problem_id(problem_id) photos = [] activities = {} comments = [] if problem_data: problems = { 'problem_id': problem_data[0], 'title': problem_data[1], 'content': problem_data[2], 'proposal': problem_data[3], 'severity': problem_data[4], 'status': problem_data[5], 'latitude': problem_data[6], 'longitude': problem_data[7], 'problem_type_id': problem_data[8], 'date': problem_data[9]} else: return jsonify({'message': ' resource not exists'}), 404 if activities_data: activities = { 'created_date': activities_data[0], 'problem_id': activities_data[1], 'user_id': activities_data[2], 'activity_type': activities_data[3]} if photos_data: for photo_data in photos_data: photos.append({'url': photo_data[0], 'description': photo_data[1], 'user_id': photo_data[2]}) if comments_data: for comment in comments_data: comments.append({'id': comment[0], 'content': comment[1], 'problem_id': comment[2], 'created_date': comment[3] * 1000, 'user_id': comment[4], 'name': '%s %s' % (comment[5], comment[6])}) response = Response(json.dumps([[problems], [activities], photos, comments]), mimetype='application/json') return response @app.route('/api/problem_post', methods=['POST']) def post_problem(): """Function which adds data about created problem into DB. :content-type: multipart/form-data :fparam title: Title of problem ('problem with rivers') :fparam type: id of problem type (2) :fparam lat: lat coordinates (49.8256101) :fparam longitude: lon coordinates (24.0600542) :fparam content: description of problem ('some text') :fparam proposal: proposition for solving problem ('text') :rtype: JSON :return: - If request data is invalid: ``{'status': False, 'error': [list of errors]}`` - If all ok: ``{"added_problem": "problem title", "problem_id": 83}`` :statuscode 400: request is invalid :statuscode 200: problem was successfully posted """ if request.method == 'POST' and request.form: data = request.form logger.warning(json.dumps(request.form)) logger.info(data) valid = validator.problem_post(data) if valid['status']: logger.debug('Checks problem post validation. %s', valid) user_id = current_user.uid posted_date = int(time.time()) last_id = db.problem_post(data['title'], data['content'], data['proposal'], data['latitude'], data['longitude'], data['type'], posted_date, user_id) if last_id: db.problem_activity_post(last_id, posted_date, user_id, 'Added') logger.debug('New problem post was created with id %s', last_id) response = jsonify(added_problem=data['title'], problem_id=last_id) else: response = Response(json.dumps(valid), mimetype='application/json'), 400 return response @app.route('/api/usersProblem/<int:user_id>', methods=['GET']) def get_user_problems(user_id): """This method retrieves all user's problem from db and shows it in user profile page on `my problems` tab. :rtype: JSON :param user_id: id of user (int) :return: - If user has problems: ``[{"id": 190,"title": "name", "latitude": 51.419765, "longitude": 29.520264, "problem_type_id": 1, "status": 0, "date": "2015-02-24T14:27:22.000Z", "severity": '3', "is_enabled": 1 },{...}]`` - If user haven't: ``{}`` :statuscode 200: no errors """ problems_list = [] problem_tuple = db.get_user_problems(user_id) logger.info(problem_tuple) for problem in problem_tuple: problems_list.append({'id': problem[0], 'title': problem[1], 'latitude': problem[2], 'logitude': problem[3], 'problem_type_id': problem[4], 'status': problem[5], 'date': problem[6] * 1000, 'severity': problem[8], 'is_enabled': problem[7]}) return Response(json.dumps(problems_list), mimetype='application/json') @app.route('/api/all_usersProblem', methods=['GET']) def get_all_users_problems(): """This method retrieves all user's problem from db. :query limit: limit number. default is 5 :query offset: offset number. default is 0 :rtype: JSON :return: list of user's problem represented with next objects: ``[{"id": 190, "title": "name", "latitude": 51.419765, "longitude": 29.520264, "problem_type_id": 1, "status": 0, "date": "2015-02-24T14:27:22.000Z", "severity": '3', "is_enabled": 1},...]`` """ offset = request.args.get('offset') or 0 per_page = request.args.get('per_page') or 5 count = db.count_problems() total_count = {} problems_list = [] problem_tuple = db.get_all_users_problems(offset, per_page) if problem_tuple: for problem in problem_tuple: problems_list.append({'id': problem[0], 'title': problem[1], 'latitude': problem[2], 'longitude': problem[3], 'problem_type_id': problem[4], 'status': problem[5], 'date': problem[6] * 1000, 'severity': problem[8], 'is_enabled': problem[7]}) if count: total_count = {'total_problem_count': count[0]} return Response(json.dumps([problems_list, [total_count]]), mimetype='application/json') @app.route('/api/photo/<int:problem_id>', methods=['POST']) def problem_photo(problem_id): """Controller for handling adding problem photos. **param** problem_id - id of problem instance for uploading new photos. :content-type: multipart/form-data :fparam file: image file in base64. Content-Type: image/png :fparam name: image name (`'image.jpg'`) :fparam description: description of image (`'some text'`) :return: json object with success message or message with error status. - if success: ``{"added_file": "/uploads/problems/77/df4c22114eb24442e8b6.png"}`` :statuscode 400: error with attaching image or request is invalid :statuscode 200: successfully added """ response = jsonify(), 400 extension = '.png' static_url = '/uploads/problems/%s/' % problem_id f_path = os.environ['STATICROOT'] + static_url user_id = current_user.uid now = time.time()*100000 unique_key = (int(now)+user_id) hashed_name = hashlib.md5(str(unique_key)) f_name = '%s%s' % (hashed_name.hexdigest(), extension) if request.method == 'POST': problem_img = request.files['file'] photo_descr = request.form['description'] if problem_img and validator.validate_image_file(problem_img): if not os.path.exists(f_path): os.makedirs(os.path.dirname('%s%s' % (f_path, f_name))) problem_img.save(os.path.join(f_path, f_name)) img_path = '%s%s' % (static_url, f_name) basewidth = 100 img = Image.open(os.path.join(f_path, f_name)) wpercent = (basewidth/float(img.size[0])) hsize = int((float(img.size[1])*float(wpercent))) img = img.resize((basewidth, hsize), PIL.Image.ANTIALIAS) f_name = '%s%s%s' % (hashed_name.hexdigest(), '.min', extension) img.save(os.path.join(f_path, f_name)) db.add_problem_photo(problem_id, img_path, photo_descr, user_id) response = json.dumps({'added_file': img_path}) else: response = jsonify(error='error with import file'), 400 return response @app.route('/api/problem/add_comment', methods=['POST']) def post_comment(): """Adds new comment to problem. :rtype: JSON :request args: `{content: "comment", problem_id: "77"}` :return: - if success: ``{"message": "Comment successfully added."}`` - if some error: ``{error: "type of validation error"}`` :statuscode 400: error with adding comment or request is invalid :statuscode 200: successfully added """ data = request.get_json() valid = validator.check_post_comment(data) if valid['status']: created_date = int(time.time()) db.add_comment(current_user.uid, data['problem_id'], data['content'], created_date) db.problem_activity_post(data['problem_id'], created_date, current_user.uid, 'Updated') response = jsonify(message='Comment successfully added.'), 200 else: response = Response(json.dumps(valid), mimetype='application/json'), 400 return response @app.route('/api/problem_comments/<int:problem_id>', methods=['GET']) def get_comments(problem_id): """Return all problem comments :rtype: JSON :param problem_id: id of problem (int) :return: - If problem has comments: ``[{content: "some comment", created_date: 1451001050000, id: 29, name: "user name", problem_id: 77, user_id: 6, },{...}]`` - If user hasn't: ``{}`` :statuscode 200: no errors """ comments_data = db.get_comments_by_problem_id(problem_id) comments = [] if comments_data: for comment in comments_data: comments.append({'id': comment[0], 'content': comment[1], 'problem_id': comment[2], 'created_date': comment[3] * 1000, 'user_id': comment[4], 'name': '%s %s' % (comment[5], comment[6])}) response = Response(json.dumps(comments), mimetype='application/json') return response