├── .dockerignore
├── .gitignore
├── .gitremotes
├── .htaccess
├── CHANGELOG.md
├── CHANGELOG.seblucas.md
├── DESIGN.md
├── LICENSE
├── README.md
├── SECURITY.md
├── TRANSLATIONS.md
├── build.xml
├── checkconfig.php
├── composer.json
├── composer.lock
├── config
├── .gitignore
├── config.php
├── default.php
├── loader.php
├── local.php.example
├── test.php
└── tooltips.php
├── docker-compose-dev.yaml
├── docker-compose-lsio.yaml
├── docker-compose.yaml
├── docker
├── Dockerfile.alpine
├── Dockerfile.linuxserver
└── Dockerfile.webdevops
├── favicon.ico
├── images
├── allbook.png
├── author.png
├── bookcover.png
├── custom.png
├── icons
│ ├── icon114.png
│ ├── icon144.png
│ ├── icon57.png
│ └── icon72.png
├── language.png
├── publisher.png
├── rating.png
├── recent.png
├── serie.png
└── tag.png
├── index.php
├── lang
├── Localization_af.json
├── Localization_bg.json
├── Localization_ca.json
├── Localization_cs.json
├── Localization_da.json
├── Localization_de.json
├── Localization_el.json
├── Localization_en.json
├── Localization_es.json
├── Localization_eu.json
├── Localization_fr.json
├── Localization_gl.json
├── Localization_hr.json
├── Localization_ht.json
├── Localization_hu.json
├── Localization_id.json
├── Localization_it.json
├── Localization_ja.json
├── Localization_ko.json
├── Localization_nb.json
├── Localization_nl.json
├── Localization_pl.json
├── Localization_pt_BR.json
├── Localization_pt_PT.json
├── Localization_ro.json
├── Localization_ru.json
├── Localization_sl.json
├── Localization_sr.json
├── Localization_sv.json
├── Localization_tr.json
├── Localization_uk.json
├── Localization_zh_CN.json
└── Localization_zh_TW.json
├── login.html
├── package.json
├── phpstan-baseline.neon
├── phpstan.neon.dist
├── phpunit.xml.dist
├── resources
├── cache.graphql.php
├── dot-php
│ ├── .hgtags
│ ├── LICENSE
│ ├── README.md
│ ├── composer.json
│ └── doT.php
├── js-cookie
│ ├── README.md
│ └── js.cookie.js
├── monocle
│ ├── README.md
│ ├── scripts
│ │ ├── monocore.js
│ │ └── monoctrl.js
│ └── styles
│ │ ├── monocore.css
│ │ └── monoctrl.css
├── openapi.json
├── schema.graphql
└── simonpioli
│ └── sortelements
│ ├── README.md
│ └── jquery.sortElements.js
├── router.php
├── src
├── .gitignore
├── Calibre
│ ├── Annotation.php
│ ├── Author.php
│ ├── Base.php
│ ├── BaseList.php
│ ├── Book.php
│ ├── BookList.php
│ ├── Category.php
│ ├── Cover.php
│ ├── CustomColumn.php
│ ├── CustomColumnType.php
│ ├── CustomColumnTypeBool.php
│ ├── CustomColumnTypeComment.php
│ ├── CustomColumnTypeDate.php
│ ├── CustomColumnTypeEnumeration.php
│ ├── CustomColumnTypeFloat.php
│ ├── CustomColumnTypeInteger.php
│ ├── CustomColumnTypeRating.php
│ ├── CustomColumnTypeSeries.php
│ ├── CustomColumnTypeText.php
│ ├── Data.php
│ ├── Database.php
│ ├── Filter.php
│ ├── Format.php
│ ├── Identifier.php
│ ├── Language.php
│ ├── Metadata.php
│ ├── Note.php
│ ├── Preference.php
│ ├── Publisher.php
│ ├── Rating.php
│ ├── Resource.php
│ ├── Serie.php
│ ├── Tag.php
│ ├── User.php
│ └── VirtualLibrary.php
├── Framework
│ ├── Adapter
│ │ ├── AdapterInterface.php
│ │ └── CustomAdapter.php
│ ├── Framework.php
│ └── FrameworkTodo.php
├── Handlers
│ ├── AdminHandler.php
│ ├── BaseHandler.php
│ ├── CalResHandler.php
│ ├── CheckHandler.php
│ ├── CorsHandler.php
│ ├── EpubFsHandler.php
│ ├── ErrorHandler.php
│ ├── FeedHandler.php
│ ├── FetchHandler.php
│ ├── GraphQLHandler.php
│ ├── HandlerManager.php
│ ├── HasRouteTrait.php
│ ├── HtmlHandler.php
│ ├── JsonHandler.php
│ ├── LoaderHandler.php
│ ├── MailHandler.php
│ ├── OpdsHandler.php
│ ├── PageHandler.php
│ ├── QueueBasedHandler.php
│ ├── ReadHandler.php
│ ├── RestApiHandler.php
│ ├── TableHandler.php
│ ├── TestHandler.php
│ ├── ZipFsHandler.php
│ └── ZipperHandler.php
├── Input
│ ├── Config.php
│ ├── HasContextInterface.php
│ ├── HasContextTrait.php
│ ├── ProxyRequest.php
│ ├── Request.php
│ ├── RequestContext.php
│ ├── Route.php
│ └── Session.php
├── Language
│ ├── Normalizer.php
│ ├── Slugger.php
│ └── Translation.php
├── Middleware
│ ├── BaseMiddleware.php
│ └── TestMiddleware.php
├── Model
│ ├── Entry.php
│ ├── EntryBook.php
│ ├── Link.php
│ ├── LinkAcquisition.php
│ ├── LinkFacet.php
│ ├── LinkFeed.php
│ ├── LinkImage.php
│ ├── LinkNavigation.php
│ └── LinkResource.php
├── Output
│ ├── BaseRenderer.php
│ ├── DotPHPTemplate.php
│ ├── EPubReader.php
│ ├── FileResponse.php
│ ├── Format.php
│ ├── GraphQLExecutor.php
│ ├── HtmlRenderer.php
│ ├── JsonRenderer.php
│ ├── KiwilanOPDS.php
│ ├── Mail.php
│ ├── OpdsRenderer.php
│ ├── OpenApi.php
│ ├── Response.php
│ ├── RestApiProvider.php
│ ├── TwigTemplate.php
│ └── Zipper.php
├── Pages
│ ├── Page.php
│ ├── PageAbout.php
│ ├── PageAllAuthors.php
│ ├── PageAllAuthorsLetter.php
│ ├── PageAllBooks.php
│ ├── PageAllBooksLetter.php
│ ├── PageAllBooksYear.php
│ ├── PageAllCustoms.php
│ ├── PageAllFormats.php
│ ├── PageAllIdentifiers.php
│ ├── PageAllLanguages.php
│ ├── PageAllPublishers.php
│ ├── PageAllPublishersLetter.php
│ ├── PageAllRating.php
│ ├── PageAllSeries.php
│ ├── PageAllSeriesLetter.php
│ ├── PageAllTags.php
│ ├── PageAllTagsLetter.php
│ ├── PageAllVirtualLibraries.php
│ ├── PageAuthorDetail.php
│ ├── PageBookDetail.php
│ ├── PageCustomDetail.php
│ ├── PageCustomize.php
│ ├── PageFilter.php
│ ├── PageFormatDetail.php
│ ├── PageId.php
│ ├── PageIdentifierDetail.php
│ ├── PageIndex.php
│ ├── PageLanguageDetail.php
│ ├── PagePublisherDetail.php
│ ├── PageQueryResult.php
│ ├── PageQueryScope.php
│ ├── PageRatingDetail.php
│ ├── PageRecentBooks.php
│ ├── PageSerieDetail.php
│ ├── PageTagDetail.php
│ └── PageWithDetail.php
├── Routing
│ ├── FastRouter.php
│ ├── RouteLoader.php
│ ├── RouterInterface.php
│ ├── Routing.php
│ ├── UriGenerator.php
│ ├── url_cached_routes.php
│ ├── url_fastroute_cache.php
│ ├── url_generating_routes.php
│ ├── url_generating_routes.php.meta
│ ├── url_generating_routes.php.meta.json
│ ├── url_matching_routes.php
│ ├── url_matching_routes.php.meta
│ └── url_matching_routes.php.meta.json
└── functions.php
├── styles
├── cops-monocle.css
└── cops-monocle.js
├── templates
├── about.html
├── admin.html
├── bootstrap
│ ├── bookdetail.html
│ ├── file.html
│ ├── footer.html
│ ├── header.html
│ ├── main.html
│ ├── page.html
│ ├── scripts
│ │ └── cops.js
│ ├── styles
│ │ ├── style-base.css
│ │ └── style-default.css
│ └── suggestion.html
├── bootstrap2
│ ├── bookdetail.html
│ ├── file.html
│ ├── footer.html
│ ├── header.html
│ ├── main.html
│ ├── page.html
│ ├── scripts
│ │ └── cops.js
│ ├── styles
│ │ ├── style-base.css
│ │ ├── style-default.css
│ │ ├── style-kindle.css
│ │ └── typeahead.css
│ └── suggestion.html
├── bootstrap5
│ ├── bookdetail.html
│ ├── file.html
│ ├── footer.html
│ ├── header.html
│ ├── main.html
│ ├── page.html
│ ├── scripts
│ │ └── cops.js
│ ├── styles
│ │ ├── bootstrap5.css
│ │ ├── style-base.css
│ │ ├── style-default.css
│ │ └── typeahead.css
│ └── suggestion.html
├── checkconfig.html
├── default
│ ├── bookdetail.html
│ ├── file.html
│ ├── footer.html
│ ├── header.html
│ ├── main.html
│ ├── page.html
│ ├── styles
│ │ ├── fa-solid.min.css
│ │ ├── fontawesome.min.css
│ │ ├── style-base.css
│ │ ├── style-default.css
│ │ ├── style-eink.css
│ │ ├── style-iphone.css
│ │ ├── style-iphone7.css
│ │ ├── style-kindle.css
│ │ └── typeahead.css
│ ├── suggestion.html
│ └── webfonts
│ │ ├── fa-solid-900.eot
│ │ ├── fa-solid-900.svg
│ │ ├── fa-solid-900.ttf
│ │ ├── fa-solid-900.woff
│ │ └── fa-solid-900.woff2
├── epubjs-reader.html
├── epubreader.html
├── error.html
├── graphql.html
├── notfound.html
├── restapi.html
├── tables.html
└── twigged
│ ├── README.md
│ ├── about.html
│ ├── authordetail.html
│ ├── base.html
│ ├── bookdetail.html
│ ├── booklist.html
│ ├── customdetail.html
│ ├── customize.html
│ ├── extra_info.html
│ ├── extra_series.html
│ ├── filters.html
│ ├── identifierdetail.html
│ ├── index.html
│ ├── languagedetail.html
│ ├── loader
│ ├── README.md
│ ├── actions.html
│ ├── databases.html
│ └── index.html
│ ├── mainlist.html
│ ├── navlist.html
│ ├── page.html
│ ├── publisherdetail.html
│ ├── ratingdetail.html
│ ├── recent.html
│ ├── scripts
│ └── cops.js
│ ├── seriedetail.html
│ ├── styles
│ ├── style-base.css
│ ├── style-default.css
│ └── typeahead.css
│ ├── suggestion.html
│ ├── tagdetail.html
│ └── var_dump.json.twig
├── tests
├── .gitignore
├── BaseWithCustomColumns
│ └── metadata.db
├── BaseWithOneBook
│ └── metadata.db
├── BaseWithSomeBooks
│ ├── .calnotes
│ │ ├── notes.db
│ │ └── resources
│ │ │ ├── 7c
│ │ │ ├── xxh64-7c301792c52eebf7
│ │ │ └── xxh64-7c301792c52eebf7.metadata
│ │ │ ├── c0
│ │ │ ├── xxh64-c062fb16e3568fdc
│ │ │ └── xxh64-c062fb16e3568fdc.metadata
│ │ │ └── d7
│ │ │ ├── xxh64-d7e814ba6a1b41d1
│ │ │ └── xxh64-d7e814ba6a1b41d1.metadata
│ ├── Lewis Carroll
│ │ └── Alice's Adventures in Wonderland (17)
│ │ │ ├── Alice's Adventures in Wonderland - Lewis Carroll.epub
│ │ │ ├── cover.jpg
│ │ │ ├── data
│ │ │ ├── hello.txt
│ │ │ └── sub folder
│ │ │ │ └── copied file.txt
│ │ │ └── metadata.opf
│ ├── Sun Wu
│ │ └── Sun Zi Bing Fa (19)
│ │ │ ├── Sun Zi Bing Fa - Sun Wu.epub
│ │ │ ├── cover.jpg
│ │ │ └── metadata.opf
│ ├── hierarchical_type2.sql
│ ├── metadata.db
│ └── users.db
├── BookListTest.php
├── BookTest.php
├── BrowserKitTest.php
├── ConfigTest.php
├── EpubFsTest.php
├── EpubReaderTest.php
├── FetchHandlerTest.php
├── FilterTest.php
├── FrameworkTest.php
├── FrameworkTodoTest.php
├── GraphQLHandlerTest.php
├── HierarchyTest.php
├── HtmlRendererTest.php
├── JsonRendererTest.php
├── KiwilanTest.php
├── MailTest.php
├── NoteResourceTest.php
├── OPDSValidator.jar
├── OpdsRendererTest.php
├── PageMultiDatabaseTest.php
├── PageTest.php
├── ResponseTest.php
├── RestApiTest.php
├── RouteTest.php
├── Routing
│ ├── FastRouterTest.php
│ ├── RoutingTest.php
│ └── UriGeneratorTest.php
├── SessionTest.php
├── TypeAheadSearchTest.php
├── UserTest.php
├── WebDriverTest.php
├── WebDriverTestCase.php
├── ZipperTest.php
├── baseTest.php
├── composer.kiwilan.json
├── customColumnsTest.php
├── graphql
│ ├── author.query.graphql
│ ├── author.query.json
│ ├── author.result.json
│ ├── authors.query.graphql
│ ├── authors.query.json
│ ├── authors.result.json
│ ├── book.query.graphql
│ ├── book.query.json
│ ├── book.result.json
│ ├── books.query.graphql
│ ├── books.query.json
│ ├── books.result.json
│ ├── customColumn.query.graphql
│ ├── customColumn.query.json
│ ├── customColumn.result.json
│ ├── customColumns.query.graphql
│ ├── customColumns.query.json
│ ├── customColumns.result.json
│ ├── data.query.graphql
│ ├── data.query.json
│ ├── data.result.json
│ ├── datas.query.graphql
│ ├── datas.query.json
│ ├── datas.result.json
│ ├── format.query.graphql
│ ├── format.query.json
│ ├── format.result.json
│ ├── formats.query.graphql
│ ├── formats.query.json
│ ├── formats.result.json
│ ├── getAuthor.3.result.json
│ ├── getAuthors.l.2.result.json
│ ├── getNode.authors.3.result.json
│ ├── getNode.books.17.result.json
│ ├── getNode.datas.20.result.json
│ ├── getNode.oops.42.result.json
│ ├── identifier.query.graphql
│ ├── identifier.query.json
│ ├── identifier.result.json
│ ├── identifiers.query.graphql
│ ├── identifiers.query.json
│ ├── identifiers.result.json
│ ├── language.query.graphql
│ ├── language.query.json
│ ├── language.result.json
│ ├── languages.query.graphql
│ ├── languages.query.json
│ ├── languages.result.json
│ ├── node.query.graphql
│ ├── node.query.json
│ ├── node.result.json
│ ├── nodelist.query.graphql
│ ├── nodelist.query.json
│ ├── nodelist.result.json
│ ├── preference.query.graphql
│ ├── preference.query.json
│ ├── preference.result.json
│ ├── preferences.query.graphql
│ ├── preferences.query.json
│ ├── preferences.result.json
│ ├── publisher.query.graphql
│ ├── publisher.query.json
│ ├── publisher.result.json
│ ├── publishers.query.graphql
│ ├── publishers.query.json
│ ├── publishers.result.json
│ ├── rating.query.graphql
│ ├── rating.query.json
│ ├── rating.result.json
│ ├── ratings.query.graphql
│ ├── ratings.query.json
│ ├── ratings.result.json
│ ├── search.query.graphql
│ ├── search.query.json
│ ├── search.result.json
│ ├── serie.query.graphql
│ ├── serie.query.json
│ ├── serie.result.json
│ ├── series.query.graphql
│ ├── series.query.json
│ ├── series.result.json
│ ├── tag.query.graphql
│ ├── tag.query.json
│ ├── tag.result.json
│ ├── tags.query.graphql
│ ├── tags.query.json
│ ├── tags.result.json
│ └── test.query.graphql
├── jing.jar
├── opds-relax-ng
│ ├── atom.rng
│ ├── opds_catalog_1_1.rng
│ ├── opds_catalog_1_2.rng
│ └── opensearchdescription.rng
├── res
│ ├── atom.rnc
│ ├── opds_v1.0.rnc
│ ├── opds_v1.1.rnc
│ └── opds_v1.2.rnc
├── restapi
│ ├── check-more.html
│ ├── check.html
│ ├── page-about.json
│ ├── page-author-id.json
│ ├── page-author.json
│ ├── page-authors-letter.json
│ ├── page-authors-letters.json
│ ├── page-authors.json
│ ├── page-book-id.json
│ ├── page-book.json
│ ├── page-books-letter.json
│ ├── page-books-letters.json
│ ├── page-books-year.json
│ ├── page-books-years.json
│ ├── page-books.json
│ ├── page-custom.json
│ ├── page-customize.json
│ ├── page-customtype.json
│ ├── page-filter.json
│ ├── page-format.json
│ ├── page-formats.json
│ ├── page-identifier-id.json
│ ├── page-identifier.json
│ ├── page-identifiers.json
│ ├── page-index.json
│ ├── page-language-id.json
│ ├── page-language.json
│ ├── page-languages.json
│ ├── page-libraries.json
│ ├── page-publisher-id.json
│ ├── page-publisher.json
│ ├── page-publishers-letter.json
│ ├── page-publishers-letters.json
│ ├── page-publishers.json
│ ├── page-query-scope.json
│ ├── page-query.json
│ ├── page-rating-id.json
│ ├── page-rating.json
│ ├── page-ratings.json
│ ├── page-recent.json
│ ├── page-search.json
│ ├── page-serie-id.json
│ ├── page-serie.json
│ ├── page-series-letter.json
│ ├── page-series-letters.json
│ ├── page-series.json
│ ├── page-tag-id.json
│ ├── page-tag.json
│ ├── page-tags-letter.json
│ ├── page-tags-letters.json
│ ├── page-tags.json
│ ├── page-typeahead.json
│ ├── restapi-annotation.json
│ ├── restapi-annotations-book.json
│ ├── restapi-annotations.json
│ ├── restapi-customtypes.json
│ ├── restapi-database-table.json
│ ├── restapi-database.json
│ ├── restapi-databases.json
│ ├── restapi-handler.json
│ ├── restapi-metadata-element-name.json
│ ├── restapi-metadata-element.json
│ ├── restapi-metadata.json
│ ├── restapi-note.json
│ ├── restapi-notes-type-id.json
│ ├── restapi-notes-type.json
│ ├── restapi-notes.json
│ ├── restapi-openapi.json
│ ├── restapi-path.html
│ ├── restapi-path.json
│ ├── restapi-preference.json
│ ├── restapi-preferences.json
│ ├── restapi-route.json
│ ├── restapi-user-details.json
│ └── restapi-user.json
└── schema
│ ├── opds
│ ├── feed-metadata.schema.json
│ ├── feed.schema.json
│ ├── properties.schema.json
│ └── publication.schema.json
│ └── readium
│ ├── contributor-object.schema.json
│ ├── contributor.schema.json
│ ├── extensions
│ ├── epub
│ │ ├── metadata.schema.json
│ │ └── properties.schema.json
│ └── presentation
│ │ ├── metadata.schema.json
│ │ └── properties.schema.json
│ ├── language-map.schema.json
│ ├── link.schema.json
│ ├── metadata.schema.json
│ ├── subcollection.schema.json
│ ├── subject-object.schema.json
│ └── subject.schema.json
├── tools
├── multi-platform.sh
└── selenium.sh
├── util.js
├── web.config
└── yarn.lock
/.dockerignore:
--------------------------------------------------------------------------------
1 | .git/
2 | *.zip
3 | config/local.php
4 | tests/
5 | # keep the test database in the image here
6 | !tests/BaseWithSomeBooks/
7 | tests/BaseWithSomeBooks/.calnotes/backup/
8 | tests/BaseWithSomeBooks/.calnotes/retired/
9 | tests/BaseWithSomeBooks/.caltrash/
10 | tests/BaseWithSomeBooks/metadata_db_prefs_backup.json
11 | vendor/
12 | # remove docker files
13 | docker/
14 | docker-compose*.yaml
15 | # remove development files
16 | .vscode/
17 | .sonarcloud.properties
18 | .sonarlint/
19 | .yarn/
20 | #!.yarn/releases
21 | #!.yarn/plugins
22 | .pnp.*
23 | # remove unused directories
24 | tools/
25 | clover.xml
26 | coverage/
27 | *.cache
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /coverage/*
2 | /vendor/
3 | /clover.xml
4 | /tests/text.*
5 | /*.phar
6 | /cops.zip
7 | /cops-*.zip
8 | /cops.sublime-*
9 | /config_local.php
10 | /config_local.*.php
11 | .yarn/*
12 | #!.yarn/releases
13 | #!.yarn/plugins
14 | .yarnrc.yml
15 | .pnp.*
16 | .editorconfig
17 | .gitattributes
18 | *.cache
19 | .devcontainer
20 | /cache/*.php
21 | rector.php
22 | .vscode/
23 | .sonarcloud.properties
24 | .sonarlint/
25 |
--------------------------------------------------------------------------------
/.gitremotes:
--------------------------------------------------------------------------------
1 | [remote "upstream"]
2 | url = https://github.com/seblucas/cops.git
3 | fetch = +refs/heads/*:refs/remotes/upstream/*
4 | [remote "tryme"]
5 | url = https://github.com/SenorSmartyPants/cops.git
6 | fetch = +refs/heads/*:refs/remotes/tryme/*
7 | [remote "peltos"]
8 | url = https://github.com/peltos/cops.git
9 | fetch = +refs/heads/*:refs/remotes/peltos/*
10 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | Use this section to tell people about which versions of your project are
6 | currently being supported with security updates.
7 |
8 | | Version | Supported |
9 | | ------- | ------------------ |
10 | | 3.5.x | :white_check_mark: |
11 | | 3.4.x | :x: |
12 | | < 3.x | :x: |
13 |
14 | ## Reporting a Vulnerability
15 |
16 | Please report any security vulnerability via https://github.com/mikespub-org/seblucas-cops/security/advisories
17 |
--------------------------------------------------------------------------------
/TRANSLATIONS.md:
--------------------------------------------------------------------------------
1 | # The software COPS
2 | COPS aka Calibre OPDS (and HTML) PHP Server. COPS is a light alternative to Calibre content server / Calibre2OPDS
3 | * COPS Github: https://github.com/mikespub-org/seblucas-cops
4 |
5 | ## Translating COPS
6 | Translate COPS to your language using free Gitlocalize platform:
7 | * COPS Gitlocalize: https://gitlocalize.com/repo/9640
8 |
9 | ## Languages and translators
10 | No software to install, just join in Gitlocalize and translate
11 | * You can request to be a translator or proofreader
12 | * New languages can be requested if missing
13 |
14 | ## Help and support
15 | * Translation Wiki page: https://github.com/mikespub-org/seblucas-cops/wiki/Update-translations
16 | * Translation Forum: https://www.mobileread.com/forums/showthread.php?t=255504
17 |
18 |
--------------------------------------------------------------------------------
/config/.gitignore:
--------------------------------------------------------------------------------
1 | local.php
2 | local.*.php
3 |
--------------------------------------------------------------------------------
/config/local.php.example:
--------------------------------------------------------------------------------
1 | "smtp.free.fr",
13 | "smtp.username" => "",
14 | "smtp.password" => "",
15 | "smtp.secure" => "",
16 | "address.from" => "cops@slucas.fr",
17 | ];
18 |
19 | // from here on, we assume that all global $config variables have been loaded
20 | Config::load($config);
21 |
22 | // initialize framework with routes etc. for tests
23 | Framework::getInstance()->getContext();
24 |
--------------------------------------------------------------------------------
/docker-compose-dev.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | dev:
3 | image: mikespub/seblucas-cops:dev
4 | build:
5 | context: .
6 | dockerfile: docker/Dockerfile.alpine
7 | target: dev-envs
8 | platforms:
9 | - "linux/amd64"
10 | - "linux/arm64"
11 | #environment:
12 | # - PORT=80
13 | ports:
14 | - '8080:80'
15 | volumes:
16 | - ./config/local.php:/app/config/local.php
17 | - ./src:/app/src
18 | - ./tests:/app/tests
19 |
--------------------------------------------------------------------------------
/docker-compose-lsio.yaml:
--------------------------------------------------------------------------------
1 | # Use latest linuxserver/cops image from linuxserver.io:
2 | # docker compose -f docker-compose-lsio.yaml up -d
3 | # See https://github.com/linuxserver/docker-cops for setup and usage
4 | services:
5 | cops:
6 | image: lscr.io/linuxserver/cops:latest
7 | #image: linuxserver/cops
8 | container_name: cops
9 | environment:
10 | - PUID=1000
11 | - PGID=1000
12 | - TZ=Etc/UTC
13 | volumes:
14 | - ./tests/config:/config
15 | - ./tests/BaseWithSomeBooks:/books
16 | ports:
17 | - 8080:80
18 | restart: unless-stopped
19 |
--------------------------------------------------------------------------------
/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | web:
3 | image: mikespub/seblucas-cops:web
4 | build:
5 | context: .
6 | dockerfile: docker/Dockerfile.alpine
7 | target: build
8 | platforms:
9 | - "linux/amd64"
10 | - "linux/arm64"
11 | tags:
12 | - "mikespub/seblucas-cops:latest"
13 | #environment:
14 | # - PORT=80
15 | ports:
16 | - "8080:80"
17 | volumes:
18 | - ./config/local.php:/app/config/local.php
19 |
--------------------------------------------------------------------------------
/docker/Dockerfile.alpine:
--------------------------------------------------------------------------------
1 | FROM alpine:3.21 AS build
2 | RUN apk add --no-cache --upgrade \
3 | php83 \
4 | php83-dom \
5 | php83-gd \
6 | php83-intl \
7 | php83-pdo_sqlite \
8 | php83-xml \
9 | composer \
10 | php83-tokenizer \
11 | php83-xmlwriter
12 |
13 | WORKDIR /app
14 | COPY . /app
15 | RUN composer install --no-dev -o -d /app
16 |
17 | ENV PORT=80
18 | EXPOSE $PORT
19 |
20 | CMD ["sh", "-c", "php -S 0.0.0.0:$PORT -t /app"]
21 |
22 | FROM build AS dev-envs
23 | RUN composer update -o -d /app
24 | #RUN apk --no-cache add nodejs yarn
25 | #RUN yarn
26 |
--------------------------------------------------------------------------------
/docker/Dockerfile.webdevops:
--------------------------------------------------------------------------------
1 | FROM webdevops/php-nginx:8.3-alpine AS build
2 | COPY . /app
3 | RUN composer install --no-dev -o -d /app
4 |
5 | FROM build AS dev-envs
6 | RUN composer update -o -d /app
7 | #RUN apk --no-cache add nodejs yarn
8 | #RUN yarn
9 |
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/favicon.ico
--------------------------------------------------------------------------------
/images/allbook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/allbook.png
--------------------------------------------------------------------------------
/images/author.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/author.png
--------------------------------------------------------------------------------
/images/bookcover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/bookcover.png
--------------------------------------------------------------------------------
/images/custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/custom.png
--------------------------------------------------------------------------------
/images/icons/icon114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/icons/icon114.png
--------------------------------------------------------------------------------
/images/icons/icon144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/icons/icon144.png
--------------------------------------------------------------------------------
/images/icons/icon57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/icons/icon57.png
--------------------------------------------------------------------------------
/images/icons/icon72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/icons/icon72.png
--------------------------------------------------------------------------------
/images/language.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/language.png
--------------------------------------------------------------------------------
/images/publisher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/publisher.png
--------------------------------------------------------------------------------
/images/rating.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/rating.png
--------------------------------------------------------------------------------
/images/recent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/recent.png
--------------------------------------------------------------------------------
/images/serie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/serie.png
--------------------------------------------------------------------------------
/images/tag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/images/tag.png
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 |
9 | * @author mikespub
10 | */
11 |
12 | use SebLucas\Cops\Framework\Framework;
13 |
14 | require_once __DIR__ . '/config/config.php'; // NOSONAR
15 |
16 | Framework::run();
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "seblucas-cops",
3 | "packageManager": "yarn@4.9.1",
4 | "dependencies": {
5 | "@mikespub/epubjs-reader": "^2025.4.8",
6 | "bootstrap": "^3.4.1",
7 | "corejs-typeahead": "^1.3.4",
8 | "datatables.net": "^2.3.1",
9 | "datatables.net-bs5": "^2.3.1",
10 | "dot": "^1.1.3",
11 | "graphiql": "^4.0.0",
12 | "graphql": "^16.11.0",
13 | "jquery": "^3.7.1",
14 | "js-cookie": "^3.0.5",
15 | "lru-fast": "^0.2.2",
16 | "magnific-popup": "^1.2.0",
17 | "normalize.css": "^8.0.1",
18 | "react": "^19.1.0",
19 | "react-dom": "^19.1.0",
20 | "swagger-ui-dist": "^5.21.0",
21 | "twig": "^1.17.1"
22 | },
23 | "license": "GPL-2.0-or-later"
24 | }
25 |
--------------------------------------------------------------------------------
/phpstan.neon.dist:
--------------------------------------------------------------------------------
1 | # baseline re-generated with level 4 to keep some issues visible on higher levels
2 | # at the time this file was updated there are 0 errors reported for levels 5 to 6
3 | includes:
4 | - phpstan-baseline.neon
5 |
6 | parameters:
7 | level: 6
8 | treatPhpDocTypesAsCertain: false
9 | paths:
10 | - .
11 | bootstrapFiles:
12 | - vendor/autoload.php
13 | excludePaths:
14 | - vendor/*
15 | - tests/WebDriverTestCase.php
16 | - tests/WebDriverTest.php
17 | - src/Framework/Adapter/LaravelAdapter.php
18 | - src/Framework/Adapter/SlimAdapter.php
19 | - src/Framework/Adapter/SymfonyAdapter.php
20 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
See CHANGELOG on Github for details: https://github.com/mikespub-org/seblucas-cops
5 | 6 |COPS is developed and maintained by Sébastien Lucas.
8 | 9 |See full history on Github to check all authors.
10 | 11 |COPS use some external libraries, check README for the details.
12 |This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or later as published by the Free Software Foundation.
14 | 15 |The complete content of license is provided in file LICENSE within distribution and also available online.
16 |For more info please visit COPS Home Page
18 | 19 |You can also check COPS's topic on MobileRead forum.
20 | 21 |DISCLAIMER : COPS is an open source software free to install everywhere. So if you have questions about any books available with any installation of COPS, please ask the owner of the website and not COPS's maintainer.
22 |Thanks a lot to Kovid Goyal for Calibre.
24 | 25 |And many thanks to all those who helped test COPS.
26 |{{=it.content}}
10 |Link: {{=it.home}}
11 | 12 | -------------------------------------------------------------------------------- /templates/bootstrap/footer.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/templates/bootstrap/footer.html -------------------------------------------------------------------------------- /templates/bootstrap/page.html: -------------------------------------------------------------------------------- 1 | {{#def.header}} 2 | {{#def.main}} 3 | {{#def.footer}} 4 | -------------------------------------------------------------------------------- /templates/bootstrap/scripts/cops.js: -------------------------------------------------------------------------------- 1 | function postRefresh() 2 | { 3 | $('[data-toggle="tooltip"]').tooltip(); 4 | } -------------------------------------------------------------------------------- /templates/bootstrap/styles/style-base.css: -------------------------------------------------------------------------------- 1 | .panel-body { padding: 5px; } 2 | 3 | .bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} -------------------------------------------------------------------------------- /templates/bootstrap/styles/style-default.css: -------------------------------------------------------------------------------- 1 | .panel-body { padding: 5px; } 2 | 3 | .bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} -------------------------------------------------------------------------------- /templates/bootstrap/suggestion.html: -------------------------------------------------------------------------------- 1 |{{=it.title}}
-------------------------------------------------------------------------------- /templates/bootstrap2/footer.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/templates/bootstrap2/footer.html -------------------------------------------------------------------------------- /templates/bootstrap2/page.html: -------------------------------------------------------------------------------- 1 | {{#def.header}} 2 | {{#def.main}} 3 | {{#def.footer}} 4 | -------------------------------------------------------------------------------- /templates/bootstrap2/scripts/cops.js: -------------------------------------------------------------------------------- 1 | function postRefresh() 2 | { 3 | $('[data-toggle="tooltip"]').tooltip(); 4 | hash = window.location.hash.replace("#", ""); 5 | var elmnt = document.getElementById(hash); 6 | if (elmnt) elmnt.scrollIntoView(); 7 | } -------------------------------------------------------------------------------- /templates/bootstrap2/styles/style-base.css: -------------------------------------------------------------------------------- 1 | .panel-body { padding: 5px; } 2 | 3 | .bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} -------------------------------------------------------------------------------- /templates/bootstrap2/styles/style-default.css: -------------------------------------------------------------------------------- 1 | .panel-body { padding: 5px; } 2 | 3 | .bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} -------------------------------------------------------------------------------- /templates/bootstrap2/suggestion.html: -------------------------------------------------------------------------------- 1 |{{=it.title}}
-------------------------------------------------------------------------------- /templates/bootstrap5/footer.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/bootstrap5/page.html: -------------------------------------------------------------------------------- 1 | {{#def.header}} 2 | 3 | {{#def.footer}} 4 | {{#def.main}} 5 | -------------------------------------------------------------------------------- /templates/bootstrap5/scripts/cops.js: -------------------------------------------------------------------------------- 1 | // Refactored to replace ES6+ features with ES5-compatible syntax 2 | function postRefresh() 3 | { 4 | var tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]'); 5 | var tooltipList = Array.prototype.map.call(tooltipTriggerList, function(tooltipTriggerEl) { 6 | return new bootstrap.Tooltip(tooltipTriggerEl); 7 | }); 8 | hash = window.location.hash.replace("#", ""); 9 | var elmnt = document.getElementById(hash); 10 | if (elmnt) { 11 | elmnt.scrollIntoView(); 12 | } 13 | $(".tt-hint").attr("name","searchTypeahead"); 14 | 15 | /* Add submenu class to body to give extra spacing */ 16 | if ($("#controls-menu").length > 0) { 17 | document.body.classList.add("submenu"); 18 | } else { 19 | if (document.body.classList.contains("submenu")) { 20 | document.body.classList.remove("submenu"); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /templates/bootstrap5/styles/style-base.css: -------------------------------------------------------------------------------- 1 | .panel-body { padding: 5px; } 2 | 3 | .bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} -------------------------------------------------------------------------------- /templates/bootstrap5/styles/style-default.css: -------------------------------------------------------------------------------- 1 | .panel-body { padding: 5px; } 2 | 3 | .bottomright {position:absolute; bottom:0; margin-bottom:25px; right: 20px;} -------------------------------------------------------------------------------- /templates/bootstrap5/suggestion.html: -------------------------------------------------------------------------------- 1 |{{=it.title}}
-------------------------------------------------------------------------------- /templates/default/footer.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/default/page.html: -------------------------------------------------------------------------------- 1 |{{=it.title}}
-------------------------------------------------------------------------------- /templates/default/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/templates/default/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /templates/default/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/templates/default/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /templates/default/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/templates/default/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /templates/default/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/templates/default/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /templates/epubjs-reader.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |COPS: {{=it.error}}
10 |Please report this issue at https://github.com/mikespub-org/seblucas-cops/issues if needed
11 |Link: Home
12 | 13 | -------------------------------------------------------------------------------- /templates/notfound.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |COPS: {{=it.error}}
10 |Link: Home
11 | 12 | -------------------------------------------------------------------------------- /templates/restapi.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 |{{it.c.i18n.linkTitle}}: {{it.extra.link}}
13 | {% endif %} 14 | {% if it.extra.content %} 15 | {{it.extra.content|raw}} 16 | {% endif %} 17 |Db num | 10 |Db name | 11 |Authors | 12 |Books | 13 |Series | 14 |Notes | 15 |Action | 16 |Db Path | 17 |Epub path | 18 |Nb Files | 19 |
---|---|---|---|---|---|---|---|---|---|
{{dbNum}} | 23 |{{dbConfig.name}} | 24 |{{dbConfig.authors}} | 25 |{{dbConfig.books}} | 26 |{{dbConfig.series}} | 27 |{{dbConfig['notes_db.notes']}} | 28 |{{actionTitle}} | 29 |{{dbConfig.db_path}} | 30 |{{dbConfig.epub_path}} | 31 |{{dbConfig.count}} | 32 |
Stats Updated: {{statsUpdated}}
36 | {% endblock content %} 37 | -------------------------------------------------------------------------------- /templates/twigged/navlist.html: -------------------------------------------------------------------------------- 1 | {# navlist.html is used for it.containsBook == 0 #} 2 | {% extends 'mainlist.html' %} 3 | 4 | {% block sortlinks %} 5 | {% if it.sortoptions ?? false %} 6 | 7 | 19 | {% endif %} 20 | {% endblock sortlinks %} 21 | 22 | {% block content %} 23 |{{it.title}}
-------------------------------------------------------------------------------- /templates/twigged/tagdetail.html: -------------------------------------------------------------------------------- 1 | {# tagdetail.html is (not) used for it.page == "tag" #} 2 | {% extends 'booklist.html' %} 3 | -------------------------------------------------------------------------------- /templates/twigged/var_dump.json.twig: -------------------------------------------------------------------------------- 1 | {# dump all template variables as json for template development or debugging #} 2 | {{ _context|json_encode()|raw }} -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- 1 | cache 2 | config 3 | BaseWithSomeBooks/.calnotes/backup/ 4 | BaseWithSomeBooks/.calnotes/retired/ 5 | BaseWithSomeBooks/.caltrash/ 6 | BaseWithSomeBooks/metadata_db_prefs_backup.json 7 | -------------------------------------------------------------------------------- /tests/BaseWithCustomColumns/metadata.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/BaseWithCustomColumns/metadata.db -------------------------------------------------------------------------------- /tests/BaseWithOneBook/metadata.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/BaseWithOneBook/metadata.db -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/.calnotes/notes.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/BaseWithSomeBooks/.calnotes/notes.db -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/.calnotes/resources/7c/xxh64-7c301792c52eebf7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/BaseWithSomeBooks/.calnotes/resources/7c/xxh64-7c301792c52eebf7 -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/.calnotes/resources/7c/xxh64-7c301792c52eebf7.metadata: -------------------------------------------------------------------------------- 1 | {"name": "330px-LewisCarrollSelfPhoto.jpg"} -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/.calnotes/resources/c0/xxh64-c062fb16e3568fdc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/BaseWithSomeBooks/.calnotes/resources/c0/xxh64-c062fb16e3568fdc -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/.calnotes/resources/c0/xxh64-c062fb16e3568fdc.metadata: -------------------------------------------------------------------------------- 1 | {"name": "image.jpg"} -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/.calnotes/resources/d7/xxh64-d7e814ba6a1b41d1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/BaseWithSomeBooks/.calnotes/resources/d7/xxh64-d7e814ba6a1b41d1 -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/.calnotes/resources/d7/xxh64-d7e814ba6a1b41d1.metadata: -------------------------------------------------------------------------------- 1 | {"name": "image-1.jpg"} -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/Lewis Carroll/Alice's Adventures in Wonderland (17)/Alice's Adventures in Wonderland - Lewis Carroll.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/BaseWithSomeBooks/Lewis Carroll/Alice's Adventures in Wonderland (17)/Alice's Adventures in Wonderland - Lewis Carroll.epub -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/Lewis Carroll/Alice's Adventures in Wonderland (17)/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/BaseWithSomeBooks/Lewis Carroll/Alice's Adventures in Wonderland (17)/cover.jpg -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/Lewis Carroll/Alice's Adventures in Wonderland (17)/data/hello.txt: -------------------------------------------------------------------------------- 1 | hello world 2 | -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/Lewis Carroll/Alice's Adventures in Wonderland (17)/data/sub folder/copied file.txt: -------------------------------------------------------------------------------- 1 | hello world 2 | -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/Sun Wu/Sun Zi Bing Fa (19)/Sun Zi Bing Fa - Sun Wu.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/BaseWithSomeBooks/Sun Wu/Sun Zi Bing Fa (19)/Sun Zi Bing Fa - Sun Wu.epub -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/Sun Wu/Sun Zi Bing Fa (19)/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/BaseWithSomeBooks/Sun Wu/Sun Zi Bing Fa (19)/cover.jpg -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/hierarchical_type2.sql: -------------------------------------------------------------------------------- 1 | -- SQLite 2 | insert into custom_column_2 values (4, "Tree"); 3 | insert into custom_column_2 values (5, "Tree.More"); 4 | update custom_column_2 set value="Tree.Tag1" where id=1; 5 | update custom_column_2 set value="Tree.More.Tag2" where id=2; 6 | update custom_column_2 set value="Tree.More.Tag3" where id=3; 7 | -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/metadata.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/BaseWithSomeBooks/metadata.db -------------------------------------------------------------------------------- /tests/BaseWithSomeBooks/users.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/BaseWithSomeBooks/users.db -------------------------------------------------------------------------------- /tests/OPDSValidator.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/OPDSValidator.jar -------------------------------------------------------------------------------- /tests/graphql/author.query.graphql: -------------------------------------------------------------------------------- 1 | query getAuthor($id: ID) { 2 | author(id: $id) { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/author.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getAuthor", 3 | "variables": { 4 | "id": 1 5 | }, 6 | "query": "query getAuthor($id: ID) {\n author(id: $id) {\n id\n title\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/author.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "author": { 4 | "id": "cops:authors:1", 5 | "title": "Arthur Conan Doyle" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /tests/graphql/authors.query.graphql: -------------------------------------------------------------------------------- 1 | query getAuthors { 2 | authors { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/authors.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getAuthors", 3 | "variables": [], 4 | "query": "query getAuthors {\n authors {\n id\n title\n }\n}" 5 | } -------------------------------------------------------------------------------- /tests/graphql/authors.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "authors": [ 4 | { 5 | "id": "cops:authors:3", 6 | "title": "Lewis Carroll" 7 | }, 8 | { 9 | "id": "cops:authors:1", 10 | "title": "Arthur Conan Doyle" 11 | }, 12 | { 13 | "id": "cops:authors:5", 14 | "title": "Alexandre Dumas" 15 | }, 16 | { 17 | "id": "cops:authors:2", 18 | "title": "Jack London" 19 | }, 20 | { 21 | "id": "cops:authors:4", 22 | "title": "H. G. Wells" 23 | }, 24 | { 25 | "id": "cops:authors:7", 26 | "title": "Émile Zola" 27 | }, 28 | { 29 | "id": "cops:authors:9", 30 | "title": "孙武" 31 | } 32 | ] 33 | } 34 | } -------------------------------------------------------------------------------- /tests/graphql/book.query.graphql: -------------------------------------------------------------------------------- 1 | query getBook($id: ID) { 2 | book(id: $id) { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/book.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getBook", 3 | "variables": { 4 | "id": 17 5 | }, 6 | "query": "query getBook($id: ID) {\n book(id: $id) {\n id\n title\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/book.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "book": { 4 | "id": "urn:uuid:d74fec58-06bc-4ba8-b8b4-24a91a58e6f9", 5 | "title": "Alice's Adventures in Wonderland" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /tests/graphql/books.query.graphql: -------------------------------------------------------------------------------- 1 | query getBooks { 2 | books { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/books.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getBooks", 3 | "variables": [], 4 | "query": "query getBooks {\n books {\n id\n title\n }\n}" 5 | } -------------------------------------------------------------------------------- /tests/graphql/customColumn.query.graphql: -------------------------------------------------------------------------------- 1 | query getCustomColumn($id: ID) { 2 | customColumn(id: $id) { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/customColumn.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getCustomColumn", 3 | "variables": { 4 | "id": 1 5 | }, 6 | "query": "query getCustomColumn($id: ID) {\n customColumn(id: $id) {\n id\n title\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/customColumn.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "customColumn": null 4 | } 5 | } -------------------------------------------------------------------------------- /tests/graphql/customColumns.query.graphql: -------------------------------------------------------------------------------- 1 | query getCustomColumns { 2 | customColumns { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/customColumns.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getCustomColumns", 3 | "variables": [], 4 | "query": "query getCustomColumns {\n customColumns {\n id\n title\n }\n}" 5 | } -------------------------------------------------------------------------------- /tests/graphql/customColumns.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "customColumns": null 4 | } 5 | } -------------------------------------------------------------------------------- /tests/graphql/data.query.graphql: -------------------------------------------------------------------------------- 1 | query getData($id: ID) { 2 | data(id: $id) { 3 | id 4 | name 5 | format 6 | } 7 | } -------------------------------------------------------------------------------- /tests/graphql/data.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getData", 3 | "variables": { 4 | "id": 1 5 | }, 6 | "query": "query getData($id: ID) {\n data(id: $id) {\n id\n name\n format\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/data.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "data": { 4 | "id": "1", 5 | "name": "The Return of Sherlock Holmes - Arthur Conan Doyle", 6 | "format": "EPUB" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /tests/graphql/datas.query.graphql: -------------------------------------------------------------------------------- 1 | query getDatas($bookId: ID) { 2 | datas(bookId: $bookId) { 3 | id 4 | name 5 | format 6 | } 7 | } -------------------------------------------------------------------------------- /tests/graphql/datas.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getDatas", 3 | "variables": { 4 | "bookId": 17 5 | }, 6 | "query": "query getDatas($bookId: ID) {\n datas(bookId: $bookId) {\n id\n name\n format\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/datas.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "datas": [ 4 | { 5 | "id": "17", 6 | "name": "Alice's Adventures in Wonderland - Lewis Carroll", 7 | "format": "MOBI" 8 | }, 9 | { 10 | "id": "19", 11 | "name": "Alice's Adventures in Wonderland - Lewis Carroll", 12 | "format": "PDF" 13 | }, 14 | { 15 | "id": "20", 16 | "name": "Alice's Adventures in Wonderland - Lewis Carroll", 17 | "format": "EPUB" 18 | } 19 | ] 20 | } 21 | } -------------------------------------------------------------------------------- /tests/graphql/format.query.graphql: -------------------------------------------------------------------------------- 1 | query getFormat($id: ID) { 2 | format(id: $id) { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/format.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getFormat", 3 | "variables": { 4 | "id": "EPUB" 5 | }, 6 | "query": "query getFormat($id: ID) {\n format(id: $id) {\n id\n title\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/format.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "format": { 4 | "id": "cops:formats:EPUB", 5 | "title": "EPUB" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /tests/graphql/formats.query.graphql: -------------------------------------------------------------------------------- 1 | query getFormats { 2 | formats { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/formats.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getFormats", 3 | "variables": [], 4 | "query": "query getFormats {\n formats {\n id\n title\n }\n}" 5 | } -------------------------------------------------------------------------------- /tests/graphql/formats.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "formats": [ 4 | { 5 | "id": "cops:formats:EPUB", 6 | "title": "EPUB" 7 | }, 8 | { 9 | "id": "cops:formats:MOBI", 10 | "title": "MOBI" 11 | }, 12 | { 13 | "id": "cops:formats:PDF", 14 | "title": "PDF" 15 | } 16 | ] 17 | } 18 | } -------------------------------------------------------------------------------- /tests/graphql/getAuthors.l.2.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "authors": [ 4 | { 5 | "id": "cops:authors:7", 6 | "title": "Émile Zola", 7 | "numberOfElement": "1", 8 | "books": [ 9 | { 10 | "id": "urn:uuid:08d43a34-fb89-446f-94ef-16bac6d8aa28", 11 | "title": "La curée", 12 | "languages": "French" 13 | } 14 | ] 15 | } 16 | ] 17 | } 18 | } -------------------------------------------------------------------------------- /tests/graphql/getNode.authors.3.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "node": { 4 | "__typename": "Entry", 5 | "id": "cops:authors:3", 6 | "title": "Lewis Carroll", 7 | "content": "No books", 8 | "books": [ 9 | { 10 | "id": "urn:uuid:d74fec58-06bc-4ba8-b8b4-24a91a58e6f9", 11 | "title": "Alice's Adventures in Wonderland" 12 | }, 13 | { 14 | "id": "urn:uuid:95029a0f-c537-4d8d-b4d0-b478ad4de645", 15 | "title": "Through the Looking Glass (And What Alice Found There)" 16 | } 17 | ] 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /tests/graphql/getNode.books.17.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "node": { 4 | "__typename": "EntryBook", 5 | "id": "urn:uuid:d74fec58-06bc-4ba8-b8b4-24a91a58e6f9", 6 | "title": "Alice's Adventures in Wonderland", 7 | "navlink": "vendor/bin/index.php/restapi/books/17/Lewis_Carroll/Alice_s_Adventures_in_Wonderland", 8 | "authors": [ 9 | { 10 | "id": "cops:authors:3", 11 | "title": "Lewis Carroll" 12 | } 13 | ] 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /tests/graphql/getNode.datas.20.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "node": { 4 | "__typename": "Data", 5 | "id": "20", 6 | "name": "Alice's Adventures in Wonderland - Lewis Carroll", 7 | "format": "EPUB", 8 | "book": { 9 | "id": "urn:uuid:d74fec58-06bc-4ba8-b8b4-24a91a58e6f9", 10 | "title": "Alice's Adventures in Wonderland" 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /tests/graphql/getNode.oops.42.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "errors": [ 3 | { 4 | "message": "Internal server error", 5 | "locations": [ 6 | { 7 | "line": 85, 8 | "column": 3 9 | } 10 | ], 11 | "path": [ 12 | "node" 13 | ], 14 | "extensions": { 15 | "debugMessage": "Invalid global identifier type" 16 | } 17 | } 18 | ], 19 | "data": { 20 | "node": null 21 | } 22 | } -------------------------------------------------------------------------------- /tests/graphql/identifier.query.graphql: -------------------------------------------------------------------------------- 1 | query getIdentifier($id: ID) { 2 | identifier(id: $id) { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/identifier.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getIdentifier", 3 | "variables": { 4 | "id": "isbn" 5 | }, 6 | "query": "query getIdentifier($id: ID) {\n identifier(id: $id) {\n id\n title\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/identifier.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "identifier": { 4 | "id": "cops:identifiers:isbn", 5 | "title": "ISBN" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /tests/graphql/identifiers.query.graphql: -------------------------------------------------------------------------------- 1 | query getIdentifiers { 2 | identifiers { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/identifiers.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getIdentifiers", 3 | "variables": [], 4 | "query": "query getIdentifiers {\n identifiers {\n id\n title\n }\n}" 5 | } -------------------------------------------------------------------------------- /tests/graphql/identifiers.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "identifiers": [ 4 | { 5 | "id": "cops:identifiers:amazon", 6 | "title": "Amazon" 7 | }, 8 | { 9 | "id": "cops:identifiers:google", 10 | "title": "Google Books" 11 | }, 12 | { 13 | "id": "cops:identifiers:isbn", 14 | "title": "ISBN" 15 | }, 16 | { 17 | "id": "cops:identifiers:olid", 18 | "title": "OpenLibrary" 19 | }, 20 | { 21 | "id": "cops:identifiers:uri", 22 | "title": "uri" 23 | }, 24 | { 25 | "id": "cops:identifiers:urn", 26 | "title": "urn" 27 | }, 28 | { 29 | "id": "cops:identifiers:wd", 30 | "title": "Wikidata" 31 | } 32 | ] 33 | } 34 | } -------------------------------------------------------------------------------- /tests/graphql/language.query.graphql: -------------------------------------------------------------------------------- 1 | query getLanguage($id: ID) { 2 | language(id: $id) { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/language.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getLanguage", 3 | "variables": { 4 | "id": 1 5 | }, 6 | "query": "query getLanguage($id: ID) {\n language(id: $id) {\n id\n title\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/language.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "language": { 4 | "id": "cops:languages:1", 5 | "title": "English" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /tests/graphql/languages.query.graphql: -------------------------------------------------------------------------------- 1 | query getLanguages { 2 | languages { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/languages.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getLanguages", 3 | "variables": [], 4 | "query": "query getLanguages {\n languages {\n id\n title\n }\n}" 5 | } -------------------------------------------------------------------------------- /tests/graphql/languages.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "languages": [ 4 | { 5 | "id": "cops:languages:1", 6 | "title": "English" 7 | }, 8 | { 9 | "id": "cops:languages:2", 10 | "title": "French" 11 | }, 12 | { 13 | "id": "cops:languages:3", 14 | "title": "Chinese" 15 | } 16 | ] 17 | } 18 | } -------------------------------------------------------------------------------- /tests/graphql/node.query.graphql: -------------------------------------------------------------------------------- 1 | query getNode($id: ID!) { 2 | node(id: $id) { 3 | __typename 4 | id 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/node.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getNode", 3 | "variables": { 4 | "id": "/books/17" 5 | }, 6 | "query": "query getNode($id: ID!) {\n node(id: $id) {\n __typename\n id\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/node.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "node": { 4 | "__typename": "EntryBook", 5 | "id": "urn:uuid:d74fec58-06bc-4ba8-b8b4-24a91a58e6f9" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /tests/graphql/nodelist.query.graphql: -------------------------------------------------------------------------------- 1 | query getNodelist($idlist: [ID!]!) { 2 | nodelist(idlist: $idlist) { 3 | __typename 4 | id 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/nodelist.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getNodelist", 3 | "variables": { 4 | "idlist": [ 5 | "/authors/3", 6 | "/books/17", 7 | "/datas/20", 8 | "/oops/42" 9 | ] 10 | }, 11 | "query": "query getNodelist($idlist: [ID!]!) {\n nodelist(idlist: $idlist) {\n __typename\n id\n }\n}" 12 | } -------------------------------------------------------------------------------- /tests/graphql/nodelist.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "errors": [ 3 | { 4 | "message": "Internal server error", 5 | "locations": [ 6 | { 7 | "line": 2, 8 | "column": 3 9 | } 10 | ], 11 | "path": [ 12 | "nodelist", 13 | 3 14 | ], 15 | "extensions": { 16 | "debugMessage": "Invalid global identifier type" 17 | } 18 | } 19 | ], 20 | "data": { 21 | "nodelist": [ 22 | { 23 | "__typename": "Entry", 24 | "id": "cops:authors:3" 25 | }, 26 | { 27 | "__typename": "EntryBook", 28 | "id": "urn:uuid:d74fec58-06bc-4ba8-b8b4-24a91a58e6f9" 29 | }, 30 | { 31 | "__typename": "Data", 32 | "id": "20" 33 | }, 34 | null 35 | ] 36 | } 37 | } -------------------------------------------------------------------------------- /tests/graphql/preference.query.graphql: -------------------------------------------------------------------------------- 1 | query getPreference($id: ID) { 2 | preference(id: $id) { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/preference.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getPreference", 3 | "variables": { 4 | "id": 1 5 | }, 6 | "query": "query getPreference($id: ID) {\n preference(id: $id) {\n id\n title\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/preference.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "preference": null 4 | } 5 | } -------------------------------------------------------------------------------- /tests/graphql/preferences.query.graphql: -------------------------------------------------------------------------------- 1 | query getPreferences { 2 | preferences { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/preferences.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getPreferences", 3 | "variables": [], 4 | "query": "query getPreferences {\n preferences {\n id\n title\n }\n}" 5 | } -------------------------------------------------------------------------------- /tests/graphql/preferences.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "preferences": null 4 | } 5 | } -------------------------------------------------------------------------------- /tests/graphql/publisher.query.graphql: -------------------------------------------------------------------------------- 1 | query getPublisher($id: ID) { 2 | publisher(id: $id) { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/publisher.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getPublisher", 3 | "variables": { 4 | "id": 2 5 | }, 6 | "query": "query getPublisher($id: ID) {\n publisher(id: $id) {\n id\n title\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/publisher.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "publisher": { 4 | "id": "cops:publishers:2", 5 | "title": "Macmillan and Co. London" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /tests/graphql/publishers.query.graphql: -------------------------------------------------------------------------------- 1 | query getPublishers { 2 | publishers { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/publishers.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getPublishers", 3 | "variables": [], 4 | "query": "query getPublishers {\n publishers {\n id\n title\n }\n}" 5 | } -------------------------------------------------------------------------------- /tests/graphql/publishers.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "publishers": [ 4 | { 5 | "id": "cops:publishers:3", 6 | "title": "D. Appleton and Company" 7 | }, 8 | { 9 | "id": "cops:publishers:9", 10 | "title": "Georges Charpentier & Eugène Fasquelle" 11 | }, 12 | { 13 | "id": "cops:publishers:2", 14 | "title": "Macmillan and Co. London" 15 | }, 16 | { 17 | "id": "cops:publishers:4", 18 | "title": "Macmillan Publishers USA" 19 | }, 20 | { 21 | "id": "cops:publishers:5", 22 | "title": "Pierson's Magazine" 23 | }, 24 | { 25 | "id": "cops:publishers:6", 26 | "title": "Strand Magazine" 27 | }, 28 | { 29 | "id": "cops:publishers:10", 30 | "title": "青苹果数据中心" 31 | } 32 | ] 33 | } 34 | } -------------------------------------------------------------------------------- /tests/graphql/rating.query.graphql: -------------------------------------------------------------------------------- 1 | query getRating($id: ID) { 2 | rating(id: $id) { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/rating.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getRating", 3 | "variables": { 4 | "id": 1 5 | }, 6 | "query": "query getRating($id: ID) {\n rating(id: $id) {\n id\n title\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/rating.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "rating": { 4 | "id": "cops:rating:1", 5 | "title": "5 stars" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /tests/graphql/ratings.query.graphql: -------------------------------------------------------------------------------- 1 | query getRatings { 2 | ratings { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/ratings.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getRatings", 3 | "variables": [], 4 | "query": "query getRatings {\n ratings {\n id\n title\n }\n}" 5 | } -------------------------------------------------------------------------------- /tests/graphql/ratings.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "ratings": [ 4 | { 5 | "id": "cops:rating:3", 6 | "title": "2 stars" 7 | }, 8 | { 9 | "id": "cops:rating:2", 10 | "title": "4 stars" 11 | }, 12 | { 13 | "id": "cops:rating:1", 14 | "title": "5 stars" 15 | } 16 | ] 17 | } 18 | } -------------------------------------------------------------------------------- /tests/graphql/search.query.graphql: -------------------------------------------------------------------------------- 1 | query getSearch($query: String!, $scope: String) { 2 | search(query: $query, scope: $scope) { 3 | __typename 4 | ... on Entry { 5 | id 6 | title 7 | content 8 | numberOfElement 9 | } 10 | ... on EntryBook { 11 | id 12 | title 13 | authors { 14 | id 15 | title 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /tests/graphql/search.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getSearch", 3 | "variables": { 4 | "query": "car" 5 | }, 6 | "query": "query getSearch($query: String!, $scope: String) {\n search(query: $query, scope: $scope) {\n __typename\n ... on Entry {\n id\n title\n content\n numberOfElement\n }\n ... on EntryBook {\n id\n title\n authors {\n id\n title\n }\n }\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/search.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "search": [ 4 | { 5 | "__typename": "Entry", 6 | "id": "db:query::book", 7 | "title": "Search result for *car* in books", 8 | "content": "1 book", 9 | "numberOfElement": "1" 10 | }, 11 | { 12 | "__typename": "EntryBook", 13 | "id": "urn:uuid:f3a4534e-d7bc-415a-8887-ba2b2810c980", 14 | "title": "A Study in Scarlet", 15 | "authors": [ 16 | { 17 | "id": "cops:authors:1", 18 | "title": "Arthur Conan Doyle" 19 | } 20 | ] 21 | }, 22 | { 23 | "__typename": "Entry", 24 | "id": "db:query::author", 25 | "title": "Search result for *car* in authors", 26 | "content": "1 author", 27 | "numberOfElement": "1" 28 | }, 29 | { 30 | "__typename": "Entry", 31 | "id": "cops:authors:3", 32 | "title": "Lewis Carroll", 33 | "content": "2 books", 34 | "numberOfElement": "2" 35 | } 36 | ] 37 | } 38 | } -------------------------------------------------------------------------------- /tests/graphql/serie.query.graphql: -------------------------------------------------------------------------------- 1 | query getSerie($id: ID) { 2 | serie(id: $id) { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/serie.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getSerie", 3 | "variables": { 4 | "id": 1 5 | }, 6 | "query": "query getSerie($id: ID) {\n serie(id: $id) {\n id\n title\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/serie.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "serie": { 4 | "id": "cops:series:1", 5 | "title": "Sherlock Holmes" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /tests/graphql/series.query.graphql: -------------------------------------------------------------------------------- 1 | query getSeries { 2 | series { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/series.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getSeries", 3 | "variables": [], 4 | "query": "query getSeries {\n series {\n id\n title\n }\n}" 5 | } -------------------------------------------------------------------------------- /tests/graphql/series.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "series": [ 4 | { 5 | "id": "cops:series:3", 6 | "title": "D'Artagnan Romances" 7 | }, 8 | { 9 | "id": "cops:series:2", 10 | "title": "Professor Challenger" 11 | }, 12 | { 13 | "id": "cops:series:1", 14 | "title": "Sherlock Holmes" 15 | }, 16 | { 17 | "id": "cops:series:5", 18 | "title": "Série des Rougon-Macquart" 19 | } 20 | ] 21 | } 22 | } -------------------------------------------------------------------------------- /tests/graphql/tag.query.graphql: -------------------------------------------------------------------------------- 1 | query getTag($id: ID) { 2 | tag(id: $id) { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/tag.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getTag", 3 | "variables": { 4 | "id": 1 5 | }, 6 | "query": "query getTag($id: ID) {\n tag(id: $id) {\n id\n title\n }\n}" 7 | } -------------------------------------------------------------------------------- /tests/graphql/tag.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "tag": { 4 | "id": "cops:tags:1", 5 | "title": "Fiction" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /tests/graphql/tags.query.graphql: -------------------------------------------------------------------------------- 1 | query getTags { 2 | tags { 3 | id 4 | title 5 | } 6 | } -------------------------------------------------------------------------------- /tests/graphql/tags.query.json: -------------------------------------------------------------------------------- 1 | { 2 | "operationName": "getTags", 3 | "variables": [], 4 | "query": "query getTags {\n tags {\n id\n title\n }\n}" 5 | } -------------------------------------------------------------------------------- /tests/graphql/tags.result.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "tags": [ 4 | { 5 | "id": "cops:tags:4", 6 | "title": "Action & Adventure" 7 | }, 8 | { 9 | "id": "cops:tags:5", 10 | "title": "Fantasy" 11 | }, 12 | { 13 | "id": "cops:tags:1", 14 | "title": "Fiction" 15 | }, 16 | { 17 | "id": "cops:tags:10", 18 | "title": "Historical" 19 | }, 20 | { 21 | "id": "cops:tags:6", 22 | "title": "Juvenile" 23 | }, 24 | { 25 | "id": "cops:tags:12", 26 | "title": "Littérature" 27 | }, 28 | { 29 | "id": "cops:tags:3", 30 | "title": "Mystery & Detective" 31 | }, 32 | { 33 | "id": "cops:tags:9", 34 | "title": "Romance" 35 | }, 36 | { 37 | "id": "cops:tags:7", 38 | "title": "Science Fiction" 39 | }, 40 | { 41 | "id": "cops:tags:2", 42 | "title": "Short Stories" 43 | }, 44 | { 45 | "id": "cops:tags:8", 46 | "title": "War & Military" 47 | } 48 | ] 49 | } 50 | } -------------------------------------------------------------------------------- /tests/jing.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/jing.jar -------------------------------------------------------------------------------- /tests/restapi/check-more.html: -------------------------------------------------------------------------------- 1 | \SebLucas\Cops\Input\Request::__set_state(array( 2 | 'urlParams' => 3 | array ( 4 | '_route' => 'check-more', 5 | 'more' => 'more', 6 | ), 7 | 'serverParams' => 8 | array ( 9 | 'HTTP_REDACTED' => true, 10 | ), 11 | 'queryParams' => 12 | array ( 13 | ), 14 | 'postParams' => 15 | array ( 16 | ), 17 | 'cookieParams' => 18 | array ( 19 | ), 20 | 'fileParams' => 21 | array ( 22 | ), 23 | 'parsed' => true, 24 | 'content' => NULL, 25 | 'locale' => 'en', 26 | 'session' => NULL, 27 | 'invalid' => false, 28 | )) -------------------------------------------------------------------------------- /tests/restapi/page-authors-letter.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "1 author starting with C", 3 | "parentTitle": "", 4 | "baseurl": "vendor/bin/index.php", 5 | "isFilterPage": false, 6 | "databaseId": "", 7 | "databaseName": "", 8 | "libraryId": "", 9 | "libraryName": "COPS", 10 | "fullTitle": "1 author starting with C", 11 | "multipleDatabase": 0, 12 | "page": "authors_letter", 13 | "entries": [ 14 | { 15 | "class": "Authors", 16 | "title": "Lewis Carroll", 17 | "content": "2 books", 18 | "navlink": "vendor/bin/index.php/restapi/authors/3/Lewis_Carroll", 19 | "number": 2 20 | } 21 | ], 22 | "entriesCount": 1, 23 | "isPaginated": 0, 24 | "sorted": "sort", 25 | "sortedBy": "sort", 26 | "sortedDir": "asc", 27 | "containsBook": 0, 28 | "filterurl": false, 29 | "sortoptions": [], 30 | "filters": false, 31 | "abouturl": "vendor/bin/index.php/restapi/about", 32 | "customizeurl": "vendor/bin/index.php/restapi/customize", 33 | "homeurl": "vendor/bin/index.php", 34 | "parenturl": "vendor/bin/index.php/restapi/authors", 35 | "hierarchy": false, 36 | "extra": false, 37 | "assets": "vendor/bin/vendor/npm-asset", 38 | "download": false, 39 | "locale": "en", 40 | "template": "bootstrap2" 41 | } -------------------------------------------------------------------------------- /tests/restapi/page-customtype.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Type1", 3 | "parentTitle": "", 4 | "baseurl": "vendor/bin/index.php", 5 | "isFilterPage": false, 6 | "databaseId": "", 7 | "databaseName": "", 8 | "libraryId": "", 9 | "libraryName": "COPS", 10 | "fullTitle": "Type1", 11 | "multipleDatabase": 0, 12 | "page": "customtype", 13 | "entries": [ 14 | { 15 | "class": "Type1", 16 | "title": "other", 17 | "content": "1 book", 18 | "navlink": "vendor/bin/index.php/restapi/custom/3/2", 19 | "number": 1 20 | }, 21 | { 22 | "class": "Type1", 23 | "title": "text", 24 | "content": "2 books", 25 | "navlink": "vendor/bin/index.php/restapi/custom/3/1", 26 | "number": 2 27 | }, 28 | { 29 | "class": "Type1", 30 | "title": "Not Set", 31 | "content": "13 books", 32 | "navlink": "vendor/bin/index.php/restapi/custom/3/not_set", 33 | "number": 13 34 | } 35 | ], 36 | "entriesCount": 3, 37 | "isPaginated": 0, 38 | "sorted": "value", 39 | "sortedBy": "value", 40 | "sortedDir": "asc", 41 | "containsBook": 0, 42 | "filterurl": false, 43 | "sortoptions": [], 44 | "filters": false, 45 | "abouturl": "vendor/bin/index.php/restapi/about", 46 | "customizeurl": "vendor/bin/index.php/restapi/customize", 47 | "homeurl": "vendor/bin/index.php", 48 | "parenturl": "vendor/bin/index.php", 49 | "hierarchy": false, 50 | "extra": false, 51 | "assets": "vendor/bin/vendor/npm-asset", 52 | "download": false, 53 | "locale": "en", 54 | "template": "bootstrap2" 55 | } -------------------------------------------------------------------------------- /tests/restapi/page-formats.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Formats", 3 | "parentTitle": "", 4 | "baseurl": "vendor/bin/index.php", 5 | "isFilterPage": false, 6 | "databaseId": "", 7 | "databaseName": "", 8 | "libraryId": "", 9 | "libraryName": "COPS", 10 | "fullTitle": "Formats", 11 | "multipleDatabase": 0, 12 | "page": "formats", 13 | "entries": [ 14 | { 15 | "class": "Format", 16 | "title": "EPUB", 17 | "content": "16 books", 18 | "navlink": "vendor/bin/index.php/restapi/formats/EPUB", 19 | "number": 16 20 | }, 21 | { 22 | "class": "Format", 23 | "title": "MOBI", 24 | "content": "1 book", 25 | "navlink": "vendor/bin/index.php/restapi/formats/MOBI", 26 | "number": 1 27 | }, 28 | { 29 | "class": "Format", 30 | "title": "PDF", 31 | "content": "1 book", 32 | "navlink": "vendor/bin/index.php/restapi/formats/PDF", 33 | "number": 1 34 | }, 35 | { 36 | "class": "Format", 37 | "title": "No format", 38 | "content": "No books", 39 | "navlink": "vendor/bin/index.php/restapi/formats/0", 40 | "number": 0 41 | } 42 | ], 43 | "entriesCount": 4, 44 | "isPaginated": 0, 45 | "sorted": "format", 46 | "sortedBy": "format", 47 | "sortedDir": "desc", 48 | "containsBook": 0, 49 | "filterurl": false, 50 | "sortoptions": [], 51 | "filters": false, 52 | "abouturl": "vendor/bin/index.php/restapi/about", 53 | "customizeurl": "vendor/bin/index.php/restapi/customize", 54 | "homeurl": "vendor/bin/index.php", 55 | "parenturl": "vendor/bin/index.php", 56 | "hierarchy": false, 57 | "extra": false, 58 | "assets": "vendor/bin/vendor/npm-asset", 59 | "download": false, 60 | "locale": "en", 61 | "template": "bootstrap2" 62 | } -------------------------------------------------------------------------------- /tests/restapi/page-languages.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Languages", 3 | "parentTitle": "", 4 | "baseurl": "vendor/bin/index.php", 5 | "isFilterPage": false, 6 | "databaseId": "", 7 | "databaseName": "", 8 | "libraryId": "", 9 | "libraryName": "COPS", 10 | "fullTitle": "Languages", 11 | "multipleDatabase": 0, 12 | "page": "languages", 13 | "entries": [ 14 | { 15 | "class": "Languages", 16 | "title": "English", 17 | "content": "14 books", 18 | "navlink": "vendor/bin/index.php/restapi/languages/1/English", 19 | "number": 14 20 | }, 21 | { 22 | "class": "Languages", 23 | "title": "French", 24 | "content": "1 book", 25 | "navlink": "vendor/bin/index.php/restapi/languages/2/French", 26 | "number": 1 27 | }, 28 | { 29 | "class": "Languages", 30 | "title": "Chinese", 31 | "content": "1 book", 32 | "navlink": "vendor/bin/index.php/restapi/languages/3/Chinese", 33 | "number": 1 34 | } 35 | ], 36 | "entriesCount": 3, 37 | "isPaginated": 0, 38 | "sorted": "lang_code", 39 | "sortedBy": "lang_code", 40 | "sortedDir": "asc", 41 | "containsBook": 0, 42 | "filterurl": false, 43 | "sortoptions": [], 44 | "filters": false, 45 | "abouturl": "vendor/bin/index.php/restapi/about", 46 | "customizeurl": "vendor/bin/index.php/restapi/customize", 47 | "homeurl": "vendor/bin/index.php", 48 | "parenturl": "vendor/bin/index.php", 49 | "hierarchy": false, 50 | "extra": false, 51 | "assets": "vendor/bin/vendor/npm-asset", 52 | "download": false, 53 | "locale": "en", 54 | "template": "bootstrap2" 55 | } -------------------------------------------------------------------------------- /tests/restapi/page-libraries.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Virtual libraries", 3 | "parentTitle": "", 4 | "baseurl": "vendor/bin/index.php", 5 | "isFilterPage": false, 6 | "databaseId": "", 7 | "databaseName": "", 8 | "libraryId": "", 9 | "libraryName": "COPS", 10 | "fullTitle": "Virtual libraries", 11 | "multipleDatabase": 0, 12 | "page": "libraries", 13 | "entries": [ 14 | { 15 | "class": "VirtualLibrary", 16 | "title": "Action Fiction from this Century (TODO)", 17 | "content": "No books", 18 | "navlink": "vendor/bin/index.php/restapi/index?vl=1.Action_Fiction_from_this_Century_TODO", 19 | "number": 0 20 | }, 21 | { 22 | "class": "VirtualLibrary", 23 | "title": "Short Stories in English", 24 | "content": "No books", 25 | "navlink": "vendor/bin/index.php/restapi/index?vl=2.Short_Stories_in_English", 26 | "number": 0 27 | }, 28 | { 29 | "class": "VirtualLibrary", 30 | "title": "No virtual libraries", 31 | "content": "16 books", 32 | "navlink": "vendor/bin/index.php/restapi/index?vl=0.No_virtual_libraries", 33 | "number": 16 34 | } 35 | ], 36 | "entriesCount": 3, 37 | "isPaginated": 0, 38 | "sorted": "", 39 | "sortedBy": "", 40 | "sortedDir": "", 41 | "containsBook": 0, 42 | "filterurl": false, 43 | "sortoptions": [], 44 | "filters": false, 45 | "abouturl": "vendor/bin/index.php/restapi/about", 46 | "customizeurl": "vendor/bin/index.php/restapi/customize", 47 | "homeurl": "vendor/bin/index.php", 48 | "parenturl": "vendor/bin/index.php", 49 | "hierarchy": false, 50 | "extra": false, 51 | "assets": "vendor/bin/vendor/npm-asset", 52 | "download": false, 53 | "locale": "en", 54 | "template": "bootstrap2" 55 | } -------------------------------------------------------------------------------- /tests/restapi/page-publishers-letter.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "2 publishers starting with M", 3 | "parentTitle": "", 4 | "baseurl": "vendor/bin/index.php", 5 | "isFilterPage": false, 6 | "databaseId": "", 7 | "databaseName": "", 8 | "libraryId": "", 9 | "libraryName": "COPS", 10 | "fullTitle": "2 publishers starting with M", 11 | "multipleDatabase": 0, 12 | "page": "publishers_letter", 13 | "entries": [ 14 | { 15 | "class": "Publishers", 16 | "title": "Macmillan and Co. London", 17 | "content": "2 books", 18 | "navlink": "vendor/bin/index.php/restapi/publishers/2/Macmillan_and_Co_London", 19 | "number": 2 20 | }, 21 | { 22 | "class": "Publishers", 23 | "title": "Macmillan Publishers USA", 24 | "content": "1 book", 25 | "navlink": "vendor/bin/index.php/restapi/publishers/4/Macmillan_Publishers_USA", 26 | "number": 1 27 | } 28 | ], 29 | "entriesCount": 2, 30 | "isPaginated": 0, 31 | "sorted": "name", 32 | "sortedBy": "name", 33 | "sortedDir": "asc", 34 | "containsBook": 0, 35 | "filterurl": false, 36 | "sortoptions": [], 37 | "filters": false, 38 | "abouturl": "vendor/bin/index.php/restapi/about", 39 | "customizeurl": "vendor/bin/index.php/restapi/customize", 40 | "homeurl": "vendor/bin/index.php", 41 | "parenturl": "vendor/bin/index.php/restapi/publishers", 42 | "hierarchy": false, 43 | "extra": false, 44 | "assets": "vendor/bin/vendor/npm-asset", 45 | "download": false, 46 | "locale": "en", 47 | "template": "bootstrap2" 48 | } -------------------------------------------------------------------------------- /tests/restapi/page-query-scope.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Search result for *car* in authors", 3 | "parentTitle": "", 4 | "baseurl": "vendor/bin/index.php", 5 | "isFilterPage": false, 6 | "databaseId": "", 7 | "databaseName": "", 8 | "libraryId": "", 9 | "libraryName": "COPS", 10 | "fullTitle": "Search result for *car* in authors", 11 | "multipleDatabase": 0, 12 | "page": "query", 13 | "entries": [ 14 | { 15 | "class": "Authors", 16 | "title": "Lewis Carroll", 17 | "content": "2 books", 18 | "navlink": "vendor/bin/index.php/restapi/authors/3/Lewis_Carroll", 19 | "number": 2 20 | } 21 | ], 22 | "entriesCount": 1, 23 | "isPaginated": 0, 24 | "sorted": "sort", 25 | "sortedBy": "sort", 26 | "sortedDir": "asc", 27 | "containsBook": 0, 28 | "filterurl": false, 29 | "sortoptions": [], 30 | "filters": false, 31 | "abouturl": "vendor/bin/index.php/restapi/about", 32 | "customizeurl": "vendor/bin/index.php/restapi/customize", 33 | "homeurl": "vendor/bin/index.php", 34 | "parenturl": "vendor/bin/index.php", 35 | "hierarchy": false, 36 | "extra": false, 37 | "assets": "vendor/bin/vendor/npm-asset", 38 | "download": false, 39 | "locale": "en", 40 | "template": "bootstrap2" 41 | } -------------------------------------------------------------------------------- /tests/restapi/page-query.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Search result for *car*", 3 | "parentTitle": "", 4 | "baseurl": "vendor/bin/index.php", 5 | "isFilterPage": false, 6 | "databaseId": "", 7 | "databaseName": "", 8 | "libraryId": "", 9 | "libraryName": "COPS", 10 | "fullTitle": "Search result for *car*", 11 | "multipleDatabase": 0, 12 | "page": "query", 13 | "entries": [ 14 | { 15 | "class": "tt-header", 16 | "title": "Search result for *car* in books", 17 | "content": "1 book", 18 | "navlink": "vendor/bin/index.php/restapi/search/car/book", 19 | "number": 1 20 | }, 21 | { 22 | "class": "tt-header", 23 | "title": "Search result for *car* in authors", 24 | "content": "1 author", 25 | "navlink": "vendor/bin/index.php/restapi/search/car/author", 26 | "number": 1 27 | } 28 | ], 29 | "entriesCount": 2, 30 | "isPaginated": 0, 31 | "sorted": "sort", 32 | "sortedBy": "sort", 33 | "sortedDir": "asc", 34 | "containsBook": 0, 35 | "filterurl": false, 36 | "sortoptions": [], 37 | "filters": false, 38 | "abouturl": "vendor/bin/index.php/restapi/about", 39 | "customizeurl": "vendor/bin/index.php/restapi/customize", 40 | "homeurl": "vendor/bin/index.php", 41 | "parenturl": "vendor/bin/index.php", 42 | "hierarchy": false, 43 | "extra": false, 44 | "assets": "vendor/bin/vendor/npm-asset", 45 | "download": false, 46 | "locale": "en", 47 | "template": "bootstrap2" 48 | } -------------------------------------------------------------------------------- /tests/restapi/page-ratings.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Ratings", 3 | "parentTitle": "", 4 | "baseurl": "vendor/bin/index.php", 5 | "isFilterPage": false, 6 | "databaseId": "", 7 | "databaseName": "", 8 | "libraryId": "", 9 | "libraryName": "COPS", 10 | "fullTitle": "Ratings", 11 | "multipleDatabase": 0, 12 | "page": "ratings", 13 | "entries": [ 14 | { 15 | "class": "Ratings", 16 | "title": "2 stars", 17 | "content": "1 book", 18 | "navlink": "vendor/bin/index.php/restapi/ratings/3/2_stars", 19 | "number": 1 20 | }, 21 | { 22 | "class": "Ratings", 23 | "title": "4 stars", 24 | "content": "2 books", 25 | "navlink": "vendor/bin/index.php/restapi/ratings/2/4_stars", 26 | "number": 2 27 | }, 28 | { 29 | "class": "Ratings", 30 | "title": "5 stars", 31 | "content": "4 books", 32 | "navlink": "vendor/bin/index.php/restapi/ratings/1/5_stars", 33 | "number": 4 34 | }, 35 | { 36 | "class": "Ratings", 37 | "title": "No star", 38 | "content": "9 books", 39 | "navlink": "vendor/bin/index.php/restapi/ratings/0/No_star", 40 | "number": 9 41 | } 42 | ], 43 | "entriesCount": 4, 44 | "isPaginated": 0, 45 | "sorted": "rating", 46 | "sortedBy": "rating", 47 | "sortedDir": "desc", 48 | "containsBook": 0, 49 | "filterurl": false, 50 | "sortoptions": [], 51 | "filters": false, 52 | "abouturl": "vendor/bin/index.php/restapi/about", 53 | "customizeurl": "vendor/bin/index.php/restapi/customize", 54 | "homeurl": "vendor/bin/index.php", 55 | "parenturl": "vendor/bin/index.php", 56 | "hierarchy": false, 57 | "extra": false, 58 | "assets": "vendor/bin/vendor/npm-asset", 59 | "download": false, 60 | "locale": "en", 61 | "template": "bootstrap2" 62 | } -------------------------------------------------------------------------------- /tests/restapi/page-series-letter.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "2 series starting with S", 3 | "parentTitle": "", 4 | "baseurl": "vendor/bin/index.php", 5 | "isFilterPage": false, 6 | "databaseId": "", 7 | "databaseName": "", 8 | "libraryId": "", 9 | "libraryName": "COPS", 10 | "fullTitle": "2 series starting with S", 11 | "multipleDatabase": 0, 12 | "page": "series_letter", 13 | "entries": [ 14 | { 15 | "class": "Series", 16 | "title": "Sherlock Holmes", 17 | "content": "7 books", 18 | "navlink": "vendor/bin/index.php/restapi/series/1/Sherlock_Holmes", 19 | "number": 7 20 | }, 21 | { 22 | "class": "Series", 23 | "title": "Série des Rougon-Macquart", 24 | "content": "1 book", 25 | "navlink": "vendor/bin/index.php/restapi/series/5/Serie_des_Rougon_Macquart", 26 | "number": 1 27 | } 28 | ], 29 | "entriesCount": 2, 30 | "isPaginated": 0, 31 | "sorted": "sort", 32 | "sortedBy": "sort", 33 | "sortedDir": "asc", 34 | "containsBook": 0, 35 | "filterurl": false, 36 | "sortoptions": [], 37 | "filters": false, 38 | "abouturl": "vendor/bin/index.php/restapi/about", 39 | "customizeurl": "vendor/bin/index.php/restapi/customize", 40 | "homeurl": "vendor/bin/index.php", 41 | "parenturl": "vendor/bin/index.php/restapi/series", 42 | "hierarchy": false, 43 | "extra": false, 44 | "assets": "vendor/bin/vendor/npm-asset", 45 | "download": false, 46 | "locale": "en", 47 | "template": "bootstrap2" 48 | } -------------------------------------------------------------------------------- /tests/restapi/page-series-letters.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Series", 3 | "parentTitle": "", 4 | "baseurl": "vendor/bin/index.php", 5 | "isFilterPage": false, 6 | "databaseId": "", 7 | "databaseName": "", 8 | "libraryId": "", 9 | "libraryName": "COPS", 10 | "fullTitle": "Series", 11 | "multipleDatabase": 0, 12 | "page": "series", 13 | "entries": [ 14 | { 15 | "class": "Letter", 16 | "title": "D", 17 | "content": "1 series", 18 | "navlink": "vendor/bin/index.php/restapi/series/letter/D", 19 | "number": 1 20 | }, 21 | { 22 | "class": "Letter", 23 | "title": "P", 24 | "content": "1 series", 25 | "navlink": "vendor/bin/index.php/restapi/series/letter/P", 26 | "number": 1 27 | }, 28 | { 29 | "class": "Letter", 30 | "title": "S", 31 | "content": "2 series", 32 | "navlink": "vendor/bin/index.php/restapi/series/letter/S", 33 | "number": 2 34 | }, 35 | { 36 | "class": "Series", 37 | "title": "No series", 38 | "content": "5 books", 39 | "navlink": "vendor/bin/index.php/restapi/series/0/No_series", 40 | "number": 5 41 | } 42 | ], 43 | "entriesCount": 4, 44 | "isPaginated": 0, 45 | "sorted": "groupid", 46 | "sortedBy": "groupid", 47 | "sortedDir": "asc", 48 | "containsBook": 0, 49 | "filterurl": false, 50 | "sortoptions": [], 51 | "filters": false, 52 | "abouturl": "vendor/bin/index.php/restapi/about", 53 | "customizeurl": "vendor/bin/index.php/restapi/customize", 54 | "homeurl": "vendor/bin/index.php", 55 | "parenturl": "vendor/bin/index.php", 56 | "hierarchy": false, 57 | "extra": false, 58 | "assets": "vendor/bin/vendor/npm-asset", 59 | "download": false, 60 | "locale": "en", 61 | "template": "bootstrap2" 62 | } -------------------------------------------------------------------------------- /tests/restapi/page-tags-letter.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "2 tags starting with F", 3 | "parentTitle": "", 4 | "baseurl": "vendor/bin/index.php", 5 | "isFilterPage": false, 6 | "databaseId": "", 7 | "databaseName": "", 8 | "libraryId": "", 9 | "libraryName": "COPS", 10 | "fullTitle": "2 tags starting with F", 11 | "multipleDatabase": 0, 12 | "page": "tags_letter", 13 | "entries": [ 14 | { 15 | "class": "Tags", 16 | "title": "Fantasy", 17 | "content": "2 books", 18 | "navlink": "vendor/bin/index.php/restapi/tags/5/Fantasy", 19 | "number": 2 20 | }, 21 | { 22 | "class": "Tags", 23 | "title": "Fiction", 24 | "content": "14 books", 25 | "navlink": "vendor/bin/index.php/restapi/tags/1/Fiction", 26 | "number": 14 27 | } 28 | ], 29 | "entriesCount": 2, 30 | "isPaginated": 0, 31 | "sorted": "name", 32 | "sortedBy": "name", 33 | "sortedDir": "asc", 34 | "containsBook": 0, 35 | "filterurl": false, 36 | "sortoptions": [], 37 | "filters": false, 38 | "abouturl": "vendor/bin/index.php/restapi/about", 39 | "customizeurl": "vendor/bin/index.php/restapi/customize", 40 | "homeurl": "vendor/bin/index.php", 41 | "parenturl": "vendor/bin/index.php/restapi/tags", 42 | "hierarchy": false, 43 | "extra": false, 44 | "assets": "vendor/bin/vendor/npm-asset", 45 | "download": false, 46 | "locale": "en", 47 | "template": "bootstrap2" 48 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-annotation.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "(17) Bookmark About #1", 3 | "baseurl": "vendor/bin/index.php/restapi", 4 | "databaseId": null, 5 | "id": 1, 6 | "name": "About #1", 7 | "link": null, 8 | "count": null, 9 | "limitSelf": true, 10 | "book": 17, 11 | "format": "EPUB", 12 | "userType": "local", 13 | "user": "viewer", 14 | "timestamp": 1710158075.128396, 15 | "type": "bookmark", 16 | "data": { 17 | "title": "About #1", 18 | "pos_type": "epubcfi", 19 | "pos": "epubcfi(/6/2/4/2/6/2:38)", 20 | "timestamp": "2024-03-11T11:54:35.128396+00:00", 21 | "type": "bookmark" 22 | } 23 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-annotations-book.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Annotations for 17", 3 | "baseurl": "vendor/bin/index.php/restapi", 4 | "databaseId": null, 5 | "entries": [ 6 | { 7 | "class": "Annotation", 8 | "title": "(17) Bookmark About #1", 9 | "navlink": "vendor/bin/index.php/restapi/annotations/17/1" 10 | }, 11 | { 12 | "class": "Annotation", 13 | "title": "(17) Highlight 5HHGuoCOtpA-umaIbBuc0Q", 14 | "navlink": "vendor/bin/index.php/restapi/annotations/17/2" 15 | }, 16 | { 17 | "class": "Annotation", 18 | "title": "(17) Highlight KFGNXVB2Heb53ghsAjVqvQ", 19 | "navlink": "vendor/bin/index.php/restapi/annotations/17/3" 20 | }, 21 | { 22 | "class": "Annotation", 23 | "title": "(17) Highlight iuGTy-WIXWDinBuszppGwA", 24 | "navlink": "vendor/bin/index.php/restapi/annotations/17/4" 25 | }, 26 | { 27 | "class": "Annotation", 28 | "title": "(17) Highlight 1ZUnS8Bf4uZGH0hS9JOKGQ", 29 | "navlink": "vendor/bin/index.php/restapi/annotations/17/5" 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-annotations.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Annotations", 3 | "baseurl": "vendor/bin/index.php/restapi", 4 | "databaseId": null, 5 | "entries": [ 6 | { 7 | "class": "Annotations", 8 | "title": "Annotations for 17", 9 | "navlink": "vendor/bin/index.php/restapi/annotations/17", 10 | "number": 5 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-customtypes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Custom Columns", 3 | "baseurl": "vendor/bin/index.php/restapi", 4 | "entries": [ 5 | { 6 | "id": 1, 7 | "label": "type4", 8 | "name": "Type4", 9 | "datatype": "series", 10 | "display": "{}", 11 | "is_multiple": 0, 12 | "normalized": 1, 13 | "navlink": "vendor/bin/index.php/restapi/custom/1" 14 | }, 15 | { 16 | "id": 2, 17 | "label": "type2", 18 | "name": "Type2", 19 | "datatype": "text", 20 | "display": "{\"is_names\": false}", 21 | "is_multiple": 1, 22 | "normalized": 1, 23 | "navlink": "vendor/bin/index.php/restapi/custom/2" 24 | }, 25 | { 26 | "id": 3, 27 | "label": "type1", 28 | "name": "Type1", 29 | "datatype": "text", 30 | "display": "{\"use_decorations\": 0}", 31 | "is_multiple": 0, 32 | "normalized": 1, 33 | "navlink": "vendor/bin/index.php/restapi/custom/3" 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-database-table.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Database Table books", 3 | "baseurl": "vendor/bin/index.php/restapi", 4 | "entries": [], 5 | "error": "Invalid api key" 6 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-database.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Database Types", 3 | "baseurl": "vendor/bin/index.php/restapi", 4 | "entries": [ 5 | { 6 | "class": "Metadata", 7 | "title": "Tables", 8 | "navlink": "vendor/bin/index.php/restapi/databases/0?type=table" 9 | }, 10 | { 11 | "class": "Metadata", 12 | "title": "Views", 13 | "navlink": "vendor/bin/index.php/restapi/databases/0?type=view" 14 | } 15 | ], 16 | "version": 26 17 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-databases.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Databases", 3 | "baseurl": "vendor/bin/index.php/restapi", 4 | "entries": [ 5 | { 6 | "class": "Database", 7 | "title": "", 8 | "id": 0, 9 | "navlink": "vendor/bin/index.php/restapi/databases/0" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-metadata-element.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Metadata for 17", 3 | "baseurl": "vendor/bin/index.php/restapi", 4 | "databaseId": null, 5 | "element": "dc:title", 6 | "entries": [ 7 | "Alice's Adventures in Wonderland" 8 | ] 9 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-note.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Note for authors #3", 3 | "baseurl": "vendor/bin/index.php/restapi", 4 | "databaseId": null, 5 | "id": 1, 6 | "item": 3, 7 | "colname": "authors", 8 | "doc": "", 9 | "mtime": 1708880895.654, 10 | "size": 227, 11 | "resources": { 12 | "xxh64:7c301792c52eebf7": { 13 | "hash": "xxh64:7c301792c52eebf7", 14 | "name": "330px-LewisCarrollSelfPhoto.jpg", 15 | "url": "vendor/bin/index.php/calres/0/xxh64/7c301792c52eebf7", 16 | "size": 37341, 17 | "mtime": 1737754398 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-notes-type-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Note for authors #3", 3 | "baseurl": "vendor/bin/index.php/restapi", 4 | "databaseId": null, 5 | "id": 1, 6 | "item": 3, 7 | "colname": "authors", 8 | "doc": "", 9 | "mtime": 1708880895.654, 10 | "size": 227, 11 | "resources": { 12 | "xxh64:7c301792c52eebf7": { 13 | "hash": "xxh64:7c301792c52eebf7", 14 | "name": "330px-LewisCarrollSelfPhoto.jpg", 15 | "url": "vendor/bin/index.php/calres/0/xxh64/7c301792c52eebf7", 16 | "size": 37341, 17 | "mtime": 1737754398 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-notes-type.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Notes for authors", 3 | "baseurl": "vendor/bin/index.php/restapi", 4 | "databaseId": null, 5 | "entries": [ 6 | { 7 | "class": "Notes", 8 | "title": "Lewis Carroll", 9 | "id": 3, 10 | "navlink": "vendor/bin/index.php/restapi/notes/authors/3/Lewis_Carroll", 11 | "size": 227, 12 | "timestamp": 1708880895.654 13 | }, 14 | { 15 | "class": "Notes", 16 | "title": "H. G. Wells", 17 | "id": 4, 18 | "navlink": "vendor/bin/index.php/restapi/notes/authors/4/H_G_Wells", 19 | "size": 21741, 20 | "timestamp": 1741359641.1851127 21 | }, 22 | { 23 | "class": "Notes", 24 | "title": "Alexandre Dumas", 25 | "id": 5, 26 | "navlink": "vendor/bin/index.php/restapi/notes/authors/5/Alexandre_Dumas", 27 | "size": 28518, 28 | "timestamp": 1741359668.481976 29 | } 30 | ] 31 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-notes.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Notes", 3 | "baseurl": "vendor/bin/index.php/restapi", 4 | "databaseId": null, 5 | "entries": [ 6 | { 7 | "class": "Notes Type", 8 | "title": "authors", 9 | "navlink": "vendor/bin/index.php/restapi/notes/authors", 10 | "number": 3 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-path.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikespub-org/seblucas-cops/d143fceca81d22a544d2da50e713668f2fb1c1f2/tests/restapi/restapi-path.html -------------------------------------------------------------------------------- /tests/restapi/restapi-path.json: -------------------------------------------------------------------------------- 1 | null -------------------------------------------------------------------------------- /tests/restapi/restapi-preference.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Preference for virtual_libraries", 3 | "baseurl": "vendor/bin/index.php/restapi", 4 | "databaseId": null, 5 | "id": 56, 6 | "key": "virtual_libraries", 7 | "val": { 8 | "Action Fiction from this Century (TODO)": "(tags:\"Fiction\" and pubdate:>=2000) and tags:\"=Action & Adventure\"", 9 | "Short Stories in English": "tags:\"=Short Stories\" and languages:\"=eng\" and formats:\"=EPUB\"" 10 | } 11 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-user-details.json: -------------------------------------------------------------------------------- 1 | { 2 | "error": "Invalid username" 3 | } -------------------------------------------------------------------------------- /tests/restapi/restapi-user.json: -------------------------------------------------------------------------------- 1 | { 2 | "error": "Invalid username" 3 | } -------------------------------------------------------------------------------- /tests/schema/opds/feed-metadata.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://drafts.opds.io/schema/feed-metadata.schema.json", 4 | "title": "OPDS Metadata", 5 | "type": "object", 6 | "properties": { 7 | "identifier": { 8 | "type": "string", 9 | "format": "uri" 10 | }, 11 | "@type": { 12 | "type": "string", 13 | "format": "uri" 14 | }, 15 | "title": { 16 | "type": [ 17 | "string", 18 | "array", 19 | "object" 20 | ] 21 | }, 22 | "subtitle": { 23 | "type": [ 24 | "string", 25 | "array", 26 | "object" 27 | ] 28 | }, 29 | "modified": { 30 | "type": "string", 31 | "format": "date-time" 32 | }, 33 | "description": { 34 | "type": "string" 35 | }, 36 | "itemsPerPage": { 37 | "type": "integer", 38 | "exclusiveMinimum": 0 39 | }, 40 | "currentPage": { 41 | "type": "integer", 42 | "exclusiveMinimum": 0 43 | }, 44 | "numberOfItems": { 45 | "type": "integer", 46 | "minimum": 0 47 | } 48 | }, 49 | "required": [ 50 | "title" 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /tests/schema/readium/contributor-object.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://readium.org/webpub-manifest/schema/contributor-object.schema.json", 4 | "title": "Contributor Object", 5 | "type": "object", 6 | "properties": { 7 | "name": { 8 | "anyOf": [ 9 | { 10 | "type": "string" 11 | }, 12 | { 13 | "description": "The language in a language map must be a valid BCP 47 tag.", 14 | "type": "object", 15 | "patternProperties": { 16 | "^((?