├── .env.example ├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── app ├── Acklam.php ├── Archive.php ├── ArchiveView.php ├── ArtistReference.php ├── AssociatedName.php ├── AssociatedNameReference.php ├── AuthorReference.php ├── Avatar.php ├── Comment.php ├── Completed.php ├── Console │ ├── Commands │ │ ├── Init.php │ │ ├── Scan.php │ │ └── Watch.php │ └── Kernel.php ├── Cover.php ├── Dropped.php ├── Events │ ├── Archive │ │ ├── NewArchives.php │ │ └── RemovedArchives.php │ ├── NewArchiveEvent.php │ ├── NewDirectoryEvent.php │ ├── RemovedArchiveEvent.php │ └── RemovedDirectoryEvent.php ├── Exceptions │ └── Handler.php ├── Facades │ └── LogParser.php ├── Favorite.php ├── Genre.php ├── GenreReference.php ├── Heat.php ├── Http │ ├── Controllers │ │ ├── AdminController.php │ │ ├── Auth │ │ │ ├── ForgotPasswordController.php │ │ │ ├── LoginController.php │ │ │ ├── RegisterController.php │ │ │ └── ResetPasswordController.php │ │ ├── AvatarController.php │ │ ├── CommentController.php │ │ ├── Controller.php │ │ ├── CoverController.php │ │ ├── FavoriteController.php │ │ ├── GenreController.php │ │ ├── GenreInformationController.php │ │ ├── HomeController.php │ │ ├── JobStatusController.php │ │ ├── LibraryController.php │ │ ├── MangaController.php │ │ ├── MangaEditController.php │ │ ├── MangaViewsController.php │ │ ├── NotificationController.php │ │ ├── PersonController.php │ │ ├── PreviewController.php │ │ ├── ReaderController.php │ │ ├── ReaderHistoryController.php │ │ ├── ReaderSettingsController.php │ │ ├── RoleController.php │ │ ├── SearchController.php │ │ ├── UserController.php │ │ ├── UserSettingsController.php │ │ ├── VoteController.php │ │ └── WatchController.php │ ├── Kernel.php │ ├── Middleware │ │ ├── EncryptCookies.php │ │ ├── RecordArchiveViews.php │ │ ├── RecordMangaViews.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── TrimStrings.php │ │ ├── UpdateLastSeen.php │ │ ├── VerifyCsrfToken.php │ │ └── VerifyRole.php │ ├── Requests │ │ ├── Admin │ │ │ ├── PatchHeatRequest.php │ │ │ ├── PatchImageExtractionRequest.php │ │ │ ├── PatchRegistrationRequest.php │ │ │ ├── PatchSchedulerRequest.php │ │ │ ├── PatchViewsRequest.php │ │ │ ├── PatchViewsTimeRequest.php │ │ │ ├── PostHeatRequest.php │ │ │ ├── PostSearchUsersRequest.php │ │ │ ├── PutDefaultRolesRequest.php │ │ │ ├── PutSchedulerRequest.php │ │ │ └── PutViewsTimeRequest.php │ │ ├── AvatarUpdateRequest.php │ │ ├── CommentCreateRequest.php │ │ ├── Edit │ │ │ └── Cover │ │ │ │ └── CoverUpdateRequest.php │ │ ├── EditMangaArtistAddRequest.php │ │ ├── EditMangaArtistRemoveRequest.php │ │ ├── EditMangaAssocNameAddRequest.php │ │ ├── EditMangaAssocNameRemoveRequest.php │ │ ├── EditMangaAuthorAddRequest.php │ │ ├── EditMangaAuthorRemoveRequest.php │ │ ├── EditMangaAutofillRequest.php │ │ ├── EditMangaDescriptionRequest.php │ │ ├── EditMangaGenresRequest.php │ │ ├── EditMangaRequest.php │ │ ├── EditMangaTypeRequest.php │ │ ├── EditMangaYearRequest.php │ │ ├── Favorite │ │ │ └── FavoriteAddRequest.php │ │ ├── Library │ │ │ ├── LibraryCreateRequest.php │ │ │ └── LibraryUpdateRequest.php │ │ ├── Notifications │ │ │ └── DeleteArchiveNotificationsRequest.php │ │ ├── Reader │ │ │ └── PutReaderHistoryRequest.php │ │ ├── ReaderSettingsRequest.php │ │ ├── Role │ │ │ ├── CreateRoleRequest.php │ │ │ └── PatchRoleRequest.php │ │ ├── User │ │ │ ├── PutStatusRequest.php │ │ │ ├── UserCreateRequest.php │ │ │ └── UserEditRequest.php │ │ ├── UserSettings │ │ │ ├── PatchPasswordRequest.php │ │ │ ├── PatchReaderDirectionRequest.php │ │ │ ├── PutAboutRequest.php │ │ │ └── PutDisplayRequest.php │ │ ├── Vote │ │ │ └── VoteCreateRequest.php │ │ └── Watch │ │ │ └── WatchCreateRequest.php │ └── ViewComposers │ │ └── NotificationsComposer.php ├── Image.php ├── ImageArchive.php ├── ImageArchiveRar.php ├── ImageArchiveZip.php ├── Interfaces │ ├── AutoFillInterface.php │ ├── EditableInterface.php │ ├── ImageArchiveInterface.php │ ├── NotificationInterface.php │ └── WatchDescriptorInterface.php ├── IntlString.php ├── JaroWinkler.php ├── Jobs │ ├── CleanupImageDisk.php │ ├── DecreaseHeats.php │ ├── IncreaseArchiveHeat.php │ ├── IncreaseMangaHeat.php │ ├── IncrementArchiveViews.php │ ├── IncrementMangaViews.php │ └── ScanLibrary.php ├── Library.php ├── Listeners │ ├── Archive │ │ ├── AddArchivesToDatabase.php │ │ └── RemoveArchivesFromDatabase.php │ ├── ArchiveEventSubscriber.php │ └── DirectoryEventSubscriber.php ├── LogParser.php ├── Manga.php ├── MangaView.php ├── Notifications │ └── NewArchiveNotification.php ├── Observers │ ├── ArchiveObserver.php │ └── MangaObserver.php ├── OnHold.php ├── Permission.php ├── Person.php ├── Planned.php ├── Policies │ ├── CommentPolicy.php │ ├── GenrePolicy.php │ ├── LibraryPolicy.php │ ├── MangaPolicy.php │ ├── PersonPolicy.php │ ├── RolePolicy.php │ └── UserPolicy.php ├── Preview.php ├── Providers │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ ├── LogParserServiceProvider.php │ ├── RouteServiceProvider.php │ └── ViewComposerServiceProvider.php ├── Rating.php ├── ReaderHistory.php ├── ReaderSettings.php ├── Reading.php ├── Role.php ├── RolePermission.php ├── Scanner.php ├── Sources │ ├── MangaUpdates.php │ └── MangaUpdates │ │ └── Series.php ├── StreamableStorageFile.php ├── Theme.php ├── User.php ├── UserPermission.php ├── UserRole.php ├── Vote.php ├── WatchReference.php └── Watcher.php ├── artisan ├── bootstrap ├── app.php ├── autoload.php └── cache │ └── .gitignore ├── composer.json ├── composer.lock ├── config ├── app.php ├── auth.php ├── broadcasting.php ├── cache.php ├── database.php ├── filesystems.php ├── logging.php ├── mail.php ├── queue.php ├── services.php ├── session.php └── view.php ├── database ├── .gitignore ├── factories │ ├── ArchiveFactory.php │ ├── CommentFactory.php │ ├── FavoriteFactory.php │ ├── LibraryFactory.php │ ├── MangaFactory.php │ ├── ModelFactory.php │ ├── PersonFactory.php │ ├── UserFactory.php │ ├── VoteFactory.php │ └── WatchReferenceFactory.php ├── migrations │ ├── 2014_10_12_000000_create_users_table.php │ ├── 2014_10_12_100000_create_password_resets_table.php │ ├── 2017_03_20_200100_create_genres_table.php │ ├── 2017_03_20_200200_create_libraries_table.php │ ├── 2017_03_20_200300_create_manga_table.php │ ├── 2017_03_20_200400_create_genre_information_table.php │ ├── 2017_03_20_200500_create_manga_information_table.php │ ├── 2017_04_15_214048_create_artists_table.php │ ├── 2017_04_15_214452_create_authors_table.php │ ├── 2017_04_15_215648_create_artist_references_table.php │ ├── 2017_04_15_215744_create_author_references_table.php │ ├── 2017_04_16_043051_create_associated_names_table.php │ ├── 2017_04_16_043150_create_associated_name_references_table.php │ ├── 2017_04_16_215053_create_library_privileges_table.php │ ├── 2017_08_31_204003_add_theme_to_user_table.php │ ├── 2017_09_15_181401_add_maintainer_to_users_table.php │ ├── 2017_10_17_195256_create_favorites_table.php │ ├── 2017_11_22_204609_rename_genre_information_to_genre_references.php │ ├── 2018_01_20_032005_migrate_manga_information_to_manga_table.php │ ├── 2018_04_27_020856_add_ignore_on_scan_to_manga_table.php │ ├── 2018_04_27_021829_add_mu_name_distance_to_manga_table.php │ ├── 2018_04_29_162515_create_reader_histories_table.php │ ├── 2018_04_30_032109_add_read_direction_to_users_table.php │ ├── 2018_05_02_200608_add_full_text_index_to_associated_names_table.php │ ├── 2018_05_15_132544_create_archives_table.php │ ├── 2018_05_15_182623_create_watch_references_table.php │ ├── 2018_05_15_231542_create_watch_notifications_table.php │ ├── 2018_06_24_194449_add_about_and_last_seen_to_users_table.php │ ├── 2018_06_30_205045_add_default_cover_archive_id_to_manga.php │ ├── 2018_07_04_165153_create_comments_table.php │ ├── 2018_07_10_012039_create_votes_table.php │ ├── 2018_07_16_190308_add_id_to_artist_references_table.php │ ├── 2018_07_16_190639_add_id_to_author_references_table.php │ ├── 2018_07_16_190751_add_id_to_associated_name_references_table.php │ ├── 2018_07_18_023228_create_archive_views_table.php │ ├── 2018_07_18_023438_create_manga_views_table.php │ ├── 2018_08_02_042159_add_id_to_favorites.php │ ├── 2018_08_25_163546_create_people_table.php │ ├── 2018_08_30_204408_drop_authors_and_artists_tables.php │ ├── 2018_09_17_011732_replace_l_t_r_with_reading_direction.php │ ├── 2018_10_09_161613_create_jobs_table.php │ ├── 2018_11_26_035157_create_failed_jobs_table.php │ ├── 2018_12_02_165843_replace_archive_name_with_id.php │ ├── 2018_12_13_041057_create_completed_table.php │ ├── 2018_12_13_041102_create_dropped_table.php │ ├── 2018_12_13_041111_create_reading_table.php │ ├── 2018_12_13_042636_create_on_hold_table.php │ ├── 2018_12_13_042648_create_planned_table.php │ ├── 2019_10_24_012759_create_roles_table.php │ ├── 2019_10_24_012806_create_permissions_table.php │ ├── 2019_10_24_012814_create_user_roles_table.php │ ├── 2019_10_24_013036_create_role_permissions_table.php │ ├── 2019_11_08_224501_create_user_permissions_table.php │ ├── 2020_02_13_182153_drop_admin_maintainer_columns_from_users_table.php │ ├── 2020_02_19_021031_add_foreign_keys_and_indices_to_reference_tables.php │ ├── 2020_02_27_035107_drop_library_privileges_table.php │ ├── 2020_03_16_181806_add_display_to_users_table.php │ ├── 2020_05_17_005518_add_foreign_keys_to_lists.php │ ├── 2020_05_19_204317_cascade_delete_reader_histories.php │ ├── 2020_05_20_192937_add_missing_cascade_deletes.php │ ├── 2020_05_20_230704_create_notifications_table.php │ └── 2020_06_03_022748_drop_watch_notifications_table.php └── seeds │ ├── DatabaseSeeder.php │ ├── GenresTableSeeder.php │ ├── PermissionsTableSeeder.php │ ├── RolesTableSeeder.php │ └── UsersTableSeeder.php ├── package-lock.json ├── package.json ├── phpunit.xml.dist ├── public ├── .htaccess ├── assets │ ├── mangapie.css │ ├── mangapie.js │ └── mu.png ├── favicon │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── browserconfig.xml │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── favicon.svg │ ├── mstile-144x144.png │ ├── mstile-150x150.png │ ├── mstile-310x150.png │ ├── mstile-310x310.png │ ├── mstile-70x70.png │ ├── safari-pinned-tab.svg │ └── site.webmanifest ├── fonts │ └── vendor │ │ └── @fortawesome │ │ └── fontawesome-free │ │ ├── webfa-brands-400.eot │ │ ├── webfa-brands-400.svg │ │ ├── webfa-brands-400.ttf │ │ ├── webfa-brands-400.woff │ │ ├── webfa-brands-400.woff2 │ │ ├── webfa-regular-400.eot │ │ ├── webfa-regular-400.svg │ │ ├── webfa-regular-400.ttf │ │ ├── webfa-regular-400.woff │ │ ├── webfa-regular-400.woff2 │ │ ├── webfa-solid-900.eot │ │ ├── webfa-solid-900.svg │ │ ├── webfa-solid-900.ttf │ │ ├── webfa-solid-900.woff │ │ └── webfa-solid-900.woff2 ├── index.php └── mix-manifest.json ├── resources ├── assets │ ├── js │ │ ├── app.js │ │ ├── bootstrap.js │ │ ├── components │ │ │ └── Example.vue │ │ └── mangapie.js │ └── sass │ │ ├── _addon.scss │ │ ├── _admin.libraries.scss │ │ ├── _files.scss │ │ ├── _manga.edit.scss │ │ ├── _manga.scss │ │ ├── _notifications.scss │ │ ├── _previews.scss │ │ ├── _reader.scss │ │ ├── _shapes.scss │ │ ├── _variables.scss │ │ ├── app.scss │ │ └── jquery-bar-rating │ │ └── _fontawesome-stars.scss ├── lang │ └── en │ │ ├── auth.php │ │ ├── pagination.php │ │ ├── passwords.php │ │ └── validation.php └── views │ ├── admin │ ├── config.blade.php │ ├── index.blade.php │ ├── layout.blade.php │ ├── libraries.blade.php │ ├── roles.blade.php │ ├── statistics.blade.php │ └── users.blade.php │ ├── auth │ ├── login.blade.php │ ├── passwords │ │ ├── email.blade.php │ │ └── reset.blade.php │ └── register.blade.php │ ├── edit │ └── manga │ │ ├── artists.blade.php │ │ ├── authors.blade.php │ │ ├── covers.blade.php │ │ ├── description.blade.php │ │ ├── genres.blade.php │ │ ├── index.blade.php │ │ ├── layout.blade.php │ │ ├── mangaupdates.blade.php │ │ ├── names.blade.php │ │ ├── type.blade.php │ │ └── year.blade.php │ ├── error │ ├── 403.blade.php │ └── 404.blade.php │ ├── favorites │ └── index.blade.php │ ├── home │ ├── advancedsearch.blade.php │ ├── artist.blade.php │ ├── author.blade.php │ ├── genre.blade.php │ ├── index.blade.php │ └── person.blade.php │ ├── layout.blade.php │ ├── lists │ ├── completed.blade.php │ ├── dropped.blade.php │ ├── layout.blade.php │ ├── nav-pills.blade.php │ ├── onhold.blade.php │ ├── planned.blade.php │ ├── reading.blade.php │ └── statistics.blade.php │ ├── manga │ ├── comments.blade.php │ ├── files.blade.php │ ├── layout.blade.php │ ├── reader.blade.php │ ├── shared │ │ ├── comments.blade.php │ │ ├── files.blade.php │ │ ├── information.blade.php │ │ └── information │ │ │ ├── actions.blade.php │ │ │ ├── artists.blade.php │ │ │ ├── associated_names.blade.php │ │ │ ├── authors.blade.php │ │ │ ├── description.blade.php │ │ │ ├── external.blade.php │ │ │ ├── genres.blade.php │ │ │ ├── path.blade.php │ │ │ └── ratings.blade.php │ └── show.blade.php │ ├── notifications │ ├── archives.blade.php │ ├── components │ │ └── menu.blade.php │ └── layout.blade.php │ ├── preview │ └── index.blade.php │ ├── search │ └── index.blade.php │ ├── settings │ ├── account.blade.php │ ├── components │ │ └── side-top-menu.blade.php │ ├── index.blade.php │ ├── layout.blade.php │ ├── profile.blade.php │ └── visuals.blade.php │ ├── shared │ ├── autocomplete.blade.php │ ├── components │ │ └── display.blade.php │ ├── errors.blade.php │ ├── index.blade.php │ ├── notifications.blade.php │ ├── searchbar.blade.php │ ├── success.blade.php │ └── warnings.blade.php │ └── user │ ├── activity.blade.php │ ├── comments.blade.php │ ├── history.blade.php │ ├── index.blade.php │ └── layout.blade.php ├── routes ├── api.php ├── channels.php ├── console.php └── web.php ├── screenshots ├── index.png ├── information-01.png ├── information-02.png ├── reader-01.png └── reader-02.png ├── server.php ├── storage ├── app │ ├── .gitignore │ └── public │ │ ├── .gitignore │ │ ├── avatars │ │ ├── .gitignore │ │ └── default.jpg │ │ ├── covers │ │ ├── .gitignore │ │ ├── medium │ │ │ ├── .gitignore │ │ │ └── default.jpg │ │ └── small │ │ │ ├── .gitignore │ │ │ └── default.jpg │ │ ├── images │ │ └── .gitignore │ │ └── previews │ │ ├── .gitignore │ │ └── small │ │ └── .gitignore ├── debugbar │ └── .gitignore ├── framework │ ├── .gitignore │ ├── cache │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ ├── testing │ │ └── .gitignore │ └── views │ │ └── .gitignore └── logs │ └── .gitignore ├── tests ├── CreatesApplication.php ├── Data │ ├── ImageArchive │ │ ├── rar │ │ │ ├── abc.cbr │ │ │ └── abc.rar │ │ └── zip │ │ │ ├── abc.cbz │ │ │ └── abc.zip │ ├── Libraries │ │ ├── .gitignore │ │ ├── manga1 │ │ │ └── .gitignore │ │ ├── manga2 │ │ │ └── .gitignore │ │ ├── manga3 │ │ │ └── .gitignore │ │ ├── manga4 │ │ │ ├── .gitignore │ │ │ ├── dest │ │ │ │ └── .gitignore │ │ │ └── src │ │ │ │ └── .gitignore │ │ ├── manga5 │ │ │ ├── .gitignore │ │ │ ├── dest │ │ │ │ └── .gitignore │ │ │ └── src │ │ │ │ └── .gitignore │ │ └── manga6 │ │ │ └── .gitignore │ └── MangaUpdates │ │ ├── Maison-Ikkoku.html │ │ └── Yu-Yu-Hakusho-Page-3.json ├── TestCase.php └── Unit │ ├── CommentPolicyTest.php │ ├── FavoriteTest.php │ ├── GenrePolicyTest.php │ ├── HeatTest.php │ ├── ImageArchiveRarTest.php │ ├── ImageArchiveTest.php │ ├── ImageArchiveZipTest.php │ ├── IntlStringTest.php │ ├── JaroWinklerTest.php │ ├── LibraryPolicyTest.php │ ├── MangaPolicyTest.php │ ├── MangaUpdatesTest.php │ ├── PersonPolicyTest.php │ ├── RolePermissionsTest.php │ ├── ScannerTest.php │ ├── ThemeTest.php │ ├── UserPermissionsTest.php │ ├── UserPolicyTest.php │ ├── VoteTest.php │ ├── WatchNotificationTest.php │ └── WatchTest.php └── webpack.mix.js /.env.example: -------------------------------------------------------------------------------- 1 | # IMPORTANT - If you ever make changes to your .env file, make sure to run `php artisan config:cache` 2 | # Additionally, you will need to restart any running queue workers or watchers for good measure 3 | 4 | APP_ENV=local 5 | APP_KEY= 6 | APP_DEBUG=false 7 | APP_LOG_LEVEL=debug 8 | APP_URL=https://192.168.1.142/ 9 | 10 | APP_IMAGE_EXTRACT=false 11 | 12 | # Valid options: nginx, apache 13 | # Always write the origin server (not the reverse proxy) 14 | APP_WEB_SERVER=nginx 15 | 16 | APP_MAIL_NOTIFICATIONS=false 17 | 18 | DB_CONNECTION=mysql 19 | DB_HOST=127.0.0.1 20 | DB_PORT=3306 21 | DB_DATABASE=homestead 22 | DB_USERNAME=homestead 23 | DB_PASSWORD=secret 24 | 25 | BROADCAST_DRIVER=log 26 | CACHE_DRIVER=file 27 | SESSION_DRIVER=file 28 | QUEUE_DRIVER=sync 29 | 30 | REDIS_HOST=127.0.0.1 31 | REDIS_PASSWORD=null 32 | REDIS_PORT=6379 33 | 34 | MAIL_DRIVER=smtp 35 | MAIL_HOST=smtp.mailtrap.io 36 | MAIL_PORT=2525 37 | MAIL_USERNAME=null 38 | MAIL_PASSWORD=null 39 | MAIL_ENCRYPTION=null 40 | 41 | PUSHER_APP_ID= 42 | PUSHER_APP_KEY= 43 | PUSHER_APP_SECRET= 44 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.html linguist-vendored 5 | 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | !public/fonts/vendor/ 3 | node_modules/ 4 | bower_components/ 5 | npm-debug.log 6 | 7 | # Laravel 4 specific 8 | bootstrap/compiled.php 9 | app/storage/ 10 | 11 | # Laravel 5 & Lumen specific 12 | public/storage 13 | public/hot 14 | storage/*.key 15 | .env.*.php 16 | .env.php 17 | .env 18 | Homestead.yaml 19 | Homestead.json 20 | 21 | # Config for additional packages 22 | config/debugbar.php 23 | config/ide-helper.php 24 | config/image.php 25 | 26 | # Rocketeer PHP task runner and deployment package. https://github.com/rocketeers/rocketeer 27 | .rocketeer/ 28 | 29 | nginx-log/ 30 | public/themes 31 | public/bootstrap-3-typeahead 32 | 33 | .idea/* 34 | .vscode/* 35 | _ide_helper.php 36 | phpunit.xml 37 | coverage/ 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mangapie 2 | 3 | This is a self-hosted server for archived manga. 4 | 5 | ## Features 6 | * Support for 7 | - zip/cbz 8 | - rar/cbr 9 | * Reader 10 | - Automatic transition from one archive to another 11 | - Image preloading 12 | - Option to read left to right or right to left 13 | - Saves archive progress 14 | - Complete, incomplete, unread 15 | - Date last read 16 | * Search 17 | - Autocomplete for quick and dirty basic searches 18 | - Advanced search 19 | - By genres 20 | - By author and/or artist 21 | - By keywords 22 | - Also matches against associated names 23 | * Metadata 24 | - Mangaupdates 25 | - Description, type, associated names, genres, authors, artists, year 26 | - Uses Jaro-Winkler for name matching 27 | - Editable 28 | - Description, type, associated names, genres, authors, artists, year 29 | - Select covers from archives 30 | 31 | ## Requirements 32 | * PHP 33 | * Any DBMS that Laravel supports 34 | * Composer 35 | 36 | ## Installation & Configuration 37 | Check out the wiki. 38 | 39 | ## Screenshots 40 | ![Manga](/screenshots/index.png?raw=true "Index") 41 | ![Reader1](/screenshots/reader-01.png?raw=true "Reader1") 42 | -------------------------------------------------------------------------------- /app/ArchiveView.php: -------------------------------------------------------------------------------- 1 | belongsTo(User::class); 17 | } 18 | 19 | public function archive() 20 | { 21 | return $this->belongsTo(Manga::class); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/ArtistReference.php: -------------------------------------------------------------------------------- 1 | manga_id; 15 | } 16 | 17 | public function getArtistId() 18 | { 19 | return $this->artist_id; 20 | } 21 | 22 | public function artist() 23 | { 24 | return $this->belongsTo(Person::class); 25 | } 26 | 27 | public function manga() 28 | { 29 | return $this->belongsTo(Manga::class); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/AssociatedName.php: -------------------------------------------------------------------------------- 1 | id; 15 | } 16 | 17 | public function getName() 18 | { 19 | return $this->name; 20 | } 21 | 22 | public function references() 23 | { 24 | return $this->hasMany(AssociatedNameReference::class); 25 | } 26 | 27 | public function scopeSearch($query, $keywords) 28 | { 29 | return empty($keywords) ? $query : $query->whereRaw('match(name) against(? in boolean mode)', [$keywords]); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/AssociatedNameReference.php: -------------------------------------------------------------------------------- 1 | belongsTo(AssociatedName::class); 14 | } 15 | 16 | public function manga() 17 | { 18 | return $this->belongsTo(Manga::class); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/AuthorReference.php: -------------------------------------------------------------------------------- 1 | manga_id; 15 | } 16 | 17 | public function getAuthorId() 18 | { 19 | return $this->author_id; 20 | } 21 | 22 | public function author() 23 | { 24 | return $this->belongsTo(Person::class); 25 | } 26 | 27 | public function manga() 28 | { 29 | return $this->belongsTo(Manga::class); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Comment.php: -------------------------------------------------------------------------------- 1 | belongsTo(\App\User::class); 21 | } 22 | 23 | /** 24 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 25 | */ 26 | public function manga() 27 | { 28 | return $this->belongsTo(\App\Manga::class); 29 | } 30 | 31 | /** 32 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 33 | */ 34 | public function archive() 35 | { 36 | return $this->belongsTo(\App\Archive::class); 37 | } 38 | 39 | /** 40 | * @return string 41 | */ 42 | public function getText() 43 | { 44 | return $this->text; 45 | } 46 | 47 | public function getCreatedAt() 48 | { 49 | return $this->created_at; 50 | } 51 | 52 | public function getUpdatedAt() 53 | { 54 | return $this->updated_at; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/Completed.php: -------------------------------------------------------------------------------- 1 | belongsTo(Manga::class); 19 | } 20 | 21 | /** 22 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 23 | */ 24 | public function user() 25 | { 26 | return $this->belongsTo(User::class); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Dropped.php: -------------------------------------------------------------------------------- 1 | belongsTo(Manga::class); 19 | } 20 | 21 | /** 22 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 23 | */ 24 | public function user() 25 | { 26 | return $this->belongsTo(User::class); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Events/Archive/NewArchives.php: -------------------------------------------------------------------------------- 1 | newArchives = $newArchives; 27 | } 28 | 29 | /** 30 | * Get the channels the event should broadcast on. 31 | * 32 | * @return \Illuminate\Broadcasting\Channel|array 33 | */ 34 | // public function broadcastOn() 35 | // { 36 | // return new PrivateChannel('channel-name'); 37 | // } 38 | } 39 | -------------------------------------------------------------------------------- /app/Events/Archive/RemovedArchives.php: -------------------------------------------------------------------------------- 1 | removedArchives = $removedArchives; 27 | } 28 | 29 | /** 30 | * Get the channels the event should broadcast on. 31 | * 32 | * @return \Illuminate\Broadcasting\Channel|array 33 | */ 34 | // public function broadcastOn() 35 | // { 36 | // return new PrivateChannel('channel-name'); 37 | // } 38 | } 39 | -------------------------------------------------------------------------------- /app/Events/NewArchiveEvent.php: -------------------------------------------------------------------------------- 1 | name = $name; 32 | $this->path = $path; 33 | $this->rootPath = $rootPath; 34 | $this->data = $data; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/Events/NewDirectoryEvent.php: -------------------------------------------------------------------------------- 1 | name = $name; 31 | $this->path = $path; 32 | $this->rootPath = $rootPath; 33 | $this->data = $data; 34 | $this->isSymbolicLink = $isSymbolicLink; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/Events/RemovedArchiveEvent.php: -------------------------------------------------------------------------------- 1 | name = $name; 30 | $this->path = $path; 31 | $this->rootPath = $rootPath; 32 | $this->data = $data; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Events/RemovedDirectoryEvent.php: -------------------------------------------------------------------------------- 1 | name = $name; 31 | $this->path = $path; 32 | $this->rootPath = $rootPath; 33 | $this->data = $data; 34 | $this->isSymbolicLink = $isSymbolicLink; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/Facades/LogParser.php: -------------------------------------------------------------------------------- 1 | belongsTo(User::class, 'user_id', 'id'); 18 | } 19 | 20 | /** 21 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 22 | */ 23 | public function manga() 24 | { 25 | return $this->belongsTo(Manga::class, 'manga_id', 'id'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/Genre.php: -------------------------------------------------------------------------------- 1 | id; 14 | } 15 | 16 | public function getName() 17 | { 18 | return $this->name; 19 | } 20 | 21 | public function getDescription() 22 | { 23 | return $this->description; 24 | } 25 | 26 | public function scopeOldest($query) 27 | { 28 | $old = Genre::orderBy('updated_at', 'asc')->first(); 29 | 30 | return $old; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/GenreReference.php: -------------------------------------------------------------------------------- 1 | belongsTo('App\Genre'); 14 | } 15 | 16 | public function manga() 17 | { 18 | return $this->belongsTo('App\Manga'); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ForgotPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ResetPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Http/Controllers/AvatarController.php: -------------------------------------------------------------------------------- 1 | response(); 17 | } 18 | 19 | public function put(AvatarUpdateRequest $request) 20 | { 21 | $avatar = new Avatar($request->user()); 22 | $putResult = $avatar->put($request->file('avatar')); 23 | 24 | if ($putResult !== false) 25 | $request->session()->flash('success', 'Your avatar has been updated.'); 26 | else 27 | $request->session()->flash('failure', 'Unable to update your avatar. Contact an admin.'); 28 | 29 | return redirect()->action('UserSettingsController@profile'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | query('sort', 'asc'); 19 | $library = request()->query('library'); 20 | $perPage = 18; 21 | 22 | $items = $user->manga(); 23 | if (! empty($library)) { 24 | $items = $items->whereIn('library_id', [$library]); 25 | } 26 | 27 | $items = $items->orderBy('name', $sort) 28 | ->with([ 29 | 'favorites', 30 | 'votes', 31 | 'authors', 32 | 'artists' 33 | ]) 34 | ->paginate($perPage, ['id', 'name']) 35 | ->appends(request()->input()); 36 | 37 | return view('home.index') 38 | ->with('manga_list', $items) 39 | ->with('sort', $sort); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/Http/Controllers/JobStatusController.php: -------------------------------------------------------------------------------- 1 | make('No such job.', 404); 13 | 14 | return response()->stream(function () use ($jobStatus) { 15 | $safeToBreak = false; 16 | 17 | do { 18 | ob_start(); 19 | 20 | echo 'data: ' . json_encode([ 21 | 'id' => $jobStatus->id, 22 | 'status' => $jobStatus->status, 23 | 'ended' => $jobStatus->is_ended, 24 | 'finished' => $jobStatus->is_finished, 25 | 'progress' => $jobStatus->progress_percentage, 26 | ]); 27 | 28 | echo "\n\n"; 29 | 30 | ob_end_flush(); 31 | flush(); 32 | 33 | if ($jobStatus->is_ended) 34 | $safeToBreak = true; 35 | 36 | sleep(0.15); 37 | } while (! $safeToBreak && $jobStatus->refresh()); 38 | }, 200, [ 39 | 'Content-Type' => 'text/event-stream', 40 | 'Cache-Control' => 'no-cache', 41 | 'X-Accel-Buffering' => 'no' 42 | ]); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/Http/Controllers/MangaViewsController.php: -------------------------------------------------------------------------------- 1 | user(); 13 | $direction = $request->get('direction'); 14 | $mangaId = $request->get('manga_id'); 15 | 16 | ReaderSettings::updateOrCreate([ 17 | 'user_id' => $user->id, 18 | 'manga_id' => $mangaId 19 | ], [ 20 | 'direction' => $direction 21 | ]); 22 | 23 | return redirect()->back(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Http/Controllers/VoteController.php: -------------------------------------------------------------------------------- 1 | user(); 13 | 14 | $user->votes()->updateOrCreate([ 15 | 'manga_id' => $request->get('manga_id') 16 | ], [ 17 | 'rating' => $request->get('rating') 18 | ]); 19 | 20 | return response()->make(); 21 | } 22 | 23 | public function destroy(Vote $vote) 24 | { 25 | $vote->forceDelete(); 26 | 27 | return redirect()->back()->with('success', 'Your vote was successfully deleted.'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/Http/Controllers/WatchController.php: -------------------------------------------------------------------------------- 1 | user(); 14 | 15 | $user->watchReferences()->create([ 16 | 'manga_id' => $request->get('manga_id'), 17 | ]); 18 | 19 | session()->flash('success', 'You are now watching this manga.'); 20 | 21 | return redirect()->back(); 22 | } 23 | 24 | public function destroy(WatchReference $watchReference) 25 | { 26 | $watchReference->forceDelete(); 27 | 28 | session()->flash('success', 'You are no longer watching this manga.'); 29 | 30 | return redirect()->back(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | route('archive'); 21 | if (\Auth::check() && ! empty($archive)) { 22 | $user = \Auth::user(); 23 | 24 | if (\Cache::tags(['config', 'views'])->get('enabled', true) == true) 25 | \Queue::push(new IncrementArchiveViews($user, $archive)); 26 | 27 | if (\Cache::tags(['config', 'heat'])->get('enabled', false) == true) 28 | \Queue::push(new IncreaseArchiveHeat($user, $archive)); 29 | } 30 | 31 | return $next($request); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/Http/Middleware/RecordMangaViews.php: -------------------------------------------------------------------------------- 1 | route('manga'); 21 | 22 | if (\Auth::check() && ! empty($manga)) { 23 | $user = \Auth::user(); 24 | 25 | if (\Cache::tags(['config', 'views'])->get('enabled', true) == true) { 26 | \Queue::push(new IncrementMangaViews($user, $manga)); 27 | } 28 | 29 | if (\Cache::tags(['config', 'heat'])->get('enabled', false) == true) 30 | \Queue::push(new IncreaseMangaHeat($user, $manga)); 31 | } 32 | 33 | return $next($request); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 21 | return redirect('/home'); 22 | } 23 | 24 | return $next($request); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | update([ 20 | 'last_seen' => \Carbon\Carbon::now() 21 | ]); 22 | } 23 | 24 | return $next($request); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | hasRole($role)) { 25 | abort(401); 26 | } 27 | 28 | return $next($request); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/PatchHeatRequest.php: -------------------------------------------------------------------------------- 1 | hasRole('Administrator'); 17 | } 18 | 19 | /** 20 | * Get the validation rules that apply to the request. 21 | * 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'enabled' => 'boolean|nullable' 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/PatchImageExtractionRequest.php: -------------------------------------------------------------------------------- 1 | hasRole('Administrator'); 17 | } 18 | 19 | /** 20 | * Get the validation rules that apply to the request. 21 | * 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'enabled' => 'boolean|nullable' 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/PatchRegistrationRequest.php: -------------------------------------------------------------------------------- 1 | hasRole('Administrator'); 17 | } 18 | 19 | /** 20 | * Get the validation rules that apply to the request. 21 | * 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'enabled' => 'boolean|nullable' 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/PatchSchedulerRequest.php: -------------------------------------------------------------------------------- 1 | hasRole('Administrator'); 17 | } 18 | 19 | /** 20 | * Get the validation rules that apply to the request. 21 | * 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'enabled' => 'boolean|nullable' 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/PatchViewsRequest.php: -------------------------------------------------------------------------------- 1 | hasRole('Administrator'); 17 | } 18 | 19 | /** 20 | * Get the validation rules that apply to the request. 21 | * 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'enabled' => 'boolean|nullable' 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/PatchViewsTimeRequest.php: -------------------------------------------------------------------------------- 1 | hasRole('Administrator'); 17 | } 18 | 19 | /** 20 | * Get the validation rules that apply to the request. 21 | * 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'enabled' => 'boolean|nullable' 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/PostHeatRequest.php: -------------------------------------------------------------------------------- 1 | hasRole('Administrator'); 17 | } 18 | 19 | /** 20 | * Get the validation rules that apply to the request. 21 | * 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'action' => 'required|in:reset,set', 28 | 'heat_default' => 'required_if:action,set|numeric', 29 | 'heat_threshold' => 'required_if:action,set|numeric|max:' . (int) request()->get('heat_default'), 30 | 'heat_heat' => 'required_if:action,set|numeric', 31 | 'heat_cooldown' => 'required_if:action,set|numeric' 32 | ]; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/PostSearchUsersRequest.php: -------------------------------------------------------------------------------- 1 | hasRole('Administrator'); 17 | } 18 | 19 | /** 20 | * Get the validation rules that apply to the request. 21 | * 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'name' => 'required|string' 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/PutDefaultRolesRequest.php: -------------------------------------------------------------------------------- 1 | hasRole('Administrator'); 17 | } 18 | 19 | /** 20 | * Get the validation rules that apply to the request. 21 | * 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'role_ids' => 'array', 28 | 'role_ids.*' => 'integer|exists:roles,id' 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/PutSchedulerRequest.php: -------------------------------------------------------------------------------- 1 | hasRole('Administrator'); 17 | } 18 | 19 | /** 20 | * Get the validation rules that apply to the request. 21 | * 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'action' => 'required|in:reset,set', 28 | 'cron' => 'required_if:action,set|string|cron' 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/Admin/PutViewsTimeRequest.php: -------------------------------------------------------------------------------- 1 | hasRole('Administrator'); 17 | } 18 | 19 | /** 20 | * Get the validation rules that apply to the request. 21 | * 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'action' => 'required|in:reset,set', 28 | 'threshold' => 'required_if:action,set|dateinterval' 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/AvatarUpdateRequest.php: -------------------------------------------------------------------------------- 1 | 'required|image|max:200' 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/CommentCreateRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string:2048', 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/Edit/Cover/CoverUpdateRequest.php: -------------------------------------------------------------------------------- 1 | hasRole('Administrator') || $user->hasRole('Editor'); 19 | } 20 | 21 | /** 22 | * Get the validation rules that apply to the request. 23 | * 24 | * @return array 25 | */ 26 | public function rules() 27 | { 28 | return [ 29 | 'manga_id' => 'required|integer|exists:manga,id', 30 | 'archive_id' => 'required|integer|exists:archives,id', 31 | 'page' => 'required|integer' 32 | ]; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Http/Requests/EditMangaArtistAddRequest.php: -------------------------------------------------------------------------------- 1 | 'required|int|exists:manga,id', 28 | 'name' => 'string', 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/EditMangaArtistRemoveRequest.php: -------------------------------------------------------------------------------- 1 | 'required|int|exists:manga,id', 28 | 'artist_reference_id' => 'required|int|exists:artist_references,id', 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/EditMangaAssocNameAddRequest.php: -------------------------------------------------------------------------------- 1 | 'required|int|exists:manga,id', 28 | 'name' => 'required|string', 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/EditMangaAssocNameRemoveRequest.php: -------------------------------------------------------------------------------- 1 | 'required|int|exists:manga,id', 28 | 'associated_name_reference_id' => 'required|int|exists:associated_name_references,id', 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/EditMangaAuthorAddRequest.php: -------------------------------------------------------------------------------- 1 | 'required|int|exists:manga,id', 28 | 'name' => 'string', 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/EditMangaAuthorRemoveRequest.php: -------------------------------------------------------------------------------- 1 | 'required|int|exists:manga,id', 28 | 'author_reference_id' => 'required|int|exists:author_references,id', 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/EditMangaAutofillRequest.php: -------------------------------------------------------------------------------- 1 | 'required|exists:manga,id', 28 | 'mu_id' => 'required_if:action,autofill|integer', 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/EditMangaDescriptionRequest.php: -------------------------------------------------------------------------------- 1 | 'required|int|exists:manga,id', 28 | 'description' => 'string:4096', 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/EditMangaGenresRequest.php: -------------------------------------------------------------------------------- 1 | 'required|int|exists:manga,id', 28 | 'genres' => 'required|array', 29 | 'genres.*' => 'required|int|exists:genres,id' 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Requests/EditMangaTypeRequest.php: -------------------------------------------------------------------------------- 1 | 'required|int|exists:manga,id', 28 | 'type' => 'string|in:Manga,Doujinshi,Manwha', 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/EditMangaYearRequest.php: -------------------------------------------------------------------------------- 1 | 'required|int|exists:manga,id', 28 | 'year' => 'regex:/^\d{1,4}$/', 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/Favorite/FavoriteAddRequest.php: -------------------------------------------------------------------------------- 1 | 'required|integer|exists:manga,id', 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/Library/LibraryCreateRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string|max:255|unique:libraries', 28 | 'path' => 'required|string|unique:libraries' 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/Library/LibraryUpdateRequest.php: -------------------------------------------------------------------------------- 1 | check(); 17 | } 18 | 19 | /** 20 | * Get the validation rules that apply to the request. 21 | * 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'action' => 'required|string|in:rename,refresh', 28 | 'name' => 'required_if:action,rename|string|nullable|unique:libraries,name' 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/Notifications/DeleteArchiveNotificationsRequest.php: -------------------------------------------------------------------------------- 1 | merge([ 22 | 'series' => json_decode($this->get('series')) 23 | ]); 24 | } 25 | 26 | /** 27 | * Get the validation rules that apply to the request. 28 | * 29 | * @return array 30 | */ 31 | public function rules() 32 | { 33 | return [ 34 | 'series' => 'array|required', 35 | 'series.*' => 'int|exists:manga,id' 36 | ]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/Http/Requests/Reader/PutReaderHistoryRequest.php: -------------------------------------------------------------------------------- 1 | 'required|integer|exists:manga,id', 28 | 'archive_id' => 'required|integer|exists:archives,id', 29 | 'page' => 'required|integer' 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Requests/ReaderSettingsRequest.php: -------------------------------------------------------------------------------- 1 | 'required|exists:manga,id', 28 | 'direction' => 'string|size:3|in:ltr,rtl,vrt' 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/Role/CreateRoleRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string|unique:roles,name', 28 | 'libraries' => 'array', 29 | 'libraries.*' => 'int|exists:libraries,id' 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Requests/User/PutStatusRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string|in:completed,dropped,on_hold,planned,reading', 28 | 'manga_id' => 'required|integer|exists:manga,id' 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/User/UserCreateRequest.php: -------------------------------------------------------------------------------- 1 | can('create', User::class); 18 | } 19 | 20 | /** 21 | * Get the validation rules that apply to the request. 22 | * 23 | * @return array 24 | */ 25 | public function rules() 26 | { 27 | return [ 28 | 'name' => 'required|string|unique:users', 29 | 'email' => 'required|email|unique:users', 30 | 'password' => 'required|string', 31 | 'roles' => 'required|array', 32 | 'roles.*' => 'required|exists:roles,id', 33 | ]; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/Http/Requests/User/UserEditRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string|exists:users', 29 | 'new-name' => 'required|string|unique:users,name' 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Requests/UserSettings/PatchPasswordRequest.php: -------------------------------------------------------------------------------- 1 | 'string', 28 | 'new' => 'string', 29 | 'verify' => 'same:new', 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Requests/UserSettings/PatchReaderDirectionRequest.php: -------------------------------------------------------------------------------- 1 | 'required|string|size:3|in:ltr,rtl,vrt' 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/UserSettings/PutAboutRequest.php: -------------------------------------------------------------------------------- 1 | 'string|nullable' 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/UserSettings/PutDisplayRequest.php: -------------------------------------------------------------------------------- 1 | check(); 17 | } 18 | 19 | /** 20 | * Get the validation rules that apply to the request. 21 | * 22 | * @return array 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'display' => 'required|string|in:grid,list' 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/Requests/Vote/VoteCreateRequest.php: -------------------------------------------------------------------------------- 1 | 'required|int|exists:manga,id', 28 | 'rating' => 'required|int|between:1,5' 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/Http/Requests/Watch/WatchCreateRequest.php: -------------------------------------------------------------------------------- 1 | 'required|integer|exists:manga,id', 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/Http/ViewComposers/NotificationsComposer.php: -------------------------------------------------------------------------------- 1 | unreadNotifications() 21 | ->orderBy('updated_at') 22 | ->get(); 23 | 24 | $view->with('notifications', $notifications); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /app/Interfaces/AutoFillInterface.php: -------------------------------------------------------------------------------- 1 | id; 19 | } 20 | 21 | public function getName() 22 | { 23 | return $this->name; 24 | } 25 | 26 | public function getPath() 27 | { 28 | return $this->path; 29 | } 30 | 31 | public function manga() 32 | { 33 | return $this->hasMany('App\Manga', 'library_id', 'id'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/Listeners/Archive/AddArchivesToDatabase.php: -------------------------------------------------------------------------------- 1 | newArchives as $archive) { 32 | Archive::updateOrCreate([ 33 | 'manga_id' => $archive['manga_id'], 34 | 'name' => $archive['name'], 35 | 'size' => $archive['size'] 36 | ]); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Listeners/Archive/RemoveArchivesFromDatabase.php: -------------------------------------------------------------------------------- 1 | removedArchives as $archive) { 32 | Archive::where('manga_id', $archive['manga_id']) 33 | ->where('name', $archive['name']) 34 | ->forceDelete(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/MangaView.php: -------------------------------------------------------------------------------- 1 | belongsTo(User::class); 17 | } 18 | 19 | public function manga() 20 | { 21 | return $this->belongsTo(Manga::class); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/OnHold.php: -------------------------------------------------------------------------------- 1 | belongsTo(Manga::class); 19 | } 20 | 21 | /** 22 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 23 | */ 24 | public function user() 25 | { 26 | return $this->belongsTo(User::class); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Permission.php: -------------------------------------------------------------------------------- 1 | belongsToMany(Role::class, 'role_permission_references'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Planned.php: -------------------------------------------------------------------------------- 1 | belongsTo(Manga::class); 19 | } 20 | 21 | /** 22 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 23 | */ 24 | public function user() 25 | { 26 | return $this->belongsTo(User::class); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Policies/RolePolicy.php: -------------------------------------------------------------------------------- 1 | hasRole('Banned') && 22 | $user->hasPermission('create', Role::class); 23 | } 24 | 25 | /** 26 | * Determine whether the user can update a user's roles. 27 | * 28 | * @param User $user 29 | * @param Role $role 30 | * @return bool 31 | */ 32 | public function update(User $user, Role $role) 33 | { 34 | /* 35 | * Technically, this is checking if the user has permission to update the specific Role, 36 | * but for our use, this is good enough. :shrug: 37 | */ 38 | return ! $user->hasRole('Banned') && 39 | $user->hasPermission('update', $role); 40 | } 41 | 42 | /** 43 | * @param User $user 44 | * @param Role $role 45 | * @return bool 46 | */ 47 | public function forceDelete(User $user, Role $role) 48 | { 49 | /* 50 | * Same comment as above in method `update`. 51 | */ 52 | return ! $user->hasRole('Banned') && 53 | $user->hasPermission('forceDelete', $role); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/Providers/AuthServiceProvider.php: -------------------------------------------------------------------------------- 1 | LibraryPolicy::class, 25 | Role::class => RolePolicy::class, 26 | Manga::class => MangaPolicy::class 27 | ]; 28 | 29 | /** 30 | * Register any authentication / authorization services. 31 | * 32 | * @return void 33 | */ 34 | public function boot() 35 | { 36 | $this->registerPolicies(); 37 | 38 | Gate::define('update-series', function (User $user, Manga $series) { 39 | return $user->can('update', $series); 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | [ 17 | \App\Listeners\Archive\AddArchivesToDatabase::class 18 | ], 19 | 20 | \App\Events\Archive\RemovedArchives::class => [ 21 | \App\Listeners\Archive\RemoveArchivesFromDatabase::class 22 | ], 23 | ]; 24 | 25 | protected $subscribe = [ 26 | \App\Listeners\ArchiveEventSubscriber::class, 27 | \App\Listeners\DirectoryEventSubscriber::class, 28 | ]; 29 | 30 | /** 31 | * Register any events for your application. 32 | * 33 | * @return void 34 | */ 35 | public function boot() 36 | { 37 | parent::boot(); 38 | 39 | \App\Archive::observe(\App\Observers\ArchiveObserver::class); 40 | \App\Manga::observe(\App\Observers\MangaObserver::class); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Providers/LogParserServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->singleton('LogParser', function () { 29 | return new LogParser; 30 | }); 31 | } 32 | 33 | /** 34 | * Get the services provided by the provider. 35 | * 36 | * @return array 37 | */ 38 | public function provides() 39 | { 40 | return ['LogParser']; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Providers/ViewComposerServiceProvider.php: -------------------------------------------------------------------------------- 1 | composer('shared.notifications', \App\Http\ViewComposers\NotificationsComposer::class); 17 | } 18 | 19 | /** 20 | * Register the application services. 21 | * 22 | * @return void 23 | */ 24 | public function register() 25 | { 26 | // 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/ReaderHistory.php: -------------------------------------------------------------------------------- 1 | id; 18 | } 19 | 20 | public function getUserId() 21 | { 22 | return $this->user_id; 23 | } 24 | 25 | public function getMangaId() 26 | { 27 | return $this->manga_id; 28 | } 29 | 30 | public function getArchiveName() 31 | { 32 | return $this->archive_name; 33 | } 34 | 35 | public function getPage() 36 | { 37 | return $this->page; 38 | } 39 | 40 | public function getPageCount() 41 | { 42 | return $this->page_count; 43 | } 44 | 45 | public function getLastUpdated() 46 | { 47 | return $this->updated_at; 48 | } 49 | 50 | public function archive() 51 | { 52 | return $this->belongsTo(Archive::class); 53 | } 54 | 55 | public function manga() 56 | { 57 | return $this->belongsTo(Manga::class); 58 | } 59 | 60 | public function user() 61 | { 62 | return $this->belongsTo(User::class); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/ReaderSettings.php: -------------------------------------------------------------------------------- 1 | belongsTo(Manga::class); 14 | } 15 | 16 | public function user() 17 | { 18 | return $this->belongsTo(User::class); 19 | } 20 | 21 | /** 22 | * Determines whether the direction is left-to-right. 23 | * 24 | * @return bool 25 | */ 26 | public function isLeftToRight() 27 | { 28 | return ! empty($this->direction) ? $this->direction === 'ltr' : false; 29 | } 30 | 31 | /** 32 | * Determines whether the direction is right-to-left. 33 | */ 34 | /** 35 | * @return bool 36 | */ 37 | public function isRightToLeft() 38 | { 39 | return ! empty($this->direction) ? $this->direction === 'rtl' : false; 40 | } 41 | 42 | /** 43 | * Determines whether the direction is vertical. 44 | * @return bool 45 | */ 46 | public function isVertical() 47 | { 48 | return ! empty($this->direction) ? $this->direction === 'vrt' : false; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/Reading.php: -------------------------------------------------------------------------------- 1 | belongsTo(Manga::class); 19 | } 20 | 21 | /** 22 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 23 | */ 24 | public function user() 25 | { 26 | return $this->belongsTo(User::class); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/RolePermission.php: -------------------------------------------------------------------------------- 1 | belongsTo(Role::class); 18 | } 19 | 20 | /** 21 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 22 | */ 23 | public function permission() 24 | { 25 | return $this->belongsTo(Permission::class); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/UserPermission.php: -------------------------------------------------------------------------------- 1 | belongsTo(User::class); 17 | } 18 | 19 | /** 20 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 21 | */ 22 | public function permission() 23 | { 24 | return $this->belongsTo(Permission::class); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/UserRole.php: -------------------------------------------------------------------------------- 1 | belongsTo(User::class); 15 | } 16 | 17 | /** 18 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 19 | */ 20 | public function role() 21 | { 22 | return $this->belongsTo(Role::class); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Vote.php: -------------------------------------------------------------------------------- 1 | belongsTo(\App\User::class); 18 | } 19 | 20 | public function manga() 21 | { 22 | return $this->belongsTo(\App\Manga::class); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/WatchReference.php: -------------------------------------------------------------------------------- 1 | belongsTo(User::class); 17 | } 18 | 19 | public function manga() 20 | { 21 | return $this->belongsTo(Manga::class); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /bootstrap/autoload.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | ], 21 | 22 | 'ses' => [ 23 | 'key' => env('SES_KEY'), 24 | 'secret' => env('SES_SECRET'), 25 | 'region' => 'us-east-1', 26 | ], 27 | 28 | 'sparkpost' => [ 29 | 'secret' => env('SPARKPOST_SECRET'), 30 | ], 31 | 32 | 'stripe' => [ 33 | 'model' => App\User::class, 34 | 'key' => env('STRIPE_KEY'), 35 | 'secret' => env('STRIPE_SECRET'), 36 | ], 37 | 38 | ]; 39 | -------------------------------------------------------------------------------- /config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => realpath(storage_path('framework/views')), 32 | 33 | ]; 34 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | -------------------------------------------------------------------------------- /database/factories/ArchiveFactory.php: -------------------------------------------------------------------------------- 1 | define(App\Archive::class, function (Faker $faker) { 6 | return [ 7 | 'name' => $faker->bothify('**********') . $faker->randomElement(['.zip', '.cbz', '.rar', '.cbr']), 8 | 'size' => $faker->numberBetween(1024 * 30, 1024 * 300) 9 | ]; 10 | }); 11 | -------------------------------------------------------------------------------- /database/factories/CommentFactory.php: -------------------------------------------------------------------------------- 1 | define(Comment::class, function (Faker $faker) { 9 | return [ 10 | 'text' => $faker->text(10), 11 | 'user_id' => factory(App\User::class)->create(), 12 | 'manga_id' => factory(App\Manga::class)->create([ 13 | 'library_id' => factory(App\Library::class)->create() 14 | ]) 15 | ]; 16 | }); 17 | -------------------------------------------------------------------------------- /database/factories/FavoriteFactory.php: -------------------------------------------------------------------------------- 1 | define(App\Favorite::class, function (Faker $faker) { 6 | return [ 7 | 'user_id' => factory(App\User::class)->create()->getId(), 8 | 'manga_id' => factory(App\Manga::class)->create([ 9 | 'library_id' => factory(App\Library::class)->create()->getId() 10 | ])->getId() 11 | ]; 12 | }); 13 | -------------------------------------------------------------------------------- /database/factories/LibraryFactory.php: -------------------------------------------------------------------------------- 1 | define(App\Library::class, function (Faker $faker) { 6 | return [ 7 | 'name' => $faker->word, 8 | 'path' => $faker->sentence(10, true) . DIRECTORY_SEPARATOR . $faker->sentence(10, true) 9 | ]; 10 | }); 11 | -------------------------------------------------------------------------------- /database/factories/MangaFactory.php: -------------------------------------------------------------------------------- 1 | define(App\Manga::class, function (Faker $faker) { 6 | $name = $faker->sentence(5, true); 7 | 8 | return [ 9 | 'name' => $name, 10 | 'path' => $faker->sentence(5, true) . DIRECTORY_SEPARATOR . $name 11 | ]; 12 | }); 13 | -------------------------------------------------------------------------------- /database/factories/ModelFactory.php: -------------------------------------------------------------------------------- 1 | define(App\User::class, function (Faker\Generator $faker) { 18 | static $password; 19 | 20 | return [ 21 | 'name' => $faker->name, 22 | 'email' => $faker->unique()->safeEmail, 23 | 'password' => $password ?: $password = bcrypt('secret'), 24 | 'remember_token' => Str::random(10), 25 | ]; 26 | }); 27 | 28 | $factory->state(App\User::class, 'admin', [ 29 | 'admin' => true 30 | ]); 31 | 32 | $factory->state(App\User::class, 'maintainer', [ 33 | 'maintainer' => true 34 | ]); 35 | -------------------------------------------------------------------------------- /database/factories/PersonFactory.php: -------------------------------------------------------------------------------- 1 | define(Person::class, function (Faker $faker) { 9 | return [ 10 | 'name' => $faker->name() 11 | ]; 12 | }); 13 | -------------------------------------------------------------------------------- /database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | define(User::class, function (Faker $faker) { 9 | return [ 10 | 'name' => $faker->name, 11 | 'password' => $faker->password, 12 | 'email' => $faker->email 13 | ]; 14 | }); 15 | -------------------------------------------------------------------------------- /database/factories/VoteFactory.php: -------------------------------------------------------------------------------- 1 | define(Vote::class, function (Faker $faker) { 11 | return [ 12 | 'user_id' => factory(User::class)->create(), 13 | 'manga_id' => factory(Manga::class)->create([ 14 | 'library_id' => factory(Library::class)->create() 15 | ]), 16 | 17 | 'rating' => 70 18 | ]; 19 | }); 20 | -------------------------------------------------------------------------------- /database/factories/WatchReferenceFactory.php: -------------------------------------------------------------------------------- 1 | define(App\WatchReference::class, function (Faker $faker) { 6 | return [ 7 | 'user_id' => factory(App\User::class)->create()->getId(), 8 | 'manga_id' => factory(App\Manga::class)->create([ 9 | 'library_id' => factory(App\Library::class)->create() 10 | ])->getId() 11 | ]; 12 | }); 13 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->string('name'); 20 | $table->string('email')->unique(); 21 | $table->string('password'); 22 | $table->boolean('admin'); 23 | 24 | $table->rememberToken(); 25 | $table->timestamps(); 26 | }); 27 | } 28 | 29 | /** 30 | * Reverse the migrations. 31 | * 32 | * @return void 33 | */ 34 | public function down() 35 | { 36 | Schema::dropIfExists('users'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 18 | $table->string('token'); 19 | $table->timestamp('created_at')->nullable(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('password_resets'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2017_03_20_200100_create_genres_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->text('name'); 20 | $table->text('description'); 21 | 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('genres'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2017_03_20_200200_create_libraries_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->string('name'); 20 | $table->text('path'); 21 | 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('libraries'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2017_03_20_200300_create_manga_table.php: -------------------------------------------------------------------------------- 1 | engine = 'InnoDB'; // required? :thinking: 18 | $table->increments('id'); 19 | 20 | $table->unsignedInteger('library_id')->references('id')->on('libraries'); 21 | 22 | $table->text('name'); 23 | $table->text('path'); 24 | 25 | $table->timestamps(); 26 | }); 27 | 28 | DB::statement('CREATE FULLTEXT INDEX name_index ON manga(name);'); 29 | } 30 | 31 | /** 32 | * Reverse the migrations. 33 | * 34 | * @return void 35 | */ 36 | public function down() 37 | { 38 | Schema::table('manga', function($table) { 39 | $table->dropIndex('name_index'); 40 | }); 41 | 42 | Schema::dropIfExists('manga'); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /database/migrations/2017_03_20_200400_create_genre_information_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('manga_id')->references('id')->on('manga'); 18 | $table->unsignedInteger('genre_id')->references('id')->on('genres'); 19 | 20 | $table->timestamps(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::dropIfExists('genre_information'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2017_03_20_200500_create_manga_information_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('id')->references('id')->on('manga'); 18 | $table->primary('id'); 19 | 20 | // nullable in case user decides not to use mangaupdates 21 | $table->unsignedInteger('mu_id')->nullable(); 22 | $table->text('name')->nullable(); 23 | $table->text('description')->nullable(); 24 | $table->string('type', 20)->nullable(); 25 | $table->string('year', 4)->nullable(); 26 | 27 | $table->timestamps(); 28 | }); 29 | 30 | // Schema::table('manga_information', function (Blueprint $table) { 31 | 32 | // }); 33 | } 34 | 35 | /** 36 | * Reverse the migrations. 37 | * 38 | * @return void 39 | */ 40 | public function down() 41 | { 42 | Schema::dropIfExists('manga_information'); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /database/migrations/2017_04_15_214048_create_artists_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->text('name'); 20 | $table->unsignedInteger('mu_id')->nullable(); 21 | 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('artists'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2017_04_15_214452_create_authors_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->text('name'); 20 | $table->unsignedInteger('mu_id')->nullable(); 21 | 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('authors'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2017_04_15_215648_create_artist_references_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('manga_id')->references('id')->on('manga'); 18 | $table->unsignedInteger('artist_id')->references('id')->on('artists'); 19 | 20 | $table->timestamps(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::dropIfExists('artist_references'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2017_04_15_215744_create_author_references_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('manga_id')->references('id')->on('manga'); 18 | $table->unsignedInteger('author_id')->references('id')->on('authors'); 19 | 20 | $table->timestamps(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::dropIfExists('author_references'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2017_04_16_043051_create_associated_names_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->text('name'); 20 | 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | * 28 | * @return void 29 | */ 30 | public function down() 31 | { 32 | Schema::dropIfExists('associated_names'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /database/migrations/2017_04_16_043150_create_associated_name_references_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('manga_id')->references('id')->on('manga'); 19 | $table->unsignedInteger('assoc_name_id')->references('id')->on('associated_names'); 20 | 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | * 28 | * @return void 29 | */ 30 | public function down() 31 | { 32 | // 33 | Schema::dropIfExists('associated_name_references'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2017_04_16_215053_create_library_privileges_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('user_id')->references('id')->on('users'); 18 | $table->unsignedInteger('library_id')->references('id')->on('libraries'); 19 | 20 | $table->timestamps(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::dropIfExists('library_privileges'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2017_08_31_204003_add_theme_to_user_table.php: -------------------------------------------------------------------------------- 1 | string('theme')->default('bootswatch/slate'); 20 | }); 21 | 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | // remove theme column from users table 32 | Schema::table('users', function ($table) { 33 | 34 | $table->dropColumn('theme'); 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /database/migrations/2017_09_15_181401_add_maintainer_to_users_table.php: -------------------------------------------------------------------------------- 1 | boolean('admin')->default(false)->change(); 19 | $table->boolean('maintainer')->default(false); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::table('users', function (Blueprint $table) { 31 | $table->boolean('admin')->change(); 32 | $table->dropColumn('maintainer'); 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2017_10_17_195256_create_favorites_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('user_id')->references('id')->on('users'); 18 | $table->unsignedInteger('manga_id')->references('id')->on('manga'); 19 | 20 | $table->timestamps(); 21 | }); 22 | } 23 | 24 | /** 25 | * Reverse the migrations. 26 | * 27 | * @return void 28 | */ 29 | public function down() 30 | { 31 | Schema::dropIfExists('favorites'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2017_11_22_204609_rename_genre_information_to_genre_references.php: -------------------------------------------------------------------------------- 1 | boolean('ignore_on_scan')->default(false); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('manga', function (Blueprint $table) { 29 | $table->dropColumn('ignore_on_scan'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2018_04_27_021829_add_mu_name_distance_to_manga_table.php: -------------------------------------------------------------------------------- 1 | text('mu_name')->nullable(); 18 | $table->float('distance')->nullable(); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('manga', function (Blueprint $table) { 30 | $table->dropColumn('mu_name'); 31 | $table->dropColumn('distance'); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /database/migrations/2018_04_29_162515_create_reader_histories_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->unsignedInteger('user_id')->references('id')->on('users'); 20 | $table->unsignedInteger('manga_id')->references('id')->on('manga'); 21 | $table->text('archive_name')->required(); 22 | $table->unsignedInteger('page')->required(); 23 | $table->unsignedInteger('page_count')->required(); 24 | 25 | $table->timestamps(); 26 | }); 27 | } 28 | 29 | /** 30 | * Reverse the migrations. 31 | * 32 | * @return void 33 | */ 34 | public function down() 35 | { 36 | Schema::dropIfExists('reader_histories'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /database/migrations/2018_04_30_032109_add_read_direction_to_users_table.php: -------------------------------------------------------------------------------- 1 | boolean('ltr')->default(true); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('users', function (Blueprint $table) { 29 | $table->dropColumn('ltr'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2018_05_02_200608_add_full_text_index_to_associated_names_table.php: -------------------------------------------------------------------------------- 1 | dropIndex('assoc_name_index'); 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /database/migrations/2018_05_15_132544_create_archives_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->unsignedInteger('manga_id')->references('id')->on('manga'); 20 | 21 | $table->text('name'); 22 | $table->unsignedInteger('size')->required(); 23 | 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('archives'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /database/migrations/2018_05_15_182623_create_watch_references_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->unsignedInteger('user_id')->references('id')->on('users'); 20 | $table->unsignedInteger('manga_id')->references('id')->on('manga'); 21 | 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('watch_references'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2018_05_15_231542_create_watch_notifications_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->unsignedInteger('user_id')->references('id')->on('users'); 20 | $table->unsignedInteger('manga_id')->references('id')->on('manga'); 21 | $table->unsignedInteger('archive_id')->references('id')->on('archives'); 22 | 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('watch_notifications'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /database/migrations/2018_06_24_194449_add_about_and_last_seen_to_users_table.php: -------------------------------------------------------------------------------- 1 | string('about', 1024)->nullable(); 18 | $table->timestamp('last_seen')->nullable(); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('users', function (Blueprint $table) { 30 | $table->dropColumn('about'); 31 | $table->dropColumn('last_seen'); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /database/migrations/2018_06_30_205045_add_default_cover_archive_id_to_manga.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('cover_archive_id')->default(0)->references('id')->on('archives'); 18 | $table->unsignedInteger('cover_archive_page')->default(1); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('manga', function (Blueprint $table) { 30 | $table->dropColumn('cover_archive_id'); 31 | $table->dropColumn('cover_archive_page'); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /database/migrations/2018_07_04_165153_create_comments_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->unsignedInteger('user_id')->references('id')->on('users'); 20 | $table->unsignedInteger('manga_id')->references('id')->on('manga'); 21 | $table->unsignedInteger('archive_id')->references('id')->on('archives')->nullable()->default(0); 22 | 23 | $table->string('text', 2048); 24 | 25 | $table->timestamps(); 26 | }); 27 | } 28 | 29 | /** 30 | * Reverse the migrations. 31 | * 32 | * @return void 33 | */ 34 | public function down() 35 | { 36 | Schema::dropIfExists('comments'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /database/migrations/2018_07_10_012039_create_votes_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->unsignedInteger('user_id')->references('id')->on('users'); 20 | $table->unsignedInteger('manga_id')->references('id')->on('manga'); 21 | 22 | $table->unsignedSmallInteger('rating'); 23 | 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('votes'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /database/migrations/2018_07_16_190308_add_id_to_artist_references_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('artist_references', function (Blueprint $table) { 29 | $table->dropColumn('id'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2018_07_16_190639_add_id_to_author_references_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('author_references', function (Blueprint $table) { 29 | $table->dropColumn('id'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2018_07_16_190751_add_id_to_associated_name_references_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('associated_name_references', function (Blueprint $table) { 29 | $table->dropColumn('id'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2018_07_18_023228_create_archive_views_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->unsignedInteger('user_id')->references('id')->on('users'); 20 | $table->unsignedInteger('archive_id')->references('id')->on('archives'); 21 | 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('archive_views'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2018_07_18_023438_create_manga_views_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->unsignedInteger('user_id')->references('id')->on('users'); 20 | $table->unsignedInteger('manga_id')->references('id')->on('manga'); 21 | 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('manga_views'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2018_08_02_042159_add_id_to_favorites.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('favorites', function (Blueprint $table) { 29 | $table->dropColumn('id'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2018_08_30_204408_drop_authors_and_artists_tables.php: -------------------------------------------------------------------------------- 1 | up(); 30 | 31 | $artistsMigration = new CreateArtistsTable(); 32 | $artistsMigration->up(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /database/migrations/2018_09_17_011732_replace_l_t_r_with_reading_direction.php: -------------------------------------------------------------------------------- 1 | dropColumn('ltr'); 18 | $table->char('read_direction', 3)->default('ltr'); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('users', function (Blueprint $table) { 30 | $table->dropColumn('read_direction'); 31 | $table->boolean('ltr')->default(true); 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /database/migrations/2018_10_09_161613_create_jobs_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 18 | $table->string('queue')->index(); 19 | $table->longText('payload'); 20 | $table->unsignedTinyInteger('attempts'); 21 | $table->unsignedInteger('reserved_at')->nullable(); 22 | $table->unsignedInteger('available_at'); 23 | $table->unsignedInteger('created_at'); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('jobs'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /database/migrations/2018_11_26_035157_create_failed_jobs_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 18 | $table->text('connection'); 19 | $table->text('queue'); 20 | $table->longText('payload'); 21 | $table->longText('exception'); 22 | $table->timestamp('failed_at')->useCurrent(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('failed_jobs'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2018_12_13_041057_create_completed_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->unsignedInteger('user_id')->references('id')->on('users'); 20 | $table->unsignedInteger('manga_id')->references('id')->on('manga'); 21 | 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('completed'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2018_12_13_041102_create_dropped_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->unsignedInteger('user_id')->references('id')->on('users'); 20 | $table->unsignedInteger('manga_id')->references('id')->on('manga'); 21 | 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('dropped'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2018_12_13_041111_create_reading_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->unsignedInteger('user_id')->references('id')->on('users'); 20 | $table->unsignedInteger('manga_id')->references('id')->on('manga'); 21 | 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('reading'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2018_12_13_042636_create_on_hold_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->unsignedInteger('user_id')->references('id')->on('users'); 20 | $table->unsignedInteger('manga_id')->references('id')->on('manga'); 21 | 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('on_hold'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2018_12_13_042648_create_planned_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | 19 | $table->unsignedInteger('user_id')->references('id')->on('users'); 20 | $table->unsignedInteger('manga_id')->references('id')->on('manga'); 21 | 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('planned'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2019_10_24_012759_create_roles_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->text('name'); 19 | $table->timestamps(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('roles'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2019_10_24_012806_create_permissions_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->text('action'); 19 | 20 | /* Create two columns for a specific model, which is optional */ 21 | $table->nullableMorphs('model'); 22 | 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('permissions'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /database/migrations/2019_10_24_012814_create_user_roles_table.php: -------------------------------------------------------------------------------- 1 | primary(['user_id', 'role_id']); 18 | 19 | $table->unsignedInteger('user_id')->index(); 20 | $table->unsignedInteger('role_id')->index(); 21 | 22 | $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); 23 | $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade'); 24 | 25 | $table->timestamps(); 26 | }); 27 | } 28 | 29 | /** 30 | * Reverse the migrations. 31 | * 32 | * @return void 33 | */ 34 | public function down() 35 | { 36 | Schema::dropIfExists('user_roles'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /database/migrations/2019_10_24_013036_create_role_permissions_table.php: -------------------------------------------------------------------------------- 1 | primary(['role_id', 'permission_id']); 18 | 19 | $table->unsignedInteger('role_id')->index(); 20 | $table->unsignedInteger('permission_id')->index(); 21 | 22 | $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade'); 23 | $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade'); 24 | 25 | $table->timestamps(); 26 | }); 27 | } 28 | 29 | /** 30 | * Reverse the migrations. 31 | * 32 | * @return void 33 | */ 34 | public function down() 35 | { 36 | Schema::dropIfExists('role_permissions'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /database/migrations/2019_11_08_224501_create_user_permissions_table.php: -------------------------------------------------------------------------------- 1 | primary(['user_id', 'permission_id']); 18 | 19 | $table->unsignedInteger('user_id')->index(); 20 | $table->unsignedInteger('permission_id')->index(); 21 | 22 | $table->foreign('user_id')->references('id')->on('roles')->onDelete('cascade'); 23 | $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade'); 24 | 25 | $table->timestamps(); 26 | }); 27 | } 28 | 29 | /** 30 | * Reverse the migrations. 31 | * 32 | * @return void 33 | */ 34 | public function down() 35 | { 36 | Schema::dropIfExists('user_permissions'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /database/migrations/2020_02_27_035107_drop_library_privileges_table.php: -------------------------------------------------------------------------------- 1 | unsignedInteger('user_id')->references('id')->on('users'); 28 | $table->unsignedInteger('library_id')->references('id')->on('libraries'); 29 | 30 | $table->timestamps(); 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /database/migrations/2020_03_16_181806_add_display_to_users_table.php: -------------------------------------------------------------------------------- 1 | string('display', 20)->default('grid'); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('users', function (Blueprint $table) { 29 | $table->dropColumn('display'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2020_05_20_230704_create_notifications_table.php: -------------------------------------------------------------------------------- 1 | uuid('id')->primary(); 18 | $table->string('type'); 19 | $table->morphs('notifiable'); 20 | $table->text('data'); 21 | $table->timestamp('read_at')->nullable(); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('notifications'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(UsersTableSeeder::class); 15 | $this->call(GenresTableSeeder::class); 16 | $this->call(PermissionsTableSeeder::class); 17 | $this->call(RolesTableSeeder::class); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /database/seeds/UsersTableSeeder.php: -------------------------------------------------------------------------------- 1 | 0) { 17 | $this->command->getOutput()->writeln('Users table is not empty, skipping...'); 18 | 19 | return; 20 | } 21 | 22 | /** @var User $dev */ 23 | $dev = User::create([ 24 | 'name' => 'dev', 25 | 'email' => 'fake@email.com', 26 | 'password' => Hash::make('dev'), 27 | ]); 28 | 29 | $dev->grantRole('Administrator'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Handle Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /public/assets/mu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/assets/mu.png -------------------------------------------------------------------------------- /public/favicon/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/favicon/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/favicon/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/favicon/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /public/favicon/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #3d3f4c 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /public/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/favicon/favicon.ico -------------------------------------------------------------------------------- /public/favicon/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/favicon/mstile-144x144.png -------------------------------------------------------------------------------- /public/favicon/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/favicon/mstile-150x150.png -------------------------------------------------------------------------------- /public/favicon/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/favicon/mstile-310x150.png -------------------------------------------------------------------------------- /public/favicon/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/favicon/mstile-310x310.png -------------------------------------------------------------------------------- /public/favicon/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/favicon/mstile-70x70.png -------------------------------------------------------------------------------- /public/favicon/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /public/favicon/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Mangapie", 3 | "short_name": "Mangapie", 4 | "icons": [ 5 | { 6 | "src": "/public/favicon/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/public/favicon/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /public/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.eot -------------------------------------------------------------------------------- /public/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.ttf -------------------------------------------------------------------------------- /public/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.woff -------------------------------------------------------------------------------- /public/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.woff2 -------------------------------------------------------------------------------- /public/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.eot -------------------------------------------------------------------------------- /public/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.ttf -------------------------------------------------------------------------------- /public/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.woff -------------------------------------------------------------------------------- /public/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.woff2 -------------------------------------------------------------------------------- /public/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.eot -------------------------------------------------------------------------------- /public/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.ttf -------------------------------------------------------------------------------- /public/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.woff -------------------------------------------------------------------------------- /public/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/public/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.woff2 -------------------------------------------------------------------------------- /public/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/assets/mangapie.js": "/assets/mangapie.js", 3 | "/assets/mangapie.css": "/assets/mangapie.css" 4 | } 5 | -------------------------------------------------------------------------------- /resources/assets/js/app.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * First we will load all of this project's JavaScript dependencies which 4 | * includes Vue and other libraries. It is a great starting point when 5 | * building robust, powerful web applications using Vue and Laravel. 6 | */ 7 | 8 | require('./bootstrap'); 9 | 10 | /** 11 | * Next, we will create a fresh Vue application instance and attach it to 12 | * the page. Then, you may begin adding components to this application 13 | * or customize the JavaScript scaffolding to fit your unique needs. 14 | */ 15 | 16 | // Vue.component('example', require('./components/Example.vue')); 17 | // 18 | // const app = new Vue({ 19 | // el: '#app' 20 | // }); 21 | -------------------------------------------------------------------------------- /resources/assets/js/components/Example.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | -------------------------------------------------------------------------------- /resources/assets/sass/_addon.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Add Notifcation block 3 | */ 4 | .badge-notify { 5 | position: absolute; 6 | top: 5px; 7 | font-size: 50%; 8 | margin-left: 3px; 9 | } -------------------------------------------------------------------------------- /resources/assets/sass/_admin.libraries.scss: -------------------------------------------------------------------------------- 1 | td.library-path-wrap { 2 | word-wrap: break-word; 3 | 4 | @include media-breakpoint-down(lg) { 5 | max-width: 10em; 6 | } 7 | 8 | @include media-breakpoint-up(lg) { 9 | max-width: 25em; 10 | } 11 | } 12 | 13 | .progress-bar.job-progress-bar { 14 | 15 | @for $i from 0 through 100 { 16 | &[data-job-progress="#{$i}"] { 17 | width: 0% + $i; 18 | } 19 | } 20 | 21 | &[data-job-ended="0"] { 22 | 23 | &[data-job-status="executing"] { 24 | @extend .bg-primary; 25 | } 26 | 27 | &[data-job-status="queued"] { 28 | @extend .bg-warning; 29 | } 30 | } 31 | 32 | &[data-job-ended="1"] { 33 | 34 | &[data-job-status="failed"] { 35 | @extend .bg-danger; 36 | } 37 | 38 | &[data-job-status="finished"] { 39 | @extend .bg-success; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /resources/assets/sass/_files.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Toggle the checkmark colors next to the archive names depending on their read state. 3 | */ 4 | .toggle-archive-read { 5 | &[data-status="Incomplete"] { 6 | @extend .text-warning 7 | } 8 | 9 | &[data-status="Incomplete"]:hover { 10 | @extend .text-success 11 | } 12 | 13 | &[data-status="Complete"] { 14 | @extend .text-success 15 | } 16 | 17 | &[data-status="Complete"]:hover { 18 | @extend .text-danger 19 | } 20 | 21 | &[data-status="Unread"] { 22 | @extend .text-muted 23 | } 24 | 25 | &[data-status="Unread"]:hover { 26 | @extend .text-success 27 | } 28 | } -------------------------------------------------------------------------------- /resources/assets/sass/_manga.scss: -------------------------------------------------------------------------------- 1 | //.card > .card-body .card-overlay-bottom { 2 | // position: relative; 3 | // top: -4em; 4 | // height: 4em; 5 | // margin-bottom: -4em; 6 | // background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAC4jAAAuIwF4pT92AAAADUlEQVQI12NgYGDYDwAAxADAwDGXeQAAAABJRU5ErkJggg=='); 7 | //} 8 | -------------------------------------------------------------------------------- /resources/assets/sass/_notifications.scss: -------------------------------------------------------------------------------- 1 | .custom-image-checkbox { 2 | input[type="checkbox"] { 3 | display: none; 4 | 5 | & + label { 6 | box-shadow: 0 0 0 4px $input-border-color; 7 | -moz-box-shadow: 0 0 0 4px $input-border-color; 8 | -webkit-box-shadow: 0 0 0 4px $input-border-color; 9 | 10 | & > span { 11 | display: none; 12 | } 13 | } 14 | 15 | &:checked + label { 16 | box-shadow: 0 0 0 4px $primary; 17 | -moz-box-shadow: 0 0 0 4px $primary; 18 | -webkit-box-shadow: 0 0 0 4px $primary; 19 | 20 | & > img { 21 | filter: brightness(50%); 22 | } 23 | 24 | & > span { 25 | display: block; 26 | transform: translate(0, -92px); 27 | height: 0; 28 | 29 | font-size: 3.3em; 30 | color: $white; 31 | text-shadow: 1px 1px; 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /resources/assets/sass/_previews.scss: -------------------------------------------------------------------------------- 1 | /* page indicator tag on the previews */ 2 | .page-indicator-left { 3 | width: 33%; 4 | position: absolute; 5 | font-size: 1.25em; 6 | 7 | border-top-left-radius: $card-inner-border-radius; 8 | border-bottom-right-radius: calc(0.5em - 1px); 9 | } 10 | 11 | /* floating action bar */ 12 | .fab { 13 | position: fixed; 14 | 15 | /* only support 4 buttons for now - shouldn't need more, right? */ 16 | @for $i from 1 through 4 { 17 | &.fab-#{$i} { 18 | /* separate the buttons on the y axis */ 19 | bottom: calc(1.25em + (#{$i - 1}em * 2.5)); 20 | 21 | /* the buttons should line up on the x axis the same */ 22 | right: 2em; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /resources/assets/sass/_reader.scss: -------------------------------------------------------------------------------- 1 | .favorite-toggler[data-favorited="no"] { 2 | 3 | &:hover { 4 | @include button-variant($success, $success); 5 | } 6 | } 7 | 8 | .favorite-toggler[data-favorited="yes"] { 9 | & { 10 | @include button-variant($success, $success); 11 | @include border-radius() 12 | } 13 | 14 | &:hover { 15 | & > span.fa-heart::before { 16 | content: fa-content($fa-var-times); 17 | } 18 | 19 | @include button-variant($danger, $danger); 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /resources/assets/sass/_shapes.scss: -------------------------------------------------------------------------------- 1 | $triangle-sizes: ( 2 | xs: 8px, 3 | sm: 16px 4 | ); 5 | 6 | @mixin triangle-variant-base() { 7 | width: 0; 8 | height: 0; 9 | 10 | border-style: solid; 11 | } 12 | 13 | @mixin triangle-variant-down($size) { 14 | @include triangle-variant-base(); 15 | 16 | border-width: map_get($triangle-sizes, $size) map_get($triangle-sizes, $size) 0 map_get($triangle-sizes, $size); 17 | } 18 | 19 | @mixin triangle-border-color($color-top, $color-right, $color-bottom, $color-left) { 20 | border-color: $color-top $color-right $color-bottom $color-left !important; 21 | } 22 | 23 | // TODO: Use voodoo magic to create rules for all directions, sizes, and colors 24 | 25 | .triangle-sm-down.triangle-primary { 26 | @include triangle-variant-down(sm); 27 | @include triangle-border-color($primary, transparent, transparent, transparent); 28 | } 29 | 30 | .triangle-sm-down.triangle-secondary { 31 | @include triangle-variant-down(sm); 32 | @include triangle-border-color($secondary, transparent, transparent, transparent); 33 | } 34 | 35 | .triangle-sm-down.triangle-light { 36 | @include triangle-variant-down(sm); 37 | @include triangle-border-color($light, transparent, transparent, transparent); 38 | } 39 | 40 | .triangle-sm-down.triangle-dark { 41 | @include triangle-variant-down(sm); 42 | @include triangle-border-color($dark, transparent, transparent, transparent); 43 | } 44 | -------------------------------------------------------------------------------- /resources/assets/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | $fa-font-path: "fonts/"; 2 | 3 | // Lazy dark theme. 4 | 5 | $white: #fff; 6 | $gray-100: #f8f9fa; 7 | $gray-200: #e9ecef; 8 | $gray-300: #dee2e6; 9 | $gray-400: #ced4da; 10 | $gray-500: #adb5bd; 11 | $gray-600: #6c757d; 12 | $gray-700: #495057; 13 | $gray-800: #343a40; 14 | $gray-900: #212529; 15 | 16 | $dark: #343641; 17 | $primary: #50b8d2; 18 | 19 | $body-bg: #3d3f4c; 20 | $body-color: $gray-500;//#a1a7b3; 21 | 22 | $border-color: lighten($dark, 10%); 23 | 24 | $card-bg: $body-bg; 25 | $card-cap-bg: lighten($dark, 8%); 26 | 27 | $dropdown-bg: $dark; 28 | $dropdown-link-color: $gray-500; 29 | 30 | $input-bg: $dark; 31 | $input-color: $gray-500; 32 | $input-group-addon-color: $gray-900; 33 | $input-border-color: $border-color; 34 | 35 | $input-group-addon-bg: $gray-400; 36 | $input-group-addon-border-color: $gray-400; 37 | 38 | $list-group-bg: $dark; 39 | 40 | $table-border-color: $border-color; 41 | 42 | $pagination-bg: lighten($dark, 8%); 43 | $pagination-border-color: $dark; 44 | $pagination-active-bg: $primary; 45 | $pagination-active-border-color: $dark; 46 | $pagination-disabled-border-color: $dark; 47 | $pagination-disabled-bg: $gray-400; 48 | $pagination-hover-border-color: $dark; 49 | -------------------------------------------------------------------------------- /resources/assets/sass/app.scss: -------------------------------------------------------------------------------- 1 | // Fonts 2 | //@import "~@fortawesome/fontawesome-free/scss/brands"; 3 | @import "~@fortawesome/fontawesome-free/scss/fontawesome"; 4 | @import "~@fortawesome/fontawesome-free/scss/regular"; 5 | @import "~@fortawesome/fontawesome-free/scss/solid"; 6 | @import "~@fortawesome/fontawesome-free/scss/v4-shims"; 7 | 8 | span.fa::before { 9 | font-weight: 900; 10 | } 11 | 12 | .w-33 { 13 | width: 33% !important; 14 | } 15 | 16 | .w-66 { 17 | width: 66% !important; 18 | } 19 | 20 | textarea { 21 | max-width: 100%; 22 | max-height: 100%; 23 | } 24 | 25 | .dropdown-menu > .dropdown-header { 26 | font-size: inherit; 27 | } 28 | 29 | .dropdown-menu > .dropdown-header > li.disabled { 30 | cursor: text; 31 | } 32 | 33 | .dropdown-menu > .dropdown-header > li.disabled > a { 34 | pointer-events: none; 35 | } 36 | 37 | // Variables 38 | @import "variables"; 39 | 40 | // Bootstrap 41 | @import "~bootstrap/scss/bootstrap"; 42 | 43 | // make container behave as container-fluid for xs and sm 44 | .container { 45 | @include media-breakpoint-down(sm) { 46 | max-width: 100%; 47 | } 48 | } 49 | 50 | // Mangapie 51 | @import "admin.libraries"; 52 | @import "files"; 53 | @import "manga"; 54 | @import "manga.edit"; 55 | @import "notifications"; 56 | @import "reader"; 57 | @import "previews"; 58 | @import "shapes"; 59 | @import "addon"; 60 | 61 | // jquery-bar-rating 62 | @import "jquery-bar-rating/fontawesome-stars"; 63 | -------------------------------------------------------------------------------- /resources/assets/sass/jquery-bar-rating/_fontawesome-stars.scss: -------------------------------------------------------------------------------- 1 | .br-theme-fontawesome-stars-o .br-widget { 2 | height: 28px; 3 | white-space: nowrap; 4 | } 5 | .br-theme-fontawesome-stars-o .br-widget a { 6 | font: normal normal normal 13px/1 'Font Awesome 5 Free'; 7 | font-weight: 500; 8 | text-rendering: auto; 9 | -webkit-font-smoothing: antialiased; 10 | text-decoration: none; 11 | color: #FFB600; 12 | margin-right: 4px; 13 | } 14 | .br-theme-fontawesome-stars-o .br-widget a:after { 15 | font-family: "Font Awesome 5 Free"; 16 | font-weight: 900; 17 | content: '\f005'; 18 | color: #d2d2d2; 19 | } 20 | .br-theme-fontawesome-stars-o .br-widget a.br-active:after { 21 | font-family: 'Font Awesome 5 Free'; 22 | font-weight: 900; 23 | content: '\f005'; 24 | color: #FFB600; 25 | } 26 | .br-theme-fontawesome-stars-o .br-widget a.br-selected:after { 27 | font-family: 'Font Awesome 5 Free'; 28 | font-weight: 900; 29 | content: '\f005'; 30 | color: #FFB600; 31 | } 32 | .br-theme-fontawesome-stars-o .br-widget .br-current-rating { 33 | display: none; 34 | } 35 | .br-theme-fontawesome-stars-o .br-readonly a { 36 | cursor: default; 37 | } 38 | 39 | .br-theme-fontawesome-stars-o .br-widget a.br-fractional:after { 40 | font-weight:900; 41 | content: '\f089'; 42 | color: #FFB600; 43 | } 44 | -------------------------------------------------------------------------------- /resources/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Passwords must be at least six characters and match the confirmation.', 17 | 'reset' => 'Your password has been reset!', 18 | 'sent' => 'We have e-mailed your password reset link!', 19 | 'token' => 'This password reset token is invalid.', 20 | 'user' => "We can't find a user with that e-mail address.", 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /resources/views/admin/index.blade.php: -------------------------------------------------------------------------------- 1 | @include ('admin.statistics') 2 | -------------------------------------------------------------------------------- /resources/views/admin/layout.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('content') 4 |
5 | @include ('shared.success') 6 | @include ('shared.warnings') 7 | @include ('shared.errors') 8 | 9 | @yield ('top-menu') 10 | @yield ('card-content') 11 |
12 | @endsection 13 | -------------------------------------------------------------------------------- /resources/views/edit/manga/index.blade.php: -------------------------------------------------------------------------------- 1 | @include ('edit.manga.mangaupdates') -------------------------------------------------------------------------------- /resources/views/edit/manga/layout.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('title') 4 | Edit · {{ $manga->name }} 5 | @endsection 6 | 7 | @section ('custom_navbar_right') 8 | @endsection 9 | 10 | @section ('content') 11 |
12 |
13 |

