Compare commits

..

No commits in common. "v0.0.1" and "main" have entirely different histories.
v0.0.1 ... main

20 changed files with 2810 additions and 34955 deletions

47
.gitignore vendored
View File

@ -1,45 +1,4 @@
# Created by https://www.toptal.com/developers/gitignore/api/composer,macos /target
# Edit at https://www.toptal.com/developers/gitignore?templates=composer,macos config.json
bib.xml
### Composer ###
composer.phar
/vendor/
# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
# composer.lock
### macOS ###
# General
.DS_Store .DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
# End of https://www.toptal.com/developers/gitignore/api/composer,macos

View File

@ -1,7 +0,0 @@
{
"com.thorlaksson.phpcs.runOnChange" : "onSave",
"com.thorlaksson.phpcs.standard" : "PSR12",
"editor.default_syntax" : "php",
"php.interpreter" : "\/opt\/homebrew\/bin\/php",
"php.validate" : "onSave"
}

1863
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

14
Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "bib-watcher"
version = "0.4.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chrono = "0.4.23"
reqwest = { version = "0.11.13", features = ["blocking"]}
rss = "2.0.2"
scraper = "0.17.1"
config = { version = "0.13.1", features = ["json"], default-features = false}
serde_json = "1.0.108"

54
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,54 @@
pipeline {
agent any
options {
buildDiscarder(logRotator(numToKeepStr: "100"))
skipDefaultCheckout(true)
}
triggers {
pollSCM("*/10 * * * *")
}
environment {
SONAR_SCANNER_VERSION="4.7.0.2747"
SONAR_SCANNER_HOME="$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux"
PATH="$SONAR_SCANNER_HOME/bin:$PATH"
SONAR_SCANNER_OPTS="-server"
}
stages {
stage('Checkout') {
steps{
//cleanWs()
checkout scm
}
}
/*stage('Clean') {
steps {
withEnv(["PATH+RUST=$HOME/.cargo/bin"]) { // Cargo needs to be installed for the jenkins user
sh 'cargo clean'
}
}
}*/
stage('Build') {
steps {
withSonarQubeEnv(installationName: 'SQ Bib Watcher', envOnly: true) {
withEnv(["PATH+RUST=$HOME/.cargo/bin"]) {
sh 'cargo build --release'
}
}
}
}
// For this to work, edit sonar-scanner script to set use_embedded_jre=false
stage('SonarQube Analysis') {
steps {
withSonarQubeEnv(installationName: 'SQ Bib Watcher', envOnly: true) {
withEnv(["PATH+RUST=$HOME/.cargo/bin"]) {
sh """
SONAR_TOKEN="$SONAR_AUTH_TOKEN"
cargo clippy --message-format=json &> clippy-output.json
sonar-scanner -Dsonar.projectKey=bib-watcher -Dsonar.sources=. -Dsonar.host.url=http://grover.local:9000
"""
}
}
}
}
}
}

View File

