瀏覽代碼

first commit

jared 2 年之前
當前提交
8b4e24bc84
共有 3 個文件被更改,包括 343 次插入0 次删除
  1. 0 0
      README.md
  2. 84 0
      main.py
  3. 259 0
      templates/index.html

+ 0 - 0
README.md


+ 84 - 0
main.py

@@ -0,0 +1,84 @@
+from fastapi import FastAPI, Form
+from fastapi import Depends, FastAPI, HTTPException, status, Request, Form, Cookie, Response, Header
+from fastapi.responses import HTMLResponse, RedirectResponse, JSONResponse
+from fastapi.templating import Jinja2Templates
+from fastapi.staticfiles import StaticFiles
+from pydantic import BaseModel
+
+import iCulture_semantic_search
+import iCulture_wordcloud
+import json
+import tqdm
+import uvicorn
+
+app = FastAPI()
+app.mount("/static", StaticFiles(directory="static"), name="static")
+templates = Jinja2Templates(directory="templates")
+
+# input model
+
+
+class Query(BaseModel):
+    query: str
+    top_k: int
+    similarity: float
+    start_date: str
+    end_date: str
+
+
+# output model
+
+
+class Semantic_search(BaseModel):
+    semantic_search: str
+
+
+class Tag_list(BaseModel):
+    tag_list: str
+
+
+class Wordcloud(BaseModel):
+    wordcloud: str
+
+
+@app.get("/", response_class=HTMLResponse)
+async def root(request: Request, response: Response):
+    return templates.TemplateResponse("index.html", {"request": request, "response": response})
+
+
+@app.post("/semantic_search", response_model=Semantic_search)
+async def semantic_search(query: Query):
+    print('-'*50,'\n')
+    print('【Request】')
+    print(query,'\n')
+    print('-'*50)
+    query = query.dict()
+    return Semantic_search(
+        semantic_search=json.dumps(
+            iCulture_semantic_search.search_event(query['query'], query['top_k'], query['similarity'], query['start_date'], query['end_date']))
+    )
+
+
+@app.post("/tag_list", response_model=Tag_list)
+async def tag_list(query: Query):
+    query = query.dict()
+    return Tag_list(
+        tag_list=json.dumps(
+            iCulture_semantic_search.search_event_for_tag_list(
+                query['query'], query['top_k'], query['similarity'], query['start_date'], query['end_date']
+            ))
+    )
+
+
+@app.post("/wordcloud", response_model=Wordcloud)
+async def wordcloud(query: Query):
+    query = query.dict()
+    return Wordcloud(
+        wordcloud=json.dumps(iCulture_wordcloud.to_wordcloud(
+            query['query'], query['top_k'], query['similarity'], query['start_date'], query['end_date']))
+    )
+
+
+# if __name__ == "__main__":
+#     print('123')
+#     uvicorn.run("setup:app", host="0.0.0.0", port=12345, reload=True)

+ 259 - 0
templates/index.html