Edit · {{ $manga->name }}

14 |
15 |
16 |

Edit · {{ $manga->name }}

17 |
18 | 19 | @include ('shared.success') 20 | @include ('shared.errors') 21 | 22 |
23 |
24 | @yield('side-top-menu') 25 |
26 |
27 | @yield('tab-content') 28 |
29 |
30 |
31 | @endsection -------------------------------------------------------------------------------- /resources/views/error/403.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('title') 4 | Access Denied 5 | @endsection 6 | 7 | @section ('content') 8 | 9 |
10 | You do not have enough privileges to access the page. 11 | Stop being naughty. 12 |
13 | 14 | @endsection -------------------------------------------------------------------------------- /resources/views/error/404.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('title') 4 | Not found 5 | @endsection 6 | 7 | @section ('content') 8 | 9 |
10 | The requested page could not be found. :( 11 |
12 | 13 | @endsection -------------------------------------------------------------------------------- /resources/views/favorites/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('title') 4 | Favorites :: Mangapie 5 | @endsection 6 | 7 | @section ('custom_navbar_right') 8 | @endsection 9 | 10 | @section ('content') 11 |
12 | @include ('shared.errors') 13 | @include ('shared.index') 14 |
15 | @endsection 16 | -------------------------------------------------------------------------------- /resources/views/home/advancedsearch.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('title') 4 | {{ $header }} :: Mangapie 5 | @endsection 6 | 7 | @section ('content') 8 |
9 | @include ('shared.errors') 10 | @include ('shared.index') 11 |
12 | @endsection 13 | -------------------------------------------------------------------------------- /resources/views/home/artist.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('title') 4 | {{ $artist->getName() }} :: Mangapie 5 | @endsection 6 | 7 | @section ('custom_navbar_right') 8 | @endsection 9 | 10 | @section ('content') 11 |
12 | @include ('shared.errors') 13 | @include ('shared.index') 14 |
15 | @endsection 16 | -------------------------------------------------------------------------------- /resources/views/home/author.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('title') 4 | {{ $author->getName() }} :: Mangapie 5 | @endsection 6 | 7 | @section ('custom_navbar_right') 8 | @endsection 9 | 10 | @section ('content') 11 |
12 | @include ('shared.errors') 13 | @include ('shared.index') 14 |
15 | @endsection 16 | -------------------------------------------------------------------------------- /resources/views/home/genre.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('title') 4 | {{ $genre->getName() }} :: Mangapie 5 | @endsection 6 | 7 | @section ('custom_navbar_right') 8 | @endsection 9 | 10 | @section ('content') 11 |
12 | @include ('shared.errors') 13 | @include ('shared.index') 14 |
15 | @endsection 16 | -------------------------------------------------------------------------------- /resources/views/home/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('title') 4 | Home :: Mangapie 5 | @endsection 6 | 7 | @section ('custom_navbar_right') 8 | @endsection 9 | 10 | @section ('content') 11 |
12 | @include ('shared.success') 13 | @include ('shared.errors') 14 | @include ('shared.index') 15 |
16 | @endsection 17 | -------------------------------------------------------------------------------- /resources/views/home/person.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('title') 4 | {{ $person->name }} :: Mangapie 5 | @endsection 6 | 7 | @section ('custom_navbar_right') 8 | @endsection 9 | 10 | @section ('content') 11 |
12 | @include ('shared.errors') 13 | @include ('shared.index') 14 |
15 | @endsection 16 | -------------------------------------------------------------------------------- /resources/views/lists/layout.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('content') 4 |
5 | @include ('shared.errors') 6 | @include ('shared.success') 7 | 8 | @yield ('list-content') 9 |
10 | @endsection 11 | -------------------------------------------------------------------------------- /resources/views/manga/shared/information.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | @include ('manga.shared.information.genres') 4 |
5 | 6 |
7 | @include ('manga.shared.information.associated_names') 8 |
9 | 10 |
11 | @include ('manga.shared.information.authors') 12 |
13 | 14 |
15 | @include ('manga.shared.information.artists') 16 |
17 | 18 |
19 | @include ('manga.shared.information.ratings') 20 |
21 | 22 |
23 | @include ('manga.shared.information.actions') 24 |
25 | 26 | @admin 27 |
28 | @include ('manga.shared.information.path') 29 |
30 | @endadmin 31 | 32 |
33 | @include ('manga.shared.information.external') 34 |
35 |
36 | 37 |
38 |
39 | @include ('manga.shared.information.description') 40 |
41 |
42 | -------------------------------------------------------------------------------- /resources/views/manga/shared/information/artists.blade.php: -------------------------------------------------------------------------------- 1 |
2 | Artist(s) 3 | @if ($user->hasRole('Administrator') || $user->hasRole('Editor')) 4 | 5 | 6 | 7 | @endif 8 |
9 | 10 | @if (! empty($manga->artistReferences)) 11 |
12 | @foreach ($manga->artistReferences as $artistReference) 13 | @php 14 | $artist = $artistReference->artist; 15 | @endphp 16 |
17 | 18 | {{ $artist->name }} 19 | 20 |
21 | @endforeach 22 |
23 | @else 24 | Unable to find artists. 25 | @endif 26 | -------------------------------------------------------------------------------- /resources/views/manga/shared/information/authors.blade.php: -------------------------------------------------------------------------------- 1 |
2 | Author(s) 3 | @if ($user->hasRole('Administrator') || $user->hasRole('Editor')) 4 | 5 | 6 | 7 | @endif 8 |
9 | 10 | @if (! empty($manga->authorReferences)) 11 |
12 | @foreach ($manga->authorReferences as $authorReference) 13 | @php 14 | $author = $authorReference->author; 15 | @endphp 16 |
17 | 18 | {{ $author->name }} 19 | 20 |
21 | @endforeach 22 |
23 | @else 24 | Unable to find authors. 25 | @endif 26 | -------------------------------------------------------------------------------- /resources/views/manga/shared/information/description.blade.php: -------------------------------------------------------------------------------- 1 |
2 | Description 3 | @if ($user->hasRole('Administrator') || $user->hasRole('Editor')) 4 | 5 | 6 | 7 | @endif 8 |
9 | 10 | @if (! empty($manga->description)) 11 | {!! nl2br(e($manga->description)) !!} 12 | @else 13 | Unable to find description. 14 | @endif 15 | -------------------------------------------------------------------------------- /resources/views/manga/shared/information/external.blade.php: -------------------------------------------------------------------------------- 1 | @if (! empty($manga->mu_id)) 2 |
3 | External Links 4 |
5 | 6 |
7 |
8 | 9 | MangaUpdates 10 |
11 |
12 | @endif -------------------------------------------------------------------------------- /resources/views/manga/shared/information/genres.blade.php: -------------------------------------------------------------------------------- 1 |
2 | Genres 3 | @if ($user->hasRole('Administrator') || $user->hasRole('Editor')) 4 | 5 | 6 | 7 | @endif 8 |
9 | 10 | @if (! empty($manga->genreReferences)) 11 |
12 | @foreach ($manga->genreReferences as $genreReference) 13 | @php 14 | $genre = $genreReference->genre; 15 | @endphp 16 |
17 | 18 | {{ $genre->name }} 19 | 20 |
21 | @endforeach 22 |
23 | @else 24 | Unable to find genres. 25 | @endif 26 | -------------------------------------------------------------------------------- /resources/views/manga/shared/information/path.blade.php: -------------------------------------------------------------------------------- 1 |
Path
2 | 3 | {{ $manga->path }} 4 | -------------------------------------------------------------------------------- /resources/views/notifications/layout.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('meta') 4 | 5 | @endsection 6 | 7 | @section ('content') 8 | 9 | @yield ('notification-content') 10 | @endsection 11 | 12 | -------------------------------------------------------------------------------- /resources/views/settings/components/side-top-menu.blade.php: -------------------------------------------------------------------------------- 1 |
2 | @foreach ($items as $item) 3 | 6 | 7 | 8 |
9 |  {{ $item['title'] }} 10 |
11 |
12 | @endforeach 13 |
14 | -------------------------------------------------------------------------------- /resources/views/settings/index.blade.php: -------------------------------------------------------------------------------- 1 | @include ('settings.account') 2 | -------------------------------------------------------------------------------- /resources/views/settings/layout.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('layout') 2 | 3 | @section ('content') 4 |
5 |
6 |

Settings

7 |
8 | 9 | @include ('shared.success') 10 | @include ('shared.errors') 11 | 12 |
13 |
14 | @yield('tab-content') 15 |
16 |
17 |
18 | @endsection 19 | -------------------------------------------------------------------------------- /resources/views/shared/errors.blade.php: -------------------------------------------------------------------------------- 1 | @if ($errors->count() > 0) 2 |
3 | 8 |
9 | @endif -------------------------------------------------------------------------------- /resources/views/shared/notifications.blade.php: -------------------------------------------------------------------------------- 1 | {{--The ml-auto is important.--}} 2 | {{--If another button is to be placed before this one, then move the ml-auto to that one.--}} 3 | @auth 4 | 5 | 11 | 12 | @endauth -------------------------------------------------------------------------------- /resources/views/shared/searchbar.blade.php: -------------------------------------------------------------------------------- 1 | @auth 2 | {{ Form::open(['action' => 'SearchController@postBasic', 'class' => 'form-inline mb-0']) }} 3 | 4 |
5 |
6 | {{ Form::text('keywords', null, ['class' => 'form-control', 7 | 'placeholder' => 'Quick search', 8 | 'id' => $searchbarId, 9 | 'autocomplete' => 'off']) }} 10 | 11 |
12 | 15 |
16 |
17 |
18 | 19 | {{ Form::close() }} 20 | @endauth 21 | -------------------------------------------------------------------------------- /resources/views/shared/success.blade.php: -------------------------------------------------------------------------------- 1 | @if (session()->has('success')) 2 |
3 | 6 |   {{ \Session::get('success') }} 7 |
8 | @endif -------------------------------------------------------------------------------- /resources/views/shared/warnings.blade.php: -------------------------------------------------------------------------------- 1 | @if (session()->has('warnings.data')) 2 |
3 | 6 |   {{ \Session::get('warnings.message') }} 7 | 12 |
13 | @endif -------------------------------------------------------------------------------- /resources/views/user/index.blade.php: -------------------------------------------------------------------------------- 1 | @include ('user.activity') 2 | -------------------------------------------------------------------------------- /routes/api.php: -------------------------------------------------------------------------------- 1 | get('/user', function (Request $request) { 17 | // return $request->user(); 18 | //}); 19 | -------------------------------------------------------------------------------- /routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 16 | }); 17 | -------------------------------------------------------------------------------- /routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 18 | // })->describe('Display an inspiring quote'); 19 | -------------------------------------------------------------------------------- /screenshots/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/screenshots/index.png -------------------------------------------------------------------------------- /screenshots/information-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/screenshots/information-01.png -------------------------------------------------------------------------------- /screenshots/information-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/screenshots/information-02.png -------------------------------------------------------------------------------- /screenshots/reader-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/screenshots/reader-01.png -------------------------------------------------------------------------------- /screenshots/reader-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/screenshots/reader-02.png -------------------------------------------------------------------------------- /server.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | $uri = urldecode( 11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 12 | ); 13 | 14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 15 | // built-in PHP web server. This provides a convenient way to test a Laravel 16 | // application without having installed a "real" web server software here. 17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { 18 | return false; 19 | } 20 | 21 | require_once __DIR__.'/public/index.php'; 22 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !avatars/ 3 | !covers/ 4 | !images/ 5 | !previews/ 6 | !.gitignore 7 | -------------------------------------------------------------------------------- /storage/app/public/avatars/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !default.jpg 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/app/public/avatars/default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/storage/app/public/avatars/default.jpg -------------------------------------------------------------------------------- /storage/app/public/covers/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !small/ 3 | !medium/ 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /storage/app/public/covers/medium/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !default.jpg 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/app/public/covers/medium/default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/storage/app/public/covers/medium/default.jpg -------------------------------------------------------------------------------- /storage/app/public/covers/small/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !default.jpg 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/app/public/covers/small/default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/storage/app/public/covers/small/default.jpg -------------------------------------------------------------------------------- /storage/app/public/images/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | -------------------------------------------------------------------------------- /storage/app/public/previews/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !small/ 3 | !medium/ 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /storage/app/public/previews/small/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/debugbar/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | config.php 2 | routes.php 3 | schedule-* 4 | compiled.php 5 | services.json 6 | events.scanned.php 7 | routes.scanned.php 8 | down 9 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Data/ImageArchive/rar/abc.cbr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/tests/Data/ImageArchive/rar/abc.cbr -------------------------------------------------------------------------------- /tests/Data/ImageArchive/rar/abc.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/tests/Data/ImageArchive/rar/abc.rar -------------------------------------------------------------------------------- /tests/Data/ImageArchive/zip/abc.cbz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/tests/Data/ImageArchive/zip/abc.cbz -------------------------------------------------------------------------------- /tests/Data/ImageArchive/zip/abc.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierobot/mangapie/d949a12eef7e20010e3661432936dfb9a8d9511a/tests/Data/ImageArchive/zip/abc.zip -------------------------------------------------------------------------------- /tests/Data/Libraries/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !manga1/ 3 | !manga2/ 4 | !manga3/ 5 | !manga4/ 6 | !manga5/ 7 | !manga6/ 8 | !.gitignore 9 | 10 | -------------------------------------------------------------------------------- /tests/Data/Libraries/manga1/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | -------------------------------------------------------------------------------- /tests/Data/Libraries/manga2/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | -------------------------------------------------------------------------------- /tests/Data/Libraries/manga3/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | -------------------------------------------------------------------------------- /tests/Data/Libraries/manga4/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !dest/ 3 | !src/ 4 | !.gitignore 5 | 6 | -------------------------------------------------------------------------------- /tests/Data/Libraries/manga4/dest/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | -------------------------------------------------------------------------------- /tests/Data/Libraries/manga4/src/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | -------------------------------------------------------------------------------- /tests/Data/Libraries/manga5/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !dest/ 3 | !src/ 4 | !.gitignore 5 | 6 | -------------------------------------------------------------------------------- /tests/Data/Libraries/manga5/dest/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | -------------------------------------------------------------------------------- /tests/Data/Libraries/manga5/src/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | -------------------------------------------------------------------------------- /tests/Data/Libraries/manga6/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | 4 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 |