You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 7-8.RSVP
Socket
Socket
Sign inDemoInstall

org.librarysimplified:org.librarysimplified.ui.datepicker

Package Overview
Dependencies
Maintainers
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

org.librarysimplified:org.librarysimplified.ui.datepicker

Library Simplified (Date picker UI component)


Version published
Maintainers
6

Readme

Source

Library Simplified

Build Status

The NYPL's Library Simplified Android client.

simplified

Image by Predrag Kezic from Pixabay

BuildStatus
Nightly, DRM, JDK 11Build Status
Nightly, DRM-Free, JDK 11Build Status
Nightly, DRM-Free, JDK 15Build Status
Last CommitBuild Status

What Is This?

The contents of this repository provide the framework of an application used to build, amongst others, the NYPL's official SimplyE application. The framework provides a base application with numerous configuration switches, and configurable branding. The expectation is that third parties will produce final builds of applications by defining application frontends that specify dependencies on the framework, custom color schemes, and logos.

The repository contains a number of applications that are all built from the same core:

ApplicationModuleDescription
Vanillasimplified-app-vanillaDRM-free generic reading application
SimplyEsimplified-app-simplyeThe NYPL's official SimplyE application
Open eBookssimplified-app-openebooksThe Open eBooks application

Contents

Building The Code

The Short Version

Make sure you clone this repository with git clone --recursive. If you forgot to use --recursive, then execute:

$ git submodule init
$ git submodule update --remote --recursive

Install an Android SDK and a JDK and run:

$ ./gradlew clean ktlint assembleDebug test

This will build all of the code and run the unit tests, but only the Vanilla application will be built by default. In order to build the other applications such as SimplyE, it's necessary to obtain the correct credentials from the NYPL and enable DRM.

The Longer Version
Android SDK

Install the Android SDK and Android Studio. We don't support the use of any other IDE at the moment.

JDK

Install a reasonably modern JDK: Java 11 is the current long-term support (LTS) release of Java. We perform nightly builds using the current LTS Java release, and the current bleeding-edge Java release in order to try to detect any upcoming compatibility issues, but we don't recommend building on anything other than the current LTS JDK for everyday usage.

Any of the following JDKs should work:

The JAVA_HOME environment variable must be set correctly. You can check what it is set to in most shells with echo $JAVA_HOME. If that command does not show anything, adding the following line to $HOME/.profile and then executing source $HOME/.profile or opening a new shell should suffice:

# Replace NNN with your particular version of 11.
export JAVA_HOME=/path/to/jdk-11+NNN

You can verify that everything is set up correctly by inspecting the results of both java -version and javac -version:

$ java -version
openjdk version "11.0.8" 2020-07-14
OpenJDK Runtime Environment (build 11.0.8+10)
OpenJDK 64-Bit Server VM (build 11.0.8+10, mixed mode)
S3 Credentials

Our application can use packages that are only available from our S3 bucket. If you wish to use these packages, you need to obtain S3 credentials and then tell Gradle to use them.

S3 credentials can be obtained by emailing malcolmwoods@nypl.org or by asking in the #mobile-development channel of librarysimplified.slack.com.

Once you have your credentials, the following lines must be added to $HOME/.gradle/gradle.properties:

# Replace ACCESS_KEY and SECRET_ACCESS_KEY appropriately.
# Do NOT use quotes around either value.
org.librarysimplified.s3.access_key_id=ACCESS_KEY
org.librarysimplified.s3.secret_access_key=SECRET_ACCESS_KEY
org.librarysimplified.s3.depend=true
APK signing

If you wish to generate a signed APK for publishing the Vanilla application, you will need to copy a keystore to release.jks and set the following values correctly in $HOME/.gradle/gradle.properties:

# Replace KEYALIAS, KEYPASSWORD, and STOREPASSWORD appropriately.
# Do NOT use quotes around values.
org.librarysimplified.keyAlias=KEYALIAS
org.librarysimplified.keyPassword=KEYPASSWORD
org.librarysimplified.storePassword=STOREPASSWORD

