Compare commits

..

No commits in common. "step3" and "api" have entirely different histories.
step3 ... api

14 changed files with 184 additions and 172 deletions

View File

@ -1,28 +1,21 @@
# app/main.py
# ---
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
from sqlalchemy.orm import Session
from app.database import SessionLocal, engine
from app import models, schemas
from typing import List, Optional
# ddfrom starlette.middleware.base import BaseHTTPMiddleware
# from starlette.responses import Response
# class CustomMIMEMiddleware(BaseHTTPMiddleware):
# async def dispatch(self, request, call_next):
# response = await call_next(request)
# if request.url.path.endswith('.vue'):
# response.headers['Content-Type'] = 'application/javascript'
# return response
from app.database import SessionLocal
from app.models import PassportData
from fastapi.staticfiles import StaticFiles
from typing import List, Optional
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
models.Base.metadata.create_all(bind=engine)
# Dependency to get DB session
def get_db():
db = SessionLocal()
try:
@ -30,18 +23,24 @@ def get_db():
finally:
db.close()
@app.post("/passport/", response_model=schemas.PassportData)
def create_passport_data(passport_data: schemas.PassportDataCreate, db: Session = Depends(get_db)):
db_passport_data = models.PassportData(**passport_data.dict())
db.add(db_passport_data)
class PassportDataRequest(BaseModel):
number: str
name: str
surname: str
gender: str
@app.post("/passport_data/")
def create_passport_data(request: PassportDataRequest, db: Session = Depends(get_db)):
db_passport = PassportData(number=request.number, name=request.name, surname=request.surname, gender=request.gender)
db.add(db_passport)
db.commit()
db.refresh(db_passport_data)
return db_passport_data
db.refresh(db_passport)
return db_passport
@app.get("/passport/{passport_number}", response_model=schemas.PassportData)
@app.get("/passport_data/{passport_number}")
def read_passport_data(passport_number: str, db: Session = Depends(get_db)):
db_passport_data = db.query(models.PassportData).filter(models.PassportData.number == passport_number).first()
if db_passport_data is None:
db_passport = db.query(PassportData).filter(PassportData.number == passport_number).first()
if db_passport is None:
raise HTTPException(status_code=404, detail="Passport data not found")
return schemas.PassportData.from_orm(db_passport_data)
return db_passport

View File

@ -1,13 +1,13 @@
# app/models.py
from sqlalchemy import Column, Integer, String
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from app.database import Base
class PassportData(Base):
__tablename__ = 'passport_data'
id = Column(Integer, primary_key=True, autoincrement=True)
number = Column(String(255), unique=True, nullable=False)
name = Column(String(255), nullable=True)
surname = Column(String(255), nullable=True)
gender = Column(String(255), nullable=True)
fingerprint_url = Column(String(255), nullable=True) # New field for fingerprint image URL
photo_url = Column(String(255), nullable=True) # New field for photo image URL
name = Column(String(255), nullable=False)
surname = Column(String(255), nullable=False)
gender = Column(String(255), nullable=False)

View File

@ -1,21 +0,0 @@
# app/schemas.py
from pydantic import BaseModel
from typing import Optional
class PassportDataBase(BaseModel):
number: str
name: Optional[str] = None
surname: Optional[str] = None
gender: Optional[str] = None
fingerprint_url: Optional[str] = None
photo_url: Optional[str] = None
class PassportDataCreate(PassportDataBase):
pass
class PassportData(PassportDataBase):
id: int
class Config:
orm_mode = True # Poprawne przypisanie

View File

@ -1,76 +1,25 @@
# entrypoint.py
#%%
from app.database import engine, SessionLocal
from app.models import Base, PassportData
from app.database import engine
from app.models import Base
import argparse
import uvicorn
import os
#%%
def load_data_from_directory(directory_path: str, db_session):
files = os.listdir(directory_path)
passport_data = {}
for file in files:
file_parts = file.split('-')
if len(file_parts) != 2:
continue
passport_number = file_parts[0]
file_type = file_parts[1].split('.')[0]
if passport_number not in passport_data:
passport_data[passport_number] = {
"fingerprint_url": None,
"photo_url": None
}
file_path = os.path.join(directory_path, file)
if file_type == 'odcisk':
passport_data[passport_number]["fingerprint_url"] = file_path
elif file_type == 'zdjecie':
passport_data[passport_number]["photo_url"] = file_path
for number, data in passport_data.items():
passport_entry = PassportData(
number=number,
name=None,
surname=None,
gender=None,
fingerprint_url=data["fingerprint_url"],
photo_url=data["photo_url"]
)
db_session.add(passport_entry)
print (passport_entry)
db_session.commit()
#%%
def main(port, data_dir):
def main(port):
# Create the database
print("Creating database tables...")
Base.metadata.create_all(bind=engine)
print("Database tables created.")
db_session = SessionLocal()
try:
print(f"Loading data from directory: {data_dir}")
load_data_from_directory(data_dir, db_session)
print("Data loaded into database.")
finally:
db_session.close()
# uvicorn.run("app.main:app", host="0.0.0.0", port=port, reload=True)
#%% main(9999,"data")
#%%
# Run the FastAPI app using uvicorn
# uvicorn.run("app.main:app", host="0.0.0.0", port=port, reload=True)
if __name__ == "__main__":
# Create argument parser
parser = argparse.ArgumentParser(description="Run the FastAPI app")
# Add port argument, default is 9999
parser.add_argument("--port", type=int, default=9999, help="Port to run the FastAPI app on")
parser.add_argument("--data-dir", type=str, default="data", help="Directory containing passport data files")
# Parse arguments
args = parser.parse_args()
main(args.port, args.data_dir)
main(args.port)

