Skip to content

Commit 8d9f27c

Browse files
authored
Merge pull request #12 from moevm/minor_fixes_november
Minor fixes
2 parents 8250c00 + 8a85dab commit 8d9f27c

File tree

15 files changed

+283
-109
lines changed

15 files changed

+283
-109
lines changed

backend/src/main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import routes
44

55
app = Flask(__name__)
6-
CORS(app)
6+
CORS(app, support_credentials=True)
77

88
app.add_url_rule('/', methods=['POST'], view_func=routes.clear_tmp)
99
app.add_url_rule('/add_art', methods=['POST'], view_func=routes.add_art)
@@ -13,6 +13,8 @@
1313
app.add_url_rule('/get_materials', methods=['GET'], view_func=routes.get_materials)
1414
app.add_url_rule('/get_genres', methods=['GET'], view_func=routes.get_genres)
1515
app.add_url_rule('/get_museums', methods=['GET'], view_func=routes.get_museums)
16+
app.add_url_rule('/get_types', methods=['GET'], view_func=routes.get_types)
17+
app.add_url_rule('/recreate_table', methods=['GET'], view_func=routes.recreate_table)
1618

1719
if __name__ == '__main__':
1820
app.run(debug=True, host="0.0.0.0")

backend/src/routes.py

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
from flask import request
21
from cachelib import MemcachedCache
3-
2+
from flask import request
43
from sqlalchemy import create_engine
54