Note that APK files are only signed if the code is built in release mode. In other words, you need to use either of these commands to produce signed APK files:

$ ./gradlew clean assembleRelease test
$ ./gradlew clean assemble test
Enabling DRM

The application contains optional support for various DRM systems, and these must be enabled explicitly in order to build SimplyE.

Firstly, make sure you have your S3 credentials correctly configured. Then, add the following property to your $HOME/.gradle/gradle.properties file:

org.librarysimplified.drm.enabled=true

This will instruct the build system that you want to build with DRM enabled. If you were to attempt to build the code right now, you would encounter a build failure: When DRM is enabled, the build system will check that you have provided various configuration files containing secrets that the DRM systems require, and will refuse to build the app if you've failed to do this. The build system can copy in the correct secrets for you if tell it the location of directories containing those secrets. For example, assuming that you have SimplyE's secrets in /path/to/simplye/secrets and Open eBook's secrets in /path/to/openebooks/secrets, you can add the following properties to your $HOME/.gradle/gradle.properties file and the build system will copy in the required secrets at build time:

org.librarysimplified.app.assets.openebooks=/path/to/openebooks/secrets
org.librarysimplified.app.assets.simplye=/path/to/simplye/secrets
Adobe DRM Support

The project currently makes calls to the NYPL's Adobe DRM API. The API is structured in a manner that means that enabling actual support for Adobe DRM simply entails adding a dependency on the NYPL's Adobe DRM implementation. This implementation is only available to DRM licensees. Please get in touch with us if you have a DRM license and want to produce a DRM-enabled build!

Findaway Audiobook DRM support

The project currently uses the NYPL's AudioBook API to provide support for playing audio books. The API is structured such that adding support for new types of audiobooks and playback engines only involves adding those modules to the classpath. By default, the application framework only specifies a dependency on the NYPL's DRM-free audiobook player module, but there is also an NYPL-developed Findaway module for Findaway licensees. Please get in touch with us if you have a Findaway license and want to produce a Findaway-enabled build.

Development

Branching/Merging

All new features should be created on feature branches and merged to develop once completed.

Project Structure / Architecture

MVC

The project, as a whole, roughly follows an MVC architecture distributed over the application modules. The controller in the application is task-based and executes all tasks on a background thread to avoid any possibility of blocking the Android UI thread.

MVVM

Newer application modules, roughly follow an MVVM architecture. The View Model in the application exposes reactive properties and executes all tasks on a background thread. The View observes those properties and updates on the Android UI thread.

API vs SPI

The project makes various references to APIs and SPIs. API stands for application programming interface and SPI stands for service provider interface.

An API module defines a user-visible contract (or specification) for a module; it defines the data types and abstract interfaces via which the user is expected to make calls in order to make use of a module. An API module is typically paired with an implementation module that provides concrete implementations of the API interface types. A good example of this is the accounts database: The Accounts database API declares a set of data types and interfaces that describe how an accounts database should behave. The Accounts database implementation module provides an implementation of the described API. Keeping the API specification strictly separated from the implementation in this manner has a number of benefits:

  • Substitutability: When an API has a sufficiently detailed specification, it's possible to replace an implementation module with a superior implementation without having to modify code that makes calls to the API.

  • Testability: Keeping API types strictly separated from implementation types tends to lead to interfaces that are easy to mock.

  • Understandability: Users of modules can go straight to the API specifications to find out how to use them. This cuts down on the amount of archaeological work necessary to learn how to use the application's internal interfaces.

An SPI module is similar to an API in that it provides a specification, however the defined interfaces are expected to be implemented by users rather than called by users directly. An implementor of an SPI is known as a service provider.