@@ -0,0 +1,259 @@
+<!DOCTYPE html>
+<html lang="zh-TW">
+
+<head>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet"
+        integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
+
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
+    <script src="https://code.jquery.com/jquery-3.6.0.js"
+        integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
+
+    <link rel="stylesheet" href="https://cdn.datatables.net/1.11.0/css/dataTables.bootstrap5.min.css">
+    <script src="https://cdn.datatables.net/1.11.0/js/jquery.dataTables.min.js"></script>
+    <script src="https://cdn.datatables.net/1.11.0/js/dataTables.bootstrap5.min.js"></script>
+
+
+    <style>
+        @font-face {
+            font-family: my_font;
+            src: local("zh-cn.ttf") format("opentype");
+        }
+
+        *{
+            font-family: my_font;
+        }
+    </style>
+
+
+    <title>iCulture</title>
+
+</head>
+
+<body>
+
+    <div class="container">
+        <div class="p-5 mt-5">
+
+            <div class="mb-3">
+                <div for="search_query" class="form-label fw-bold">iCulture Semantic Search</div>
+                <hr>
+                <div class="row mb-3">
+
+                    <div class="col">
+                        <label for="start_date" class="form-label">Start Date</label>
+                        <input type="date" name="start_date" class="form-control col" id="start_date">
+                    </div>
+                    <div class="col">
+                        <label for="end_date" class="form-label">End Date</label>
+                        <input type="date" name="end_date" class="form-control col" id="end_date">
+                    </div>
+                </div>
+                <div class="row mb-3">
+                    <div class="col">
+                        <label for="top_k" class="form-label">Top K</label>
+                        <input type="number" name="top_k" class="form-control col" id="top_k"
+                            placeholder="default: 100">
+                    </div>
+                    <div class="col">
+                        <label for="similarity" class="form-label">Similarity</label>
+                        <input type="number" name="similarity" class="form-control col" id="similarity"
+                            placeholder="-1 - 1 (default: 0)">
+                    </div>
+                </div>
+                <label for="search_query" class="form-label">Search Query</label>
+                <div class="input-group mb-3">
+
+                    <input type="text" name="query" class="form-control" id="search_query"
+                        placeholder="Search query...">
+                    <button class="btn btn-outline-primary" type="button" id="search"><i
+                            class="fas fa-search"></i></button>
+                </div>
+            </div>
+        </div>
+        <div class="p-1 text-center" id="wordcloud">
+
+        </div>
+        <div class="p-5 about" id="tag_list">
+
+        </div>
+        <div class="p-5" id="results">
+
+        </div>
+    </div>
+
+
+
+    <!-- Optional JavaScript; choose one of the two! -->
+
+    <!-- Option 1: Bootstrap Bundle with Popper -->
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js"
+        integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj"
+        crossorigin="anonymous"></script>
+
+    <!-- Option 2: Separate Popper and Bootstrap JS -->
+
+    <!-- <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.3/dist/umd/popper.min.js"
+        integrity="sha384-eMNCOe7tC1doHpGoWe/6oMVemdAVTMs2xqW4mwXrXsW0L84Iytr2wi5v2QjrP/xp"
+        crossorigin="anonymous"></script>
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.min.js"
+        integrity="sha384-cn7l7gDp0eyniUwwAZgrzD06kc/tftFf19TOAs2zVinnD/C7E91j9yyk5//jjpt/"
+        crossorigin="anonymous"></script> -->
+
+</body>
+
+<script>
+    function semantic_search() {
+
+        if ($('#search_query').val() != '') {
+
+            $('#tag_list').empty()
+            $('#wordcloud').empty()
+            $('#results').empty()
+
+            $('#wordcloud').append(`
+            <div class="spinner-border text-primary" role="status">
+                <span class="visually-hidden">Loading...</span>
+            </div>`)
+
+            top_k = parseInt($("#top_k").val())
+            if (isNaN(top_k)) {
+                top_k = 100
+            }
+
+            similarity = parseFloat($("#similarity").val())
+            if (isNaN(similarity)) {
+                similarity = 0.0
+            }
+
+            data = {
+                "query": $("#search_query").val(),
+                "top_k": top_k,
+                "similarity": similarity,
+                "start_date": $("#start_date").val(),
+                "end_date": $("#end_date").val()
+            }
+            data = JSON.stringify(data)
+
+            console.log(data);
+
+            $.ajax({
+                url: "/semantic_search",
+                type: 'post',
+                dataType: 'json', // 預期從server接收的資料型態
+                contentType: 'application/json; charset=utf-8', // 要送到server的資料型態
+                data: data,
+            }).done(function (data) {
+                data = JSON.parse(data['semantic_search'])
+                $('#results').empty()
+                $('#results').append(`<table class="table table-striped table-hover">
+                <thead>
+                    <tr>
+                        <th>title</th>
+                        <th>content_tags</th>
+                        <th>descriptionFilterHtml</th>
+                        <th>masterUnit</th>
+                        <th>startDate</th>
+                        <th>endDate</th>
+                        
+                    </tr>
+                </thead>
+                <tbody>
+                    
+                </tbody>
+            </table>`)
+                $.each(data, function (indexInArray, valueOfElement) {
+                    $('tbody').append(`
+                    <tr>
+                        <td>${valueOfElement.title}</td>
+                        <td><details>
+                                <summary>${valueOfElement.content_tags.slice(0, 10) + '...'}</summary>
+                                <p>${valueOfElement.content_tags}</p>
+                            </details>
+                        </td>
+                        <td><details>
+                                <summary>${valueOfElement.descriptionFilterHtml.slice(0, 50) + '...'}</summary>
+                                <p>${valueOfElement.descriptionFilterHtml}</p>
+                            </details>
+                        </td>
+                        <td>${valueOfElement.masterUnit}</td>
+                        <td>${valueOfElement.startDate}</td>
+                        <td>${valueOfElement.endDate}</td>
+                    </tr>
+                 `)
+                });
+
+                $('table').DataTable({
+                    "order": []
+                });
+
+            }).fail(function () {
+                console.log("error");
+            });
+
+
+
+
+            $.ajax({
+                url: "/wordcloud",
+                type: 'post',
+                dataType: 'json', // 預期從server接收的資料型態
+                contentType: 'application/json; charset=utf-8', // 要送到server的資料型態
+                data: data,
+            }).done(function (data) {
+                data = JSON.parse(data['wordcloud'])
+                $('#wordcloud').empty()
+                $('#wordcloud').append(data)
+
+            }).fail(function () {
+                console.log("error");
+            });
+
+
+            $.ajax({
+                url: "/tag_list",
+                type: 'post',
+                dataType: 'json', // 預期從server接收的資料型態
+                contentType: 'application/json; charset=utf-8', // 要送到server的資料型態
+                data: data,
+            }).done(function (data) {
+                data = JSON.parse(data['tag_list'])
+
+                $('#tag_list').empty()
+                if (data.length != 0) {
+                    $('#tag_list').append(`Top 100 Tags<br>`)
+
+                    $.each(data, function (indexInArray, valueOfElement) {
+                        $('#tag_list').append(`
+                            <span class="badge bg-primary">#${valueOfElement}&nbsp;</span>
+                    `)
+                    });
+                }
+
+            }).fail(function () {
+                console.log("error");
+            });
+        }
+    }
+
+    $('#search').on("click", function () {
+        semantic_search()
+    });
+
+    $('#search_query').on("keyup", function (event) {
+        // Number 13 is the "Enter" key on the keyboard
+        if (event.keyCode === 13) {
+            // Cancel the default action, if needed
+            event.preventDefault();
+            // Trigger the button element with a click
+            $('#search').click();
+        }
+    });
+
+</script>
+
+</html>