├── ui ├── src │ ├── app │ │ ├── library │ │ │ ├── edit │ │ │ │ └── edit.page.sass │ │ │ ├── series │ │ │ │ └── series.page.sass │ │ │ ├── publishers │ │ │ │ └── publishers.page.sass │ │ │ ├── issues │ │ │ │ ├── issue-actions │ │ │ │ │ ├── issue-actions.component.sass │ │ │ │ │ ├── issue-actions.component.html │ │ │ │ │ └── issue-actions.component.ts │ │ │ │ └── issues.page.sass │ │ │ └── volumes │ │ │ │ ├── volume-actions │ │ │ │ ├── volume-actions.component.sass │ │ │ │ └── volume-actions.component.html │ │ │ │ ├── covers │ │ │ │ ├── covers.page.sass │ │ │ │ └── covers.page.html │ │ │ │ └── volumes.page.sass │ │ ├── settings │ │ │ ├── settings.page.sass │ │ │ ├── queue │ │ │ │ └── queue.page.sass │ │ │ ├── scanner │ │ │ │ └── scanner.component.sass │ │ │ └── settings.module.ts │ │ ├── bookmarks │ │ │ ├── bookmark-actions │ │ │ │ ├── bookmark-actions.component.sass │ │ │ │ ├── bookmark-actions.component.html │ │ │ │ └── bookmark-actions.component.ts │ │ │ ├── bookmarks.page.sass │ │ │ └── bookmarks.module.ts │ │ ├── series.ts │ │ ├── setting.ts │ │ ├── caches.token.ts │ │ ├── location.token.ts │ │ ├── publisher.ts │ │ ├── user.ts │ │ ├── app.component.sass │ │ ├── volume.ts │ │ ├── stats.ts │ │ ├── thumbnail.ts │ │ ├── secure │ │ │ ├── secure.module.ts │ │ │ └── secure.pipe.ts │ │ ├── login │ │ │ ├── login.page.sass │ │ │ └── login.module.ts │ │ ├── app.component.html │ │ ├── auth.interceptor.ts │ │ ├── reader │ │ │ └── reader.module.ts │ │ ├── stats.service.ts │ │ ├── auth.guard.ts │ │ ├── cache-storage.service.ts │ │ ├── settings.service.ts │ │ ├── thumbnails.service.ts │ │ ├── stats.service.spec.ts │ │ ├── user-settings.service.ts │ │ ├── comic.ts │ │ └── cache-storage.service.spec.ts │ ├── assets │ │ └── icons │ │ │ ├── favicon.ico │ │ │ ├── alfred-72x72.png │ │ │ ├── alfred-96x96.png │ │ │ ├── alfred-128x128.png │ │ │ ├── alfred-144x144.png │ │ │ ├── alfred-152x152.png │ │ │ ├── alfred-192x192.png │ │ │ ├── alfred-384x384.png │ │ │ ├── alfred-512x512.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ └── alfred-512x512-splash.png │ ├── testing │ │ ├── mock.component.ts │ │ ├── user.fixtures.ts │ │ ├── stats.http.mocks.ts │ │ ├── setting.fixtures.ts │ │ ├── queue.service.mocks.ts │ │ ├── stats.service.mocks.ts │ │ ├── thumbnail.fixtures.ts │ │ ├── thumbnails.service.mocks.ts │ │ ├── settings.service.mocks.ts │ │ ├── user.service.mocks.ts │ │ ├── swupdate.mocks.ts │ │ ├── series.fixtures.ts │ │ ├── toast.controller.mocks.ts │ │ ├── volume.fixtures.ts │ │ ├── alert.controller.mocks.ts │ │ ├── indexed-db.service.mocks.ts │ │ ├── comic-storage.service.mocks.ts │ │ ├── loading.controller.mocks.ts │ │ ├── volumes.service.mocks.ts │ │ ├── popover.controller.mocks.ts │ │ └── comic-database.service.mocks.ts │ ├── zone-flags.ts │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── main.ts │ ├── styles.sass │ ├── test.ts │ └── index.html ├── resources │ ├── icon.png.md5 │ ├── splash.png.md5 │ ├── icon.png │ ├── splash.png │ ├── android │ │ ├── icon │ │ │ ├── drawable-hdpi-icon.png │ │ │ ├── drawable-ldpi-icon.png │ │ │ ├── drawable-mdpi-icon.png │ │ │ ├── drawable-xhdpi-icon.png │ │ │ ├── drawable-xxhdpi-icon.png │ │ │ └── drawable-xxxhdpi-icon.png │ │ └── splash │ │ │ ├── drawable-land-hdpi-screen.png │ │ │ ├── drawable-land-ldpi-screen.png │ │ │ ├── drawable-land-mdpi-screen.png │ │ │ ├── drawable-land-xhdpi-screen.png │ │ │ ├── drawable-port-hdpi-screen.png │ │ │ ├── drawable-port-ldpi-screen.png │ │ │ ├── drawable-port-mdpi-screen.png │ │ │ ├── drawable-port-xhdpi-screen.png │ │ │ ├── drawable-land-xxhdpi-screen.png │ │ │ ├── drawable-land-xxxhdpi-screen.png │ │ │ ├── drawable-port-xxhdpi-screen.png │ │ │ └── drawable-port-xxxhdpi-screen.png │ └── README.md ├── proxy.conf.json ├── ionic.config.json ├── e2e │ ├── protractor.headless.conf.js │ ├── tsconfig.json │ └── src │ │ ├── app.po.ts │ │ ├── app.e2e-spec.ts │ │ ├── settings.e2e-spec.ts │ │ ├── mongodb.tools.ts │ │ └── proxy-settings.ts ├── tsconfig.app.json ├── build.gradle ├── .browserslistrc ├── tsconfig.spec.json ├── .gitignore └── tsconfig.json ├── .dockerignore ├── lombok.config ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── src ├── test │ ├── resources │ │ ├── fixtures │ │ │ ├── full │ │ │ │ ├── Batgirl 000 (2011).cbz │ │ │ │ ├── Batgirl 001 (2000).cbz │ │ │ │ ├── Batgirl 001 (2009).cbz │ │ │ │ ├── Batgirl 001 (2011).cbz │ │ │ │ ├── Batgirl 001 (2016).cbz │ │ │ │ ├── Batgirl 002 (2000).cbz │ │ │ │ ├── Batgirl 002 (2009).cbz │ │ │ │ ├── Batgirl 002 (2011).cbz │ │ │ │ ├── Batgirl 002 (2016).cbz │ │ │ │ ├── Batgirl 003 (2000).cbz │ │ │ │ ├── Batgirl 003 (2009).cbz │ │ │ │ ├── Batgirl 003 (2011).cbz │ │ │ │ ├── Batgirl 003 (2016).cbz │ │ │ │ ├── Batgirl 004 (2000).cbz │ │ │ │ ├── Batgirl 004 (2009).cbz │ │ │ │ ├── Batgirl 004 (2011).cbz │ │ │ │ ├── Batgirl 004 (2016).cbz │ │ │ │ ├── Batgirl 005 (2000).cbz │ │ │ │ ├── Batgirl 005 (2009).cbz │ │ │ │ ├── Batgirl 005 (2011).cbz │ │ │ │ ├── Batgirl 005 (2016).cbz │ │ │ │ ├── Batgirl 006 (2000).cbz │ │ │ │ ├── Batgirl 006 (2009).cbz │ │ │ │ ├── Batgirl 006 (2011).cbz │ │ │ │ ├── Batgirl 006 (2016).cbz │ │ │ │ ├── Batgirl 007 (2000).cbz │ │ │ │ ├── Batgirl 007 (2009).cbz │ │ │ │ ├── Batgirl 007 (2011).cbz │ │ │ │ ├── Batgirl 008 (2000).cbz │ │ │ │ ├── Batgirl 008 (2009).cbz │ │ │ │ ├── Batgirl 008 (2011).cbz │ │ │ │ ├── Batgirl 009 (2000).cbz │ │ │ │ ├── Batgirl 009 (2009).cbz │ │ │ │ ├── Batgirl 009 (2011).cbz │ │ │ │ ├── Batgirl 01 (2008).cbz │ │ │ │ ├── Batgirl 010 (2000).cbz │ │ │ │ ├── Batgirl 010 (2009).cbz │ │ │ │ ├── Batgirl 010 (2011).cbz │ │ │ │ ├── Batgirl 011 (2000).cbz │ │ │ │ ├── Batgirl 011 (2009).cbz │ │ │ │ ├── Batgirl 011 (2011).cbz │ │ │ │ ├── Batgirl 012 (2000).cbz │ │ │ │ ├── Batgirl 012 (2009).cbz │ │ │ │ ├── Batgirl 012 (2011).cbz │ │ │ │ ├── Batgirl 013 (2000).cbz │ │ │ │ ├── Batgirl 013 (2009).cbz │ │ │ │ ├── Batgirl 013 (2011).cbz │ │ │ │ ├── Batgirl 014 (2000).cbz │ │ │ │ ├── Batgirl 014 (2009).cbz │ │ │ │ ├── Batgirl 014 (2011).cbz │ │ │ │ ├── Batgirl 015 (2000).cbz │ │ │ │ ├── Batgirl 015 (2009).cbz │ │ │ │ ├── Batgirl 015 (2011).cbz │ │ │ │ ├── Batgirl 016 (2000).cbz │ │ │ │ ├── Batgirl 016 (2009).cbz │ │ │ │ ├── Batgirl 016 (2011).cbz │ │ │ │ ├── Batgirl 017 (2000).cbz │ │ │ │ ├── Batgirl 017 (2009).cbz │ │ │ │ ├── Batgirl 017 (2011).cbz │ │ │ │ ├── Batgirl 018 (2000).cbz │ │ │ │ ├── Batgirl 018 (2009).cbz │ │ │ │ ├── Batgirl 018 (2011).cbz │ │ │ │ ├── Batgirl 019 (2000).cbz │ │ │ │ ├── Batgirl 019 (2009).cbz │ │ │ │ ├── Batgirl 019 (2011).cbz │ │ │ │ ├── Batgirl 02 (2008).cbz │ │ │ │ ├── Batgirl 020 (2000).cbz │ │ │ │ ├── Batgirl 020 (2009).cbz │ │ │ │ ├── Batgirl 020 (2011).cbz │ │ │ │ ├── Batgirl 021 (2000).cbz │ │ │ │ ├── Batgirl 021 (2009).cbz │ │ │ │ ├── Batgirl 021 (2011).cbz │ │ │ │ ├── Batgirl 022 (2000).cbz │ │ │ │ ├── Batgirl 022 (2009).cbz │ │ │ │ ├── Batgirl 022 (2011).cbz │ │ │ │ ├── Batgirl 023 (2000).cbz │ │ │ │ ├── Batgirl 023 (2009).cbz │ │ │ │ ├── Batgirl 023 (2011).cbz │ │ │ │ ├── Batgirl 024 (2000).cbz │ │ │ │ ├── Batgirl 024 (2009).cbz │ │ │ │ ├── Batgirl 024 (2011).cbz │ │ │ │ ├── Batgirl 025 (2000).cbz │ │ │ │ ├── Batgirl 025 (2011).cbz │ │ │ │ ├── Batgirl 026 (2000).cbz │ │ │ │ ├── Batgirl 026 (2011).cbz │ │ │ │ ├── Batgirl 027 (2000).cbz │ │ │ │ ├── Batgirl 027 (2011).cbz │ │ │ │ ├── Batgirl 028 (2000).cbz │ │ │ │ ├── Batgirl 028 (2011).cbz │ │ │ │ ├── Batgirl 029 (2000).cbz │ │ │ │ ├── Batgirl 029 (2011).cbz │ │ │ │ ├── Batgirl 03 (2008).cbz │ │ │ │ ├── Batgirl 030 (2000).cbz │ │ │ │ ├── Batgirl 030 (2011).cbz │ │ │ │ ├── Batgirl 031 (2000).cbz │ │ │ │ ├── Batgirl 031 (2011).cbz │ │ │ │ ├── Batgirl 032 (2000).cbz │ │ │ │ ├── Batgirl 032 (2011).cbz │ │ │ │ ├── Batgirl 033 (2000).cbz │ │ │ │ ├── Batgirl 033 (2011).cbz │ │ │ │ ├── Batgirl 034 (2000).cbz │ │ │ │ ├── Batgirl 034 (2011).cbz │ │ │ │ ├── Batgirl 035 (2000).cbz │ │ │ │ ├── Batgirl 035 (2011).cbz │ │ │ │ ├── Batgirl 036 (2000).cbz │ │ │ │ ├── Batgirl 036 (2011).cbz │ │ │ │ ├── Batgirl 037 (2000).cbz │ │ │ │ ├── Batgirl 037 (2011).cbz │ │ │ │ ├── Batgirl 038 (2000).cbz │ │ │ │ ├── Batgirl 038 (2011).cbz │ │ │ │ ├── Batgirl 039 (2000).cbz │ │ │ │ ├── Batgirl 039 (2011).cbz │ │ │ │ ├── Batgirl 04 (2008).cbz │ │ │ │ ├── Batgirl 040 (2000).cbz │ │ │ │ ├── Batgirl 040 (2011).cbz │ │ │ │ ├── Batgirl 041 (2000).cbz │ │ │ │ ├── Batgirl 041 (2011).cbz │ │ │ │ ├── Batgirl 042 (2000).cbz │ │ │ │ ├── Batgirl 042 (2011).cbz │ │ │ │ ├── Batgirl 043 (2000).cbz │ │ │ │ ├── Batgirl 043 (2011).cbz │ │ │ │ ├── Batgirl 044 (2000).cbz │ │ │ │ ├── Batgirl 044 (2011).cbz │ │ │ │ ├── Batgirl 045 (2000).cbz │ │ │ │ ├── Batgirl 045 (2011).cbz │ │ │ │ ├── Batgirl 046 (2000).cbz │ │ │ │ ├── Batgirl 046 (2011).cbz │ │ │ │ ├── Batgirl 047 (2000).cbz │ │ │ │ ├── Batgirl 047 (2011).cbz │ │ │ │ ├── Batgirl 048 (2000).cbz │ │ │ │ ├── Batgirl 048 (2011).cbz │ │ │ │ ├── Batgirl 049 (2000).cbz │ │ │ │ ├── Batgirl 049 (2011).cbz │ │ │ │ ├── Batgirl 05 (2008).cbz │ │ │ │ ├── Batgirl 050 (2000).cbz │ │ │ │ ├── Batgirl 050 (2011).cbz │ │ │ │ ├── Batgirl 051 (2000).cbz │ │ │ │ ├── Batgirl 051 (2011).cbz │ │ │ │ ├── Batgirl 052 (2000).cbz │ │ │ │ ├── Batgirl 052 (2011).cbz │ │ │ │ ├── Batgirl 053 (2000).cbz │ │ │ │ ├── Batgirl 054 (2000).cbz │ │ │ │ ├── Batgirl 055 (2000).cbz │ │ │ │ ├── Batgirl 056 (2000).cbz │ │ │ │ ├── Batgirl 057 (2000).cbz │ │ │ │ ├── Batgirl 058 (2000).cbz │ │ │ │ ├── Batgirl 059 (2000).cbz │ │ │ │ ├── Batgirl 06 (2008).cbz │ │ │ │ ├── Batgirl 060 (2000).cbz │ │ │ │ ├── Batgirl 061 (2000).cbz │ │ │ │ ├── Batgirl 062 (2000).cbz │ │ │ │ ├── Batgirl 063 (2000).cbz │ │ │ │ ├── Batgirl 064 (2000).cbz │ │ │ │ ├── Batgirl 065 (2000).cbz │ │ │ │ ├── Batgirl 066 (2000).cbz │ │ │ │ ├── Batgirl 067 (2000).cbz │ │ │ │ ├── Batgirl 068 (2000).cbz │ │ │ │ ├── Batgirl 069 (2000).cbz │ │ │ │ ├── Batgirl 070 (2000).cbz │ │ │ │ ├── Batgirl 071 (2000).cbz │ │ │ │ ├── Batgirl 072 (2000).cbz │ │ │ │ ├── Batgirl 073 (2000).cbz │ │ │ │ ├── Batman 001 (1940).cbz │ │ │ │ ├── Batman 002 (1940).cbz │ │ │ │ ├── Batman 003 (1940).cbz │ │ │ │ ├── Batman 004 (1940).cbz │ │ │ │ ├── Batman 005 (1940).cbz │ │ │ │ ├── Batman 006 (1940).cbz │ │ │ │ ├── Batman 007 (1940).cbz │ │ │ │ ├── Batman 008 (1940).cbz │ │ │ │ ├── Batman 009 (1940).cbz │ │ │ │ ├── Batman 010 (1940).cbz │ │ │ │ ├── Batman 011 (1940).cbz │ │ │ │ ├── Batman 012 (1940).cbz │ │ │ │ ├── Batman 013 (1940).cbz │ │ │ │ ├── Batman 014 (1940).cbz │ │ │ │ ├── Batman 015 (1940).cbz │ │ │ │ ├── Batman 016 (1940).cbz │ │ │ │ ├── Batman 017 (1940).cbz │ │ │ │ ├── Batman 018 (1940).cbz │ │ │ │ ├── Batman 019 (1940).cbz │ │ │ │ ├── Batman 020 (1940).cbz │ │ │ │ ├── Batman 021 (1940).cbz │ │ │ │ ├── Batman 022 (1940).cbz │ │ │ │ ├── Batman 023 (1940).cbz │ │ │ │ ├── Batman 024 (1940).cbz │ │ │ │ ├── Batman 025 (1940).cbz │ │ │ │ ├── Batman 026 (1940).cbz │ │ │ │ ├── Batman 027 (1940).cbz │ │ │ │ ├── Batman 028 (1940).cbz │ │ │ │ ├── Batman 029 (1940).cbz │ │ │ │ ├── Batman 030 (1940).cbz │ │ │ │ ├── Batman 031 (1940).cbz │ │ │ │ ├── Batman 032 (1940).cbz │ │ │ │ ├── Batman 033 (1940).cbz │ │ │ │ ├── Batman 034 (1940).cbz │ │ │ │ ├── Batman 035 (1940).cbz │ │ │ │ ├── Batman 036 (1940).cbz │ │ │ │ ├── Batman 037 (1940).cbz │ │ │ │ ├── Batman 038 (1940).cbz │ │ │ │ ├── Batman 039 (1940).cbz │ │ │ │ ├── Batman 040 (1940).cbz │ │ │ │ ├── Batman 041 (1940).cbz │ │ │ │ ├── Batman 042 (1940).cbz │ │ │ │ ├── Batman 043 (1940).cbz │ │ │ │ ├── Batman 044 (1940).cbz │ │ │ │ ├── Batman 045 (1940).cbz │ │ │ │ ├── Batman 046 (1940).cbz │ │ │ │ ├── Batman 047 (1940).cbz │ │ │ │ ├── Batman 048 (1940).cbz │ │ │ │ ├── Batman 049 (1940).cbz │ │ │ │ ├── Batman 050 (1940).cbz │ │ │ │ ├── Batman 051 (1940).cbz │ │ │ │ ├── Batman 052 (1940).cbz │ │ │ │ ├── Batman 053 (1940).cbz │ │ │ │ ├── Batman 054 (1940).cbz │ │ │ │ ├── Batman 055 (1940).cbz │ │ │ │ ├── Batman 056 (1940).cbz │ │ │ │ ├── Batman 057 (1940).cbz │ │ │ │ ├── Batman 058 (1940).cbz │ │ │ │ ├── Batman 059 (1940).cbz │ │ │ │ ├── Batman 060 (1940).cbz │ │ │ │ ├── Batman 061 (1940).cbz │ │ │ │ ├── Batman 062 (1940).cbz │ │ │ │ ├── Batman 063 (1940).cbz │ │ │ │ ├── Batman 064 (1940).cbz │ │ │ │ ├── Batman 065 (1940).cbz │ │ │ │ ├── Batman 066 (1940).cbz │ │ │ │ ├── Batman 067 (1940).cbz │ │ │ │ ├── Batman 068 (1940).cbz │ │ │ │ ├── Batman 069 (1940).cbz │ │ │ │ ├── Batman 070 (1940).cbz │ │ │ │ ├── Batman 071 (1940).cbz │ │ │ │ ├── Batman 072 (1940).cbz │ │ │ │ ├── Batman 073 (1940).cbz │ │ │ │ ├── Batman 074 (1940).cbz │ │ │ │ ├── Batman 075 (1940).cbz │ │ │ │ ├── Batman 076 (1940).cbz │ │ │ │ ├── Batman 077 (1940).cbz │ │ │ │ ├── Batman 078 (1940).cbz │ │ │ │ ├── Batman 079 (1940).cbz │ │ │ │ ├── Batman 080 (1940).cbz │ │ │ │ ├── Batman 081 (1940).cbz │ │ │ │ ├── Batman 082 (1940).cbz │ │ │ │ ├── Batman 083 (1940).cbz │ │ │ │ ├── Batman 084 (1940).cbz │ │ │ │ ├── Batman 085 (1940).cbz │ │ │ │ ├── Batman 086 (1940).cbz │ │ │ │ ├── Batman 087 (1940).cbz │ │ │ │ ├── Batman 088 (1940).cbz │ │ │ │ ├── Batman 089 (1940).cbz │ │ │ │ ├── Batman 090 (1940).cbz │ │ │ │ ├── Batman 091 (1940).cbz │ │ │ │ ├── Batman 092 (1940).cbz │ │ │ │ ├── Batman 093 (1940).cbz │ │ │ │ ├── Batman 094 (1940).cbz │ │ │ │ ├── Batman 095 (1940).cbz │ │ │ │ ├── Batman 096 (1940).cbz │ │ │ │ ├── Batman 097 (1940).cbz │ │ │ │ ├── Batman 098 (1940).cbz │ │ │ │ ├── Batman 099 (1940).cbz │ │ │ │ ├── Batman 100 (1940).cbz │ │ │ │ ├── The Tenth 01 (1997).cbz │ │ │ │ ├── The Tenth 02 (1997).cbz │ │ │ │ ├── The Tenth 03 (1997).cbz │ │ │ │ ├── The Tenth 04 (1997).cbz │ │ │ │ ├── The Tenth 05 (1997).cbz │ │ │ │ ├── The Tenth 06 (1997).cbz │ │ │ │ ├── The Tenth 07 (1997).cbz │ │ │ │ ├── The Tenth 08 (1997).cbz │ │ │ │ ├── The Tenth 09 (1997).cbz │ │ │ │ ├── The Tenth 10 (1997).cbz │ │ │ │ ├── The Tenth 11 (1997).cbz │ │ │ │ ├── The Tenth 12 (1997).cbz │ │ │ │ ├── The Tenth 13 (1997).cbz │ │ │ │ ├── The Tenth 14 (1997).cbz │ │ │ │ ├── Rising Stars 00 (1999).cbz │ │ │ │ ├── Rising Stars 01 (1999).cbz │ │ │ │ ├── Rising Stars 02 (1999).cbz │ │ │ │ ├── Rising Stars 03 (1999).cbz │ │ │ │ ├── Rising Stars 04 (1999).cbz │ │ │ │ ├── Rising Stars 05 (1999).cbz │ │ │ │ ├── Rising Stars 06 (1999).cbz │ │ │ │ ├── Rising Stars 07 (1999).cbz │ │ │ │ ├── Rising Stars 08 (1999).cbz │ │ │ │ ├── Rising Stars 09 (1999).cbz │ │ │ │ ├── Rising Stars 10 (1999).cbz │ │ │ │ ├── Rising Stars 11 (1999).cbz │ │ │ │ ├── Rising Stars 12 (1999).cbz │ │ │ │ ├── Rising Stars 13 (1999).cbz │ │ │ │ ├── Rising Stars 14 (1999).cbz │ │ │ │ ├── Rising Stars 15 (1999).cbz │ │ │ │ ├── Rising Stars 16 (1999).cbz │ │ │ │ ├── Rising Stars 17 (1999).cbz │ │ │ │ ├── Rising Stars 18 (1999).cbz │ │ │ │ ├── Rising Stars 19 (1999).cbz │ │ │ │ ├── Rising Stars 20 (1999).cbz │ │ │ │ ├── Rising Stars 21 (1999).cbz │ │ │ │ ├── Rising Stars 22 (1999).cbz │ │ │ │ ├── Rising Stars 23 (1999).cbz │ │ │ │ ├── Rising Stars 24 (1999).cbz │ │ │ │ ├── The Tenth - Resurrected 001 (2001).cbz │ │ │ │ ├── The Tenth - Resurrected 002 (2001).cbz │ │ │ │ ├── The Tenth - Resurrected 003 (2001).cbz │ │ │ │ └── The Tenth - Resurrected 004 (2001).cbz │ │ │ ├── simple │ │ │ │ └── Batman 402 (1940).cbz │ │ │ ├── not_flat │ │ │ │ └── Batman 402 (1940).cbz │ │ │ ├── special_cases │ │ │ │ ├── no_images │ │ │ │ │ └── Batman 402 (1940).cbz │ │ │ │ ├── invalid_xml │ │ │ │ │ └── Batman 402 (1940).cbz │ │ │ │ ├── invalid_month │ │ │ │ │ └── Batman 402 (1940).cbz │ │ │ │ ├── invalid_number │ │ │ │ │ └── Batman 402 (1940).cbz │ │ │ │ ├── corrupt_archive │ │ │ │ │ └── Batman 402 (1940).cbz │ │ │ │ ├── containing_directory │ │ │ │ │ └── Batman 402 (1940).cbz │ │ │ │ ├── containing_invalid_file │ │ │ │ │ └── Batman 402 (1940).cbz │ │ │ │ └── not_flat_with_duplicate │ │ │ │ │ └── Batman 402 (1940).cbz │ │ │ └── incomplete │ │ │ │ └── DC Comics │ │ │ │ └── Batman (1940) │ │ │ │ └── Batman 701 (1940).cbz │ │ ├── jwt-valid.txt │ │ └── jwt-invalid-claim.txt │ └── java │ │ └── de │ │ └── wasenweg │ │ └── alfred │ │ ├── EnableEmbeddedMongo.java │ │ ├── fixtures │ │ ├── SecurityFixtures.java │ │ ├── VolumeFixtures.java │ │ ├── LoginFixtures.java │ │ └── ProgressFixtures.java │ │ ├── unit │ │ ├── TestHelper.java │ │ ├── JwtServiceTest.java │ │ ├── IndexControllerTest.java │ │ └── ComicConstructionTest.java │ │ └── integration │ │ └── IntegrationTestHelper.java └── main │ ├── java │ └── de │ │ └── wasenweg │ │ └── alfred │ │ ├── security │ │ ├── IJwtService.java │ │ ├── DevJwtFilter.java │ │ ├── GoogleIdTokenVerifierBuilder.java │ │ ├── JwtCreator.java │ │ ├── DevSecurityConfig.java │ │ └── MockJwtService.java │ │ ├── scanner │ │ ├── NoImagesException.java │ │ ├── NoMetaDataException.java │ │ ├── InvalidFileException.java │ │ ├── ScanProgressRepository.java │ │ ├── InvalidIssueNumberException.java │ │ ├── ScannerIssue.java │ │ ├── ScanProgress.java │ │ └── ScannerController.java │ │ ├── thumbnails │ │ ├── NoThumbnailsException.java │ │ ├── ThumbnailRepository.java │ │ ├── Thumbnail.java │ │ └── ThumbnailController.java │ │ ├── user │ │ ├── Login.java │ │ └── User.java │ │ ├── series │ │ ├── Series.java │ │ └── SeriesService.java │ │ ├── IndexController.java │ │ ├── publishers │ │ ├── Publisher.java │ │ └── PublishersService.java │ │ ├── stats │ │ ├── Stats.java │ │ └── StatsController.java │ │ ├── settings │ │ ├── SettingRepository.java │ │ └── Setting.java │ │ ├── progress │ │ ├── ProgressRepository.java │ │ ├── Progress.java │ │ └── ProgressController.java │ │ ├── volumes │ │ ├── VolumesService.java │ │ └── Volume.java │ │ ├── AlfredApplication.java │ │ └── comics │ │ ├── ComicRepository.java │ │ ├── ComicQueryRepository.java │ │ └── ComicSearchService.java │ └── resources │ ├── application-prod.yml │ ├── application.yml │ ├── application-test.yml │ └── logback.xml ├── .travis.yml ├── .Dockerfile.local ├── docker-compose.yml ├── .docker-compose.test.yml ├── .gitignore ├── Dockerfile ├── .Dockerfile.test └── config └── pmd └── pmd-main.xml /ui/src/app/library/edit/edit.page.sass: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/app/settings/settings.page.sass: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/app/library/series/series.page.sass: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/app/settings/queue/queue.page.sass: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/app/library/publishers/publishers.page.sass: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/app/settings/scanner/scanner.component.sass: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/resources/icon.png.md5: -------------------------------------------------------------------------------- 1 | 3d28a70303024ab562ce5da04e514129 -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | /sample* 2 | /ui/node_modules 3 | /ui/.gradle 4 | -------------------------------------------------------------------------------- /lombok.config: -------------------------------------------------------------------------------- 1 | lombok.addLombokGeneratedAnnotation = true 2 | -------------------------------------------------------------------------------- /ui/resources/splash.png.md5: -------------------------------------------------------------------------------- 1 | 282fc5575646def9e5dffc28ef1e4256 -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'alfred' 2 | include 'ui' 3 | -------------------------------------------------------------------------------- /ui/src/app/library/issues/issue-actions/issue-actions.component.sass: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/app/bookmarks/bookmark-actions/bookmark-actions.component.sass: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/src/app/library/volumes/volume-actions/volume-actions.component.sass: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/icon.png -------------------------------------------------------------------------------- /ui/resources/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/splash.png -------------------------------------------------------------------------------- /ui/src/assets/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/src/assets/icons/favicon.ico -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ui/proxy.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "/api": { 3 | "target": "http://localhost:8080", 4 | "secure": false 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ui/src/assets/icons/alfred-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/src/assets/icons/alfred-72x72.png -------------------------------------------------------------------------------- /ui/src/assets/icons/alfred-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/src/assets/icons/alfred-96x96.png -------------------------------------------------------------------------------- /ui/src/assets/icons/alfred-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/src/assets/icons/alfred-128x128.png -------------------------------------------------------------------------------- /ui/src/assets/icons/alfred-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/src/assets/icons/alfred-144x144.png -------------------------------------------------------------------------------- /ui/src/assets/icons/alfred-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/src/assets/icons/alfred-152x152.png -------------------------------------------------------------------------------- /ui/src/assets/icons/alfred-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/src/assets/icons/alfred-192x192.png -------------------------------------------------------------------------------- /ui/src/assets/icons/alfred-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/src/assets/icons/alfred-384x384.png -------------------------------------------------------------------------------- /ui/src/assets/icons/alfred-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/src/assets/icons/alfred-512x512.png -------------------------------------------------------------------------------- /ui/src/assets/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/src/assets/icons/favicon-16x16.png -------------------------------------------------------------------------------- /ui/src/assets/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/src/assets/icons/favicon-32x32.png -------------------------------------------------------------------------------- /ui/src/app/series.ts: -------------------------------------------------------------------------------- 1 | export interface Series { 2 | name: string; 3 | publisher: string; 4 | volumesCount: number; 5 | } 6 | -------------------------------------------------------------------------------- /ui/ionic.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Alfred", 3 | "integrations": { 4 | "cordova": {} 5 | }, 6 | "type": "angular" 7 | } 8 | -------------------------------------------------------------------------------- /ui/src/assets/icons/alfred-512x512-splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/src/assets/icons/alfred-512x512-splash.png -------------------------------------------------------------------------------- /ui/resources/android/icon/drawable-hdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/icon/drawable-hdpi-icon.png -------------------------------------------------------------------------------- /ui/resources/android/icon/drawable-ldpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/icon/drawable-ldpi-icon.png -------------------------------------------------------------------------------- /ui/resources/android/icon/drawable-mdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/icon/drawable-mdpi-icon.png -------------------------------------------------------------------------------- /ui/resources/android/icon/drawable-xhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/icon/drawable-xhdpi-icon.png -------------------------------------------------------------------------------- /ui/resources/android/icon/drawable-xxhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/icon/drawable-xxhdpi-icon.png -------------------------------------------------------------------------------- /ui/resources/android/icon/drawable-xxxhdpi-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/icon/drawable-xxxhdpi-icon.png -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 000 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 000 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 001 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 001 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 001 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 001 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 001 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 001 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 001 (2016).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 001 (2016).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 002 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 002 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 002 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 002 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 002 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 002 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 002 (2016).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 002 (2016).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 003 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 003 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 003 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 003 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 003 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 003 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 003 (2016).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 003 (2016).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 004 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 004 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 004 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 004 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 004 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 004 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 004 (2016).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 004 (2016).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 005 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 005 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 005 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 005 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 005 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 005 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 005 (2016).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 005 (2016).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 006 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 006 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 006 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 006 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 006 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 006 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 006 (2016).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 006 (2016).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 007 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 007 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 007 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 007 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 007 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 007 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 008 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 008 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 008 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 008 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 008 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 008 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 009 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 009 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 009 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 009 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 009 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 009 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 01 (2008).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 01 (2008).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 010 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 010 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 010 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 010 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 010 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 010 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 011 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 011 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 011 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 011 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 011 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 011 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 012 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 012 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 012 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 012 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 012 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 012 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 013 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 013 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 013 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 013 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 013 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 013 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 014 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 014 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 014 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 014 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 014 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 014 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 015 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 015 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 015 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 015 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 015 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 015 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 016 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 016 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 016 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 016 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 016 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 016 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 017 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 017 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 017 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 017 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 017 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 017 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 018 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 018 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 018 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 018 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 018 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 018 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 019 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 019 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 019 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 019 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 019 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 019 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 02 (2008).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 02 (2008).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 020 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 020 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 020 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 020 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 020 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 020 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 021 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 021 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 021 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 021 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 021 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 021 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 022 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 022 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 022 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 022 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 022 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 022 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 023 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 023 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 023 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 023 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 023 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 023 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 024 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 024 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 024 (2009).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 024 (2009).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 024 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 024 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 025 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 025 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 025 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 025 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 026 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 026 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 026 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 026 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 027 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 027 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 027 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 027 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 028 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 028 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 028 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 028 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 029 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 029 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 029 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 029 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 03 (2008).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 03 (2008).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 030 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 030 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 030 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 030 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 031 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 031 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 031 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 031 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 032 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 032 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 032 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 032 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 033 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 033 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 033 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 033 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 034 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 034 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 034 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 034 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 035 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 035 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 035 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 035 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 036 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 036 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 036 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 036 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 037 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 037 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 037 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 037 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 038 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 038 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 038 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 038 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 039 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 039 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 039 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 039 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 04 (2008).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 04 (2008).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 040 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 040 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 040 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 040 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 041 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 041 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 041 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 041 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 042 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 042 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 042 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 042 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 043 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 043 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 043 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 043 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 044 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 044 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 044 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 044 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 045 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 045 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 045 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 045 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 046 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 046 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 046 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 046 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 047 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 047 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 047 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 047 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 048 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 048 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 048 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 048 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 049 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 049 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 049 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 049 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 05 (2008).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 05 (2008).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 050 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 050 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 050 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 050 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 051 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 051 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 051 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 051 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 052 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 052 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 052 (2011).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 052 (2011).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 053 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 053 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 054 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 054 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 055 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 055 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 056 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 056 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 057 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 057 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 058 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 058 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 059 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 059 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 06 (2008).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 06 (2008).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 060 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 060 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 061 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 061 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 062 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 062 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 063 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 063 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 064 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 064 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 065 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 065 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 066 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 066 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 067 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 067 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 068 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 068 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 069 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 069 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 070 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 070 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 071 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 071 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 072 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 072 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batgirl 073 (2000).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batgirl 073 (2000).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 001 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 001 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 002 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 002 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 003 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 003 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 004 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 004 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 005 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 005 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 006 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 006 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 007 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 007 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 008 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 008 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 009 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 009 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 010 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 010 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 011 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 011 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 012 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 012 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 013 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 013 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 014 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 014 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 015 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 015 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 016 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 016 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 017 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 017 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 018 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 018 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 019 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 019 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 020 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 020 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 021 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 021 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 022 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 022 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 023 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 023 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 024 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 024 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 025 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 025 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 026 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 026 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 027 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 027 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 028 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 028 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 029 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 029 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 030 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 030 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 031 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 031 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 032 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 032 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 033 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 033 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 034 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 034 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 035 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 035 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 036 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 036 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 037 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 037 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 038 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 038 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 039 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 039 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 040 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 040 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 041 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 041 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 042 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 042 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 043 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 043 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 044 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 044 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 045 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 045 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 046 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 046 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 047 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 047 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 048 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 048 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 049 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 049 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 050 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 050 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 051 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 051 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 052 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 052 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 053 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 053 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 054 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 054 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 055 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 055 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 056 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 056 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 057 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 057 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 058 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 058 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 059 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 059 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 060 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 060 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 061 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 061 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 062 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 062 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 063 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 063 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 064 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 064 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 065 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 065 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 066 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 066 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 067 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 067 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 068 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 068 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 069 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 069 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 070 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 070 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 071 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 071 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 072 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 072 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 073 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 073 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 074 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 074 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 075 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 075 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 076 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 076 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 077 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 077 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 078 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 078 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 079 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 079 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 080 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 080 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 081 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 081 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 082 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 082 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 083 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 083 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 084 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 084 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 085 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 085 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 086 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 086 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 087 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 087 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 088 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 088 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 089 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 089 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 090 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 090 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 091 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 091 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 092 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 092 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 093 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 093 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 094 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 094 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 095 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 095 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 096 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 096 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 097 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 097 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 098 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 098 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 099 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 099 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Batman 100 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Batman 100 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 01 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 01 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 02 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 02 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 03 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 03 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 04 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 04 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 05 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 05 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 06 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 06 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 07 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 07 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 08 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 08 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 09 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 09 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 10 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 10 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 11 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 11 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 12 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 12 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 13 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 13 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth 14 (1997).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth 14 (1997).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/simple/Batman 402 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/simple/Batman 402 (1940).cbz -------------------------------------------------------------------------------- /ui/src/app/setting.ts: -------------------------------------------------------------------------------- 1 | export interface Setting { 2 | id: string; 3 | key: string; 4 | name: string; 5 | value: string; 6 | comment: string; 7 | } 8 | -------------------------------------------------------------------------------- /src/test/resources/fixtures/not_flat/Batman 402 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/not_flat/Batman 402 (1940).cbz -------------------------------------------------------------------------------- /ui/resources/android/splash/drawable-land-hdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/splash/drawable-land-hdpi-screen.png -------------------------------------------------------------------------------- /ui/resources/android/splash/drawable-land-ldpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/splash/drawable-land-ldpi-screen.png -------------------------------------------------------------------------------- /ui/resources/android/splash/drawable-land-mdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/splash/drawable-land-mdpi-screen.png -------------------------------------------------------------------------------- /ui/resources/android/splash/drawable-land-xhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/splash/drawable-land-xhdpi-screen.png -------------------------------------------------------------------------------- /ui/resources/android/splash/drawable-port-hdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/splash/drawable-port-hdpi-screen.png -------------------------------------------------------------------------------- /ui/resources/android/splash/drawable-port-ldpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/splash/drawable-port-ldpi-screen.png -------------------------------------------------------------------------------- /ui/resources/android/splash/drawable-port-mdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/splash/drawable-port-mdpi-screen.png -------------------------------------------------------------------------------- /ui/resources/android/splash/drawable-port-xhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/splash/drawable-port-xhdpi-screen.png -------------------------------------------------------------------------------- /ui/src/testing/mock.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | template: '' 5 | }) 6 | export class MockComponent { 7 | } 8 | -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 00 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 00 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 01 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 01 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 02 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 02 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 03 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 03 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 04 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 04 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 05 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 05 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 06 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 06 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 07 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 07 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 08 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 08 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 09 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 09 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 10 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 10 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 11 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 11 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 12 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 12 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 13 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 13 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 14 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 14 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 15 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 15 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 16 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 16 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 17 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 17 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 18 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 18 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 19 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 19 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 20 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 20 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 21 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 21 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 22 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 22 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 23 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 23 (1999).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/Rising Stars 24 (1999).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/Rising Stars 24 (1999).cbz -------------------------------------------------------------------------------- /ui/resources/android/splash/drawable-land-xxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/splash/drawable-land-xxhdpi-screen.png -------------------------------------------------------------------------------- /ui/resources/android/splash/drawable-land-xxxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/splash/drawable-land-xxxhdpi-screen.png -------------------------------------------------------------------------------- /ui/resources/android/splash/drawable-port-xxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/splash/drawable-port-xxhdpi-screen.png -------------------------------------------------------------------------------- /ui/resources/android/splash/drawable-port-xxxhdpi-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/ui/resources/android/splash/drawable-port-xxxhdpi-screen.png -------------------------------------------------------------------------------- /ui/src/app/caches.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | 3 | export const CACHES_TOKEN = new InjectionToken('Window caches object'); 4 | -------------------------------------------------------------------------------- /ui/src/app/location.token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | 3 | export const LOCATION_TOKEN = new InjectionToken('Window location object'); 4 | -------------------------------------------------------------------------------- /ui/src/app/publisher.ts: -------------------------------------------------------------------------------- 1 | import { Series } from './series'; 2 | 3 | export interface Publisher { 4 | name: string; 5 | seriesCount: number; 6 | series: Series[]; 7 | } 8 | -------------------------------------------------------------------------------- /ui/src/app/user.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | id: string; 3 | email: string; 4 | error: string | null; 5 | name: string; 6 | picture: string; 7 | token: string; 8 | } 9 | -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth - Resurrected 001 (2001).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth - Resurrected 001 (2001).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth - Resurrected 002 (2001).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth - Resurrected 002 (2001).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth - Resurrected 003 (2001).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth - Resurrected 003 (2001).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/full/The Tenth - Resurrected 004 (2001).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/full/The Tenth - Resurrected 004 (2001).cbz -------------------------------------------------------------------------------- /ui/src/app/app.component.sass: -------------------------------------------------------------------------------- 1 | \:host 2 | 3 | ion-menu.menu-pane-visible 4 | max-width: 277px !important 5 | 6 | img.avatar 7 | height: 24px 8 | width: 24px 9 | 10 | -------------------------------------------------------------------------------- /ui/src/zone-flags.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Prevents Angular change detection from 3 | * running with certain Web Component callbacks 4 | */ 5 | (window as any).__Zone_disable_customElements = true; 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | services: 2 | - docker 3 | jobs: 4 | include: 5 | - stage: Tests 6 | script: 7 | - docker-compose -f .docker-compose.test.yml up --abort-on-container-exit 8 | 9 | -------------------------------------------------------------------------------- /src/test/resources/fixtures/special_cases/no_images/Batman 402 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/special_cases/no_images/Batman 402 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/special_cases/invalid_xml/Batman 402 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/special_cases/invalid_xml/Batman 402 (1940).cbz -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/security/IJwtService.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.security; 2 | 3 | public interface IJwtService { 4 | 5 | Boolean verifyToken(String token, String secret); 6 | } 7 | -------------------------------------------------------------------------------- /src/test/resources/fixtures/special_cases/invalid_month/Batman 402 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/special_cases/invalid_month/Batman 402 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/special_cases/invalid_number/Batman 402 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/special_cases/invalid_number/Batman 402 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/special_cases/corrupt_archive/Batman 402 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/special_cases/corrupt_archive/Batman 402 (1940).cbz -------------------------------------------------------------------------------- /ui/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | import packageJson from '../../package.json'; 2 | const version = packageJson.version; 3 | 4 | export const environment = { 5 | production: true, 6 | version 7 | }; 8 | -------------------------------------------------------------------------------- /src/main/resources/application-prod.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | config: 3 | activate: 4 | on-profile: prod 5 | data: 6 | mongodb: 7 | database: alfred 8 | uri: mongodb://mongo/alfred 9 | 10 | -------------------------------------------------------------------------------- /src/test/resources/fixtures/incomplete/DC Comics/Batman (1940)/Batman 701 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/incomplete/DC Comics/Batman (1940)/Batman 701 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/special_cases/containing_directory/Batman 402 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/special_cases/containing_directory/Batman 402 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/special_cases/containing_invalid_file/Batman 402 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/special_cases/containing_invalid_file/Batman 402 (1940).cbz -------------------------------------------------------------------------------- /src/test/resources/fixtures/special_cases/not_flat_with_duplicate/Batman 402 (1940).cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaethorn/alfred/HEAD/src/test/resources/fixtures/special_cases/not_flat_with_duplicate/Batman 402 (1940).cbz -------------------------------------------------------------------------------- /ui/src/app/volume.ts: -------------------------------------------------------------------------------- 1 | export interface Volume { 2 | name: string; 3 | series: string; 4 | publisher: string; 5 | issueCount: number; 6 | readCount: number; 7 | read: boolean; 8 | firstComicId: string; 9 | } 10 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | data: 3 | rest: 4 | base-path: /api 5 | mongodb: 6 | database: alfred 7 | uri: mongodb://mongo/alfred 8 | mongodb: 9 | embedded: 10 | version: 4.2.22 11 | -------------------------------------------------------------------------------- /ui/src/app/stats.ts: -------------------------------------------------------------------------------- 1 | export interface Stats { 2 | lastScanFinished: Date | null; 3 | lastScanStarted: Date | null; 4 | issues: number; 5 | publishers: number; 6 | series: number; 7 | volumes: number; 8 | users: number; 9 | } 10 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /ui/e2e/protractor.headless.conf.js: -------------------------------------------------------------------------------- 1 | const config = require('./protractor.conf').config; 2 | 3 | config.capabilities.chromeOptions = { 4 | args: [ '--headless', '--window-size=3840,2160', '--no-sandbox', '--disable-setuid-sandbox' ] 5 | }; 6 | 7 | exports.config = config; 8 | -------------------------------------------------------------------------------- /src/test/resources/jwt-valid.txt: -------------------------------------------------------------------------------- 1 | eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaXNzIjoiYWxmcmVkLmN4IiwiQVBJX0FMTE9XRUQiOnRydWUsImp0aSI6ImNjOTFiYjQ2LTI2YjktNDg1Yy1hMzljLWJjNGUxZDliYTdhZSIsImlhdCI6MTU4MjcxMDUxMSwiZXhwIjoyMzgyNzM1MTQzfQ.z6wPEbpcmzVHE4bAXpModoVSQfTat1YsfGbeMklaGW0 -------------------------------------------------------------------------------- /.Dockerfile.local: -------------------------------------------------------------------------------- 1 | FROM openjdk:17-jdk 2 | VOLUME /tmp 3 | EXPOSE 8080 4 | ARG DEPENDENCY=target/dependency 5 | COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib 6 | COPY ${DEPENDENCY}/META-INF /app/META-INF 7 | COPY ${DEPENDENCY}/BOOT-INF/classes /app 8 | ENTRYPOINT ["java","-cp","app:app/lib/*","de.wasenweg.alfred.AlfredApplication"] 9 | -------------------------------------------------------------------------------- /src/test/resources/jwt-invalid-claim.txt: -------------------------------------------------------------------------------- 1 | eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaXNzIjoiYWxmcmVkLmN4IiwiQVBJX05PVF9BTExPV0VEIjp0cnVlLCJqdGkiOiJjYzkxYmI0Ni0yNmI5LTQ4NWMtYTM5Yy1iYzRlMWQ5YmE3YWUiLCJpYXQiOjE1ODI3MTA1MTEsImV4cCI6MjM4MjczNTIzNH0.AdneDKvMLmi8Az9uh7Hrvgt8Aha8oK951-Qsm_KoitY -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/scanner/NoImagesException.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.scanner; 2 | 3 | public class NoImagesException extends Exception { 4 | 5 | private static final long serialVersionUID = 7335176735056733527L; 6 | 7 | public NoImagesException() { 8 | super("No images found."); 9 | } 10 | } -------------------------------------------------------------------------------- /ui/src/app/thumbnail.ts: -------------------------------------------------------------------------------- 1 | import { SafeUrl } from '@angular/platform-browser'; 2 | 3 | export enum ThumbnailType { 4 | FRONT_COVER, 5 | BACK_COVER 6 | } 7 | 8 | export interface Thumbnail { 9 | id: string; 10 | comicId: string; 11 | type: ThumbnailType; 12 | image: string; 13 | path: string; 14 | url?: SafeUrl; 15 | } 16 | -------------------------------------------------------------------------------- /ui/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../out-tsc/e2e", 6 | "module": "commonjs", 7 | "target": "es2018", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ui/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app" 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | alfred: 4 | build: . 5 | ports: 6 | - "8080:8080" 7 | volumes: 8 | - $PWD/src/test/resources/fixtures/full:/comics 9 | environment: 10 | SPRING_PROFILES_ACTIVE: test 11 | SPRING_DATA_MONGODB_URI: mongodb://mongo/alfred 12 | mongo: 13 | image: "mongo:4.2" 14 | -------------------------------------------------------------------------------- /ui/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'com.github.node-gradle.node' version '2.2.3' 4 | } 5 | 6 | node { 7 | download = false 8 | npmInstallCommand = 'ci' 9 | } 10 | 11 | npmInstall { 12 | args = ['--loglevel', 'error'] 13 | } 14 | 15 | jar.dependsOn 'npm_run_buildProd' 16 | 17 | jar { 18 | from 'dist/alfred' into 'static' 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/scanner/NoMetaDataException.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.scanner; 2 | 3 | public class NoMetaDataException extends Exception { 4 | 5 | private static final long serialVersionUID = 8750400589574572222L; 6 | 7 | public NoMetaDataException(final Throwable err) { 8 | super("No meta data file 'ComicInfo.xml' found.", err); 9 | } 10 | } -------------------------------------------------------------------------------- /ui/src/testing/user.fixtures.ts: -------------------------------------------------------------------------------- 1 | import { User } from '../app/user'; 2 | 3 | export class UserFixtures { 4 | 5 | public static get user(): User { 6 | const user: User = {} as User; 7 | user.id = 'foo@bar.com'; 8 | user.email = 'foo@bar.com'; 9 | user.name = 'Foo Bar'; 10 | user.picture = 'https://bar.com/foo.png'; 11 | 12 | return user; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/scanner/InvalidFileException.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.scanner; 2 | 3 | public class InvalidFileException extends Exception { 4 | 5 | private static final long serialVersionUID = -1310341819120533363L; 6 | 7 | public InvalidFileException(final Throwable err) { 8 | super("At least one file in the archive was unreadable.", err); 9 | } 10 | } -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/thumbnails/NoThumbnailsException.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.thumbnails; 2 | 3 | public class NoThumbnailsException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 137629900102L; 6 | 7 | public NoThumbnailsException(final Throwable err) { 8 | super("No thumbnails could be extracted.", err); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/user/Login.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.user; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @NoArgsConstructor 10 | @AllArgsConstructor 11 | @Builder 12 | public class Login { 13 | 14 | private String username; 15 | private String password; 16 | } 17 | -------------------------------------------------------------------------------- /ui/src/app/library/volumes/covers/covers.page.sass: -------------------------------------------------------------------------------- 1 | \:host 2 | 3 | ion-card-content 4 | display: flex 5 | flex-direction: row 6 | 7 | .thumbnail 8 | margin: 1em 9 | display: flex 10 | flex-direction: column 11 | justify-content: space-between 12 | 13 | img 14 | margin: 1em auto 15 | width: 400px 16 | border: 3px gray solid 17 | -------------------------------------------------------------------------------- /ui/src/testing/stats.http.mocks.ts: -------------------------------------------------------------------------------- 1 | export class StatsHttpMocks { 2 | 3 | public static get stats(): Object { 4 | return { 5 | _links: { 6 | self: { 7 | href: 'http://localhost:4200/api/stats' 8 | } 9 | }, 10 | issues: 305, 11 | publishers: 3, 12 | series: 5, 13 | users: 1, 14 | volumes: 9 15 | }; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | config: 3 | activate: 4 | on-profile: test 5 | data: 6 | mongodb: 7 | uri: mongodb://localhost/alfred 8 | 9 | management: 10 | endpoints: 11 | web: 12 | exposure: 13 | include: '*' 14 | 15 | comics: 16 | path: src/test/resources/fixtures/full 17 | comicVine: 18 | baseUrl: http://localhost:1080/ 19 | -------------------------------------------------------------------------------- /ui/src/app/secure/secure.module.ts: -------------------------------------------------------------------------------- 1 | import { HttpClientModule } from '@angular/common/http'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { SecurePipe } from './secure.pipe'; 5 | 6 | @NgModule({ 7 | declarations: [ 8 | SecurePipe 9 | ], 10 | exports: [ 11 | SecurePipe 12 | ], 13 | imports: [ 14 | HttpClientModule 15 | ] 16 | }) 17 | export class SecureModule {} 18 | -------------------------------------------------------------------------------- /ui/src/app/bookmarks/bookmark-actions/bookmark-actions.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | View in volume 5 | 6 | 7 | 8 | View in library 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/series/Series.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.series; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | public class Series { 11 | 12 | private String id; 13 | 14 | private String name; 15 | private String publisher; 16 | private Integer volumesCount; 17 | } 18 | -------------------------------------------------------------------------------- /ui/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /ui/src/app/login/login.page.sass: -------------------------------------------------------------------------------- 1 | \:host 2 | ion-button, ion-item 3 | margin: 1em auto 4 | max-width: 26em 5 | 6 | .message 7 | font-size: 0.9em 8 | font-style: italic 9 | width: 100% 10 | text-align: center 11 | 12 | div 13 | display: flex 14 | color: var(--ion-color-dark) 15 | 16 | svg 17 | fill: currentColor 18 | width: 50% 19 | max-height: 30vh 20 | margin: 4em auto 21 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/scanner/ScanProgressRepository.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.scanner; 2 | 3 | import org.springframework.data.mongodb.repository.MongoRepository; 4 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 5 | 6 | @RepositoryRestResource(collectionResourceRel = "scan_progress", path = "scan_progress") 7 | public interface ScanProgressRepository extends MongoRepository { 8 | } 9 | -------------------------------------------------------------------------------- /ui/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | # 5 | # For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed 6 | 7 | > 0.5% 8 | last 2 versions 9 | Firefox ESR 10 | not dead 11 | not IE 9-11 12 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/scanner/InvalidIssueNumberException.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.scanner; 2 | 3 | public class InvalidIssueNumberException extends Exception { 4 | 5 | private static final long serialVersionUID = -1026247018579804966L; 6 | 7 | public InvalidIssueNumberException(final String number, final Exception exception) { 8 | super("Couldn't read number '" + number + "'. Falling back to '0'.", exception); 9 | } 10 | } -------------------------------------------------------------------------------- /ui/src/testing/setting.fixtures.ts: -------------------------------------------------------------------------------- 1 | import { Setting } from '../app/setting'; 2 | 3 | export class SettingFixtures { 4 | 5 | public static get setting(): Setting { 6 | const setting: Setting = {} as Setting; 7 | setting.id = '9'; 8 | setting.key = 'comics.path'; 9 | setting.name = 'Path'; 10 | setting.value = '/all/comics'; 11 | setting.comment = 'Path to your comic library'; 12 | 13 | return setting; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ui/resources/README.md: -------------------------------------------------------------------------------- 1 | These are Cordova resources. You can replace icon.png and splash.png and run 2 | `ionic cordova resources` to generate custom icons and splash screens for your 3 | app. See `ionic cordova resources --help` for details. 4 | 5 | Cordova reference documentation: 6 | 7 | - Icons: https://cordova.apache.org/docs/en/latest/config_ref/images.html 8 | - Splash Screens: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-splashscreen/ 9 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/user/User.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.user; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @NoArgsConstructor 10 | @AllArgsConstructor 11 | @Builder 12 | public class User { 13 | 14 | private String id; 15 | private String email; 16 | private String name; 17 | private String picture; 18 | private String token; 19 | } 20 | -------------------------------------------------------------------------------- /ui/src/testing/queue.service.mocks.ts: -------------------------------------------------------------------------------- 1 | import { of } from 'rxjs'; 2 | 3 | import { QueueService } from '../app/queue.service'; 4 | 5 | import { ComicFixtures } from './comic.fixtures'; 6 | 7 | export class QueueServiceMocks { 8 | 9 | public static get queueService(): jasmine.SpyObj { 10 | return jasmine.createSpyObj('QueueService', { 11 | add: Promise.resolve(), 12 | process: of(ComicFixtures.comic) 13 | }); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/IndexController.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred; 2 | 3 | import org.springframework.boot.web.servlet.error.ErrorController; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | 7 | @Controller 8 | public class IndexController implements ErrorController { 9 | 10 | @RequestMapping("/error") 11 | public String error() { 12 | return "forward:/index.html"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ui/src/testing/stats.service.mocks.ts: -------------------------------------------------------------------------------- 1 | import { of } from 'rxjs'; 2 | 3 | import { StatsService } from '../app/stats.service'; 4 | 5 | export class StatsServiceMocks { 6 | 7 | public static get statsService(): jasmine.SpyObj { 8 | return jasmine.createSpyObj('StatsService', { 9 | get: of({ 10 | issues: 218, 11 | publishers: 4, 12 | series: 18, 13 | users: 2, 14 | volumes: 29 15 | }) 16 | }); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/de/wasenweg/alfred/EnableEmbeddedMongo.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred; 2 | 3 | import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration; 4 | import org.springframework.context.annotation.Import; 5 | 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Import(EmbeddedMongoAutoConfiguration.class) 11 | public @interface EnableEmbeddedMongo { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/de/wasenweg/alfred/fixtures/SecurityFixtures.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.fixtures; 2 | 3 | import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload; 4 | 5 | public final class SecurityFixtures { 6 | 7 | private SecurityFixtures() { 8 | } 9 | 10 | public static Payload getMockPayload() { 11 | final Payload payload = new Payload(); 12 | payload.set("name", "Foo Bar"); 13 | payload.setEmail("foo@bar.com"); 14 | return payload; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ui/src/app/library/volumes/volumes.page.sass: -------------------------------------------------------------------------------- 1 | \:host 2 | 3 | .volume 4 | height: fit-content 5 | max-width: 400px 6 | 7 | a.thumbnail 8 | cursor: pointer 9 | display: inline-block 10 | position: relative 11 | 12 | ion-badge 13 | font-size: x-large 14 | position: absolute 15 | 16 | &.read-badge 17 | right: 0.1em 18 | top: -0.4em 19 | 20 | &.synced-badge 21 | left: 0.1em 22 | top: -0.4em 23 | 24 | -------------------------------------------------------------------------------- /ui/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "strictNullChecks": false, 7 | "types": [ 8 | "gapi", 9 | "gapi.auth2", 10 | "jasmine" 11 | ] 12 | }, 13 | "files": [ 14 | "src/test.ts", 15 | "src/polyfills.ts" 16 | ], 17 | "include": [ 18 | "src/**/*.spec.ts", 19 | "src/**/*.d.ts" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/publishers/Publisher.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.publishers; 2 | 3 | import de.wasenweg.alfred.series.Series; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.util.List; 9 | 10 | @Data 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class Publisher { 14 | 15 | private String id; 16 | 17 | private String name; 18 | private List series; 19 | private Integer seriesCount; 20 | } 21 | -------------------------------------------------------------------------------- /ui/src/testing/thumbnail.fixtures.ts: -------------------------------------------------------------------------------- 1 | import { Thumbnail } from '../app/thumbnail'; 2 | 3 | export class ThumbnailFixtures { 4 | 5 | public static get thumbnail(): Thumbnail { 6 | const thumbnail: Thumbnail = {} as Thumbnail; 7 | thumbnail.id = '142'; 8 | thumbnail.comicId = '923'; 9 | thumbnail.image = 'abcedf1234'; 10 | thumbnail.path = '/1.png'; 11 | thumbnail.url = { 12 | changingThisBreaksApplicationSecurity: 'data:image/jpeg;base64,9312321' 13 | }; 14 | 15 | return thumbnail; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ui/src/testing/thumbnails.service.mocks.ts: -------------------------------------------------------------------------------- 1 | import { of } from 'rxjs'; 2 | 3 | import { ThumbnailsService } from '../app/thumbnails.service'; 4 | 5 | import { ThumbnailFixtures } from './thumbnail.fixtures'; 6 | 7 | export class ThumbnailsServiceMocks { 8 | 9 | public static get thumbnailsService(): jasmine.SpyObj { 10 | return jasmine.createSpyObj('ThumbnailsService', { 11 | getBackCover: of(ThumbnailFixtures.thumbnail), 12 | getFrontCover: of(ThumbnailFixtures.thumbnail) 13 | }); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ui/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element, promise } from 'protractor'; 2 | 3 | export class AppPage { 4 | 5 | public static navigateTo(): promise.Promise { 6 | return browser.get('/'); 7 | } 8 | 9 | public static getPublishersText(): promise.Promise { 10 | return element(by.css('app-publishers')).getText(); 11 | } 12 | 13 | public static clickMenuItem(item: string): promise.Promise { 14 | return element(by.cssContainingText('ion-tabs ion-tab-button ion-label', item)).click(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ui/src/testing/settings.service.mocks.ts: -------------------------------------------------------------------------------- 1 | import { of } from 'rxjs'; 2 | 3 | import { SettingsService } from '../app/settings.service'; 4 | 5 | import { SettingFixtures } from './setting.fixtures'; 6 | 7 | export class SettingsServiceMocks { 8 | 9 | public static get settingsService(): jasmine.SpyObj { 10 | return jasmine.createSpyObj('SettingsService', { 11 | get: of(SettingFixtures.setting), 12 | list: of([ SettingFixtures.setting ]), 13 | update: of(SettingFixtures.setting) 14 | }); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.docker-compose.test.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | 4 | app: 5 | build: 6 | context: . 7 | dockerfile: .Dockerfile.test 8 | shm_size: '2gb' 9 | ports: 10 | - '8080:8080' 11 | volumes: 12 | - $PWD/src/test/resources/fixtures/full:/comics 13 | - /dev/shm:/dev/shm 14 | environment: 15 | DOCKER_MODE: 'true' 16 | SPRING_PROFILES_ACTIVE: test 17 | SPRING_DATA_MONGODB_URI: mongodb://mongo/alfred 18 | 19 | mongo: 20 | image: 'mongo:4.2' 21 | logging: 22 | driver: none 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /build/ 3 | /target/ 4 | /logs 5 | /run-*.sh 6 | /bin/ 7 | !gradle/wrapper/gradle-wrapper.jar 8 | /sample* 9 | /.gradletasknamecache 10 | /.vscode 11 | /GH_TOKEN 12 | 13 | ### STS ### 14 | .apt_generated 15 | .classpath 16 | .factorypath 17 | .project 18 | .settings 19 | .springBeans 20 | .sts4-cache 21 | /.attach_pid* 22 | /.checkstyle 23 | 24 | ### IntelliJ IDEA ### 25 | .idea 26 | *.iws 27 | *.iml 28 | *.ipr 29 | /out/ 30 | 31 | ### NetBeans ### 32 | /nbproject/private/ 33 | /nbbuild/ 34 | /dist/ 35 | /nbdist/ 36 | /.nb-gradle/ 37 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/stats/Stats.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.stats; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.util.Date; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class Stats { 15 | 16 | private long issues; 17 | private int publishers; 18 | private int series; 19 | private int volumes; 20 | private Date lastScanFinished; 21 | private Date lastScanStarted; 22 | 23 | private long users; 24 | } 25 | -------------------------------------------------------------------------------- /ui/src/testing/user.service.mocks.ts: -------------------------------------------------------------------------------- 1 | import { BehaviorSubject, of } from 'rxjs'; 2 | 3 | import { UserService } from '../app/user.service'; 4 | 5 | import { UserFixtures } from './user.fixtures'; 6 | 7 | export class UserServiceMocks { 8 | 9 | public static get userService(): jasmine.SpyObj { 10 | const userService = jasmine.createSpyObj('UserService', { 11 | login: null, 12 | logout: of(null), 13 | setupGoogleSignIn: null 14 | }); 15 | userService.user = new BehaviorSubject(UserFixtures.user); 16 | return userService; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/publishers/PublishersService.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.publishers; 2 | 3 | import de.wasenweg.alfred.comics.ComicQueryRepositoryImpl; 4 | import lombok.RequiredArgsConstructor; 5 | import org.springframework.stereotype.Service; 6 | 7 | import java.util.List; 8 | 9 | @Service 10 | @RequiredArgsConstructor 11 | public class PublishersService { 12 | 13 | private final ComicQueryRepositoryImpl repository; 14 | 15 | public List findAllPublishers(final String userId) { 16 | return this.repository.findAllPublishers(userId); 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/settings/SettingRepository.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.settings; 2 | 3 | import org.springframework.data.mongodb.repository.MongoRepository; 4 | import org.springframework.data.repository.query.Param; 5 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 6 | 7 | import java.util.Optional; 8 | 9 | @RepositoryRestResource(collectionResourceRel = "settings", path = "settings") 10 | public interface SettingRepository extends MongoRepository { 11 | Optional findByKey(@Param("key") String key); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/series/SeriesService.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.series; 2 | 3 | import de.wasenweg.alfred.comics.ComicQueryRepositoryImpl; 4 | import lombok.RequiredArgsConstructor; 5 | import org.springframework.stereotype.Service; 6 | 7 | import java.util.List; 8 | 9 | @Service 10 | @RequiredArgsConstructor 11 | public class SeriesService { 12 | 13 | private final ComicQueryRepositoryImpl repository; 14 | 15 | public List findAllSeriesByPublisher(final String userId, final String publisher) { 16 | return this.repository.findAllSeries(userId, publisher); 17 | } 18 | } -------------------------------------------------------------------------------- /ui/src/app/library/volumes/volume-actions/volume-actions.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Mark volume as read 5 | 6 | 7 | 8 | Mark volume as not read 9 | 10 | 11 | 12 | View front- and back covers. 13 | 14 | 15 | -------------------------------------------------------------------------------- /ui/src/styles.sass: -------------------------------------------------------------------------------- 1 | @import './theme/variables' 2 | 3 | // http://ionicframework.com/docs/theming/ 4 | @import '~@ionic/angular/css/core.css' 5 | @import '~@ionic/angular/css/normalize.css' 6 | @import '~@ionic/angular/css/structure.css' 7 | @import '~@ionic/angular/css/typography.css' 8 | @import '~@ionic/angular/css/display.css' 9 | @import '~@ionic/angular/css/padding.css' 10 | @import '~@ionic/angular/css/float-elements.css' 11 | @import '~@ionic/angular/css/text-alignment.css' 12 | @import '~@ionic/angular/css/text-transformation.css' 13 | @import '~@ionic/angular/css/flex-utils.css' 14 | 15 | @import './theme/dark' -------------------------------------------------------------------------------- /ui/src/testing/swupdate.mocks.ts: -------------------------------------------------------------------------------- 1 | import { SwUpdate } from '@angular/service-worker'; 2 | import { of } from 'rxjs'; 3 | 4 | export class SwUpdateMocks { 5 | 6 | public static get swUpdate(): jasmine.SpyObj { 7 | const updates = jasmine.createSpyObj('SwUpdate', { 8 | activateUpdate: Promise.resolve(), 9 | checkForUpdate: Promise.resolve() 10 | }); 11 | updates.available = of({ available: { hash: '2' }, current: { hash: '1' } }); 12 | updates.activated = of({ current: { hash: '4' }, previous: { hash: '3' } }); 13 | updates.isEnabled = false; 14 | 15 | return updates; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/de/wasenweg/alfred/fixtures/VolumeFixtures.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.fixtures; 2 | 3 | import de.wasenweg.alfred.volumes.Volume; 4 | 5 | public final class VolumeFixtures { 6 | 7 | public static final Volume VOLUME_1 = Volume.builder() 8 | .name(ComicFixtures.COMIC_V1_1.getVolume()) 9 | .series(ComicFixtures.COMIC_V1_1.getSeries()) 10 | .publisher(ComicFixtures.COMIC_V1_1.getPublisher()) 11 | .issueCount(3) 12 | .read(false) 13 | .readCount(0) 14 | .firstComicId(ComicFixtures.COMIC_V1_1.getId()) 15 | .build(); 16 | 17 | private VolumeFixtures() { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/progress/ProgressRepository.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.progress; 2 | 3 | import org.bson.types.ObjectId; 4 | import org.springframework.data.mongodb.repository.MongoRepository; 5 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 6 | 7 | import java.util.Optional; 8 | 9 | @RepositoryRestResource(collectionResourceRel = "progress", path = "progress") 10 | public interface ProgressRepository extends MongoRepository { 11 | 12 | Optional findByUserIdAndComicId(String userId, ObjectId comicId); 13 | 14 | void deleteByUserId(String userId); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/volumes/VolumesService.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.volumes; 2 | 3 | import de.wasenweg.alfred.comics.ComicQueryRepositoryImpl; 4 | import lombok.RequiredArgsConstructor; 5 | import org.springframework.stereotype.Service; 6 | 7 | import java.util.List; 8 | 9 | @Service 10 | @RequiredArgsConstructor 11 | public class VolumesService { 12 | 13 | private final ComicQueryRepositoryImpl repository; 14 | 15 | public List findAllVolumesByPublisherAndSeries(final String userId, final String publisher, final String series) { 16 | return this.repository.findAllVolumes(userId, publisher, series); 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/AlfredApplication.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration; 6 | import org.springframework.cache.annotation.EnableCaching; 7 | 8 | @EnableCaching 9 | @SpringBootApplication(exclude = EmbeddedMongoAutoConfiguration.class) 10 | public class AlfredApplication { // NOPMD 11 | 12 | public static void main(final String[] args) { 13 | SpringApplication.run(AlfredApplication.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ui/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Bookmarks 7 | 8 | 9 | 10 | Library 11 | 12 | 13 | 14 | Settings 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ui/src/app/auth.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; 2 | import { Injectable } from '@angular/core'; 3 | import { Observable } from 'rxjs'; 4 | 5 | @Injectable() 6 | export class AuthInterceptor implements HttpInterceptor { 7 | 8 | public intercept(req: HttpRequest, next: HttpHandler): Observable> { 9 | const token = localStorage.getItem('token'); 10 | 11 | if (!token) { 12 | return next.handle(req); 13 | } 14 | 15 | return next.handle(req.clone({ 16 | headers: req.headers.set('Authorization', `Bearer ${ token }`) 17 | })); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/thumbnails/ThumbnailRepository.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.thumbnails; 2 | 3 | import de.wasenweg.alfred.thumbnails.Thumbnail.ThumbnailType; 4 | import org.bson.types.ObjectId; 5 | import org.springframework.data.mongodb.repository.MongoRepository; 6 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 7 | 8 | import java.util.Optional; 9 | 10 | @RepositoryRestResource(collectionResourceRel = "thumbnail", path = "thumbnail") 11 | public interface ThumbnailRepository extends MongoRepository { 12 | 13 | Optional findByComicIdAndType(ObjectId comicId, ThumbnailType type); 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/de/wasenweg/alfred/fixtures/LoginFixtures.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.fixtures; 2 | 3 | import de.wasenweg.alfred.user.Login; 4 | 5 | public final class LoginFixtures { 6 | 7 | public static final Login LOGIN_1 = Login.builder() 8 | .username("foo@bar.com") 9 | .password("foo") 10 | .build(); 11 | 12 | public static final Login LOGIN_MISMATCH = Login.builder() 13 | .username("foo@bar.com") 14 | .password("bar") 15 | .build(); 16 | 17 | public static final Login LOGIN_NONEXISTENT = Login.builder() 18 | .username("new@user.com") 19 | .password("oh") 20 | .build(); 21 | 22 | private LoginFixtures() { 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ui/src/app/login/login.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 4 | import { Routes, RouterModule } from '@angular/router'; 5 | import { IonicModule } from '@ionic/angular'; 6 | 7 | import { LoginPage } from './login.page'; 8 | 9 | const routes: Routes = [{ 10 | component: LoginPage, path: '' 11 | }]; 12 | 13 | @NgModule({ 14 | declarations: [ LoginPage ], 15 | imports: [ 16 | CommonModule, 17 | FormsModule, 18 | ReactiveFormsModule, 19 | IonicModule, 20 | RouterModule.forChild(routes) 21 | ] 22 | }) 23 | export class LoginPageModule {} 24 | -------------------------------------------------------------------------------- /ui/src/testing/series.fixtures.ts: -------------------------------------------------------------------------------- 1 | import { Series } from '../app/series'; 2 | 3 | export class SeriesFixtures { 4 | 5 | public static get serie(): Series { 6 | return { 7 | name: 'Batgirl', 8 | publisher: 'DC Comics', 9 | volumesCount: 7 10 | }; 11 | } 12 | 13 | public static get series(): Series[] { 14 | return [ 15 | this.serie, 16 | Object.assign(this.serie, { name: 'Batman', volumesCount: 1 }), 17 | Object.assign(this.serie, { name: 'Superman', volumesCount: 3 }), 18 | Object.assign(this.serie, { name: 'Green Lantern', volumesCount: 2 }), 19 | Object.assign(this.serie, { name: 'Arrow', volumesCount: 4 }) 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ui/.gitignore: -------------------------------------------------------------------------------- 1 | /.angular/cache 2 | # Specifies intentionally untracked files to ignore when using Git 3 | # http://git-scm.com/docs/gitignore 4 | 5 | /local.properties 6 | /gradle/ 7 | /gradlew 8 | /gradlew.bat 9 | *~ 10 | *.sw[mnpcod] 11 | *.log 12 | *.tmp 13 | *.tmp.* 14 | log.txt 15 | *.sublime-project 16 | *.sublime-workspace 17 | .vscode/ 18 | npm-debug.log* 19 | 20 | .idea/ 21 | .ionic/ 22 | .sourcemaps/ 23 | .sass-cache/ 24 | .tmp/ 25 | .versions/ 26 | coverage/ 27 | www/ 28 | node_modules/ 29 | tmp/ 30 | temp/ 31 | platforms/ 32 | plugins/ 33 | plugins/android.json 34 | plugins/ios.json 35 | $RECYCLE.BIN/ 36 | build/ 37 | dist/ 38 | 39 | .DS_Store 40 | Thumbs.db 41 | UserInterfaceState.xcuserstate 42 | -------------------------------------------------------------------------------- /ui/src/app/reader/reader.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { RouterModule } from '@angular/router'; 5 | import { IonicModule } from '@ionic/angular'; 6 | 7 | import { SecureModule } from '../secure/secure.module'; 8 | 9 | import { ReaderPage } from './reader.page'; 10 | 11 | @NgModule({ 12 | declarations: [ 13 | ReaderPage 14 | ], 15 | imports: [ 16 | CommonModule, 17 | FormsModule, 18 | IonicModule, 19 | RouterModule.forChild([{ 20 | component: ReaderPage, path: '' 21 | }]), 22 | SecureModule 23 | ] 24 | }) 25 | export class ReaderPageModule {} 26 | -------------------------------------------------------------------------------- /ui/src/app/library/issues/issue-actions/issue-actions.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Download 5 | 6 | 7 | 8 | Mark read until here 9 | 10 | 11 | 12 | View in library 13 | 14 | 15 | 16 | Edit 17 | 18 | 19 | -------------------------------------------------------------------------------- /ui/src/testing/toast.controller.mocks.ts: -------------------------------------------------------------------------------- 1 | import { ToastController } from '@ionic/angular'; 2 | 3 | export class ToastControllerMocks { 4 | 5 | private static toastElement: jasmine.SpyObj; 6 | 7 | public static get toastElementSpy(): jasmine.SpyObj { 8 | if (!this.toastElement) { 9 | this.toastElement = jasmine.createSpyObj('HTMLIonToastElement', [ 'present' ]); 10 | } 11 | return this.toastElement; 12 | } 13 | 14 | public static get toastController(): jasmine.SpyObj { 15 | this.toastElement = null as any; 16 | return jasmine.createSpyObj('ToastController', { 17 | create: Promise.resolve(this.toastElementSpy) 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ui/src/testing/volume.fixtures.ts: -------------------------------------------------------------------------------- 1 | import { Volume } from '../app/volume'; 2 | 3 | export class VolumeFixtures { 4 | 5 | public static get volume(): Volume { 6 | const volume: Volume = {} as Volume; 7 | volume.name = '1999'; 8 | volume.series = 'Batgirl'; 9 | volume.publisher = 'DC Comics'; 10 | volume.read = false; 11 | volume.issueCount = 10; 12 | volume.readCount = 0; 13 | volume.firstComicId = '1234'; 14 | 15 | return volume; 16 | } 17 | 18 | public static get volumes(): Volume[] { 19 | return [ 20 | this.volume, 21 | Object.assign(this.volume, { name: '2003' }), 22 | Object.assign(this.volume, { name: '2008' }), 23 | Object.assign(this.volume, { name: '2009' }) 24 | ]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/settings/Setting.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.settings; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.NonNull; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.data.annotation.Id; 10 | import org.springframework.data.mongodb.core.mapping.Document; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @RequiredArgsConstructor 17 | @Document 18 | public class Setting { 19 | 20 | @Id 21 | private String id; 22 | 23 | @NonNull 24 | private String key; 25 | @NonNull 26 | private String name; 27 | @NonNull 28 | private String value; 29 | @NonNull 30 | private String comment; 31 | } 32 | -------------------------------------------------------------------------------- /ui/src/app/bookmarks/bookmarks.page.sass: -------------------------------------------------------------------------------- 1 | \:host 2 | 3 | @keyframes spin 4 | 100% 5 | transform: rotate(-360deg) 6 | transform: rotate(-360deg) 7 | 8 | ion-icon[name="sync"].syncing 9 | animation: spin 2s linear infinite 10 | 11 | .comic-tile 12 | height: fit-content 13 | max-width: 400px 14 | float: left 15 | 16 | .progress 17 | position: absolute 18 | z-index: 2 19 | height: 5px 20 | margin-top: -5px 21 | background-color: rgba(var(--ion-color-secondary-rgb), 0.7) 22 | 23 | a.thumbnail 24 | cursor: pointer 25 | display: inline-block 26 | position: relative 27 | 28 | ion-badge 29 | font-size: x-large 30 | position: absolute 31 | 32 | &.synced-badge 33 | left: 0.1em 34 | top: -0.4em 35 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/volumes/Volume.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.volumes; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import static java.lang.String.format; 9 | 10 | @Data 11 | @Builder 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class Volume { 15 | 16 | private String id; 17 | 18 | private String name; 19 | private String series; 20 | private String publisher; 21 | private Integer issueCount; 22 | private Integer readCount; 23 | private boolean read; 24 | private String firstComicId; 25 | 26 | @Override 27 | public String toString() { 28 | return format( 29 | "%s (Vol. %s) by %s", 30 | this.series, this.name, this.publisher); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/security/DevJwtFilter.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.security; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | 5 | import javax.servlet.Filter; 6 | import javax.servlet.FilterChain; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.ServletRequest; 9 | import javax.servlet.ServletResponse; 10 | 11 | import java.io.IOException; 12 | 13 | @RequiredArgsConstructor 14 | public class DevJwtFilter implements Filter { 15 | 16 | private final IJwtService jwtService; 17 | 18 | @Override 19 | public void doFilter( 20 | final ServletRequest req, 21 | final ServletResponse res, 22 | final FilterChain chain) throws IOException, ServletException { 23 | 24 | this.jwtService.verifyToken("", ""); 25 | chain.doFilter(req, res); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ui/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { browser } from 'protractor'; 2 | 3 | import { AppPage } from './app.po'; 4 | import { MongoDBTools } from './mongodb.tools'; 5 | import { Page } from './page.po'; 6 | 7 | describe('AppComponent', () => { 8 | 9 | beforeAll(async () => { 10 | await MongoDBTools.prepare(); 11 | }); 12 | 13 | it('displays the top level library view', async () => { 14 | await AppPage.navigateTo(); 15 | expect(await browser.getCurrentUrl()).toContain('library/publishers'); 16 | }); 17 | 18 | it('informs the user how to populate the library', async () => { 19 | await Page.waitForLoadingGone(); 20 | expect(await AppPage.getPublishersText()).toContain('No comics found'); 21 | expect(await AppPage.getPublishersText()).toContain('SCAN FOR COMICS'); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /ui/src/testing/alert.controller.mocks.ts: -------------------------------------------------------------------------------- 1 | import { AlertController } from '@ionic/angular'; 2 | 3 | export class AlertControllerMocks { 4 | 5 | private static alertElement: jasmine.SpyObj; 6 | 7 | public static get alertElementSpy(): jasmine.SpyObj { 8 | if (!this.alertElement) { 9 | this.alertElement = jasmine.createSpyObj('HTMLIonAlertElement', { 10 | dismiss: Promise.resolve(), 11 | present: Promise.resolve() 12 | }); 13 | } 14 | return this.alertElement; 15 | } 16 | 17 | public static get alertController(): jasmine.SpyObj { 18 | this.alertElement = null as any; 19 | return jasmine.createSpyObj('AlertController', { 20 | create: Promise.resolve(this.alertElementSpy) 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/security/GoogleIdTokenVerifierBuilder.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.security; 2 | 3 | import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; 4 | import com.google.api.client.http.apache.v2.ApacheHttpTransport; 5 | import com.google.api.client.json.jackson2.JacksonFactory; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | @Configuration 10 | public class GoogleIdTokenVerifierBuilder { 11 | 12 | @Bean 13 | public GoogleIdTokenVerifier.Builder getBuilder() { 14 | final ApacheHttpTransport transport = new ApacheHttpTransport(); 15 | final JacksonFactory jsonFactory = new JacksonFactory(); 16 | return new GoogleIdTokenVerifier.Builder(transport, jsonFactory); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/scanner/ScannerIssue.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.scanner; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.util.Date; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class ScannerIssue { 15 | 16 | public enum Severity { 17 | INFO, 18 | WARNING, 19 | ERROR 20 | } 21 | 22 | public enum Type { 23 | UNKNOWN, 24 | NOT_FLAT, 25 | NO_MONTH, 26 | NO_YEAR, 27 | NO_IMAGES, 28 | INVALID_FILE_FORMAT 29 | } 30 | 31 | private String message; 32 | private Severity severity; 33 | private Type type; 34 | 35 | private boolean fixable; 36 | 37 | @Builder.Default 38 | private Date date = new Date(); 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/stats/StatsController.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.stats; 2 | 3 | import de.wasenweg.alfred.util.BaseController; 4 | import lombok.RequiredArgsConstructor; 5 | import org.springframework.hateoas.EntityModel; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @RestController 11 | @RequestMapping(value = "/api/stats", produces = { "application/hal+json" }) 12 | @RequiredArgsConstructor 13 | public class StatsController extends BaseController { 14 | 15 | private final StatsService service; 16 | 17 | @GetMapping 18 | public EntityModel getStats() { 19 | return this.wrapRoot(this.service.getStats()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ui/src/testing/indexed-db.service.mocks.ts: -------------------------------------------------------------------------------- 1 | import { AsyncSubject } from 'rxjs'; 2 | 3 | import { IndexedDbService } from '../app/indexed-db.service'; 4 | 5 | export class IndexedDbServiceMocks { 6 | 7 | public static get indexedDbService(): jasmine.SpyObj { 8 | const service = jasmine.createSpyObj('IndexedDbService', { 9 | delete: Promise.resolve(new Event('')), 10 | get: Promise.resolve(), 11 | getAll: Promise.resolve([]), 12 | getAllBy: Promise.resolve([]), 13 | hasKey: Promise.resolve(true), 14 | open: null, 15 | save: Promise.resolve(new Event('')) 16 | }); 17 | service.ready = new AsyncSubject(); 18 | 19 | service.open.and.callFake(() => { 20 | service.ready.complete(); 21 | }); 22 | 23 | return service; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/de/wasenweg/alfred/unit/TestHelper.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.unit; 2 | 3 | import com.fasterxml.jackson.databind.JsonNode; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.nio.charset.StandardCharsets; 9 | import java.nio.file.Files; 10 | import java.nio.file.Paths; 11 | 12 | public final class TestHelper { 13 | 14 | private TestHelper() { 15 | } 16 | 17 | public static JsonNode parseJson(final String path) throws IOException { 18 | return new ObjectMapper().readTree(new File("src/test/resources/" + path)); 19 | } 20 | 21 | public static String readString(final String path) throws IOException { 22 | return Files.readString(Paths.get("src/test/resources/" + path), StandardCharsets.US_ASCII); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ui/src/testing/comic-storage.service.mocks.ts: -------------------------------------------------------------------------------- 1 | import { ComicStorageService } from '../app/comic-storage.service'; 2 | 3 | import { ComicFixtures } from './comic.fixtures'; 4 | 5 | export class ComicStorageServiceMocks { 6 | 7 | public static get comicStorageService(): jasmine.SpyObj { 8 | return jasmine.createSpyObj('ComicStorageService', { 9 | deleteVolume: Promise.resolve(), 10 | get: Promise.resolve(ComicFixtures.comic), 11 | getBookmarks: Promise.resolve(ComicFixtures.volume), 12 | getFrontCoverThumbnail: Promise.resolve(''), 13 | getPageUrl: Promise.resolve('/api/read/923/0'), 14 | saveIfStored: Promise.resolve(), 15 | saveProgress: Promise.resolve(), 16 | store: Promise.resolve({}), 17 | storeSurrounding: Promise.resolve({}) 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gradle:7.5.1-jdk17 as builder 2 | WORKDIR /workspace/app 3 | COPY settings.gradle build.gradle ./ 4 | RUN gradle dependencies > /dev/null 5 | COPY src src 6 | COPY ui ui 7 | COPY config config 8 | RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - 9 | RUN apt-get install -y --no-install-recommends nodejs 10 | RUN gradle build unpack -x test -x check 11 | WORKDIR /workspace/app/build/dependency 12 | RUN jar -xf ../libs/*.jar 13 | 14 | FROM openjdk:19-jdk-slim-bullseye 15 | VOLUME /tmp 16 | EXPOSE 8080 17 | ARG DEPENDENCY=/workspace/app/build/dependency 18 | COPY --from=builder ${DEPENDENCY}/BOOT-INF/lib /app/lib 19 | COPY --from=builder ${DEPENDENCY}/META-INF /app/META-INF 20 | COPY --from=builder ${DEPENDENCY}/BOOT-INF/classes /app 21 | ENTRYPOINT ["java","-cp","app:app/lib/*","de.wasenweg.alfred.AlfredApplication"] 22 | 23 | -------------------------------------------------------------------------------- /ui/src/testing/loading.controller.mocks.ts: -------------------------------------------------------------------------------- 1 | import { LoadingController } from '@ionic/angular'; 2 | 3 | export class LoadingControllerMocks { 4 | 5 | private static loadingElement: jasmine.SpyObj; 6 | 7 | public static get loadingElementSpy(): jasmine.SpyObj { 8 | if (!this.loadingElement) { 9 | this.loadingElement = jasmine.createSpyObj('HTMLIonLoadingElement', { 10 | dismiss: Promise.resolve(), 11 | present: Promise.resolve() 12 | }); 13 | } 14 | return this.loadingElement; 15 | } 16 | 17 | public static get loadingController(): jasmine.SpyObj { 18 | this.loadingElement = null as any; 19 | return jasmine.createSpyObj('LoadingController', { 20 | create: Promise.resolve(this.loadingElementSpy) 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ui/src/testing/volumes.service.mocks.ts: -------------------------------------------------------------------------------- 1 | import { of } from 'rxjs'; 2 | 3 | import { VolumesService } from '../app/volumes.service'; 4 | 5 | import { PublisherFixtures } from './publisher.fixtures'; 6 | import { SeriesFixtures } from './series.fixtures'; 7 | import { VolumeFixtures } from './volume.fixtures'; 8 | 9 | export class VolumesServiceMocks { 10 | 11 | public static get volumesService(): jasmine.SpyObj { 12 | return jasmine.createSpyObj('VolumesService', { 13 | listPublishers: of(PublisherFixtures.publishers), 14 | listSeries: of(SeriesFixtures.series), 15 | listVolumes: of(VolumeFixtures.volumes), 16 | listVolumesByPublisher: of([ VolumeFixtures.volume ]), 17 | markAllAsReadUntil: of(null), 18 | markAsRead: of(null), 19 | markAsUnread: of(null) 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/scanner/ScanProgress.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.scanner; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import org.springframework.data.annotation.Id; 8 | import org.springframework.data.mongodb.core.mapping.Document; 9 | 10 | import java.util.Date; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @Document 17 | public class ScanProgress { 18 | 19 | public enum Status { 20 | START, 21 | CURRENT_FILE, 22 | TOTAL, 23 | CLEAN_UP, 24 | ASSOCIATION, 25 | DONE, 26 | SCAN_ISSUE 27 | } 28 | 29 | @Id 30 | private String id; 31 | 32 | private Status status; 33 | 34 | private int count; 35 | 36 | private Date started; 37 | 38 | private Date finished; 39 | } 40 | -------------------------------------------------------------------------------- /ui/src/app/bookmarks/bookmarks.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { RouterModule } from '@angular/router'; 5 | import { IonicModule } from '@ionic/angular'; 6 | 7 | import { SecureModule } from '../secure/secure.module'; 8 | 9 | import { BookmarkActionsComponent } from './bookmark-actions/bookmark-actions.component'; 10 | import { BookmarksPage } from './bookmarks.page'; 11 | 12 | @NgModule({ 13 | declarations: [ 14 | BookmarksPage, 15 | BookmarkActionsComponent 16 | ], 17 | imports: [ 18 | CommonModule, 19 | FormsModule, 20 | IonicModule, 21 | RouterModule.forChild([{ 22 | component: BookmarksPage, path: '' 23 | }]), 24 | SecureModule 25 | ] 26 | }) 27 | export class BookmarksPageModule {} 28 | -------------------------------------------------------------------------------- /ui/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | import packageJson from '../../package.json'; 2 | const version = packageJson.version; 3 | 4 | // This file can be replaced during build by using the `fileReplacements` array. 5 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 6 | // The list of file replacements can be found in `angular.json`. 7 | 8 | export const environment = { 9 | production: false, 10 | version 11 | }; 12 | 13 | /* 14 | * For easier debugging in development mode, you can import the following file 15 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 16 | * 17 | * This import should be commented out in production mode because it will have a negative impact 18 | * on performance if an error is thrown. 19 | */ 20 | import 'zone.js/plugins/zone-error'; // Included with Angular CLI. 21 | -------------------------------------------------------------------------------- /ui/src/app/stats.service.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient } from '@angular/common/http'; 2 | import { Injectable } from '@angular/core'; 3 | import { Observable } from 'rxjs'; 4 | import { map } from 'rxjs/operators'; 5 | 6 | import { Stats } from './stats'; 7 | 8 | @Injectable({ 9 | providedIn: 'root' 10 | }) 11 | export class StatsService { 12 | 13 | constructor( 14 | private http: HttpClient 15 | ) { } 16 | 17 | public get(): Observable { 18 | return this.http.get('/api/stats').pipe( 19 | map((stats: any) => ({ 20 | issues: stats.issues, 21 | lastScanFinished: stats.lastScanFinished, 22 | lastScanStarted: stats.lastScanStarted, 23 | publishers: stats.publishers, 24 | series: stats.series, 25 | users: stats.users, 26 | volumes: stats.volumes 27 | })) 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ui/src/app/secure/secure.pipe.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient, HttpHeaders } from '@angular/common/http'; 2 | import { Pipe, PipeTransform } from '@angular/core'; 3 | import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; 4 | import { Observable } from 'rxjs'; 5 | import { map } from 'rxjs/operators'; 6 | 7 | @Pipe({ 8 | name: 'secure' 9 | }) 10 | export class SecurePipe implements PipeTransform { 11 | 12 | constructor( 13 | private http: HttpClient, 14 | private sanitizer: DomSanitizer 15 | ) { } 16 | 17 | public transform(url: string): Observable { 18 | const token = localStorage.getItem('token'); 19 | const headers = new HttpHeaders({ Authorization: `Bearer ${ token }` }); 20 | return this.http.get(url, { headers, responseType: 'blob' }).pipe( 21 | map(val => this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(val))) 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ui/e2e/src/settings.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { MongoDBTools } from './mongodb.tools'; 2 | import { Page } from './page.po'; 3 | import { SettingsPage } from './settings.po'; 4 | 5 | describe('SettingsPage', () => { 6 | 7 | beforeAll(async () => { 8 | await MongoDBTools.prepare(); 9 | }); 10 | 11 | it('has default settings', async () => { 12 | await SettingsPage.navigateTo(); 13 | const setting: string = await SettingsPage.getComicsPath(); 14 | expect(setting.length).toBeGreaterThan(0); 15 | }); 16 | 17 | it('sets settings', async () => { 18 | await SettingsPage.getComicsPathInput().clear(); 19 | await SettingsPage.getComicsPathInput().sendKeys('some-other-path'); 20 | await SettingsPage.getSaveButton().click(); 21 | }); 22 | 23 | it('confirms that settings are saved', async () => { 24 | expect(await Page.getToastMessage()).toEqual('Settings saved.'); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/comics/ComicRepository.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.comics; 2 | 3 | import org.springframework.data.mongodb.repository.MongoRepository; 4 | import org.springframework.data.repository.query.Param; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | public interface ComicRepository extends MongoRepository, ComicQueryRepository { 10 | 11 | Optional findByPath(@Param("path") String path); 12 | 13 | List findAllByOrderByPublisherAscSeriesAscVolumeAscPositionAsc(); 14 | 15 | List findAllBySeriesAndVolumeOrderByPosition( 16 | @Param("series") String series, 17 | @Param("volume") String volume); 18 | 19 | Optional findFirstByPublisherAndSeriesAndVolumeOrderByPosition( 20 | @Param("publisher") String publisher, 21 | @Param("series") String series, 22 | @Param("volume") String volume); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/scanner/ScannerController.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.scanner; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.http.codec.ServerSentEvent; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | import reactor.core.publisher.Flux; 9 | 10 | @RestController 11 | @RequestMapping("/api/scan") 12 | @RequiredArgsConstructor 13 | public class ScannerController { 14 | 15 | private final ScannerService scannerService; 16 | 17 | @GetMapping("/start") 18 | public Flux> startScanProgress() { 19 | return this.scannerService.scan(); 20 | } 21 | 22 | @GetMapping("/resume") 23 | public Flux> resumeScanProgress() { 24 | return this.scannerService.resume(); 25 | } 26 | } -------------------------------------------------------------------------------- /ui/src/testing/popover.controller.mocks.ts: -------------------------------------------------------------------------------- 1 | import { PopoverController } from '@ionic/angular'; 2 | 3 | export class PopoverControllerMocks { 4 | 5 | private static popoverElement: jasmine.SpyObj; 6 | 7 | public static get popoverElementSpy(): jasmine.SpyObj { 8 | if (!this.popoverElement) { 9 | this.popoverElement = jasmine.createSpyObj('HTMLIonPopoverElement', { 10 | onDidDismiss: Promise.resolve({}), 11 | onWillDismiss: Promise.resolve(), 12 | present: null 13 | }); 14 | } 15 | return this.popoverElement; 16 | } 17 | 18 | public static get popoverController(): jasmine.SpyObj { 19 | this.popoverElement = null as any; 20 | return jasmine.createSpyObj('PopoverController', { 21 | create: Promise.resolve(this.popoverElementSpy), 22 | dismiss: Promise.resolve(true) 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/progress/Progress.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.progress; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.NonNull; 8 | import lombok.RequiredArgsConstructor; 9 | import org.bson.types.ObjectId; 10 | import org.springframework.data.annotation.Id; 11 | import org.springframework.data.mongodb.core.mapping.Document; 12 | 13 | import java.util.Date; 14 | 15 | @Data 16 | @Builder 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | @RequiredArgsConstructor 20 | @Document 21 | public class Progress { 22 | 23 | @Id 24 | private String id; 25 | 26 | @NonNull 27 | private String userId; 28 | 29 | @NonNull 30 | private ObjectId comicId; 31 | 32 | private boolean read; 33 | 34 | @NonNull 35 | @Builder.Default 36 | private Integer currentPage = 0; 37 | 38 | private Date lastRead; 39 | } 40 | -------------------------------------------------------------------------------- /ui/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/testing'; 4 | import 'hammerjs'; 5 | import { getTestBed } from '@angular/core/testing'; 6 | import { 7 | BrowserDynamicTestingModule, 8 | platformBrowserDynamicTesting 9 | } from '@angular/platform-browser-dynamic/testing'; 10 | 11 | declare const require: { 12 | context(path: string, deep?: boolean, filter?: RegExp): { 13 | (id: string): T; 14 | keys(): string[]; 15 | }; 16 | }; 17 | 18 | // First, initialize the Angular testing environment. 19 | getTestBed().initTestEnvironment( 20 | BrowserDynamicTestingModule, 21 | platformBrowserDynamicTesting(), { 22 | teardown: { destroyAfterEach: false } 23 | } 24 | ); 25 | // Then we find all the tests. 26 | const context = require.context('./', true, /\.spec\.ts$/); 27 | // And load the modules. 28 | context.keys().map(context); 29 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/progress/ProgressController.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.progress; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.web.bind.annotation.DeleteMapping; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | import java.security.Principal; 9 | 10 | @RestController 11 | @RequestMapping(value = "/api/progress", produces = { "application/hal+json" }) 12 | @RequiredArgsConstructor 13 | public class ProgressController { 14 | 15 | private final ProgressService progressService; 16 | 17 | @DeleteMapping("") 18 | public void deleteProgress() { 19 | this.progressService.deleteProgress(); 20 | } 21 | 22 | @DeleteMapping("/me") 23 | public void deleteProgressForCurrentUser(final Principal principal) { 24 | this.progressService.deleteProgressForCurrentUser(principal.getName()); 25 | } 26 | } -------------------------------------------------------------------------------- /ui/src/app/auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; 3 | import { Observable, of } from 'rxjs'; 4 | import { catchError, map } from 'rxjs/operators'; 5 | 6 | import { UserService } from './user.service'; 7 | 8 | @Injectable({ 9 | providedIn: 'root' 10 | }) 11 | export class AuthGuard implements CanActivate { 12 | 13 | constructor( 14 | private userService: UserService, 15 | private router: Router 16 | ) { 17 | this.userService.verifyCurrentUser(); 18 | } 19 | 20 | public canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { 21 | return this.userService.user.pipe( 22 | catchError(() => { 23 | this.router.navigate([ '/login' ], { queryParams: { target: state.url } }); 24 | return of(false); 25 | }), 26 | map(user => !!user) 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/de/wasenweg/alfred/integration/IntegrationTestHelper.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.integration; 2 | 3 | import de.wasenweg.alfred.TestUtil; 4 | import de.wasenweg.alfred.settings.Setting; 5 | import de.wasenweg.alfred.settings.SettingRepository; 6 | import lombok.RequiredArgsConstructor; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.io.File; 11 | 12 | @Component 13 | @RequiredArgsConstructor(onConstructor_ = @Autowired) 14 | class IntegrationTestHelper { 15 | 16 | private final SettingRepository settingsRepository; 17 | 18 | public void setComicsPath(final String comicsPath, final File temp) { 19 | TestUtil.copyResources(temp, comicsPath); 20 | final Setting comicsPathSetting = this.settingsRepository.findByKey("comics.path").get(); 21 | comicsPathSetting.setValue(temp.getAbsolutePath()); 22 | this.settingsRepository.save(comicsPathSetting); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "noImplicitReturns": true, 10 | "noFallthroughCasesInSwitch": true, 11 | "allowSyntheticDefaultImports": true, 12 | "sourceMap": true, 13 | "declaration": false, 14 | "downlevelIteration": true, 15 | "experimentalDecorators": true, 16 | "moduleResolution": "node", 17 | "importHelpers": true, 18 | "resolveJsonModule": true, 19 | "target": "es2015", 20 | "module": "es2020", 21 | "lib": [ 22 | "es2020", 23 | "dom" 24 | ] 25 | }, 26 | "angularCompilerOptions": { 27 | "enableI18nLegacyMessageIdFormat": false, 28 | "strictInjectionParameters": true, 29 | "strictInputAccessModifiers": true, 30 | "strictTemplates": true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/thumbnails/Thumbnail.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.thumbnails; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import lombok.NonNull; 8 | import lombok.RequiredArgsConstructor; 9 | import org.bson.types.ObjectId; 10 | import org.springframework.data.annotation.Id; 11 | import org.springframework.data.mongodb.core.index.Indexed; 12 | import org.springframework.data.mongodb.core.mapping.Document; 13 | 14 | @Data 15 | @Builder 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | @RequiredArgsConstructor 19 | @Document 20 | public class Thumbnail { 21 | 22 | public enum ThumbnailType { 23 | FRONT_COVER, 24 | BACK_COVER 25 | } 26 | 27 | @Id 28 | private String id; 29 | 30 | @NonNull 31 | @Indexed 32 | private ObjectId comicId; 33 | 34 | @NonNull 35 | @Indexed 36 | private ThumbnailType type; 37 | 38 | private String path; 39 | 40 | private byte[] image; 41 | } 42 | -------------------------------------------------------------------------------- /ui/src/app/library/issues/issues.page.sass: -------------------------------------------------------------------------------- 1 | \:host 2 | 3 | .comic-summary 4 | margin: 1em 0 5 | height: 38em 6 | 7 | &.expanded 8 | height: inherit 9 | 10 | &:after 11 | width: 0 12 | 13 | &:after 14 | content: "" 15 | text-align: right 16 | position: absolute 17 | bottom: 0 18 | right: 0 19 | width: 100% 20 | height: 3.0em 21 | background: linear-gradient(to bottom, rgba(var(--ion-item-background-rgb), 0), rgba(var(--ion-item-background-rgb), 1) 50%) 22 | 23 | .thumbnail 24 | 25 | a 26 | position: relative 27 | width: fit-content 28 | display: block 29 | margin: 0 auto 30 | 31 | img 32 | margin: 1em auto 33 | border: 3px gray solid 34 | 35 | ion-badge 36 | font-size: x-large 37 | position: absolute 38 | 39 | &.read-badge 40 | right: 0.1em 41 | top: -0.4em 42 | 43 | &.synced-badge 44 | left: 0.1em 45 | top: -0.4em 46 | 47 | -------------------------------------------------------------------------------- /ui/src/testing/comic-database.service.mocks.ts: -------------------------------------------------------------------------------- 1 | import { of } from 'rxjs'; 2 | 3 | import { ComicDatabaseService } from '../app/comic-database.service'; 4 | 5 | import { ComicFixtures } from './comic.fixtures'; 6 | 7 | export class ComicDatabaseServiceMocks { 8 | 9 | public static get comicDatabaseService(): jasmine.SpyObj { 10 | const comicDatabaseService = jasmine.createSpyObj('ComicDatabaseService', { 11 | delete: Promise.resolve(), 12 | deleteAll: Promise.resolve(), 13 | getComic: Promise.resolve(ComicFixtures.comic), 14 | getComics: Promise.resolve([]), 15 | getComicsBy: Promise.resolve([]), 16 | getImageUrl: Promise.resolve('blob:http://localhost:4200/ed2dfdaa-b9b5-4e1a-b9af-28cbb34c4e4d'), 17 | isStored: Promise.resolve(true), 18 | ready: null, 19 | save: Promise.resolve(new Event('')), 20 | store: Promise.resolve() 21 | }); 22 | comicDatabaseService.ready = of({ }); 23 | 24 | return comicDatabaseService; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ui/e2e/src/mongodb.tools.ts: -------------------------------------------------------------------------------- 1 | import { connect, connection } from 'mongoose'; 2 | 3 | export class MongoDBTools { 4 | 5 | private static connect: Promise = new Promise((resolve, reject) => { 6 | const host = process.env.DOCKER_MODE === 'true' ? 'mongo' : 'localhost'; 7 | connect(`mongodb://${ host }/alfred`); 8 | connection.on('error', error => { 9 | reject(error); 10 | }); 11 | connection.once('open', () => { 12 | resolve(null); 13 | }); 14 | }); 15 | 16 | // Prepare DB and fixtures for E2E tests. 17 | public static async prepare(): Promise { 18 | const comicsPath = process.env.DOCKER_MODE === 'true' ? '/comics' : 'src/test/resources/fixtures/full'; 19 | await this.connect; 20 | await connection.db.dropDatabase(); 21 | const collection = await connection.db.createCollection('setting'); 22 | return collection.insertOne({ 23 | comment: 'Path to your comic library', 24 | key : 'comics.path', 25 | name : 'Path', 26 | value : comicsPath 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/security/JwtCreator.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.security; 2 | 3 | import com.auth0.jwt.JWT; 4 | import com.auth0.jwt.JWTCreator.Builder; 5 | import com.auth0.jwt.algorithms.Algorithm; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.Calendar; 9 | import java.util.Date; 10 | 11 | @Service 12 | public class JwtCreator { 13 | 14 | public String issueToken(final String[] claims, final String subject, final String jwtSecret) { 15 | 16 | final Algorithm algorithm = Algorithm.HMAC256(jwtSecret); 17 | 18 | final Calendar calendar = Calendar.getInstance(); 19 | calendar.setTime(new Date()); 20 | calendar.add(Calendar.MONTH, 1); 21 | final Date expiryDate = calendar.getTime(); 22 | 23 | final Builder tokenBuilder = JWT.create() 24 | .withIssuer("alfred.cx") 25 | .withSubject(subject) 26 | .withExpiresAt(expiryDate); 27 | 28 | for (final String claim : claims) { 29 | tokenBuilder.withClaim(claim, true); 30 | } 31 | 32 | return tokenBuilder.sign(algorithm); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/de/wasenweg/alfred/unit/JwtServiceTest.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.unit; 2 | 3 | import de.wasenweg.alfred.security.JwtService; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.extension.ExtendWith; 6 | import org.mockito.InjectMocks; 7 | import org.mockito.junit.jupiter.MockitoExtension; 8 | 9 | import static org.assertj.core.api.Assertions.assertThat; 10 | 11 | @ExtendWith(MockitoExtension.class) 12 | class JwtServiceTest { 13 | 14 | @InjectMocks 15 | private transient JwtService jwtService; 16 | 17 | @Test 18 | void verifyValidToken() throws Exception { 19 | assertThat(this.jwtService.verifyToken( 20 | TestHelper.readString("jwt-valid.txt"), 21 | "secret")).isTrue(); 22 | } 23 | 24 | @Test 25 | void verifyInvalidToken() throws Exception { 26 | assertThat(this.jwtService.verifyToken("invalid", "")).isFalse(); 27 | } 28 | 29 | @Test 30 | void verifyInvalidClaim() throws Exception { 31 | assertThat(this.jwtService.verifyToken( 32 | TestHelper.readString("jwt-invalid-claim.txt"), 33 | "secret")).isFalse(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ui/src/app/bookmarks/bookmark-actions/bookmark-actions.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | import { PopoverController, NavParams } from '@ionic/angular'; 4 | 5 | import { Comic } from '../../comic'; 6 | 7 | @Component({ 8 | selector: 'app-bookmark-actions', 9 | styleUrls: [ './bookmark-actions.component.sass' ], 10 | templateUrl: './bookmark-actions.component.html' 11 | }) 12 | export class BookmarkActionsComponent { 13 | 14 | public comic: Comic; 15 | 16 | constructor( 17 | private popoverCtrl: PopoverController, 18 | private router: Router, 19 | private navParams: NavParams 20 | ) { 21 | this.comic = this.navParams.get('comic'); 22 | } 23 | 24 | public goToVolume(comic: Comic): void { 25 | this.router.navigate([ '/library/publishers', comic.publisher, 'series', comic.series, 'volumes', comic.volume, 'issues' ]); 26 | this.popoverCtrl.dismiss(); 27 | } 28 | 29 | public goToLibrary(comic: Comic): void { 30 | this.router.navigate([ '/library/publishers', comic.publisher, 'series', comic.series, 'volumes' ]); 31 | this.popoverCtrl.dismiss(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/security/DevSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.security; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.context.annotation.Profile; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 8 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 9 | import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; 10 | 11 | @Configuration 12 | @EnableWebSecurity 13 | @RequiredArgsConstructor 14 | @Profile({"dev", "test"}) 15 | public class DevSecurityConfig extends WebSecurityConfigurerAdapter { 16 | 17 | private final IJwtService jwtService; 18 | 19 | @Override 20 | protected void configure(final HttpSecurity http) throws Exception { 21 | http 22 | .csrf().disable() 23 | .addFilterAfter(new DevJwtFilter(this.jwtService), BasicAuthenticationFilter.class) 24 | .authorizeRequests() 25 | .antMatchers("*").permitAll(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/comics/ComicQueryRepository.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.comics; 2 | 3 | import de.wasenweg.alfred.publishers.Publisher; 4 | import de.wasenweg.alfred.series.Series; 5 | import de.wasenweg.alfred.volumes.Volume; 6 | 7 | import java.util.List; 8 | import java.util.Optional; 9 | 10 | public interface ComicQueryRepository { 11 | 12 | Optional findById(String userId, String comicId); 13 | 14 | Optional findLastReadForVolume( 15 | String userId, 16 | String publisher, 17 | String series, 18 | String volume); 19 | 20 | List findAllLastReadPerVolume(String userId); 21 | 22 | List findAllByPublisherAndSeriesAndVolumeOrderByPosition( 23 | String userId, 24 | String publisher, 25 | String series, 26 | String volume); 27 | 28 | List findAllWithErrors(); 29 | 30 | List findAllWithoutErrors(String publisher, String series, String volume); 31 | 32 | List findAllPublishers(String userId); 33 | 34 | List findAllSeries(String userId, String publisher); 35 | 36 | List findAllVolumes(String userId, String publisher, String series); 37 | } 38 | -------------------------------------------------------------------------------- /ui/src/app/cache-storage.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Inject } from '@angular/core'; 2 | 3 | import { CACHES_TOKEN } from './caches.token'; 4 | 5 | @Injectable({ 6 | providedIn: 'root' 7 | }) 8 | export class CacheStorageService { 9 | 10 | constructor( 11 | @Inject(CACHES_TOKEN) private caches: CacheStorage 12 | ) { } 13 | 14 | /** 15 | * Remove the thumbnails for the given comic ID. 16 | * 17 | * Angular currently establishes the following Cache Storage entry responsible 18 | * for thumbnails from the API: 19 | * "ngsw:/:1:data:dynamic:thumbnails-api:cache" 20 | */ 21 | public async resetThumbnailsCache(comicId: string): Promise { 22 | const cacheNames = await this.caches.keys(); 23 | const thumbnailCaches = cacheNames.filter(cacheName => /:thumbnails-api:cache$/.test(cacheName)); 24 | for (const thumbailCache of thumbnailCaches) { 25 | const cache = await this.caches.open(thumbailCache); 26 | const requests = await cache.keys(); 27 | const matchingRequests = requests.filter(request => request.url.includes(comicId)); 28 | await Promise.all(matchingRequests.map(request => cache.delete(request))); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ui/src/app/settings/settings.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { HttpClientModule } from '@angular/common/http'; 3 | import { NgModule } from '@angular/core'; 4 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 5 | import { RouterModule } from '@angular/router'; 6 | import { IonicModule } from '@ionic/angular'; 7 | import { MomentModule } from 'ngx-moment'; 8 | 9 | import { EditPage } from '../library/edit/edit.page'; 10 | 11 | import { QueuePage } from './queue/queue.page'; 12 | import { ScannerComponent } from './scanner/scanner.component'; 13 | import { SettingsPage } from './settings.page'; 14 | 15 | @NgModule({ 16 | declarations: [ 17 | QueuePage, 18 | SettingsPage, 19 | ScannerComponent 20 | ], 21 | imports: [ 22 | CommonModule, 23 | FormsModule, 24 | IonicModule, 25 | HttpClientModule, 26 | MomentModule, 27 | ReactiveFormsModule, 28 | RouterModule.forChild([{ 29 | component: SettingsPage, path: '' 30 | }, { 31 | component: QueuePage, path: 'queue' 32 | }, { 33 | component: EditPage, path: 'queue/edit/:id' 34 | }]) 35 | ] 36 | }) 37 | export class SettingsPageModule {} 38 | -------------------------------------------------------------------------------- /ui/src/app/settings.service.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient } from '@angular/common/http'; 2 | import { Injectable } from '@angular/core'; 3 | import { Observable } from 'rxjs'; 4 | import { map } from 'rxjs/operators'; 5 | 6 | import { Setting } from './setting'; 7 | 8 | @Injectable({ 9 | providedIn: 'root' 10 | }) 11 | export class SettingsService { 12 | 13 | constructor( 14 | private http: HttpClient 15 | ) { } 16 | 17 | public list(): Observable { 18 | return this.http.get('/api/settings').pipe( 19 | this.consumeHateoas(), 20 | map((data: any) => data.map((item: any) => this.addId(item))) 21 | ); 22 | } 23 | 24 | public get(key: string): Observable { 25 | return this.http.get(`/api/settings/search/findByKey?key=${ key }`).pipe( 26 | map((item: any) => this.addId(item)) 27 | ); 28 | } 29 | 30 | public update(setting: Setting): Observable { 31 | return this.http.put(`/api/settings/${ setting.id }`, setting); 32 | } 33 | 34 | private consumeHateoas(): any { 35 | return map((data: any) => data._embedded.settings); 36 | } 37 | 38 | private addId(item: any): any { 39 | item.id = item._links.self.href.split('/').pop(); 40 | return item; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ui/src/app/thumbnails.service.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient } from '@angular/common/http'; 2 | import { Injectable } from '@angular/core'; 3 | import { DomSanitizer } from '@angular/platform-browser'; 4 | import { Observable } from 'rxjs'; 5 | import { map } from 'rxjs/operators'; 6 | 7 | import { Thumbnail } from './thumbnail'; 8 | 9 | @Injectable({ 10 | providedIn: 'root' 11 | }) 12 | export class ThumbnailsService { 13 | 14 | constructor( 15 | private sanitizer: DomSanitizer, 16 | private http: HttpClient 17 | ) {} 18 | 19 | public getFrontCover(comicId: string): Observable { 20 | return this.http.get(`/api/thumbnails/front-cover/${ comicId }`).pipe( 21 | map((thumbnail: any) => { 22 | thumbnail.url = this.sanitizer.bypassSecurityTrustUrl(`data:image/jpeg;base64,${ thumbnail.image }`); 23 | return thumbnail; 24 | }) 25 | ); 26 | } 27 | 28 | public getBackCover(comicId: string): Observable { 29 | return this.http.get(`/api/thumbnails/back-cover/${ comicId }`).pipe( 30 | map((thumbnail: any) => { 31 | thumbnail.url = this.sanitizer.bypassSecurityTrustUrl(`data:image/jpeg;base64,${ thumbnail.image }`); 32 | return thumbnail; 33 | }) 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/security/MockJwtService.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.security; 2 | 3 | import org.springframework.context.annotation.Profile; 4 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 5 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 6 | import org.springframework.security.core.context.SecurityContextHolder; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.ArrayList; 10 | 11 | @Service 12 | @Profile({"dev", "test"}) 13 | public class MockJwtService implements IJwtService { 14 | 15 | @Override 16 | public Boolean verifyToken(final String token, final String secret) { 17 | final ArrayList authorities = new ArrayList<>(); 18 | authorities.add(new SimpleGrantedAuthority("iss")); 19 | authorities.add(new SimpleGrantedAuthority("sub")); 20 | authorities.add(new SimpleGrantedAuthority("API_ALLOWED")); 21 | authorities.add(new SimpleGrantedAuthority("exp")); 22 | 23 | final UsernamePasswordAuthenticationToken mockAuth = 24 | new UsernamePasswordAuthenticationToken("mock-user-1", "", authorities); 25 | 26 | SecurityContextHolder.getContext().setAuthentication(mockAuth); 27 | return true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/thumbnails/ThumbnailController.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.thumbnails; 2 | 3 | import de.wasenweg.alfred.util.BaseController; 4 | import lombok.RequiredArgsConstructor; 5 | import org.springframework.hateoas.EntityModel; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | @RestController 12 | @RequestMapping(value = "/api/thumbnails", produces = { "application/hal+json" }) 13 | @RequiredArgsConstructor 14 | public class ThumbnailController extends BaseController { 15 | 16 | private final ThumbnailService thumbnailService; 17 | 18 | @GetMapping("/front-cover/{comicId}") 19 | public EntityModel findFrontCoverByComicId(@PathVariable("comicId") final String comicId) { 20 | return this.wrap(this.thumbnailService.findFrontCoverByComicId(comicId)); 21 | } 22 | 23 | @GetMapping("/back-cover/{comicId}") 24 | public EntityModel findBackCoverByComicId(@PathVariable("comicId") final String comicId) { 25 | return this.wrap(this.thumbnailService.findBackCoverByComicId(comicId)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/de/wasenweg/alfred/fixtures/ProgressFixtures.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.fixtures; 2 | 3 | import de.wasenweg.alfred.comics.Comic; 4 | import de.wasenweg.alfred.progress.Progress; 5 | import org.bson.types.ObjectId; 6 | 7 | import java.util.GregorianCalendar; 8 | 9 | public final class ProgressFixtures { 10 | 11 | private ProgressFixtures() { 12 | } 13 | 14 | public static Progress comicStarted(final Comic comic, final String userId) { 15 | return Progress.builder() 16 | .comicId(new ObjectId(comic.getId())) 17 | .userId(userId) 18 | .currentPage(4) 19 | .lastRead(new GregorianCalendar(2019, 3, 20).getTime()) 20 | .build(); 21 | } 22 | 23 | public static Progress comicStarted(final Comic comic) { 24 | return comicStarted(comic, "mock-user-1"); 25 | } 26 | 27 | public static Progress comicRead(final Comic comic, final int timeOffset) { 28 | return Progress.builder() 29 | .comicId(new ObjectId(comic.getId())) 30 | .userId("mock-user-1") 31 | .read(true) 32 | .lastRead(new GregorianCalendar(2019, 3, 1 + timeOffset).getTime()) 33 | .build(); 34 | } 35 | 36 | public static Progress comicRead(final Comic comic) { 37 | return comicRead(comic, 0); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /.Dockerfile.test: -------------------------------------------------------------------------------- 1 | FROM gradle:7.5.1-jdk17 as builder 2 | 3 | # Install Chrome 4 | RUN apt-get update && apt-get install -y --no-install-recommends \ 5 | gnupg apt-transport-https \ 6 | && curl -sSL https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \ 7 | && echo 'deb https://dl.google.com/linux/chrome/deb/ stable main' > /etc/apt/sources.list.d/google-chrome.list \ 8 | && apt-get update && apt-get install -y --no-install-recommends \ 9 | google-chrome-stable fontconfig fonts-ipafont-gothic fonts-freefont-ttf \ 10 | && apt-get purge --auto-remove -y gnupg \ 11 | && rm -rf /var/lib/apt/lists/* 12 | 13 | # Install Node.js 14 | RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - 15 | RUN apt-get install -y --no-install-recommends nodejs 16 | 17 | # Build, unit test & lint 18 | WORKDIR /workspace/app 19 | COPY settings.gradle build.gradle ./ 20 | COPY src src 21 | COPY ui ui 22 | COPY config config 23 | RUN gradle build jacocoTestReport 24 | 25 | # Start the application and run tests 26 | CMD bash -c 'gradle bootRun &> /dev/null & \ 27 | echo -n "Waiting for boot to complete " && \ 28 | while ! curl --output /dev/null --silent --head --fail http://localhost:8080; do echo -n "." && sleep 1; done && \ 29 | echo " done!" && \ 30 | gradle -q npm_run_e2eHeadless' 31 | 32 | -------------------------------------------------------------------------------- /ui/src/app/stats.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; 2 | import { TestBed } from '@angular/core/testing'; 3 | 4 | import { StatsHttpMocks } from '../testing/stats.http.mocks'; 5 | 6 | import { StatsService } from './stats.service'; 7 | 8 | let service: StatsService; 9 | let httpMock: HttpTestingController; 10 | 11 | describe('StatsService', () => { 12 | 13 | beforeEach(() => { 14 | TestBed.configureTestingModule({ 15 | imports: [ HttpClientTestingModule ] 16 | }); 17 | service = TestBed.inject(StatsService); 18 | httpMock = TestBed.inject(HttpTestingController); 19 | }); 20 | 21 | afterEach(() => { 22 | httpMock.verify(); 23 | TestBed.resetTestingModule(); 24 | }); 25 | 26 | describe('#get', () => { 27 | 28 | it('lists all statistics', () => { 29 | service.get().subscribe(stats => { 30 | expect(stats.issues).toBe(305); 31 | expect(stats.publishers).toBe(3); 32 | expect(stats.series).toBe(5); 33 | expect(stats.volumes).toBe(9); 34 | expect(stats.users).toBe(1); 35 | }); 36 | 37 | const req = httpMock.expectOne('/api/stats'); 38 | expect(req.request.method).toBe('GET'); 39 | req.flush(StatsHttpMocks.stats); 40 | }); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /ui/src/app/user-settings.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable({ 4 | providedIn: 'root' 5 | }) 6 | export class UserSettingsService { 7 | 8 | private userSettings: { [key: string]: any } = {}; 9 | 10 | constructor() { } 11 | 12 | public get(): { [key: string]: any } { 13 | return this.userSettings; 14 | } 15 | 16 | public save(): void { 17 | this.toggleColorScheme(); 18 | localStorage.setItem('userSettings', JSON.stringify(this.userSettings)); 19 | } 20 | 21 | public load(): void { 22 | this.userSettings = JSON.parse(localStorage.getItem('userSettings') || '{}'); 23 | this.handleColorScheme(); 24 | } 25 | 26 | private handleColorScheme(): void { 27 | if (!('darkMode' in this.userSettings)) { 28 | const prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); 29 | this.userSettings.darkMode = prefersDark.matches; 30 | this.toggleColorScheme(); 31 | prefersDark.addEventListener('change', mediaQuery => { 32 | this.userSettings.darkMode = mediaQuery.matches; 33 | this.save(); 34 | }); 35 | } else { 36 | this.toggleColorScheme(); 37 | } 38 | } 39 | 40 | private toggleColorScheme(): void { 41 | document.body.classList.toggle('dark', this.userSettings.darkMode); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ui/src/app/comic.ts: -------------------------------------------------------------------------------- 1 | export enum ScannerIssueSeverity { 2 | INFO, 3 | WARNING, 4 | ERROR 5 | } 6 | 7 | export enum ScannerIssueType { 8 | UNKNOWN, 9 | NOT_FLAT, 10 | NO_MONTH, 11 | NO_YEAR, 12 | NO_IMAGES, 13 | INVALID_FILE_FORMAT 14 | } 15 | 16 | export interface ScannerIssue { 17 | date: Date; 18 | type: ScannerIssueType; 19 | message: string; 20 | fixable: boolean; 21 | inProgress?: boolean; 22 | severity: ScannerIssueSeverity; 23 | } 24 | 25 | export interface Comic { 26 | id: string; 27 | path: string; 28 | fileName: string; 29 | title: string; 30 | series: string; 31 | number: number; 32 | position: string; 33 | volume: string; 34 | summary?: string; 35 | notes?: string; 36 | year: number; 37 | month: number; 38 | writer?: string; 39 | penciller?: string; 40 | inker?: string; 41 | colorist?: string; 42 | letterer?: string; 43 | coverArtist?: string; 44 | editor?: string; 45 | publisher: string; 46 | web?: string; 47 | pageCount: number; 48 | manga?: boolean; 49 | characters?: string; 50 | teams?: string; 51 | locations?: string; 52 | nextId: string | null; 53 | previousId: string | null; 54 | read?: boolean; 55 | currentPage?: number; 56 | lastRead?: Date; 57 | dirty?: number; 58 | errors?: ScannerIssue[]; 59 | files: string[]; 60 | } 61 | -------------------------------------------------------------------------------- /ui/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Alfred 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/test/java/de/wasenweg/alfred/unit/IndexControllerTest.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.unit; 2 | 3 | import de.wasenweg.alfred.IndexController; 4 | import org.junit.jupiter.api.BeforeEach; 5 | import org.junit.jupiter.api.Test; 6 | import org.junit.jupiter.api.extension.ExtendWith; 7 | import org.mockito.InjectMocks; 8 | import org.mockito.junit.jupiter.MockitoExtension; 9 | import org.springframework.test.web.servlet.MockMvc; 10 | import org.springframework.test.web.servlet.setup.MockMvcBuilders; 11 | 12 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 13 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl; 14 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 15 | 16 | @ExtendWith(MockitoExtension.class) 17 | class IndexControllerTest { 18 | 19 | private transient MockMvc mockMvc; 20 | 21 | @InjectMocks 22 | private transient IndexController controller; 23 | 24 | @BeforeEach 25 | public void setUp() { 26 | this.mockMvc = MockMvcBuilders.standaloneSetup(this.controller) 27 | .build(); 28 | } 29 | 30 | @Test 31 | void redirectToIndex() throws Exception { 32 | this.mockMvc.perform(get("/error")) 33 | .andExpect(forwardedUrl("/index.html")) 34 | .andExpect(status().isOk()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ui/src/app/cache-storage.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { CacheStorageMocks } from '../testing/cache-storage.mocks'; 4 | import { ComicFixtures } from '../testing/comic.fixtures'; 5 | 6 | import { CacheStorageService } from './cache-storage.service'; 7 | import { CACHES_TOKEN } from './caches.token'; 8 | 9 | let service: CacheStorageService; 10 | let caches: jasmine.SpyObj; 11 | let cache: jasmine.SpyObj; 12 | 13 | describe('CacheStorageService', () => { 14 | 15 | beforeEach(() => { 16 | caches = CacheStorageMocks.cacheStorage; 17 | cache = CacheStorageMocks.cache; 18 | caches.open.and.resolveTo(cache); 19 | 20 | TestBed.configureTestingModule({ 21 | providers: [{ 22 | provide: CACHES_TOKEN, useValue: caches 23 | }] 24 | }); 25 | service = TestBed.inject(CacheStorageService); 26 | }); 27 | 28 | afterEach(() => { 29 | TestBed.resetTestingModule(); 30 | }); 31 | 32 | describe('#resetThumbnailsCache', () => { 33 | 34 | it('removes all cached thumbnails for the given comic ID', async () => { 35 | await service.resetThumbnailsCache(ComicFixtures.comic.id); 36 | expect(caches.keys).toHaveBeenCalled(); 37 | expect(caches.open).toHaveBeenCalled(); 38 | expect(cache.keys).toHaveBeenCalled(); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /src/main/java/de/wasenweg/alfred/comics/ComicSearchService.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.comics; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Service; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | @Service 10 | @RequiredArgsConstructor 11 | public class ComicSearchService { 12 | 13 | private final ComicQueryRepositoryImpl queryRepository; 14 | private final ComicRepository comicRepository; 15 | 16 | public List findAllLastReadPerVolume(final String userId) { 17 | return this.queryRepository.findAllLastReadPerVolume(userId); 18 | } 19 | 20 | public List findAllByOrderByPublisherAscSeriesAscVolumeAscPositionAsc() { 21 | return this.comicRepository.findAllByOrderByPublisherAscSeriesAscVolumeAscPositionAsc(); 22 | } 23 | 24 | public Optional findLastReadForVolume( 25 | final String userId, final String publisher, final String series, final String volume) { 26 | return this.queryRepository.findLastReadForVolume(userId, publisher, series, volume); 27 | } 28 | 29 | public List findAllByPublisherAndSeriesAndVolumeOrderByPosition( 30 | final String userId, final String publisher, final String series, final String volume) { 31 | return this.queryRepository.findAllByPublisherAndSeriesAndVolumeOrderByPosition( 32 | userId, publisher, series, volume); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/de/wasenweg/alfred/unit/ComicConstructionTest.java: -------------------------------------------------------------------------------- 1 | package de.wasenweg.alfred.unit; 2 | 3 | import de.wasenweg.alfred.comics.Comic; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.assertj.core.api.Assertions.assertThat; 7 | 8 | class ComicConstructionTest { 9 | 10 | @Test 11 | void constructWithNew() throws Exception { 12 | final Comic comic = new Comic(); 13 | assertThat(comic.getCurrentPage()).isEqualTo(0); 14 | assertThat(comic.isRead()).isFalse(); 15 | } 16 | 17 | @Test 18 | void constructWithBuilder() throws Exception { 19 | final Comic comic = Comic.builder() 20 | .path("") 21 | .fileName("") 22 | .title("") 23 | .series("") 24 | .volume("") 25 | .number("") 26 | .position("") 27 | .year(2000) 28 | .month(5) 29 | .publisher("") 30 | .build(); 31 | assertThat(comic.getCurrentPage()).isEqualTo(0); 32 | assertThat(comic.isRead()).isFalse(); 33 | } 34 | 35 | @Test 36 | void updatePosition() throws Exception { 37 | final Comic comic = new Comic(); 38 | comic.setNumber("1/2"); 39 | assertThat(comic.getPosition()).isEqualTo("0000.5"); 40 | comic.setNumber("1"); 41 | assertThat(comic.getPosition()).isEqualTo("0001.0"); 42 | comic.setNumber("0.5"); 43 | assertThat(comic.getPosition()).isEqualTo("0000.5"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ui/src/app/library/volumes/covers/covers.page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Front- and back covers of your comics 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | No issues 16 | Please scan your library first 17 | 18 | 19 | 20 | 21 | 22 | {{ comic.fileName }} 23 | {{ comic.path }} 24 | 25 | 26 |
27 | 28 | 29 | Delete front cover 30 | 31 |
32 |
33 | 34 | 35 | Delete back cover 36 | 37 |
38 |
39 |
40 |
41 | -------------------------------------------------------------------------------- /ui/src/app/library/issues/issue-actions/issue-actions.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | import { PopoverController, NavParams } from '@ionic/angular'; 4 | 5 | import { Comic } from '../../../comic'; 6 | 7 | @Component({ 8 | selector: 'app-issue-actions', 9 | styleUrls: [ './issue-actions.component.sass' ], 10 | templateUrl: './issue-actions.component.html' 11 | }) 12 | export class IssueActionsComponent { 13 | 14 | public comic: Comic; 15 | 16 | constructor( 17 | private popoverCtrl: PopoverController, 18 | private router: Router, 19 | private navParams: NavParams 20 | ) { 21 | this.comic = this.navParams.get('comic'); 22 | } 23 | 24 | public download(): void { 25 | this.popoverCtrl.dismiss(); 26 | } 27 | 28 | public markAsReadUntil(comic: Comic): void { 29 | this.popoverCtrl.dismiss({ markAsReadUntil: comic }); 30 | } 31 | 32 | public goToLibrary(comic: Comic): void { 33 | this.router.navigate([ '/library/publishers', comic.publisher, 'series', comic.series, 'volumes' ]); 34 | this.popoverCtrl.dismiss(); 35 | } 36 | 37 | public edit(comic: Comic): void { 38 | this.router.navigate([ 39 | '/library/publishers', comic.publisher, 40 | 'series', comic.series, 41 | 'volumes', comic.volume, 42 | 'issues', comic.id, 'edit' ]); 43 | this.popoverCtrl.dismiss(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ui/e2e/src/proxy-settings.ts: -------------------------------------------------------------------------------- 1 | import * as http from 'http'; 2 | 3 | export class ProxySettings { 4 | 5 | public static set(flag: {} | undefined): Promise { 6 | return this.post('/flags', flag); 7 | } 8 | 9 | private static post(path: string, body = {}): Promise { 10 | const bodyString = JSON.stringify(body); 11 | return new Promise((resolve, reject) => { 12 | const req = http.request({ 13 | headers: { 14 | 'Content-Length': Buffer.byteLength(bodyString), 15 | 'Content-Type' : 'application/json' 16 | }, 17 | method: 'POST', 18 | path, 19 | port : '8090' 20 | }, res => { 21 | try { 22 | if ((res.statusCode || 0) > 399) { 23 | reject(res.statusCode); 24 | } else { 25 | res.setEncoding('utf8'); 26 | let rawData = ''; 27 | res.on('data', chunk => { 28 | rawData += chunk; 29 | }); 30 | res.on('end', () => { 31 | try { 32 | resolve(JSON.parse(rawData)); 33 | } catch (e) { 34 | reject((e).message); 35 | } 36 | }); 37 | } 38 | } catch (e) { 39 | reject((e).message); 40 | } 41 | }).on('error', e => { 42 | reject(e.message); 43 | }); 44 | req.end(bodyString); 45 | }); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /config/pmd/pmd-main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | Rules for main files. 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | --------------------------------------------------------------------------------