A good example of an SPI is the Account provider source SPI; the SPI defines an interface that is expected to be implemented by account provider sources. The file-based source module is capable of delivering account provider descriptions from a bundled asset file. The registry source implementation is capable of fetching account provider descriptions from the NYPL's registry server. Neither the SPI or the implementation modules are expected to be used by application programmers directly: Instead, implementation modules are loaded using ServiceLoader by the Account provider registry, and users interact with the registry via a published registry API. This same design pattern is used by the NYPL AudioBook API to provide a common API into which new audio book players and parsers can be introduced without needing to modify application code at all.

Modules should make every attempt not to specify explicit dependencies on implementation modules. API and implementation modules should typically only depend on other API modules, leaving the choice of implementation modules to the final application assembly. In other words, a module should say "I can work with any module that provides this API" rather than "I depend on implementation M of a particular API". Following this convention allows us to replace module implementation without having to modify lots of different parts of the application; it allows us to avoid strong coupling between modules.

Most of the modularity concepts described here were pioneered by the OSGi module system and so, although the Library Simplified application is not an OSGi application, much of the design and architecture conforms to conventions followed by OSGi applications. Further reading can be found on the OSGi web site.

Build System

The build is driven by the build.gradle file in the root of the project, with the build.gradle files in each module typically only listing dependencies (the actual dependency definitions are defined in the root build.gradle file to avoid duplicating version numbers over the whole project). Metadata used to publish builds (such as Maven group IDs, version numbers, etc) is defined in the gradle.properties file in each module. The gradle.properties file in the root of the project defines default values that are overridden as necessary by each module.

Test suite

We aggregate all unit tests in the simplified-tests module. Tests should be written using the JUnit 5 library, although at the time of writing we have one test that still requires JUnit 4 due to the use of Roboelectric.

Modules

The project is heavily modularized in order to keep the separate application components as loosely coupled as possible. New features should typically be implemented as new modules.

