New view to see available editions from inventaire
This commit is contained in:
BIN
front/public/defaultinventairebook.png
Normal file
BIN
front/public/defaultinventairebook.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -32,7 +32,7 @@ function openBook() {
|
|||||||
if (props.id != 0) {
|
if (props.id != 0) {
|
||||||
router.push(`/book/${props.id}`);
|
router.push(`/book/${props.id}`);
|
||||||
} else {
|
} else {
|
||||||
router.push(`/importinventaire/${props.inventaireid}`)
|
router.push(`/import/inventaire/${props.inventaireid}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
68
front/src/ImportInventaire.vue
Normal file
68
front/src/ImportInventaire.vue
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import ImportListElement from './ImportListElement.vue';
|
||||||
|
import { getInventaireEditionBooks } from './api.js'
|
||||||
|
import { onBeforeRouteUpdate } from 'vue-router'
|
||||||
|
import Pagination from './Pagination.vue'
|
||||||
|
|
||||||
|
const limit = 5;
|
||||||
|
const pageNumber = ref(1);
|
||||||
|
|
||||||
|
const offset = computed(() => (pageNumber.value - 1) * limit);
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
inventaireid: String,
|
||||||
|
});
|
||||||
|
|
||||||
|
let data = ref(null);
|
||||||
|
let error = ref(null);
|
||||||
|
|
||||||
|
const pageTotal = computed(() => {
|
||||||
|
let countValue = (data.value !== null) ? data.value['count'] : 0;
|
||||||
|
return Math.ceil(countValue / limit);
|
||||||
|
});
|
||||||
|
|
||||||
|
fetchData(props.inventaireid);
|
||||||
|
|
||||||
|
|
||||||
|
function fetchData(inventaireid, authorId) {
|
||||||
|
if (inventaireid != null) {
|
||||||
|
let lang = navigator.language.substring(0,2);
|
||||||
|
getInventaireEditionBooks(data, error, inventaireid, lang, limit, offset.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onBeforeRouteUpdate(async (to, from) => {
|
||||||
|
pageNumber.value = 1;
|
||||||
|
fetchData(to.params.inventaireid);
|
||||||
|
})
|
||||||
|
|
||||||
|
function pageChange(newPageNumber) {
|
||||||
|
pageNumber.value = newPageNumber;
|
||||||
|
data.value = null;
|
||||||
|
fetchData(props.inventaireid);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="booksearch my-2">
|
||||||
|
<h1 class="title">{{$t('importinventaire.title')}}</h1>
|
||||||
|
<div v-if="error">{{$t('searchbook.error', {error: error.message})}}</div>
|
||||||
|
<div v-else-if="data && data.results && data.results.length > 0">
|
||||||
|
<div class="booksearchlist" v-for="book in data.results" :key="book.id">
|
||||||
|
<ImportListElement v-bind="book" />
|
||||||
|
</div>
|
||||||
|
<Pagination
|
||||||
|
:pageNumber="pageNumber"
|
||||||
|
:pageTotal="pageTotal"
|
||||||
|
maxItemDisplayed="11"
|
||||||
|
@pageChange="pageChange"/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="data === null">{{$t('searchbook.loading')}}</div>
|
||||||
|
<div v-else>{{$t('searchbook.noresult')}}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
|
|
||||||
69
front/src/ImportListElement.vue
Normal file
69
front/src/ImportListElement.vue
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { getInventaireImagePathOrDefault } from './api.js'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const props = defineProps({
|
||||||
|
id: String,
|
||||||
|
title: String,
|
||||||
|
image: String,
|
||||||
|
publisher: String,
|
||||||
|
date: String,
|
||||||
|
isbn: String,
|
||||||
|
});
|
||||||
|
const imagePathOrDefault = computed(() => getInventaireImagePathOrDefault(props.image));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div v-if="error" class="notification is-danger">
|
||||||
|
<p>{{error}}</p>
|
||||||
|
</div>
|
||||||
|
<div class="columns no-padding box container has-background-dark">
|
||||||
|
<div class="media column no-margin" @click="openBook">
|
||||||
|
<div class="media-left">
|
||||||
|
<figure class="image mb-3">
|
||||||
|
<img v-bind:src="imagePathOrDefault" v-bind:alt="title">
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
<div class="media-content">
|
||||||
|
<div class="is-size-4">{{title}}</div>
|
||||||
|
<div v-if="props.date" class="is-size-5">{{$t('importlistelement.releasedate') + "" + date}}</div>
|
||||||
|
<div v-if="props.publisher" class="is-size-5">{{$t('importlistelement.publisher') + "" + publisher}}</div>
|
||||||
|
<div v-if="props.isbn" class="is-size-5">{{"ISBN: " + isbn}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
img {
|
||||||
|
max-height:180px;
|
||||||
|
max-width:180px;
|
||||||
|
height:auto;
|
||||||
|
width:auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
transition:ease-in-out 0.04s;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box:hover {
|
||||||
|
transform: scale(1.01);
|
||||||
|
transition: ease-in-out 0.02s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verticalbutton {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-padding {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-margin {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -2,9 +2,17 @@ import { useAuthStore } from './auth.store.js'
|
|||||||
|
|
||||||
const baseUrl = "http://localhost:8080"
|
const baseUrl = "http://localhost:8080"
|
||||||
|
|
||||||
|
export function getInventaireImagePathOrDefault(path) {
|
||||||
|
return getImagePathOrGivenDefault(path, "../../defaultinventairebook.png")
|
||||||
|
}
|
||||||
|
|
||||||
export function getImagePathOrDefault(path) {
|
export function getImagePathOrDefault(path) {
|
||||||
|
return getImagePathOrGivenDefault(path, "../defaultbook.png")
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getImagePathOrGivenDefault(path, defaultpath) {
|
||||||
if (path == "" || typeof path === 'undefined') {
|
if (path == "" || typeof path === 'undefined') {
|
||||||
return "../defaultbook.png";
|
return defaultpath;
|
||||||
} else if (path.startsWith("https://")) {
|
} else if (path.startsWith("https://")) {
|
||||||
return path;
|
return path;
|
||||||
} else {
|
} else {
|
||||||
@@ -38,6 +46,11 @@ export function getSearchBooks(data, error, searchterm, lang, limit, offset) {
|
|||||||
return useFetch(data, error, baseUrl + '/search/' + encodeURIComponent(searchterm) + "?" + queryParams.toString());
|
return useFetch(data, error, baseUrl + '/search/' + encodeURIComponent(searchterm) + "?" + queryParams.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getInventaireEditionBooks(data, error, inventaireId, lang, limit, offset) {
|
||||||
|
const queryParams = new URLSearchParams({lang: lang, limit: limit, offset: offset});
|
||||||
|
return useFetch(data, error, baseUrl + '/inventaire/books/' + encodeURIComponent(inventaireId) + "?" + queryParams.toString());
|
||||||
|
}
|
||||||
|
|
||||||
export function getAuthor(data, error, id) {
|
export function getAuthor(data, error, id) {
|
||||||
return useFetch(data, error, baseUrl + '/author/' + id);
|
return useFetch(data, error, baseUrl + '/author/' + id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,8 +58,16 @@
|
|||||||
"goto":"Goto page {pageNumber}",
|
"goto":"Goto page {pageNumber}",
|
||||||
"page":"Page {pageNumber}"
|
"page":"Page {pageNumber}"
|
||||||
},
|
},
|
||||||
"bookdatewidget" :{
|
"bookdatewidget": {
|
||||||
"started": "Started at :",
|
"started": "Started at :",
|
||||||
"finished": "Finished at :"
|
"finished": "Finished at :"
|
||||||
|
},
|
||||||
|
"importinventaire": {
|
||||||
|
"title":"Please select a book to import"
|
||||||
|
},
|
||||||
|
"importlistelement": {
|
||||||
|
"releasedate":"Release date:",
|
||||||
|
"publisher":"Publisher:"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,8 +58,15 @@
|
|||||||
"goto":"Aller à la page {pageNumber}",
|
"goto":"Aller à la page {pageNumber}",
|
||||||
"page":"Page {pageNumber}"
|
"page":"Page {pageNumber}"
|
||||||
},
|
},
|
||||||
"bookdatewidget" :{
|
"bookdatewidget": {
|
||||||
"started": "Commencé le :",
|
"started": "Commencé le :",
|
||||||
"finished": "Fini le :"
|
"finished": "Fini le :"
|
||||||
|
},
|
||||||
|
"importinventaire": {
|
||||||
|
"title":"Sélectionner l'édition à importer"
|
||||||
|
},
|
||||||
|
"importlistelement": {
|
||||||
|
"releasedate":"Date de publication : ",
|
||||||
|
"publisher":"Maison d'édition : "
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import SignUp from './SignUp.vue'
|
|||||||
import LogIn from './LogIn.vue'
|
import LogIn from './LogIn.vue'
|
||||||
import Home from './Home.vue'
|
import Home from './Home.vue'
|
||||||
import SearchBook from './SearchBook.vue'
|
import SearchBook from './SearchBook.vue'
|
||||||
|
import ImportInventaire from './ImportInventaire.vue'
|
||||||
import InventaireImport from './InventaireImport.vue'
|
import InventaireImport from './InventaireImport.vue'
|
||||||
import { useAuthStore } from './auth.store'
|
import { useAuthStore } from './auth.store'
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ const routes = [
|
|||||||
{ path: '/importinventaire/:inventaireid', component: InventaireImport, props: true },
|
{ path: '/importinventaire/:inventaireid', component: InventaireImport, props: true },
|
||||||
{ path: '/author/:id', component: AuthorForm, props: true },
|
{ path: '/author/:id', component: AuthorForm, props: true },
|
||||||
{ path: '/search/:searchterm', component: SearchBook, props: true },
|
{ path: '/search/:searchterm', component: SearchBook, props: true },
|
||||||
|
{ path: '/import/inventaire/:inventaireid', component: ImportInventaire, props: true },
|
||||||
{ path: '/add', component: AddBook },
|
{ path: '/add', component: AddBook },
|
||||||
{ path: '/signup', component: SignUp },
|
{ path: '/signup', component: SignUp },
|
||||||
{ path: '/login', component: LogIn },
|
{ path: '/login', component: LogIn },
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ type InventaireSearchResult struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type InventaireSearchBook struct {
|
type InventaireSearchBook struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"uri"`
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Image string `json:"image"`
|
Image string `json:"image"`
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package inventaire
|
package inventaire
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -53,3 +54,56 @@ func TestCallInventaireBook_BraveNewWorld(t *testing.T) {
|
|||||||
assert.Equal(t, "Aldous Huxley", result.Author.Name)
|
assert.Equal(t, "Aldous Huxley", result.Author.Name)
|
||||||
assert.Equal(t, "écrivain, romancier et philosophe britannique (1894–1963)", result.Author.Description)
|
assert.Equal(t, "écrivain, romancier et philosophe britannique (1894–1963)", result.Author.Description)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCallInventaireEdition_TestLimit(t *testing.T) {
|
||||||
|
result, err := CallInventaireEdition("wd:Q339761", "fr", 10, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, int64(34), result.Count)
|
||||||
|
assert.Equal(t, 10, len(result.Results))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCallInventaireEdition_TestOffset(t *testing.T) {
|
||||||
|
result, err := CallInventaireEdition("wd:Q3213142", "fr", 0, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, 3, len(result.Results))
|
||||||
|
sortedResults := result.Results
|
||||||
|
sort.Slice(sortedResults, func(i, j int) bool {
|
||||||
|
return sortedResults[i].Id > sortedResults[j].Id
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t,
|
||||||
|
InventaireEditionResultBook{
|
||||||
|
Id: "isbn:9782072525216",
|
||||||
|
Title: "La théorie de l'information",
|
||||||
|
ISBN: "978-2-07-252521-6",
|
||||||
|
ReleaseDate: "",
|
||||||
|
Image: "https://inventaire.io/img/entities/fac578440d9bf7afc7f4c5698aa618b8a4d80d21",
|
||||||
|
Lang: "fr",
|
||||||
|
},
|
||||||
|
result.Results[0])
|
||||||
|
assert.Equal(t,
|
||||||
|
InventaireEditionResultBook{
|
||||||
|
Id: "isbn:9782070456260",
|
||||||
|
Title: "La théorie de l'information",
|
||||||
|
ISBN: "978-2-07-045626-0",
|
||||||
|
ReleaseDate: "2014",
|
||||||
|
Image: "https://inventaire.io/img/entities/5044c2265cc42675ac4335387aef189862cbeec1",
|
||||||
|
Lang: "fr",
|
||||||
|
},
|
||||||
|
result.Results[1])
|
||||||
|
assert.Equal(t,
|
||||||
|
InventaireEditionResultBook{
|
||||||
|
Id: "isbn:9782070138098",
|
||||||
|
Title: "La théorie de l'information",
|
||||||
|
ISBN: "978-2-07-013809-8",
|
||||||
|
Publisher: "Éditions Gallimard",
|
||||||
|
ReleaseDate: "2012",
|
||||||
|
Image: "https://inventaire.io/img/entities/a7b9d05c041b98e98c2f429e11cb2b424d78223b",
|
||||||
|
Lang: "fr",
|
||||||
|
},
|
||||||
|
result.Results[2])
|
||||||
|
}
|
||||||
|
|||||||
240
internal/inventaire/inventaireedition.go
Normal file
240
internal/inventaire/inventaireedition.go
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
package inventaire
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"math"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.artlef.fr/PersonalLibraryManager/internal/callapiutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InventaireEditionResult struct {
|
||||||
|
Results []InventaireEditionResultBook `json:"results"`
|
||||||
|
Count int64 `json:"count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InventaireEditionResultBook struct {
|
||||||
|
Id string `json:"uri"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
ISBN string `json:"isbn"`
|
||||||
|
Publisher string `json:"publisher"`
|
||||||
|
ReleaseDate string `json:"date"`
|
||||||
|
Image string `json:"image"`
|
||||||
|
Lang string `json:"lang"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type inventaireReverseClaimsResult struct {
|
||||||
|
Uris []string `json:"uris"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type inventaireEditionQueryResult struct {
|
||||||
|
Entities []inventaireEditionQueryEntity
|
||||||
|
}
|
||||||
|
|
||||||
|
type inventaireEditionQueryEntity struct {
|
||||||
|
WdId string
|
||||||
|
EditionId string
|
||||||
|
Title string
|
||||||
|
ISBN string
|
||||||
|
Uri string
|
||||||
|
Image string
|
||||||
|
Lang string
|
||||||
|
ReleaseDate string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *inventaireEditionQueryResult) UnmarshalJSON(b []byte) error {
|
||||||
|
var parsed struct {
|
||||||
|
Entities map[string]json.RawMessage `json:"entities"`
|
||||||
|
}
|
||||||
|
err := json.Unmarshal(b, &parsed)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, entity := range parsed.Entities {
|
||||||
|
var parsedEntity struct {
|
||||||
|
WdId string `json:"wdId"`
|
||||||
|
Labels map[string]json.RawMessage `json:"labels"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Uri string `json:"uri"`
|
||||||
|
Image map[string]json.RawMessage `json:"image"`
|
||||||
|
Lang string `json:"originalLang"`
|
||||||
|
Claims map[string]json.RawMessage `json:"claims"`
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(entity, &parsedEntity)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if parsedEntity.Type == "edition" {
|
||||||
|
editionId, err := parseStringArrayFieldInJsonRaw(parsedEntity.Claims, "wdt:P123")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
releaseDate, err := parseStringArrayFieldInJsonRaw(parsedEntity.Claims, "wdt:P577")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
isbn, err := parseStringArrayFieldInJsonRaw(parsedEntity.Claims, "wdt:P212")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
label, err := findLangageField(parsedEntity.Labels, "fromclaims")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
image := ""
|
||||||
|
imageFieldToParse, ok := parsedEntity.Image["url"]
|
||||||
|
if ok {
|
||||||
|
err := json.Unmarshal(imageFieldToParse, &image)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if image != "" {
|
||||||
|
image = GetBaseInventaireUrl() + image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i.Entities = append(i.Entities, inventaireEditionQueryEntity{
|
||||||
|
WdId: parsedEntity.WdId,
|
||||||
|
EditionId: editionId,
|
||||||
|
Title: label,
|
||||||
|
ISBN: isbn,
|
||||||
|
Uri: parsedEntity.Uri,
|
||||||
|
Image: image,
|
||||||
|
Lang: parsedEntity.Lang,
|
||||||
|
ReleaseDate: releaseDate,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseStringArrayFieldInJsonRaw(jsonRawMap map[string]json.RawMessage, key string) (string, error) {
|
||||||
|
fieldToParse, ok := jsonRawMap[key]
|
||||||
|
if !ok {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
var fieldArray []string
|
||||||
|
s := ""
|
||||||
|
err := json.Unmarshal(fieldToParse, &fieldArray)
|
||||||
|
if err != nil {
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
if len(fieldArray) > 0 {
|
||||||
|
s = fieldArray[0]
|
||||||
|
}
|
||||||
|
return s, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CallInventaireEdition(inventaireId string, lang string, limit int, offset int) (InventaireEditionResult, error) {
|
||||||
|
var queryResult InventaireEditionResult
|
||||||
|
uris, err := callInventaireUris(inventaireId)
|
||||||
|
if err != nil {
|
||||||
|
return queryResult, err
|
||||||
|
}
|
||||||
|
queryResult.Count = int64(len(uris.Uris))
|
||||||
|
limitedUris := uris.Uris
|
||||||
|
if limit != 0 {
|
||||||
|
l := len(uris.Uris)
|
||||||
|
startIndex := int(math.Min(float64(offset), float64(l)))
|
||||||
|
endIndex := int(math.Min(float64(limit+offset), float64(l)))
|
||||||
|
limitedUris = uris.Uris[startIndex:endIndex]
|
||||||
|
}
|
||||||
|
editionEntities, err := callInventaireEditionEntities(limitedUris)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return queryResult, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entity := range editionEntities.Entities {
|
||||||
|
publisher := ""
|
||||||
|
if entity.EditionId != "" {
|
||||||
|
publisher, err = callInventairePublisherGetName(entity.EditionId, lang)
|
||||||
|
if err != nil {
|
||||||
|
return queryResult, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
queryResult.Results = append(queryResult.Results, InventaireEditionResultBook{
|
||||||
|
Id: entity.Uri,
|
||||||
|
ISBN: entity.ISBN,
|
||||||
|
Title: entity.Title,
|
||||||
|
ReleaseDate: entity.ReleaseDate,
|
||||||
|
Image: entity.Image,
|
||||||
|
Publisher: publisher,
|
||||||
|
Lang: entity.Lang,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return queryResult, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func callInventaireUris(inventaireId string) (inventaireReverseClaimsResult, error) {
|
||||||
|
var queryResult inventaireReverseClaimsResult
|
||||||
|
u, err := computeInventaireApiUrl("entities")
|
||||||
|
if err != nil {
|
||||||
|
return queryResult, err
|
||||||
|
}
|
||||||
|
callapiutils.AddQueryParam(u, "action", "reverse-claims")
|
||||||
|
callapiutils.AddQueryParam(u, "property", "wdt:P629")
|
||||||
|
callapiutils.AddQueryParam(u, "value", inventaireId)
|
||||||
|
|
||||||
|
err = callapiutils.FetchAndParseResult(u, &queryResult)
|
||||||
|
return queryResult, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func callInventaireEditionEntities(uris []string) (inventaireEditionQueryResult, error) {
|
||||||
|
var queryResult inventaireEditionQueryResult
|
||||||
|
u, err := computeInventaireApiUrl("entities")
|
||||||
|
if err != nil {
|
||||||
|
return queryResult, err
|
||||||
|
}
|
||||||
|
|
||||||
|
callapiutils.AddQueryParam(u, "action", "by-uris")
|
||||||
|
callapiutils.AddQueryParam(u, "uris", strings.Join(uris, "|"))
|
||||||
|
|
||||||
|
err = callapiutils.FetchAndParseResult(u, &queryResult)
|
||||||
|
|
||||||
|
return queryResult, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type inventaireEditionPublisherResult struct {
|
||||||
|
Lang string
|
||||||
|
Label string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *inventaireEditionPublisherResult) UnmarshalJSON(b []byte) error {
|
||||||
|
var parsed struct {
|
||||||
|
Entities map[string]json.RawMessage
|
||||||
|
}
|
||||||
|
err := json.Unmarshal(b, &parsed)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entity := range parsed.Entities {
|
||||||
|
var publisherEntity struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Labels map[string]json.RawMessage `json:"labels"`
|
||||||
|
}
|
||||||
|
err := json.Unmarshal(entity, &publisherEntity)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
label, _ := findLangageField(publisherEntity.Labels, i.Lang)
|
||||||
|
i.Label = label
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func callInventairePublisherGetName(editionId string, lang string) (string, error) {
|
||||||
|
var queryResult inventaireEditionPublisherResult
|
||||||
|
u, err := computeInventaireApiUrl("entities")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
queryResult.Lang = lang
|
||||||
|
|
||||||
|
callapiutils.AddQueryParam(u, "action", "by-uris")
|
||||||
|
callapiutils.AddQueryParam(u, "uris", editionId)
|
||||||
|
callapiutils.AddQueryParam(u, "attributes", "info|labels")
|
||||||
|
|
||||||
|
err = callapiutils.FetchAndParseResult(u, &queryResult)
|
||||||
|
return queryResult.Label, err
|
||||||
|
}
|
||||||
38
internal/routes/booksinventaireget.go
Normal file
38
internal/routes/booksinventaireget.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"git.artlef.fr/PersonalLibraryManager/internal/appcontext"
|
||||||
|
"git.artlef.fr/PersonalLibraryManager/internal/dto"
|
||||||
|
"git.artlef.fr/PersonalLibraryManager/internal/inventaire"
|
||||||
|
"git.artlef.fr/PersonalLibraryManager/internal/myvalidator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetInventaireBooks(ac appcontext.AppContext) {
|
||||||
|
workId := ac.C.Param("workId")
|
||||||
|
var params dto.BookSearchGetParam
|
||||||
|
err := ac.C.ShouldBind(¶ms)
|
||||||
|
if err != nil {
|
||||||
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
limit, err := ac.GetQueryLimit()
|
||||||
|
if err != nil {
|
||||||
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
offset, err := ac.GetQueryOffset()
|
||||||
|
if err != nil {
|
||||||
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
inventaireEditionResult, err := inventaire.CallInventaireEdition(workId, params.Lang, limit, offset)
|
||||||
|
if err != nil {
|
||||||
|
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ac.C.JSON(http.StatusOK, inventaireEditionResult)
|
||||||
|
}
|
||||||
@@ -36,6 +36,9 @@ func Setup(config *config.Config) *gin.Engine {
|
|||||||
r.GET("/search/:searchterm", func(c *gin.Context) {
|
r.GET("/search/:searchterm", func(c *gin.Context) {
|
||||||
routes.GetSearchBooksHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
routes.GetSearchBooksHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
||||||
})
|
})
|
||||||
|
r.GET("/inventaire/books/:workId", func(c *gin.Context) {
|
||||||
|
routes.GetInventaireBooks(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
||||||
|
})
|
||||||
r.GET("/book/:id", func(c *gin.Context) {
|
r.GET("/book/:id", func(c *gin.Context) {
|
||||||
routes.GetBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
routes.GetBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user