@ -1,3 +0,0 @@
PHP API to interact with a [PhotoPrism](https://www.photoprism.app) instance.
Needs a configuration array to instantiate with the keys: `host`, `username`, and `password`

697
bib.xml Normal file
View File

@ -0,0 +1,697 @@
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Bib Watcher</title>
<link>https://phlaym.net</link>
<description>Watches availability status of library books</description>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Tue, 17 Jan 2023 19:45:23 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[vorbestellt]]></description>
<pubDate>Mon, 06 Feb 2023 07:33:03 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Tue, 07 Feb 2023 16:30:02 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Thu, 09 Feb 2023 15:30:26 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Sun, 26 Feb 2023 12:00:25 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Sun, 26 Feb 2023 12:30:02 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[vorbestellt]]></description>
<pubDate>Tue, 25 Apr 2023 14:30:03 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Tue, 25 Apr 2023 15:30:03 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Wed, 24 May 2023 08:35:06 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Thu, 25 May 2023 14:30:03 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Fri, 26 May 2023 10:33:04 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Sat, 27 May 2023 10:07:25 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Wed, 31 May 2023 07:31:36 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Fri, 02 Jun 2023 09:01:49 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Sat, 17 Jun 2023 09:37:02 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Sun, 25 Jun 2023 19:30:01 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Mon, 26 Jun 2023 01:00:03 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Tue, 27 Jun 2023 10:03:23 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Thu, 06 Jul 2023 14:04:49 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Tue, 11 Jul 2023 16:00:22 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Sat, 02 Sep 2023 11:05:19 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Tue, 05 Sep 2023 13:00:03 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Tue, 26 Sep 2023 12:30:02 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Tue, 26 Sep 2023 13:00:02 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[vorbestellt]]></description>
<pubDate>Wed, 04 Oct 2023 07:00:02 +0000</pubDate>
</item>
<item>
<title>Klufti Affenhitze</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Sat, 07 Oct 2023 09:30:02 +0000</pubDate>
</item>
<item>
<title>Cryptos Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTgyMDU4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Thu, 9 Nov 2023 14:52:14 +0000</pubDate>
</item>
<item>
<title>Shelter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9UG96bmFuc2tpJSVnXzA9LTEmYW1wO0NhdGFsb2d1ZUlkPTEwNDAyNCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[online]]></description>
<pubDate>Thu, 9 Nov 2023 14:52:15 +0000</pubDate>
</item>
<item>
<title>Sträter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPUR1IGthbm5zdCBhbGxlcyBsYXNzZW4sIGR1IG11c3N0IGVzIG51ciB3b2xsZW4lJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyNTAxMyZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Thu, 9 Nov 2023 14:52:17 +0000</pubDate>
</item>
<item>
<title>Thalamus</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MiZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTkwODk4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Thu, 9 Nov 2023 14:52:19 +0000</pubDate>
</item>
<item>
<title>°C Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMzU2MiZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Thu, 9 Nov 2023 14:52:20 +0000</pubDate>
</item>
<item>
<title>°C Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMTQ5MCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[vorbestellt]]></description>
<pubDate>Thu, 9 Nov 2023 14:52:21 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI2NjUzJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Thu, 9 Nov 2023 14:52:23 +0000</pubDate>
</item>
<item>
<title>Elsberg Zero</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmcgemVybyUlZ18wPS0xJmFtcDtjbWQ9MSZhbXA7Q2F0YWxvZ3VlSWQ9NDgzOTAmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9MiZhbXA7cFM9MTA%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Thu, 9 Nov 2023 14:52:24 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI1NTU4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Thu, 9 Nov 2023 14:52:25 +0000</pubDate>
</item>
<item>
<title>Shelter Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEwMDkwMSZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[vorbestellt]]></description>
<pubDate>Thu, 9 Nov 2023 14:52:27 +0000</pubDate>
</item>
<item>
<title>Cryptos Ebook</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTI4NDIwJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[online]]></description>
<pubDate>Thu, 9 Nov 2023 14:52:27 +0000</pubDate>
</item>
<item>
<title>Cryptos Ebook</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTI4NDIwJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Thu, 9 Nov 2023 18:42:20 +0000</pubDate>
</item>
<item>
<title>Shelter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9UG96bmFuc2tpJSVnXzA9LTEmYW1wO0NhdGFsb2d1ZUlkPTEwNDAyNCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Thu, 9 Nov 2023 18:44:40 +0000</pubDate>
</item>
<item>
<title>°C Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMTQ5MCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Fri, 10 Nov 2023 17:00:18 +0000</pubDate>
</item>
<item>
<title>Shelter Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEwMDkwMSZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Tue, 14 Nov 2023 12:30:14 +0000</pubDate>
</item>
<item>
<title>Shelter Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEwMDkwMSZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Tue, 14 Nov 2023 13:00:25 +0000</pubDate>
</item>
<item>
<title>Cryptos Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTgyMDU4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Mon, 20 Nov 2023 11:30:01 +0000</pubDate>
</item>
<item>
<title>Shelter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9UG96bmFuc2tpJSVnXzA9LTEmYW1wO0NhdGFsb2d1ZUlkPTEwNDAyNCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Mon, 20 Nov 2023 11:30:01 +0000</pubDate>
</item>
<item>
<title>Sträter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPUR1IGthbm5zdCBhbGxlcyBsYXNzZW4sIGR1IG11c3N0IGVzIG51ciB3b2xsZW4lJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyNTAxMyZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Mon, 20 Nov 2023 11:30:02 +0000</pubDate>
</item>
<item>
<title>Thalamus</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MiZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTkwODk4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Mon, 20 Nov 2023 11:30:02 +0000</pubDate>
</item>
<item>
<title>Elsberg Zero</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmcgemVybyUlZ18wPS0xJmFtcDtjbWQ9MSZhbXA7Q2F0YWxvZ3VlSWQ9NDgzOTAmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9MiZhbXA7cFM9MTA%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Mon, 20 Nov 2023 11:30:02 +0000</pubDate>
</item>
<item>
<title>°C Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMTQ5MCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Mon, 20 Nov 2023 11:30:02 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI2NjUzJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Mon, 20 Nov 2023 11:30:03 +0000</pubDate>
</item>
<item>
<title>Shelter Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEwMDkwMSZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Mon, 20 Nov 2023 11:30:03 +0000</pubDate>
</item>
<item>
<title>°C Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMzU2MiZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Mon, 20 Nov 2023 11:30:03 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI1NTU4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Mon, 20 Nov 2023 11:30:04 +0000</pubDate>
</item>
<item>
<title>Cryptos Ebook</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTI4NDIwJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Mon, 20 Nov 2023 11:30:04 +0000</pubDate>
</item>
<item>
<title>Shelter Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEwMDkwMSZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Mon, 20 Nov 2023 12:03:08 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI2NjUzJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Mon, 20 Nov 2023 12:03:10 +0000</pubDate>
</item>
<item>
<title>°C Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMTQ5MCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Mon, 20 Nov 2023 12:03:11 +0000</pubDate>
</item>
<item>
<title>Thalamus</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MiZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTkwODk4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Mon, 20 Nov 2023 12:03:12 +0000</pubDate>
</item>
<item>
<title>Shelter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9UG96bmFuc2tpJSVnXzA9LTEmYW1wO0NhdGFsb2d1ZUlkPTEwNDAyNCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Mon, 20 Nov 2023 12:03:14 +0000</pubDate>
</item>
<item>
<title>Cryptos Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTgyMDU4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Mon, 20 Nov 2023 12:03:16 +0000</pubDate>
</item>
<item>
<title>Sträter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPUR1IGthbm5zdCBhbGxlcyBsYXNzZW4sIGR1IG11c3N0IGVzIG51ciB3b2xsZW4lJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyNTAxMyZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Mon, 20 Nov 2023 12:03:18 +0000</pubDate>
</item>
<item>
<title>Cryptos Ebook</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTI4NDIwJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Mon, 20 Nov 2023 12:03:19 +0000</pubDate>
</item>
<item>
<title>Elsberg Zero</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmcgemVybyUlZ18wPS0xJmFtcDtjbWQ9MSZhbXA7Q2F0YWxvZ3VlSWQ9NDgzOTAmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9MiZhbXA7cFM9MTA%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Mon, 20 Nov 2023 12:03:21 +0000</pubDate>
</item>
<item>
<title>°C Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMzU2MiZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Mon, 20 Nov 2023 12:03:23 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI1NTU4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Mon, 20 Nov 2023 12:03:24 +0000</pubDate>
</item>
<item>
<title>Cryptos Ebook</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTI4NDIwJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Tue, 21 Nov 2023 23:00:12 +0000</pubDate>
</item>
<item>
<title>Cryptos Ebook</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTI4NDIwJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Thu, 23 Nov 2023 20:00:05 +0000</pubDate>
</item>
<item>
<title>°C Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMzU2MiZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Fri, 24 Nov 2023 09:00:09 +0000</pubDate>
</item>
<item>
<title>°C Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMzU2MiZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Sat, 25 Nov 2023 12:00:07 +0000</pubDate>
</item>
<item>
<title>°C Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMzU2MiZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Sun, 26 Nov 2023 01:00:15 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI2NjUzJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Sun, 26 Nov 2023 01:00:16 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI2NjUzJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Sun, 26 Nov 2023 01:30:05 +0000</pubDate>
</item>
<item>
<title>°C Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMzU2MiZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Sun, 26 Nov 2023 01:30:09 +0000</pubDate>
</item>
<item>
<title>Sträter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPUR1IGthbm5zdCBhbGxlcyBsYXNzZW4sIGR1IG11c3N0IGVzIG51ciB3b2xsZW4lJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyNTAxMyZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Sun, 26 Nov 2023 02:00:15 +0000</pubDate>
</item>
<item>
<title>Sträter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPUR1IGthbm5zdCBhbGxlcyBsYXNzZW4sIGR1IG11c3N0IGVzIG51ciB3b2xsZW4lJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyNTAxMyZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Sun, 26 Nov 2023 02:30:10 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI2NjUzJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[Unknown]]></description>
<pubDate>Mon, 27 Nov 2023 02:00:15 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI2NjUzJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Mon, 27 Nov 2023 02:30:10 +0000</pubDate>
</item>
<item>
<title>Shelter Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEwMDkwMSZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Wed, 29 Nov 2023 02:34:18 +0000</pubDate>
</item>
<item>
<title>Elsberg Zero</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmcgemVybyUlZ18wPS0xJmFtcDtjbWQ9MSZhbXA7Q2F0YWxvZ3VlSWQ9NDgzOTAmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9MiZhbXA7cFM9MTA%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Wed, 29 Nov 2023 12:00:04 +0000</pubDate>
</item>
<item>
<title>°C Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMTQ5MCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Wed, 29 Nov 2023 12:34:34 +0000</pubDate>
</item>
<item>
<title>Shelter Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEwMDkwMSZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[entliehen]]></description>
<pubDate>Wed, 29 Nov 2023 16:00:12 +0000</pubDate>
</item>
<item>
<title>Sträter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPUR1IGthbm5zdCBhbGxlcyBsYXNzZW4sIGR1IG11c3N0IGVzIG51ciB3b2xsZW4lJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyNTAxMyZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<pubDate>Wed, 29 Nov 2023 17:30:05 +0000</pubDate>
</item>
<item>
<title>Cryptos Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTgyMDU4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[Unknown]]></description>
<guid isPermaLink="false">Cryptos PapierFri, 1 Dec 2023 02:00:14 +0000</guid>
<pubDate>Fri, 1 Dec 2023 02:00:14 +0000</pubDate>
</item>
<item>
<title>Cryptos Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTgyMDU4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<guid isPermaLink="false">Cryptos PapierFri, 1 Dec 2023 02:30:13 +0000</guid>
<pubDate>Fri, 1 Dec 2023 02:30:13 +0000</pubDate>
</item>
<item>
<title>°C Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMzU2MiZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<guid isPermaLink="false">°C HörbuchFri, 1 Dec 2023 17:00:10 +0000</guid>
<pubDate>Fri, 1 Dec 2023 17:00:10 +0000</pubDate>
</item>
<item>
<title>°C Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMTQ5MCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<guid isPermaLink="false">°C HardcoverSat, 2 Dec 2023 12:00:08 +0000</guid>
<pubDate>Sat, 2 Dec 2023 12:00:08 +0000</pubDate>
</item>
<item>
<title>Cryptos Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTgyMDU4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[verfügbar]]></description>
<guid isPermaLink="false">Cryptos PapierSat, 2 Dec 2023 12:00:09 +0000</guid>
<pubDate>Sat, 2 Dec 2023 12:00:09 +0000</pubDate>
</item>
<item>
<title>°C Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMzU2MiZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[Unknown]]></description>
<guid isPermaLink="false">°C HörbuchSun, 3 Dec 2023 01:00:14 +0000</guid>
<pubDate>Sun, 3 Dec 2023 01:00:14 +0000</pubDate>
</item>
<item>
<title>°C Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMzU2MiZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<guid isPermaLink="false">°C HörbuchSun, 3 Dec 2023 03:30:05 +0000</guid>
<pubDate>Sun, 3 Dec 2023 03:30:05 +0000</pubDate>
</item>
<item>
<title>Cryptos Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTgyMDU4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[Unknown]]></description>
<guid isPermaLink="false">Cryptos PapierSun, 3 Dec 2023 21:37:36 +0000</guid>
<pubDate>Sun, 3 Dec 2023 21:37:36 +0000</pubDate>
</item>
<item>
<title>Thalamus</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MiZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTkwODk4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[Unknown]]></description>
<guid isPermaLink="false">ThalamusSun, 3 Dec 2023 21:37:36 +0000</guid>
<pubDate>Sun, 3 Dec 2023 21:37:36 +0000</pubDate>
</item>
<item>
<title>Shelter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9UG96bmFuc2tpJSVnXzA9LTEmYW1wO0NhdGFsb2d1ZUlkPTEwNDAyNCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[Unknown]]></description>
<guid isPermaLink="false">ShelterSun, 3 Dec 2023 21:37:37 +0000</guid>
<pubDate>Sun, 3 Dec 2023 21:37:37 +0000</pubDate>
</item>
<item>
<title>Sträter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPUR1IGthbm5zdCBhbGxlcyBsYXNzZW4sIGR1IG11c3N0IGVzIG51ciB3b2xsZW4lJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyNTAxMyZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[Unknown]]></description>
<guid isPermaLink="false">SträterSun, 3 Dec 2023 21:37:37 +0000</guid>
<pubDate>Sun, 3 Dec 2023 21:37:37 +0000</pubDate>
</item>
<item>
<title>°C Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMTQ5MCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[Unknown]]></description>
<guid isPermaLink="false">°C HardcoverSun, 3 Dec 2023 21:37:37 +0000</guid>
<pubDate>Sun, 3 Dec 2023 21:37:37 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI2NjUzJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[Unknown]]></description>
<guid isPermaLink="false">Moers Leuchttürme HardcoverSun, 3 Dec 2023 21:37:37 +0000</guid>
<pubDate>Sun, 3 Dec 2023 21:37:37 +0000</pubDate>
</item>
<item>
<title>Cryptos Ebook</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTI4NDIwJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[Unknown]]></description>
<guid isPermaLink="false">Cryptos EbookSun, 3 Dec 2023 21:37:38 +0000</guid>
<pubDate>Sun, 3 Dec 2023 21:37:38 +0000</pubDate>
</item>
<item>
<title>Elsberg Zero</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmcgemVybyUlZ18wPS0xJmFtcDtjbWQ9MSZhbXA7Q2F0YWxvZ3VlSWQ9NDgzOTAmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9MiZhbXA7cFM9MTA%3d</link>
<description><![CDATA[Unknown]]></description>
<guid isPermaLink="false">Elsberg ZeroSun, 3 Dec 2023 21:37:38 +0000</guid>
<pubDate>Sun, 3 Dec 2023 21:37:38 +0000</pubDate>
</item>
<item>
<title>°C Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMzU2MiZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[Unknown]]></description>
<guid isPermaLink="false">°C HörbuchSun, 3 Dec 2023 21:37:38 +0000</guid>
<pubDate>Sun, 3 Dec 2023 21:37:38 +0000</pubDate>
</item>
<item>
<title>Shelter Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEwMDkwMSZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[Unknown]]></description>
<guid isPermaLink="false">Shelter PapierSun, 3 Dec 2023 21:37:38 +0000</guid>
<pubDate>Sun, 3 Dec 2023 21:37:38 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI1NTU4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[Unknown]]></description>
<guid isPermaLink="false">Moers Leuchttürme HörbuchSun, 3 Dec 2023 21:37:39 +0000</guid>
<pubDate>Sun, 3 Dec 2023 21:37:39 +0000</pubDate>
</item>
<item>
<title>Elsberg Zero</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmcgemVybyUlZ18wPS0xJmFtcDtjbWQ9MSZhbXA7Q2F0YWxvZ3VlSWQ9NDgzOTAmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9MiZhbXA7cFM9MTA%3d</link>
<description><![CDATA[verfügbar]]></description>
<guid isPermaLink="false">Elsberg ZeroSun, 3 Dec 2023 23:00:12 +0000</guid>
<pubDate>Sun, 3 Dec 2023 23:00:12 +0000</pubDate>
</item>
<item>
<title>Cryptos Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTgyMDU4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[verfügbar]]></description>
<guid isPermaLink="false">Cryptos PapierSun, 3 Dec 2023 23:00:14 +0000</guid>
<pubDate>Sun, 3 Dec 2023 23:00:14 +0000</pubDate>
</item>
<item>
<title>Sträter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPUR1IGthbm5zdCBhbGxlcyBsYXNzZW4sIGR1IG11c3N0IGVzIG51ciB3b2xsZW4lJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyNTAxMyZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<guid isPermaLink="false">SträterSun, 3 Dec 2023 23:00:15 +0000</guid>
<pubDate>Sun, 3 Dec 2023 23:00:15 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI2NjUzJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<guid isPermaLink="false">Moers Leuchttürme HardcoverSun, 3 Dec 2023 23:00:16 +0000</guid>
<pubDate>Sun, 3 Dec 2023 23:00:16 +0000</pubDate>
</item>
<item>
<title>Thalamus</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MiZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTkwODk4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[verfügbar]]></description>
<guid isPermaLink="false">ThalamusSun, 3 Dec 2023 23:00:18 +0000</guid>
<pubDate>Sun, 3 Dec 2023 23:00:18 +0000</pubDate>
</item>
<item>
<title>°C Hardcover</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMTQ5MCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[entliehen]]></description>
<guid isPermaLink="false">°C HardcoverSun, 3 Dec 2023 23:00:19 +0000</guid>
<pubDate>Sun, 3 Dec 2023 23:00:19 +0000</pubDate>
</item>
<item>
<title>Moers Leuchttürme Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9RGllIEluc2VsIGRlciBUYXVzZW5kIExldWNodHQmIzI1MjtybWUlJWdfMD0tMSZhbXA7Q2F0YWxvZ3VlSWQ9MTI1NTU4JmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<guid isPermaLink="false">Moers Leuchttürme HörbuchSun, 3 Dec 2023 23:00:20 +0000</guid>
<pubDate>Sun, 3 Dec 2023 23:00:20 +0000</pubDate>
</item>
<item>
<title>Shelter Papier</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEwMDkwMSZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[entliehen]]></description>
<guid isPermaLink="false">Shelter PapierSun, 3 Dec 2023 23:00:21 +0000</guid>
<pubDate>Sun, 3 Dec 2023 23:00:21 +0000</pubDate>
</item>
<item>
<title>°C Hörbuch</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtzQz1jXzA9MSUlbV8wPTElJWZfMD0yJSVvXzA9OCUldl8wPWVsc2JlcmclJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTEyMzU2MiZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMA%3d%3d</link>
<description><![CDATA[verfügbar]]></description>
<guid isPermaLink="false">°C HörbuchSun, 3 Dec 2023 23:00:22 +0000</guid>
<pubDate>Sun, 3 Dec 2023 23:00:22 +0000</pubDate>
</item>
<item>
<title>Shelter</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=Y21kPTEmYW1wO3NDPWNfMD0wJSVtXzA9MSUlZl8wPTIlJW9fMD04JSV2XzA9UG96bmFuc2tpJSVnXzA9LTEmYW1wO0NhdGFsb2d1ZUlkPTEwNDAyNCZhbXA7cGFnZUlkPTImYW1wO1NyYz0yJmFtcDtwUz0xMCZhbXA7U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWsp</link>
<description><![CDATA[entliehen]]></description>
<guid isPermaLink="false">ShelterSun, 3 Dec 2023 23:00:23 +0000</guid>
<pubDate>Sun, 3 Dec 2023 23:00:23 +0000</pubDate>
</item>
<item>
<title>Cryptos Ebook</title>
<link>https://webopac.winbiap.de/konstanz/detail.aspx?data=cEk9MSZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1Qb3puYW5za2klJWdfMD0tMSZhbXA7Y21kPTEmYW1wO0NhdGFsb2d1ZUlkPTI4NDIwJmFtcDtwYWdlSWQ9MiZhbXA7U3JjPTImYW1wO3BTPTEwJmFtcDtTb3J0PVp1Z2FuZ3NkYXR1bSAoQmlibGlvdGhlayk%3d</link>
<description><![CDATA[entliehen]]></description>
<guid isPermaLink="false">Cryptos EbookSun, 3 Dec 2023 23:00:24 +0000</guid>
<pubDate>Sun, 3 Dec 2023 23:00:24 +0000</pubDate>
</item>
</channel>
</rss>