ModuleDescription
org.librarysimplified.accessibilityAccessibility APIs and functionality
org.librarysimplified.accounts.apiAccounts API
org.librarysimplified.accounts.databaseAccounts database implementation
org.librarysimplified.accounts.database.apiAccounts database API
org.librarysimplified.accounts.jsonShared JSON classes
org.librarysimplified.accounts.registryAccount provider registry implementation
org.librarysimplified.accounts.registry.apiAccount provider registry API
org.librarysimplified.accounts.source.filebasedFile/asset based registry source implementation
org.librarysimplified.accounts.source.nyplregistryNYPL registry client implementation
org.librarysimplified.accounts.source.spiAccount provider source SPI
org.librarysimplified.adobe.extensionsAdobe DRM convenience functions
org.librarysimplified.analytics.apiAnalytics API
org.librarysimplified.analytics.circulationCirculation manager analytics implementation
org.librarysimplified.android.ktxKotlin Android Extensions
org.librarysimplified.announcementsAnnouncements API
org.nypl.labs.OpenEbooks.appOpen eBooks Application
org.librarysimplified.simplye.appSimplyE Application
org.librarysimplified.app.vanillaVanilla application
org.librarysimplified.books.apiBook types
org.librarysimplified.books.audioAudio book support code
org.librarysimplified.books.borrowingBook borrowing
org.librarysimplified.books.bundled.apiBundled books API
org.librarysimplified.books.controllerBooks/Profiles controller implementation
org.librarysimplified.books.controller.apiBooks controller API
org.librarysimplified.books.coversBook cover loading and generation
org.librarysimplified.books.databaseBook database implementation
org.librarysimplified.books.database.apiBook database API
org.librarysimplified.books.formatsBook formats implementation
org.librarysimplified.books.formats.apiBook formats API
org.librarysimplified.books.registry.apiBook registry API
org.librarysimplified.boot.apiApplication boot API
org.librarysimplified.buildconfig.apiBuild-time configuration API
org.librarysimplified.cardcreatorNYPL card creator
org.librarysimplified.content.apiContent resolver API
org.librarysimplified.crashlyticsCrashlytics
org.librarysimplified.crashlytics.apiCrashlytics functionality
org.librarysimplified.documentsDocuments
org.librarysimplified.feeds.apiFeed API
org.librarysimplified.filesFile utilities
org.librarysimplified.futuresGuava Future extensions
org.librarysimplified.json.coreJSON utilities
org.librarysimplified.linksLink types
org.librarysimplified.links.jsonLink JSON parsing
org.librarysimplified.mainMain application module
org.librarysimplified.networkconnectivityNetwork connectivity
org.librarysimplified.networkconnectivity.apiNetwork connectivity API
org.librarysimplified.notificationsNotification service
org.librarysimplified.oauthOAuth
org.librarysimplified.opds.auth_documentOPDS authentication document parser implementation
org.librarysimplified.opds.auth_document.apiOPDS authentication document parser API
org.librarysimplified.opds.coreOPDS feed parser
org.librarysimplified.opds2OPDS 2.0 model definitions
org.librarysimplified.opds2.irradiaOPDS 2.0 Parser (Irradia)
org.librarysimplified.opds2.parser.apiOPDS 2.0 parser API
org.librarysimplified.opds2.r2OPDS 2.0 Parser (R2)
org.librarysimplified.parser.apiParser API
org.librarysimplified.patronPatron user profile parser implementation
org.librarysimplified.patron.apiPatron user profile parser API
org.librarysimplified.presentableerror.apiPresentable error API
org.librarysimplified.profilesProfile database implementation
org.librarysimplified.profiles.apiProfile database API
org.librarysimplified.profiles.controller.apiProfile controller API
org.librarysimplified.reader.apiReader API types
org.librarysimplified.reader.bookmarksReader bookmark service implementation
org.librarysimplified.reader.bookmarks.apiReader bookmark service API
org.librarysimplified.reportsError reporting
org.librarysimplified.services.apiApplication services API
org.librarysimplified.taskrecorder.apiTask recorder API
org.librarysimplified.tenprint10PRINT implementation
org.librarysimplified.testsTest suite
org.librarysimplified.tests.sandboxSandbox for informal testing
org.librarysimplified.threadsThread utilities
org.librarysimplified.ui.accountsAccounts UI components
org.librarysimplified.ui.announcementsAnnouncements UI components
org.librarysimplified.ui.brandingBranding functionality
org.librarysimplified.ui.catalogCatalog components
org.librarysimplified.ui.errorpageError details screen
org.librarysimplified.ui.imagesImage loader API for general image resources
org.librarysimplified.ui.listeners.apiListeners API
org.librarysimplified.ui.tabsTabbed UI
org.librarysimplified.ui.onboardingOnboarding
org.librarysimplified.ui.profilesProfiles UI
org.librarysimplified.ui.screenScreen API
org.librarysimplified.ui.settingsSettings screens
org.librarysimplified.ui.splashSplash screen
org.librarysimplified.ui.thread.apiUI thread service
org.librarysimplified.viewer.apiViewer API
org.librarysimplified.viewer.audiobookAudioBook viewer
org.librarysimplified.viewer.epub.readium2Readium 2 EPUB reader
org.librarysimplified.viewer.pdfPDF reader
org.librarysimplified.viewer.spiViewer SPI
org.librarysimplified.webviewWebView utilities

The above table is generated with ReadMe.java.

Ktlint

The codebase uses ktlint to enforce a consistent code style. It's possible to ensure that any changes you've made to the code continue to pass ktlint checks by running:

$ ./gradlew ktlint

To auto-format code style shortcomings with ktlint, run:

$ ./gradlew ktlintFormat

Release Process

Please see RELEASING.md for documentation on our release process.

License

Copyright 2015 The New York Public Library, Astor, Lenox, and Tilden Foundations

Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

FAQs

Package last updated on 15 Jul 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc