diff --git a/DataBase/mongoDB.py b/DataBase/mongoDB.py index 1c794be960f8066261232216803a596ad07f0c79..ef437fce2c84554924a3b4a118cacd9010c77783 100644 --- a/DataBase/mongoDB.py +++ b/DataBase/mongoDB.py @@ -98,9 +98,6 @@ def get_documents_json(opt, identifier): for item in data: item.pop("_id") file[typeName].append(item) - print("===============================================") - print(file) - print("===============================================") return json.dumps(file) diff --git a/RegularExpressionParser/Parser.py b/RegularExpressionParser/Parser.py index 8df3f22052aad5a29c6e2a70b00e058d37cbe8bc..abb8e0299e6d4df202b168f895786afb818146d0 100644 --- a/RegularExpressionParser/Parser.py +++ b/RegularExpressionParser/Parser.py @@ -77,6 +77,8 @@ def parse_query_to_json(pair): else: return {elements[0].split(".")[1]: {"$regex": elements[1], "$options": "i"}} else: + if len(elements[0].split(".")) != 2: + return {"wrong": "True"} if re.search(">", pair): return {elements[0].split(".")[1]: {"$gt": float(elements[1])}} elif re.search("<", pair): diff --git a/Server/SimpleServer.py b/Server/SimpleServer.py index fa1ed3b88b48e38e7471cdf704d0b2630e70189d..bdc8d5c4311128f608e822c19dab99d3071b5908 100644 --- a/Server/SimpleServer.py +++ b/Server/SimpleServer.py @@ -7,8 +7,10 @@ from flask import request from flask import abort from flask import jsonify from urllib.parse import urlparse, parse_qs +from flask_cors import CORS app = Flask(__name__) +cors = CORS(app) # app.config["DEBUG"] = True @@ -26,22 +28,33 @@ def data_base(collection): url_parsed = urlparse(request.url) qs_parsed = parse_qs(url_parsed.query) if qs_parsed == {}: - return jsonify(DataBase.get_documents_json(0, {})) - return jsonify(search_document(["book.id:" + qs_parsed["id"][0]])) + return DataBase.get_documents_json(0, {}) + result = search_document(["book.id:" + qs_parsed["id"][0]]) + if result == {"wrong": "True"}: + abort(400, "Bad Request") + else: + return result elif collection == "author": url_parsed = urlparse(request.url) qs_parsed = parse_qs(url_parsed.query) if qs_parsed == {}: - return jsonify(DataBase.get_documents_json(1, {})) - return jsonify(search_document(["author.id:" + qs_parsed["id"][0]])) + return DataBase.get_documents_json(1, {}) + result = search_document(["author.id:" + qs_parsed["id"][0]]) + if result == {"wrong": "True"}: + abort(400, "Bad Request") + else: + return result elif collection == "search": url_parsed = urlparse(request.url) query = Parser.parse_url_to_query(url_parsed.query) qs_parsed = query.replace("q=", "") result = search_document(qs_parsed.split("&")) - return result + if result == {"wrong": "True"}: + abort(400, "Bad Request") + else: + return result else: - abort(404) + abort(400, "Bad Request") elif request.method == "PUT": if request.headers["Content-Type"] != "application/json": abort(415) @@ -51,7 +64,7 @@ def data_base(collection): elif collection == "author": opt = 1 else: - abort(400) + abort(400, "Bad Request") DataBase.update_dicts(opt, request.args.to_dict(), json_update_info) return "200: PUT succeeded" elif request.method == "POST": @@ -74,7 +87,7 @@ def data_base(collection): Scrape.scrape_api(url, max_book, max_author) return "200: new data has been added to database" else: - abort(400) + abort(400, "Bad Request") return "200: POST succeeded" elif request.method == "DELETE": identifier = request.args.to_dict() @@ -93,6 +106,8 @@ def search_document(identifiers): """ function used to find one or several document in database """ if len(identifiers) == 1: json_idt = Parser.parse_query_to_json(identifiers[0]) + if json_idt == {"wrong": "True"}: + return {"wrong": "True"} print(json_idt) if re.search("^book.*", identifiers[0]): return DataBase.get_documents_json(0, json_idt) @@ -113,6 +128,8 @@ def search_document(identifiers): opt = 1 json_idt1 = Parser.parse_query_to_json(identifiers[0]) json_idt2 = Parser.parse_query_to_json(identifiers[2]) + if json_idt1 == {"wrong": "True"} or json_idt2 == {"wrong": "True"}: + return {"wrong": "True"} if identifiers[1] == "AND": exp = {"$and": [json_idt1, json_idt2]} elif identifiers[1] == "OR": @@ -124,7 +141,8 @@ def search_document(identifiers): print(exp) return DataBase.get_documents_json(opt, exp) else: - return "Error, unknown identifiers" + print("Error, unknown identifiers") + return {} if __name__ == "__main__": diff --git a/Tests/ServerTests.py b/Tests/ServerTests.py index f069b7c25f803a449c404f689d11d5e8726a5e8e..e0aff9964a5d8311bb3fb839a8da837c2c4aa6d7 100644 --- a/Tests/ServerTests.py +++ b/Tests/ServerTests.py @@ -38,13 +38,13 @@ class DataBaseTests(unittest.TestCase): url = "http://127.0.0.1:5000/api/book?id=12345678" res = requests.get(url) self.assertEqual(res.status_code, 200) - self.assertEqual(res.json(), "{'books': []}") + self.assertEqual(res.json(), {'books': []}) def test_invalid_get_wrong_collection_name(self): db.insert_document(self.test_data1, 0) url = "http://127.0.0.1:5000/api/bookssss?id=38746485" res = requests.get(url) - self.assertEqual(res.status_code, 404) + self.assertEqual(res.status_code, 400) def test_valid_put(self): db.insert_document(self.test_data1, 0) diff --git a/web/app/src/App.js b/web/app/src/App.js index de608ebc19b0643398dc3d0326d3709bc3053b1b..a219b6e09f23642beefb048c0ad1a46f6c31bcc9 100644 --- a/web/app/src/App.js +++ b/web/app/src/App.js @@ -25,59 +25,139 @@ //export default App; import React, { useState } from 'react'; -import FourButtons from './Components/FourButtons' +import FourButtons from './Components/FourButtons'; +import { Dialog } from 'react-overlay-pack'; +import CorrectSign from './material/sign_correct.png'; +import ErrorSign from './material/sign_error.png'; + function App() { const { useState } = React; const [queryStr, setQueryStr] = useState('') - const [jsonValue, setJsonValue] = useState('') + const [sign, setSign] = useState(CorrectSign) const [text, setText] = useState('This area shows the result of requests..') + const [formState, setFormState] = useState('hide') + const [dialogState, setDialogState] = useState(false) const axios = require('axios').default; + var center = {display: 'flex', justifyContent: 'center', alignItems: 'center'} + + function get() { + axios.get('http://127.0.0.1:5000/api/' + queryStr) + .then(function (response) { + // handle success + setSign(CorrectSign) + showDialog() + document.getElementById('dialog').value = response.status + ":\n" + response.statusText + document.getElementById('board').value = JSON.stringify(response.data) + }) + .catch(function (error) { + // handle error + setSign(ErrorSign) + showDialog() + document.getElementById('dialog').value = error + }) + } + function put() { + changeFormState() + } function mesg() { - alert('Hey!') + document.getElementById('board').value = 'Hello there!' + } + function changeFormState() { + if (formState === 'hide') { + setFormState('show') + } else { + setFormState('hide') + } + } + function showDialog() { + setDialogState(true) } return ( <div> + {dialogState === true && + <Dialog + show={dialogState} + onOutsideClick={() => setDialogState(false)}> + <div style={{marginTop:'20%'}}> + <div style={{ + marginLeft: '35%' + }}> + <img src={sign}/> + </div> + <div> + <textarea id='dialog' + readOnly={true} + rows="3" + cols="38" + style={{ + border:'2px solid silver', + backgroundColor: 'white', + fontSize: '200%', + margin: '50px' + }}> + {text} + </textarea> + </div> + </div> + </Dialog>} <form name='mainform'> - <h1> Welcome to the home page of GoodReads Crawler! </h1> - <h3> Please input your query string:</h3> - <input - id='queryString' - type='text' - placeholder='example: book?id=12345678' - size='40' - value={queryStr} - onChange={(e) => setQueryStr(e.target.value)} - /> - <h3> Please input your json parameters (only effective for POST and PUT):</h3> - <input - id='jsonValue' - type='text' - placeholder='example: {"rating_counr": 1000000}' - size='40' - value={jsonValue} - onChange={(e) => setJsonValue(e.target.value)} - /> + <h1 style={center}> + Welcome to the home page of GoodReads Crawler! </h1> + <h3 style={center}> Please input your query string:</h3> + <div style={center}> + <input + id='queryString' + type='text' + placeholder='example: book?id=12345678' + size='40' + value={queryStr} + onChange={(e) => setQueryStr(e.target.value)} + /> + </div> + <h3 style={center}> Please input your data for uploading (only effective for POST and PUT):</h3> + {formState === 'hide' && + <div style={center}> + <button style={{width:60}} onClick={changeFormState}> + book + </button> + <button style={{marginLeft:10, width:60}} onClick={changeFormState}> + author + </button> + </div>} + {formState === 'show' && + <form style={center}> + <table border="1" style="width:100%;"> + <tr> + <td>Cell 1</td> + <input/> + </tr> + <tr> + <td>Cell 3</td> + <input/> + </tr> + </table> + </form>} </form> - <div style={{marginTop:20}}> + <div style={{marginTop:20, display: 'flex', justifyContent: 'center', alignItems: 'center'}}> <FourButtons backColor='blue' borderColor='RoyalBlue' leftMargin={0} text='GET' - func={mesg} /> + func={get} /> <FourButtons backColor='black' borderColor='gray' leftMargin={20} text='PUT' - func={mesg} /> + func={put} /> <FourButtons backColor='green' borderColor='seagreen' leftMargin={20} text='POST' - func={mesg} /> + func={showDialog} /> <FourButtons backColor='red' borderColor='indianred' @@ -85,7 +165,7 @@ function App() { text='DELETE' func={mesg} /> </div> - <div style={{marginTop:20}}> + <div style={{marginTop:20, display: 'flex', justifyContent: 'center', alignItems: 'center'}}> <textarea id="board" name="returnData" rows="6" cols="50" value={text} readOnly={true}> </textarea> </div> diff --git a/web/app/src/material/sign_correct.png b/web/app/src/material/sign_correct.png new file mode 100644 index 0000000000000000000000000000000000000000..f4c62915fc0b2c590da99790c4369a3e73f75cfe Binary files /dev/null and b/web/app/src/material/sign_correct.png differ diff --git a/web/app/src/material/sign_error.png b/web/app/src/material/sign_error.png new file mode 100644 index 0000000000000000000000000000000000000000..52c8cb30694f970a86ed6baf14741e1a03183ca1 Binary files /dev/null and b/web/app/src/material/sign_error.png differ