View File

@ -1,11 +0,0 @@
curl -X POST "http://localhost:9999/passport/" \
-H "Content-Type: application/json" \
-d '{
"number": "444",
"name": null,
"surname": null,
"gender": null,
"fingerprint_url": "data/444-odcisk.jpg",
"photo_url": "data/444-zdjecie.jpg"
}'

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,16 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Passport Form App</title>
<link rel="stylesheet" href="./style.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Library Management</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app"></div>
<script src="./js/axios.min.js"></script>
<script type="module" src="./script.js"></script>
<header>Library Management</header>
<div class="container">
<aside class="sidebar">
<h2>Add Author</h2>
<form id="addAuthorForm">
<input type="text" id="authorName" placeholder="Author Name" required>
<button type="submit">Add Author</button>
</form>
<h2>Add Book</h2>
<form id="addBookForm">
<input type="text" id="bookTitle" placeholder="Book Title" required>
<select id="bookAuthorId">
<!-- Autorzy będą dodawani tutaj dynamicznie -->
</select>
<button type="submit">Add Book</button>
</form>
</aside>
<main class="content">
<h2>Authors</h2>
<ul id="authorsList"></ul>
<h2>Books</h2>
<ul id="booksList"></ul>
<button id="loadBooksWithAuthors">Load Books with Authors</button>
<ul id="booksWithAuthorsList"></ul>
</main>
</div>
<footer>2024 Library Management System</footer>
<script src="script.js"></script>
</body>
</html>

View File

@ -1,16 +1,69 @@
import { createApp } from './js/vue.esm-browser.js';
import PassportForm from './components/Tabs.js';
const BASE_URL = 'http://qstack.pl:1111'; // Zaktualizuj zgodnie z konfiguracją Twojego serwera
const App = {
name: 'App',
components: {
PassportForm
},
template: `
<div id="app">
<PassportForm />
</div>
`,
};
document.addEventListener('DOMContentLoaded', function() {
loadAuthors();
loadBooks();
});
document.getElementById('addAuthorForm').addEventListener('submit', function(e) {
e.preventDefault();
const authorName = document.getElementById('authorName').value;
fetch(`${BASE_URL}/authors/`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: authorName }),
})
.then(response => response.json())
.then(() => {
loadAuthors(); // Ponowne ładowanie listy autorów po dodaniu nowego autora
})
.catch(error => console.error('Error:', error));
});
document.getElementById('addBookForm').addEventListener('submit', function(e) {
e.preventDefault();
const bookTitle = document.getElementById('bookTitle').value;
const bookAuthorId = document.getElementById('bookAuthorId').value;
fetch(`${BASE_URL}/books/`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: bookTitle, author_id: parseInt(bookAuthorId, 10) }),
})
.then(response => response.json())
.then(() => {
loadBooks(); // Ponowne ładowanie listy książek po dodaniu nowej książki
})
.catch(error => console.error('Error:', error));
});
function loadAuthors() {
fetch(`${BASE_URL}/authors/`)
.then(response => response.json())
.then(data => {
const authorsSelect = document.getElementById('bookAuthorId');
authorsSelect.innerHTML = '<option value="">Select an Author</option>'; // Dodaj domyślną opcję
data.forEach(author => {
const option = document.createElement('option');
option.value = author.id;
option.textContent = author.name;
authorsSelect.appendChild(option);
});
})
.catch(error => console.error('Error:', error));
}
function loadBooks() {
fetch(`${BASE_URL}/books/`)
.then(response => response.json())
.then(data => {
const booksList = document.getElementById('booksList');
booksList.innerHTML = '';
data.forEach(book => {
const listItem = document.createElement('li');
listItem.textContent = `${book.title} - Author ID: ${book.author_id}`;
booksList.appendChild(listItem);
});
})
.catch(error => console.error('Error:', error));
}
createApp(App).mount('#app');

View File

@ -1,24 +1,43 @@
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
body, html {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
header, footer {
background-color: #333;
color: #fff;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
nav {
margin-bottom: 20px;
}
button {
padding: 10px 20px;
margin: 5px;
padding: 1rem 0;
}
.container {
display: flex;
min-height: calc(100vh - 100px); /* Adjust based on header/footer height */
}
.sidebar {
width: 30%;
padding: 20px;
background-color: #f4f4f4;
}
.content {
flex-grow: 1;
padding: 20px;
}
form > * {
display: block;
margin-bottom: 10px;
}
button {
cursor: pointer;
}
button.active {
background-color: #2c3e50;
color: white;
}
}
ul {
list-style-type: none;
padding-left: 0;
}