View File

@ -1,20 +0,0 @@
{
"name": "phlaym/photoprism-api",
"description": "An API for interacting with PhotoPrism",
"type": "library",
"require": {
"monolog/monolog": "^3.3",
"php": "^7.2 || ^8.0"
},
"autoload": {
"psr-4": {
"Phlaym\\PhotoprismApi\\": "src/"
}
},
"authors": [
{
"name": "Max Nuding",
"email": "max.nuding@icloud.com"
}
]
}

172
composer.lock generated
View File

@ -1,172 +0,0 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "efa28f7cbc00fac5f1688c4970983720",
"packages": [
{
"name": "monolog/monolog",
"version": "3.3.1",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "9b5daeaffce5b926cac47923798bba91059e60e2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/9b5daeaffce5b926cac47923798bba91059e60e2",
"reference": "9b5daeaffce5b926cac47923798bba91059e60e2",
"shasum": ""
},
"require": {
"php": ">=8.1",
"psr/log": "^2.0 || ^3.0"
},
"provide": {
"psr/log-implementation": "3.0.0"
},
"require-dev": {
"aws/aws-sdk-php": "^3.0",
"doctrine/couchdb": "~1.0@dev",
"elasticsearch/elasticsearch": "^7 || ^8",
"ext-json": "*",
"graylog2/gelf-php": "^1.4.2 || ^2@dev",
"guzzlehttp/guzzle": "^7.4.5",
"guzzlehttp/psr7": "^2.2",
"mongodb/mongodb": "^1.8",
"php-amqplib/php-amqplib": "~2.4 || ^3",
"phpstan/phpstan": "^1.9",
"phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-strict-rules": "^1.4",
"phpunit/phpunit": "^9.5.26",
"predis/predis": "^1.1 || ^2",
"ruflin/elastica": "^7",
"symfony/mailer": "^5.4 || ^6",
"symfony/mime": "^5.4 || ^6"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
"elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
"ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
"ext-mbstring": "Allow to work properly with unicode symbols",
"ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
"ext-openssl": "Required to send log messages using SSL",
"ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
"mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
"ruflin/elastica": "Allow sending log messages to an Elastic Search server"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Monolog\\": "src/Monolog"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "https://seld.be"
}
],
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
"homepage": "https://github.com/Seldaek/monolog",
"keywords": [
"log",
"logging",
"psr-3"
],
"support": {
"issues": "https://github.com/Seldaek/monolog/issues",
"source": "https://github.com/Seldaek/monolog/tree/3.3.1"
},
"funding": [
{
"url": "https://github.com/Seldaek",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
"type": "tidelift"
}
],
"time": "2023-02-06T13:46:10+00:00"
},
{
"name": "psr/log",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
"shasum": ""
},
"require": {
"php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/3.0.0"
},
"time": "2021-07-14T16:46:02+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": "^7.2 || ^8.0"
},
"platform-dev": [],
"plugin-api-version": "2.3.0"
}