65
db_name = 'testdb'
@@ -34,21 +33,20 @@
3433
materials varchar(200),
3534
type varchar(100),
3635
museum_name varchar(200),
37-
museum_address varchar(200),
3836
genre varchar(100),
3937
url varchar(10000)
4038
);
4139
"""
4240

4341
ADD_PICTURE = """
44-
INSERT INTO ArtWorks (name, author,
45-
description, start_year,
46-
end_year, materials,
42+
INSERT INTO ArtWorks (name, author,
43+
description, start_year,
44+
end_year, materials,
4745
type, museum_name,
48-
museum_address, genre, url)
49-
VALUES (%s, %s, %s, %s,
50-
%s, %s, %s, %s,
51-
%s, %s, %s)
46+
genre, url)
47+
VALUES (%s, %s, %s, %s,
48+
%s, %s, %s, %s,
49+
%s, %s)
5250
RETURNING artworkid;
5351
"""
5452

@@ -83,6 +81,14 @@ def get_museums():
8381
return museums_list
8482

8583

84+
def get_types():
85+
res = db.execute("""SELECT DISTINCT(type) FROM ArtWorks""")
86+
museums_list = []
87+
for i in res:
88+
museums_list.append(dict(i)['type'])
89+
return museums_list
90+
91+
8692
def add_art():
8793
data = request.get_json()
8894
# adding into postgres
@@ -91,8 +97,7 @@ def add_art():
9197
data['description'], data['start_year'],
9298
data['end_year'], data['materials'],
9399
data['type'], data['museum_name'],
94-
data['museum_address'], data['genre'],
95-
data['url']))
100+
data['genre'], data['url']))
96101

97102
res = db.execute("""SELECT * FROM ArtWorks""")
98103
for i in res:
@@ -117,8 +122,7 @@ def reimport_arts():
117122
data['description'], data['start_year'],
118123
data['end_year'], data['materials'],
119124
data['type'], data['museum_name'],
120-
data['museum_address'], data['genre'],
121-
data['url']))
125+
data['genre'], data['url']))
122126
key = str(key.all()[0][0])
123127
cache.set(key, data)
124128
print("Value is written into memcached by key: {}".format(key))
@@ -134,37 +138,49 @@ def get_arts():
134138
return json
135139

136140

141+
def is_number_correct(requested_number):
142+
if not requested_number:
143+
return False
144+
try:
145+
return int(requested_number) > 0
146+
except ValueError:
147+
return False
148+
149+
150+
def string_or_any(requested_string):
151+
if not requested_string:
152+
return "%%"
153+
return requested_string
154+
155+
137156
def get_arts_by_filter():
138157
requestJson = request.get_json()
139-
140-
titleFilter = requestJson['title']
141-
authorFilter = requestJson['author']
142-
startYearFilter = requestJson['start_year']
143-
endYearFilter = requestJson['end_year']
144-
museumFilter = requestJson['museum_name']
145-
genreFilter = requestJson['genre']
146-
materialFilter = requestJson['material']
147-
res = []
158+
print("by filter: ", requestJson)
159+
titleFilter = string_or_any(requestJson['title'])
160+
authorFilter = string_or_any(requestJson['author'])
161+
museumFilter = string_or_any(requestJson['museum_name'])
162+
genreFilter = string_or_any(requestJson['genre'])
163+
materialFilter = string_or_any(requestJson['material'])
164+
typeFilter = string_or_any(requestJson['type'])
148165

149166
titleFilter = '%' + titleFilter + '%'
150-
151167
authorFilter = '%' + authorFilter + '%'
152168

153-
startYearFilter = '0001' if startYearFilter == '' else startYearFilter
154-
endYearFilter = '9999' if endYearFilter == '' else endYearFilter
169+
startYearFilter = requestJson['start_year'] if is_number_correct(requestJson['start_year']) else -1
170+
endYearFilter = requestJson['end_year'] if is_number_correct(requestJson['end_year']) else 3000
155171

156172
res = db.execute(
157-
158173
"""
159174
SELECT * FROM ArtWorks
160175
WHERE
161176
name LIKE %s
162177
AND author LIKE %s
163-
AND start_year > %s
164-
AND end_year < %s
165-
AND museum_name = %s
166-
AND genre = %s
167-
AND materials = %s
178+
AND start_year >= %s
179+
AND end_year <= %s
180+
AND museum_name LIKE %s
181+
AND genre LIKE %s
182+
AND materials LIKE %s
183+
AND type LIKE %s
168184
""",
169185
(
170186
titleFilter,
@@ -173,7 +189,8 @@ def get_arts_by_filter():
173189
endYearFilter,
174190
museumFilter,
175191
genreFilter,
176-
materialFilter
192+
materialFilter,
193+
typeFilter
177194
)
178195
)
179196

@@ -187,3 +204,4 @@ def recreate_table(): # it's not used but it useful when you need to change tab
187204
db.execute(DROP_TABLE)
188205
db.execute(CREATE_TABLE)
189206
cache.clear()
207+
return ''

catalog_100.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

catalog_1000.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

database/create_fixtures.sql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ CREATE TABLE IF NOT EXISTS ArtWorks (
88
materials varchar(200),
99
type varchar(100),
1010
museum_name varchar(200),
11-
museum_address varchar(200),
1211
genre varchar(100),
1312
url varchar(10000)
1413
);

frontend/Dockerfile

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
FROM node:12-alpine as build
2-
WORKDIR /frontend
3-
COPY package.json /app/package.json
4-
RUN npm install --only=prod
5-
RUN npm install -g serve
6-
CMD serve -s build
7-
COPY . /frontend
1+
FROM node:13.12.0-alpine
2+
WORKDIR /app
3+
ENV PATH /app/node_modules/.bin:$PATH
4+
COPY package.json ./
5+
RUN npm install --silent
6+
RUN npm install react-scripts@3.4.1 -g --silent
7+
COPY . ./
88
EXPOSE 3000

frontend/src/App/App.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@
7979
width: 80%;
8080
height: 100%;
8181
flex-grow: 0;
82-
border: 2px solid black;
83-
border-radius: 10px;
82+
/*border: 2px solid black;*/
83+
/*border-radius: 10px;*/
8484
}
8585

8686
.leftSide {

frontend/src/App/App.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,20 @@ import UpdaterComp from '../components/UpdaterComp';
77
import TableComp from '../components/TableComp';
88
import {Box, Button} from '@mui/material';
99
import FilterComp from '../components/FilterComp';
10-
import {API_GET_ARTS, API_GET_MATERIALS, API_GET_GENRES, API_GET_MUSEUMS} from "../constants";
10+
import {
11+
API_GET_ARTS,
12+
API_GET_MATERIALS,
13+
API_GET_GENRES,
14+
API_GET_MUSEUMS,
15+
NOT_CHOSEN_LABEL,
16+
API_GET_TYPES
17+
} from "../constants";
1118
import AddArtworkForm from "../components/AddArtworkForm";
1219
import Axios from "axios";
1320
import {saveAs} from 'file-saver'
1421

22+
const defaultFilterValue = {value: "0", label: NOT_CHOSEN_LABEL};
23+
1524
function App() {
1625

1726
const [displayEditor, setDisplay] = React.useState(true);
@@ -22,12 +31,14 @@ function App() {
2231
const [museums, setMuseums] = React.useState([]);
2332
const [genres, setGenres] = React.useState([]);
2433
const [materials, setMaterials] = React.useState([]);
34+
const [types, setTypes] = React.useState([]);
2535

2636
useEffect(() => {
2737
UpdateData()
2838
getMaterials();
2939
getGenres();
3040
getMuseums();
41+
getTypes();
3142
}, [])
3243

3344
function DisplayEditor() {
@@ -58,7 +69,7 @@ function App() {
5869
function onExport() {
5970
try {
6071
Axios.get(API_GET_ARTS).then(r => {
61-
let blob = new Blob([JSON.stringify(r.data)], {type: 'application/json'})
72+
let blob = new Blob([JSON.stringify(data)], {type: 'application/json'})
6273
saveAs(blob, 'exported_data.json')
6374
});
6475
} catch (e) {
@@ -83,30 +94,41 @@ function App() {
8394
}
8495
}
8596

97+
const getTypes = async () => {
98+
const response = await Axios.get(API_GET_TYPES)
99+
console.log('types', response.data);
100+
const list = response.data.map((value, index) => ({value: `${index+1}`, label: value}));
101+
setTypes([defaultFilterValue].concat(list));
102+
};
103+
86104
const getMaterials = async () => {
87105
const response = await Axios.get(API_GET_MATERIALS)
88106
console.log('materials', response.data);
89-
setMaterials(response.data.map((value, index) => ({value: `${index}`, label: value})));
107+
const list = response.data.map((value, index) => ({value: `${index+1}`, label: value}));
108+
setMaterials([defaultFilterValue].concat(list));
90109
};
91110

92111
const getGenres = async () => {
93112
const response = await Axios.get(API_GET_GENRES)
94113
console.log('genres', response.data);
95-
setGenres(response.data.map((value, index) => ({value: `${index}`, label: value})));
114+
const list = response.data.map((value, index) => ({value: `${index+1}`, label: value}));
115+
setGenres([defaultFilterValue].concat(list));
96116
};
97117

98118
const getMuseums = async () => {
99119
const response = await Axios.get(API_GET_MUSEUMS)
100120
console.log('museums', response.data);
101-
setMuseums(response.data.map((value, index) => ({value: `${index}`, label: value})));
121+
const list = response.data.map((value, index) => ({value: `${index+1}`, label: value}));
122+
setMuseums([defaultFilterValue].concat(list));
102123
};
103124

104125
return (
105126
<div>
106127
<AppBarComp changeView={EditorDisplayChange} updateData={UpdateData} editor={displayEditor}/>
107128
<div className='mainContainer'>
108129
<div className='leftSide'>
109-
<FilterComp setData={setData} museums={museums} genres={genres} materials={materials}
130+
<FilterComp setData={setData} museums={museums} genres={genres}
131+
types={types} materials={materials}
110132
getAllData={UpdateData}/>
111133
<DisplayEditor updateMaterialsSelect={getMaterials} updateGenresSelect={getGenres}
112134
updateMuseumsSelect={getMuseums}/>

frontend/src/components/AppBarComp.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,15 @@ export default class AppBarComp extends PureComponent {
5959
</IconButton>
6060
<Typography variant='h6' className='title' align='left'>Paintings</Typography>
6161
<Box mr={3}>
62-
<Button color='inherit' variant='outlined' align='right' component="label">Import
62+
{this.props.editor
63+
? <Button color='inherit' variant='outlined' align='right' component="label">Import
6364
<input
64-
type="file"
65-
hidden
66-
onChange={this.onFileChange}
65+
type="file"
66+
hidden
67+
onChange={this.onFileChange}
6768
/></Button>
69+
: <div/>
70+
}
6871
</Box>
6972
<Box mr={3}>
7073
{this.props.editor
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import {
2+
Dialog,
3+
DialogContent,
4+
DialogActions,
5+
Button,
6+
TextareaAutosize
7+
} from '@mui/material';
8+
import React, {PureComponent} from 'react';
9+
import '../App/App.css';
10+
11+
export default class DescriptionViewer extends PureComponent {
12+
constructor(props) {
13+
super(props)
14+
15+
this.state = {
16+
description: ''
17+
}
18+
}
19+
20+
21+
render() {
22+
return (
23+
<Dialog open={this.props.is_open} onClose={this.props.func}>
24+
<DialogContent sx={{width: '25vw', height: '25vh'}}>
25+
<TextareaAutosize
26+
style={{width:550, height:300}}
27+
autoFocus={true}
28+
defaultValue={this.props.dataToPass}
29+
label={'Description'}
30+
id='Description'
31+
fullWidth={true}
32+
readOnly/>
33+
</DialogContent>
34+
</Dialog>
35+
);
36+
}
37+
}

0 commit comments

Comments
 (0)