diff --git a/.dockerignore b/.dockerignore index 942b75ec5..11cc0bbce 100644 --- a/.dockerignore +++ b/.dockerignore @@ -12,4 +12,5 @@ dev.js test/ /client/.nuxt/ /client/dist/ -/dist/ \ No newline at end of file +/dist/ +/deploy/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 53a60bef2..8df68f625 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,7 @@ test/ /client/.nuxt/ /client/dist/ /dist/ -library/ +/deploy/ sw.* .DS_STORE diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..2fb8b48fb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,20 @@ +{ + "vetur.format.defaultFormatterOptions": { + "prettier": { + "semi": false, + "singleQuote": true, + "printWidth": 400, + "proseWrap": "never", + "trailingComma": "none" + }, + "prettyhtml": { + "printWidth": 400, + "singleQuote": false, + "wrapAttributes": false, + "sortAttributes": false + } + }, + "editor.formatOnSave": true, + "editor.detectIndentation": true, + "editor.tabSize": 2 +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 47aced8a9..db7642bb9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,9 @@ RUN npm ci && npm cache clean --force RUN npm run generate ### STAGE 1: Build server ### +FROM sandreas/tone:v0.1.2 AS tone FROM node:16-alpine + ENV NODE_ENV=production RUN apk update && \ apk add --no-cache --update \ @@ -14,6 +16,7 @@ RUN apk update && \ tzdata \ ffmpeg +COPY --from=tone /usr/local/bin/tone /usr/local/bin/ COPY --from=build /client/dist /client/dist COPY index.js package* / COPY server server diff --git a/build/debian/DEBIAN/preinst b/build/debian/DEBIAN/preinst index 0ad58d94d..be2d8b794 100644 --- a/build/debian/DEBIAN/preinst +++ b/build/debian/DEBIAN/preinst @@ -8,8 +8,6 @@ CONFIG_PATH="/etc/default/audiobookshelf" DEFAULT_PORT=13378 DEFAULT_HOST="0.0.0.0" - - add_user() { : "${1:?'User was not defined'}" declare -r user="$1" @@ -51,7 +49,8 @@ add_group() { install_ffmpeg() { echo "Starting FFMPEG Install" - WGET="wget https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz" + WGET="wget https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz --output-document=ffmpeg-git-amd64-static.tar.xz" + WGET_TONE="wget https://github.com/sandreas/tone/releases/download/v0.1.2/tone-0.1.2-linux-x64.tar.gz --output-document=tone-0.1.2-linux-x64.tar.gz" if ! cd "$FFMPEG_INSTALL_DIR"; then echo "Creating ffmpeg install dir at $FFMPEG_INSTALL_DIR" @@ -64,13 +63,26 @@ install_ffmpeg() { tar xvf ffmpeg-git-amd64-static.tar.xz --strip-components=1 rm ffmpeg-git-amd64-static.tar.xz - echo "Good to go on Ffmpeg... hopefully" + # Temp downloading tone library to the ffmpeg dir + echo "Getting tone.." + $WGET_TONE + tar xvf tone-0.1.2-linux-x64.tar.gz --strip-components=1 + rm tone-0.1.2-linux-x64.tar.gz + + echo "Good to go on Ffmpeg (& tone)... hopefully" } setup_config() { if [ -f "$CONFIG_PATH" ]; then echo "Existing config found." cat $CONFIG_PATH + + # TONE_PATH variable added in 2.1.6, if it doesnt exist then add it + if ! grep -q "TONE_PATH" "$CONFIG_PATH"; then + echo "Adding TONE_PATH to existing config" + echo "TONE_PATH=$FFMPEG_INSTALL_DIR/tone" >> "$CONFIG_PATH" + fi + else if [ ! -d "$DEFAULT_DATA_DIR" ]; then @@ -83,11 +95,12 @@ setup_config() { echo "Creating default config." config_text="METADATA_PATH=$DEFAULT_DATA_DIR/metadata - CONFIG_PATH=$DEFAULT_DATA_DIR/config - FFMPEG_PATH=/usr/lib/audiobookshelf-ffmpeg/ffmpeg - FFPROBE_PATH=/usr/lib/audiobookshelf-ffmpeg/ffprobe - PORT=$DEFAULT_PORT - HOST=$DEFAULT_HOST" +CONFIG_PATH=$DEFAULT_DATA_DIR/config +FFMPEG_PATH=$FFMPEG_INSTALL_DIR/ffmpeg +FFPROBE_PATH=$FFMPEG_INSTALL_DIR/ffprobe +TONE_PATH=$FFMPEG_INSTALL_DIR/tone +PORT=$DEFAULT_PORT +HOST=$DEFAULT_HOST" echo "$config_text" diff --git a/build/debian/lib/systemd/system/audiobookshelf.service b/build/debian/lib/systemd/system/audiobookshelf.service index 528a2c30a..7dd657dad 100644 --- a/build/debian/lib/systemd/system/audiobookshelf.service +++ b/build/debian/lib/systemd/system/audiobookshelf.service @@ -10,6 +10,7 @@ ExecStart=/usr/share/audiobookshelf/audiobookshelf ExecReload=/bin/kill -HUP $MAINPID Restart=always User=audiobookshelf +Group=audiobookshelf PermissionsStartOnly=true [Install] diff --git a/client/assets/absicons.css b/client/assets/absicons.css new file mode 100644 index 000000000..b2c0f8e88 --- /dev/null +++ b/client/assets/absicons.css @@ -0,0 +1,106 @@ +@font-face { + font-family: 'absicons'; + src: url('~static/fonts/absicons/absicons.eot?2jfq33'); + src: url('~static/fonts/absicons/absicons.eot?2jfq33#iefix') format('embedded-opentype'), + url('~static/fonts/absicons/absicons.ttf?2jfq33') format('truetype'), + url('~static/fonts/absicons/absicons.woff?2jfq33') format('woff'), + url('~static/fonts/absicons/absicons.svg?2jfq33#absicons') format('svg'); + font-weight: normal; + font-style: normal; + font-display: block; +} + +.abs-icons { + /* use !important to prevent issues with browser extensions that change fonts */ + font-family: 'absicons' !important; + speak: never; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-books-1:before { + content: "\e905"; +} + +.icon-microphone-1:before { + content: "\e902"; +} + +.icon-radio:before { + content: "\e903"; +} + +.icon-podcast:before { + content: "\e904"; +} + +.icon-audiobookshelf:before { + content: "\e900"; +} + +.icon-database:before { + content: "\e906"; +} + +.icon-microphone-2:before { + content: "\e901"; +} + +.icon-headphones:before { + content: "\e910"; +} + +.icon-music:before { + content: "\e911"; +} + +.icon-video:before { + content: "\e914"; +} + +.icon-microphone-3:before { + content: "\e91e"; +} + +.icon-book-1:before { + content: "\e91f"; +} + +.icon-books-2:before { + content: "\e920"; +} + +.icon-file-picture:before { + content: "\e927"; +} + +.icon-database-1:before { + content: "\e964"; +} + +.icon-rocket:before { + content: "\e9a5"; +} + +.icon-power:before { + content: "\e9b5"; +} + +.icon-star:before { + content: "\e9d9"; +} + +.icon-heart:before { + content: "\e9da"; +} + +.icon-rss:before { + content: "\ea9b"; +} \ No newline at end of file diff --git a/client/assets/app.css b/client/assets/app.css index e870e7664..c823af2f8 100644 --- a/client/assets/app.css +++ b/client/assets/app.css @@ -2,6 +2,7 @@ @import './transitions.css'; @import './draggable.css'; @import './defaultStyles.css'; +@import './absicons.css'; :root { --bookshelf-texture-img: url(/textures/wood_default.jpg); diff --git a/client/assets/fonts.css b/client/assets/fonts.css index 46e007aa2..f3c586e34 100644 --- a/client/assets/fonts.css +++ b/client/assets/fonts.css @@ -2,14 +2,14 @@ font-family: 'Material Icons'; font-style: normal; font-weight: 400; - src: url(/fonts/MaterialIcons.woff2) format('woff2'); + src: url(~static/fonts/MaterialIcons.woff2) format('woff2'); } @font-face { font-family: 'Material Icons Outlined'; font-style: normal; font-weight: 400; - src: url(/fonts/MaterialIconsOutlined.woff2) format('woff2'); + src: url(~static/fonts/MaterialIconsOutlined.woff2) format('woff2'); } .material-icons { @@ -54,7 +54,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/GentiumBookBasic.woff2) format('woff2'); + src: url(~static/fonts/GentiumBookBasic.woff2) format('woff2'); unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; } @@ -64,7 +64,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/GentiumBookBasic.woff2) format('woff2'); + src: url(~static/fonts/GentiumBookBasic.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } @@ -74,7 +74,7 @@ font-style: normal; font-weight: 300; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; } @@ -84,7 +84,7 @@ font-style: normal; font-weight: 300; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } @@ -94,7 +94,7 @@ font-style: normal; font-weight: 300; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); unicode-range: U+1F00-1FFF; } @@ -104,7 +104,7 @@ font-style: normal; font-weight: 300; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); unicode-range: U+0370-03FF; } @@ -114,7 +114,7 @@ font-style: normal; font-weight: 300; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; } @@ -124,7 +124,7 @@ font-style: normal; font-weight: 300; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; } @@ -134,7 +134,7 @@ font-style: normal; font-weight: 300; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf) format('truetype'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } @@ -144,7 +144,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('ttf'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('ttf'); unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; } @@ -154,7 +154,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype'); unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } @@ -164,7 +164,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype'); unicode-range: U+1F00-1FFF; } @@ -174,7 +174,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype'); unicode-range: U+0370-03FF; } @@ -184,7 +184,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype'); unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; } @@ -194,7 +194,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype'); unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; } @@ -204,7 +204,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf) format('truetype'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } @@ -214,7 +214,7 @@ font-style: normal; font-weight: 600; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; } @@ -224,7 +224,7 @@ font-style: normal; font-weight: 600; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } @@ -234,7 +234,7 @@ font-style: normal; font-weight: 600; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); unicode-range: U+1F00-1FFF; } @@ -244,7 +244,7 @@ font-style: normal; font-weight: 600; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); unicode-range: U+0370-03FF; } @@ -254,7 +254,7 @@ font-style: normal; font-weight: 600; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; } @@ -264,7 +264,7 @@ font-style: normal; font-weight: 600; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; } @@ -274,7 +274,7 @@ font-style: normal; font-weight: 600; font-display: swap; - src: url(/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); + src: url(~static/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf) format('truetype'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } @@ -284,7 +284,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype'); + src: url(~static/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype'); unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; } @@ -294,7 +294,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype'); + src: url(~static/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype'); unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } @@ -304,7 +304,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype'); + src: url(~static/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype'); unicode-range: U+1F00-1FFF; } @@ -314,7 +314,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype'); + src: url(~static/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype'); unicode-range: U+0370-03FF; } @@ -324,7 +324,7 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype'); + src: url(~static/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype'); unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; } @@ -334,6 +334,6 @@ font-style: normal; font-weight: 400; font-display: swap; - src: url(/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype'); + src: url(~static/fonts/Ubuntu_Mono/UbuntuMono-Regular.ttf) format('truetype'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } \ No newline at end of file diff --git a/client/components/app/Appbar.vue b/client/components/app/Appbar.vue index cc417739b..f39e88398 100644 --- a/client/components/app/Appbar.vue +++ b/client/components/app/Appbar.vue @@ -3,11 +3,11 @@
{{ shelf.label }}
+{{ $strings[shelf.labelStringKey] }}
{{ shelf.label }}
+{{ $strings[shelf.labelStringKey] }}
{{ shelf.label }}
+{{ $strings[shelf.labelStringKey] }}
{{ shelf.label }}
+{{ $strings[shelf.labelStringKey] }}
{{ shelf.label }}
+{{ $strings[shelf.labelStringKey] }}
Home
+{{ $strings.ButtonHome }}
+Library
+{{ $strings.ButtonLibrary }}
+Series
+{{ $strings.ButtonLatest }}
Collections
+{{ $strings.ButtonSeries }}
+ +{{ $strings.ButtonCollections }}
+ +{{ $strings.ButtonAuthors }}
+Search
+{{ $strings.ButtonSearch }}
Home
+{{ $strings.ButtonHome }}
+{{ $strings.ButtonLatest }}
+ + +Library
+{{ $strings.ButtonLibrary }}
Series
+{{ $strings.ButtonSeries }}
@@ -37,7 +45,7 @@Collections
+{{ $strings.ButtonCollections }}
Authors
+{{ $strings.ButtonAuthors }}
Search
+{{ $strings.ButtonSearch }}
Issues
+{{ $strings.ButtonIssues }}
{{ Source }}
Unknown
+{{ $strings.LabelUnknown }}
{{ book.publishedYear }}
by {{ book.author }}
+by {{ book.author }}
Narrated by {{ book.narrator }}
Runtime: {{ $elapsedPrettyExtended(book.duration * 60) }}
- {{ series.series }} #{{ series.volumeNumber }} + {{ series.series }} #{{ series.sequence }}
Directory (auto)
+{{ $strings.LabelDirectory }} (auto)
Directory (auto)
+{{ $strings.LabelDirectory }} (auto)
Successfully Uploaded!
+{{ $strings.MessageUploaderItemSuccess }}
Failed to upload
+{{ $strings.MessageUploaderItemFailed }}
{{ displaySortLine }}
-#{{ seriesSequenceList }}
+{{ booksInSeries }}
+{{ titleCleaned }}
++ {{ titleCleaned }} +