4
config.json.example Normal file
View File

@ -0,0 +1,4 @@
{
"Klufti Affenhitze":
"https://webopac.winbiap.de/konstanz/detail.aspx?data=U29ydD1adWdhbmdzZGF0dW0gKEJpYmxpb3RoZWspJmFtcDtjbWQ9MSZhbXA7cFM9MTAmYW1wO0NhdGFsb2d1ZUlkPTEwNjYwNCZhbXA7cEk9MCZhbXA7c0M9Y18wPTAlJW1fMD0xJSVmXzA9MiUlb18wPTglJXZfMD1hZmZlbmhpdHplJSVnXzA9LTEmYW1wO3NDYXRJZD0xMDY2MDQmYW1wO3BhZ2VJZD0yJmFtcDtTcmM9Mg%3d%3d"
}

1
sonar-project.properties Normal file
View File

@ -0,0 +1 @@
community.rust.clippy.reportPaths=clippy-output.json

View File

@ -1,39 +0,0 @@
<?php
namespace Phlaym\PhotoprismApi\API;
use Monolog\Logger;
use Monolog\Handler\HandlerInterface;
/** Simple factory to create a logger without needing to set stream handlers every time */
class LoggerFactory
{
private static $handlers = [];
/**
* Add a new handler which is automatically added to the list of handlers
* for all _future_ loggers
*
* @param HandlerInterface $handler The handler to add
*
* @return void
*/
public static function addHandler(HandlerInterface $handler): void
{
self::$handlers[] = $handler;
}
/**
* Create a new Logger with the specified name
*
* @param string $name
*
* @return Logger
*/
public static function create(string $name): Logger
{
$l = new Logger($name);
$l->setHandlers(self::$handlers);
return $l;
}
}

View File

@ -1,448 +0,0 @@
<?php
namespace Phlaym\PhotoprismApi\API;
use Monolog\Logger;
use Monolog\Handler\RotatingFileHandler;
use Psr\Log\LoggerInterface;
use Phlaym\PhotoprismApi\Exceptions\NetworkException;
use Phlaym\PhotoprismApi\Exceptions\AuthenticationException;
use Phlaym\PhotoprismApi\Entities\Album;
use Phlaym\PhotoprismApi\Entities\Photo;
/**
* The main API class to interface with PhotoPrism
*/
class PhotoPrism
{
/** @var string $base_url Base URL of the PhotoPrism instance */
public string $base_url = 'https://photos.phlaym.net';
/** @var string $api_url API URL of the PhotoPrism instance */
public string $api_url = '';
/** @var string|null $session_id Session id of the currently logged in user */
protected ?string $session_id = null;
/** @var string|null $download_token Token for downloading files */
protected ?string $download_token = null;
/** @var string|null $preview_token Token for thumbnails files */
protected ?string $preview_token = null;
/** @var array $config Configuration options */
protected array $config;
/** @var LoggerInterface $logger Logger object */
protected LoggerInterface $logger;
/**
* Creates a new Photoprism API object from the configuration
*
* @param array $config Configuration dictionary
* @param string|null $log_path Path where the log files end up in.
* Will be set to `$log_path = __DIR__.'/logs/log.log';` if empty.
*
* @return void
*/
public function __construct(
array $config,
?string $log_path = null
) {
if (isset($config['host'])) {
$this->base_url = $str = rtrim($config['host'], '/');
}
$this->api_url = $this->base_url . '/api/v1';
$this->config = $config;
if (empty($log_path)) {
$log_path = __DIR__ . '/logs/log.log';
}
LoggerFactory::addHandler(new RotatingFileHandler($log_path, 5, Logger::DEBUG, true));
$this->logger = LoggerFactory::create('Phlaym\PhotoprismApi');
if (isset($_SESSION['pp_sessionid'])) {
$this->session_id = $_SESSION['pp_sessionid'];
$this->preview_token = $_SESSION['pp_preview_token'];
$this->download_token = $_SESSION['pp_download_token'];
}
}
/**
* Parse headers from a cURL HTTP response.
* Returns an array with the keys `headers` and `content`.
* The former is an array containing the headers (header name as key, value as value).
* The latter is a string with the body of the response
*
* @param string $response The complete response, containing the headers and body
*
* @return array
*/
private function parseHeaders(string $response): array
{
$response = explode("\r\n\r\n", $response, 2);
if (count($response) === 3) {
$dropped = array_shift($response);
$this->logger->warning('Dropping start of response:' . $dropped);
}
$headers = $response[0];
if ($headers === 'HTTP/1.1 100 Continue') {
$response = explode("\r\n\r\n", $response[1], 2);
$headers = $response[0];
}
if (isset($response[1])) {
$content = $response[1];
} else {
$content = '';
}
// this is not a good way to parse http headers
// it will not (for example) take into account multiline headers
// but what we're looking for is pretty basic, so we can ignore those shortcomings
$response_headers = explode("\r\n", $headers);
$header_arr = [];
foreach ($response_headers as $header) {
$header = explode(': ', $header, 2);
if (count($header) < 2) {
continue;
}
list($k,$v) = $header;
$header_arr[$k] = $v;
}
return ['headers' => $header_arr, 'content' => $content];
}
/**
* Sends a HTTP request using cURL
* Returns the body of the response
*
* @param string $method -The HTTP method to use
* @param string $path The HTTP request path without the API URL
* @param array $data Request data to send
* @param string $content_type Content-Type to use
*
* @throws NetworkException on failure
*
* @return string The response body
*/
private function makeRequest(
string $method,
string $path,
array $data = [],
string $content_type = 'application/json'
): string {
$url = $this->api_url . $path;
$method = strtolower($method);
$query_data = [];
$headers = [];
$result = null;
try {
if (is_array($data) && $method !== 'post-raw') {
if ($content_type === 'application/json') {
$query_data = json_encode($data);
} elseif ($content_type === 'multipart/form-data') {
$query_data = $data;
} else {
$query_data = http_build_query($data);
}
}
$ch = curl_init();
if ($method === 'get' && !empty($query_data)) {
$url .= '?' . $query_data;
}
if ($method !== 'get') {
$headers[] = 'Content-Type: ' . $content_type;
}
if (!empty($this->session_id)) {
$headers[] = 'X-Session-Id: ' . $this->session_id;
}
$this->logger->info($method . ' request to ' . $url);
$this->logger->debug('Headers ' . json_encode($headers));
$this->logger->debug('postfields data ' . json_encode($data));
$this->logger->debug('postfields ' . json_encode($query_data));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, $method !== 'get');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if ($method !== 'get' && !empty($query_data)) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $query_data);
}
$output = curl_exec($ch);
// $request = curl_getinfo($ch, CURLINFO_HEADER_OUT);
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($output === false) {
throw new NetworkException("Error sending request to " . $url, 0);
}
if (empty($output) || $output === false) {
$e = new NetworkException("No answer from" . $url, 0);
$this->logger->error(
"Error sending request. No answer from server",
['Exception' => print_r($e, true)]
);
throw $e;
}
if ($http_status === 0) {
throw new NetworkException('Unable to connect to API ' . $url);
}
if ($http_status >= 400) {
throw new NetworkException('Invalid response ' . $url . ': ' . $http_status);
}
$result = $this->parseHeaders($output);
} catch (\Exception $e) {
$this->logger->error("Error sending request", ['Exception' => print_r($e, true)]);
throw new NetworkException("Error sending request to " . $url, 0, $e);
}
return $result['content'];
}
/**
* Log in to PhotoPrism.
* If already logged in nothing happens.
* No check whether the session is still valid is performed
* @throws AuthenticationException on failure
*
* @param bool $force -Force re-login even if already logged in
*/
public function login(bool $force = false): void
{
if (!empty($this->session_id) && !$force) {
$this->logger->info('Skipping login, already logged in');
return;
}
$data = [
'username' => $this->config['username'],
'password' => $this->config['password'],
];
$res = $this->makeRequest('POST', '/session', $data);
$this->logger->info('Login result: ' . $res);
$response = json_decode($res, true);
if (!empty($response['error'])) {
throw new AuthenticationException($response['error']);
}
$this->session_id = $response['id'];
$this->download_token = $response['config']['downloadToken'];
$this->preview_token = $response['config']['previewToken'];
$_SESSION['pp_sessionid'] = $this->session_id;
$_SESSION['pp_preview_token'] = $this->preview_token;
$_SESSION['pp_download_token'] = $this->download_token;
$this->logger->debug('Session ID: ' . $this->session_id . ', preview token: ' . $this->preview_token);
}
/**
* Fetches albums from PhotoPrism
* @throws NetworkException on failure
*
* @param int $count -Maximum amount of albums to fetch
* @param int $offset -Number of albums to skip
* @return Album[]
*/
public function getAlbums(int $count = 1000, int $offset = 0): array
{
$data = [
'count' => $count,
'offset' => $offset,
'type' => 'album'
];
$res = $this->makeRequest('GET', '/albums', $data, 'text/plain');
$response = json_decode($res, true);
if (!empty($response['error'])) {
throw new NetworkException($response['error']);
}
$albums = array_map(
function ($entry) {
return new Album($entry);
},
$response
);
$this->logger->debug('Albums' . json_encode($albums));
return $albums;
}
/**
* Fetches albums from PhotoPrism which can be viewed with the provided tokens
* @throws NetworkException on failure
* @param string[] $tokens -A list of tokens by which the albums are filtered
* @param int $count -Maximum amount of albums to fetch
* @param int $offset -Number of albums to skip
* @return Album[]
*/
public function getAlbumsByTokens(array $tokens, int $count = 1000, int $offset = 0): array
{
$this->logger->debug('getAlbumsByToken');
$albums = $this->getAlbums($count, $offset);
$visibleAlbums = [];
foreach ($albums as $album) {
$token = $this->getAlbumToken($album);
$album->token = $token;
if ($token != null && in_array($album->token, $tokens)) {
$visibleAlbums[] = $album;
} else {
$this->logger->debug('Skipping album without access: ' . $album->title);
}
}
$this->logger->debug('getAlbumsByToken' . json_encode($visibleAlbums));
return $visibleAlbums;
}
/**
* Fetches an album from PhotoPrism which can be viewed with the provided token
* @throws NetworkException on failure
* @param string $token -A token by which the albums are filtered
* @return Album|null
*/
public function getAlbumByToken(string $token): ?Album
{
$this->logger->debug('getAlbumByToken');
$albums = $this->getAlbumsByTokens([$token]);
if (empty($albums)) {
$this->logger->debug('Could not find album for token' . $token);
return null;
}
$this->logger->debug('getAlbumByToken done');
return $albums[0];
}
/**
* Fetches an album from PhotoPrism with the specified id. Needs an access token!
* @throws NetworkException on failure
* @param string $id -id of the album
* @param string $token -Access token
* @return Album|null
*/
public function getAlbumById(string $id, string $token): ?Album
{
$this->logger->debug('getAlbumById', ['id' => $id]);
$res = $this->makeRequest('GET', '/albums/' . $id, [], 'text/plain');
$response = json_decode($res, true);
if (!empty($response['error'])) {
throw new NetworkException($response['error']);
}
$album = new Album($response);
$album_token = $this->getAlbumToken($album);
$album->token = $album_token;
if ($album_token != null && $album_token == $token) {
return $album;
}
$this->logger->warning('getAlbumById: Invalid token');
return null;
}
/**
* Fetches the secret token of an album
* @throws NetworkException on failure
*
* @param Album $album -The album which's toke should be fetched
* @return string|null Album token or null if the album is private
*/
public function getAlbumToken($album): ?string
{
$uid = is_string($album) ? $album : $album->uid;
$res = $this->makeRequest('GET', '/albums/' . $uid . '/links');
/** @var array $response */
$this->logger->debug('Token response: ' . $res);
$response_array = json_decode($res, true);
if (empty($response_array)) {
$this->logger->warning('Empty response: ' . json_encode($res));
return null;
}
$response = $response_array[0];
if (!empty($response['error'])) {
throw new NetworkException($response['error']);
}
if (!isset($response['Token'])) {
return null;
}
return $response['Token'];
}
/**
* Upload photos, optionally add them to a specific album
* @throws NetworkException on failure
* @param string|null $album -The album UID to which the photos should be aded
*/
public function uploadPhotos(?string $album = null): void
{
$path = time();
$url = '/upload/' . $path;
$import_url = '/import' . $url;
foreach (array_keys($_FILES['files']['tmp_name']) as $key) {
$file_tmpname = $_FILES['files']['tmp_name'][$key];
$this->logger->info('Uploading ' . $file_tmpname . ' to ' . $url);
$filename = basename($_FILES['files']['name'][$key]);
$cFile = curl_file_create($file_tmpname, $_FILES['files']['type'][$key], $filename);
$data = ['files' => $cFile];
$res = $this->makeRequest('POST', $url, $data, 'multipart/form-data');
$this->logger->info('Upload result: ' . $res);
}
$this->logger->info('Importing files');
/** @var string[] $albums */
$albums = empty($album) ? [] : [$album];
$import_data = ["move" => true, "albums" => $albums];
$res = $this->makeRequest('POST', $import_url, $import_data);
$this->logger->info('Import result: ' . $res);
}
/**
* Retrieves the photos of an album
* @throws NetworkException on failure
* @param Album $album - The album to which the photos should be loaded
* @param int $count - How many photos should be loaded
* @param int $offset - Offset for paging
* @return Photo[] - Photos in the album
*/
public function getAlbumPhotos(Album $album, int $count = 60, int $offset = 0): array
{
$this->logger->debug('getAlbumPhotos');
$data = [
'album' => $album->uid,
'count' => $count,
'offset' => $offset
];
$res = $this->makeRequest('GET', '/photos', $data, 'text/plain');
$response = json_decode($res, true);
if (!empty($response['error'])) {
throw new NetworkException($response['error']);
}
$this->logger->debug('getAlbumPhotos response');
$photos = array_map(
function ($entry) {
$photo = new Photo($entry);
$photo->thumbnail_token = $this->preview_token;
return $photo;
},
$response
);
$this->logger->info('Got photos:' . json_encode($photos));
$photos = array_filter(
$photos,
function ($obj) {
static $idList = array();
if (in_array($obj->uid, $idList)) {
return false;
}
$idList[] = $obj->uid;
return true;
}
);
$this->logger->info('unique photos:' . json_encode($photos));
return $photos;
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,62 +0,0 @@
<?php
namespace Phlaym\PhotoprismApi\Entities;
use Phlaym\PhotoprismApi\API\LoggerFactory;
use Psr\Log\LoggerInterface;
/** A PhotoPrism Album */
class Album
{
/** @var string $uid Unique Id of the album */
public string $uid = '';
/** @var string $slug URL slug of the album */
public string $slug = '';
/** @var string $title Title of the album */
public string $title = '';
/** @var string|null $token Secret token of the album. Needs to be set by the API */
public ?string $token = null;
/** @var int $photoCount Number of photos in Album */
public int $photoCount = 0;
/** @var LoggerInterface $logger Logger object */
private LoggerInterface $logger;
/**
* Creates a new album from the api response
*
* @param array $response Photoprism API response containing an album object
*
* @return void
*/
public function __construct(
array $response
) {
$this->uid = $response['UID'];
$this->slug = $response['Slug'];
$this->title = $response['Title'];
if (isset($response['PhotoCount'])) {
$this->photoCount = $response['PhotoCount'];
}
$this->logger = LoggerFactory::create('Phlaym\PhotoprismApi.Album');
}
/**
* Gets the URL path for this album.
* Starts with a leading /
* Returns null if the album's token is not set
*
* @return string|null
*/
public function getUrlPath(): ?string
{
if (empty($this->token)) {
return null;
}
return "/s/{$this->token}/{$this->slug}";
}
}

View File

@ -1,77 +0,0 @@
<?php
namespace Phlaym\PhotoprismApi\Entities;
use Phlaym\PhotoprismApi\API\LoggerFactory;
use Psr\Log\LoggerInterface;
/** A PhotoPrism Photo */
class Photo
{
/** @var string $thumbnail_token Token for fetching the thumbnail*/
public string $thumbnail_token = '';
/** @var string $uid Unique Id of the photo */
public string $uid = '';
/** @var string $id Id of the photo */
public int $id = 0;
/** @var string $type Type of the photo (image, video, etc) */
public string $type = '';
public string $fileUID;
public string $fileRoot;
public string $fileName;
public string $hash;
public int $width;
public int $height;
public array $files;
/** @var LoggerInterface $logger Logger object */
private LoggerInterface $logger;
/**
* Creates a new photo from the api response
*
* @param array $response Photoprism API response containing a photo object
*
* @return void
*/
public function __construct(
array $response
) {
$this->uid = $response['UID'];
$this->id = intval($response['ID']);
$this->type = $response['Type'];
$this->fileUID = $response['FileUID'];
$this->fileRoot = $response['FileRoot'];
$this->fileName = $response['FileName'];
$this->hash = $response['Hash'];
$this->width = intval($response['Width']);
$this->height = intval($response['Height']);
$this->logger = LoggerFactory::create('Phlaym\PhotoprismApi.Photo');
}
/**
* Gets the thumbnail URL path for this image.
* Starts with a leading /
*
* @return string
*/
public function getThumbnailUrl(string $size = 'tile_500'): string
{
return "/t/{$this->hash}/{$this->thumbnail_token}/{$size}";
}
/**
* Gets the thumbnail URL path for this image.
* Starts with a leading /
*
* @return string
*/
public function getEmbedUrl(string $size = 'fit_1920'): string
{
return "/api/v1/t/{$this->hash}/{$this->thumbnail_token}/{$size}";
}
}

View File

@ -1,7 +0,0 @@
<?php
namespace Phlaym\PhotoprismApi\Exceptions;
class AuthenticationException extends \Exception
{
}

View File

@ -1,7 +0,0 @@
<?php
namespace Phlaym\PhotoprismApi\Exceptions;
class NetworkException extends \Exception
{
}

173
src/main.rs Normal file
View File

@ -0,0 +1,173 @@
use config::Config;
use reqwest::header;
use rss::{Channel, ChannelBuilder, GuidBuilder, ItemBuilder};
use scraper::{Html, Selector};
use std::collections::{HashMap, HashSet};
use std::{error::Error, fs::File, io::BufReader};
use chrono::prelude::*;
const FILE_NAME: &str = "bib.xml";
fn get_last_status(title: &str) -> Result<String, Box<dyn Error>> {
let file = File::open(FILE_NAME);
let channel = match file {
Ok(f) => Channel::read_from(BufReader::new(f)),
Err(_) => {
let c = ChannelBuilder::default()
.title("Bib Watcher".to_string())
.description("Watches availability status of library books".to_string())
.link("https://feeds.phlaym.net/".to_string() + FILE_NAME)
.build();
c.pretty_write_to(File::create(FILE_NAME)?, b' ', 4)?;
Ok(c)
}
}?;
Ok(channel
.items()
.iter()
.filter(|i| i.title().unwrap_or("") == title)
.last()
.and_then(|i| i.description())
.unwrap_or("")
.into())
}
fn main() -> Result<(), Box<dyn Error>> {
let settings = Config::builder()
.add_source(config::File::with_name("config.json"))
.build()?;
let books = settings.try_deserialize::<HashMap<String, String>>()?;
let searches = books.iter().collect::<HashMap<&String, &String>>();
for (title, url) in searches {
search(url, title)?
}
let urls = books.values().collect();
remove_old_books(&urls)?;
Ok(())
}
fn remove_old_books(urls: &HashSet<&String>) -> Result<(), Box<dyn Error>> {
let file = File::open(FILE_NAME)?;
let mut channel = Channel::read_from(BufReader::new(file))?;
let items: Vec<_> = channel.items
.iter()
.filter(|i|i.link.as_ref().is_some_and(|l|urls.contains(&l)))
.map(|i|i.clone())
.collect();
channel.set_items(items);
channel.pretty_write_to(File::create(FILE_NAME)?, b' ', 4)?;
Ok(())
}
fn search(url: &str, title: &str) -> Result<(), Box<dyn Error>> {
let mut headers = header::HeaderMap::new();
headers.append(
header::ACCEPT,
header::HeaderValue::from_static(
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
),
);
headers.append(
header::HOST,
header::HeaderValue::from_static("webopac.winbiap.de"),
);
headers.append(
header::REFERER,
header::HeaderValue::from_static("https://webopac.winbiap.de/"),
);
let client = reqwest::blocking::Client::builder()
.default_headers(headers)
.build()?;
let request = client.get(url).build()?;
let response = client.execute(request)?;
let response_text = response.text()?;
let status = parse(&response_text.clone())?;
match status {
None => Ok(()),
Some(x) if x == "online" => {
let id = parse_id(&response_text)?;
let s = check_ebook_status(id)?;
write_item(&s, title, url)?;
Ok(())
}
Some(s) => {
write_item(&s, title, url)?;
Ok(())
}
}
}
fn write_item(status: &str, title: &str, url: &str) -> Result<(), Box<dyn Error>> {
let last_status = get_last_status(title)?;
if last_status == status {
return Ok(());
}
let file = File::open(FILE_NAME);
let mut channel = match file {
Ok(f) => Channel::read_from(BufReader::new(f)),
Err(_) => Ok(ChannelBuilder::default()
.title("Bib Watcher".to_string())
.description("Watches availability status of library books".to_string())
.link("https://feeds.phlaym.net/".to_string() + FILE_NAME)
.build()),
}?;
let mut items = channel.clone().into_items();
let guid = GuidBuilder::default()
.value(title.to_string() + &Utc::now().to_rfc2822())
.permalink(false)
.build();
items.push(
ItemBuilder::default()
.title(Some(title.to_string()))
.pub_date(Some(Utc::now().to_rfc2822()))
.link(Some(url.to_string()))
.description(Some(status.into()))
.guid(Some(guid))
.build(),
);
channel.set_items(items);
channel.pretty_write_to(File::create(FILE_NAME)?, b' ', 4)?;
Ok(())
}
fn check_ebook_status(ebook_id: u32) -> Result<String, Box<dyn Error>> {
let id_param = ebook_id.to_string();
let client = reqwest::blocking::Client::new(); // ::builder().build()?;
let request = client
.post("https://webopac.winbiap.de/konstanz/service/ncipservice.ashx")
.form(&HashMap::from([
("action", "lookup"),
("itemId", &id_param),
]))
.build()?;
let response = client.execute(request)?;
let v: serde_json::Value = serde_json::from_reader(response)?;
let v2: &serde_json::Value = &v["MediaItem"]["Available"];
let a: bool = serde_json::value::from_value(v2.clone())?;
Ok((if a { "verfügbar" } else { "entliehen" }).into())
}
fn parse(html: &str) -> Result<Option<String>, Box<dyn Error>> {
let document = Html::parse_document(html);
let selector = Selector::parse("#detail-left-wrapper .mediaStatus span")?;
Ok(document
.select(&selector)
.next()
.map(|r| r.text().collect::<String>()))
}
fn parse_id(html: &str) -> Result<u32, Box<dyn Error>> {
let document = Html::parse_document(html);
let selector = Selector::parse("#hyperlinkDiviBib")?;
document
.select(&selector)
.next()
.and_then(|r| r.value().attr("data-id"))
.unwrap_or("Unknown")
.parse::<u32>()
.map_err(From::from)
}