├── postcss.config.js ├── src ├── test │ ├── resources │ │ ├── i18n │ │ │ └── messages_en.properties │ │ └── mails │ │ │ └── testEmail.html │ ├── javascript │ │ └── spec │ │ │ ├── helpers │ │ │ ├── mock-route.service.ts │ │ │ ├── mock-principal.service.ts │ │ │ ├── mock-language.service.ts │ │ │ └── mock-account.service.ts │ │ │ ├── entry.ts │ │ │ └── test.module.ts │ └── java │ │ └── com │ │ └── caosg │ │ └── ytbdl │ │ └── config │ │ └── WebConfigurerTestController.java └── main │ ├── resources │ ├── config │ │ └── liquibase │ │ │ ├── authorities.csv │ │ │ ├── users_authorities.csv │ │ │ ├── users.csv │ │ │ └── master.xml │ ├── .h2.server.properties │ ├── banner.txt │ ├── i18n │ │ ├── messages.properties │ │ ├── messages_en.properties │ │ └── messages_zh_cn.properties │ └── mails │ │ ├── creationEmail.html │ │ ├── passwordResetEmail.html │ │ └── activationEmail.html │ ├── webapp │ ├── app │ │ ├── shared │ │ │ ├── constants │ │ │ │ ├── pagination.constants.ts │ │ │ │ └── pagination.constants.js │ │ │ ├── model │ │ │ │ ├── base-entity.js │ │ │ │ ├── base-entity.ts │ │ │ │ ├── response-wrapper.model.ts │ │ │ │ ├── response-wrapper.model.js │ │ │ │ ├── request-util.js │ │ │ │ └── request-util.ts │ │ │ ├── user │ │ │ │ ├── account.model.ts │ │ │ │ ├── account.model.js │ │ │ │ ├── user.model.js │ │ │ │ ├── user.model.ts │ │ │ │ └── user.service.ts │ │ │ ├── auth │ │ │ │ ├── csrf.service.ts │ │ │ │ ├── account.service.ts │ │ │ │ ├── csrf.service.js │ │ │ │ ├── account.service.js │ │ │ │ ├── has-any-authority.directive.ts │ │ │ │ ├── state-storage.service.ts │ │ │ │ └── user-route-access-service.ts │ │ │ ├── language │ │ │ │ ├── language.constants.ts │ │ │ │ ├── language.constants.js │ │ │ │ └── find-language-from-key.pipe.ts │ │ │ ├── shared-common.module.ts │ │ │ ├── login │ │ │ │ ├── login-modal.service.ts │ │ │ │ ├── login.service.ts │ │ │ │ └── login-modal.service.js │ │ │ ├── alert │ │ │ │ ├── alert.component.ts │ │ │ │ └── alert.component.js │ │ │ ├── shared-libs.module.ts │ │ │ ├── index.ts │ │ │ ├── shared.module.ts │ │ │ ├── index.js │ │ │ └── shared-common.module.js │ │ ├── home │ │ │ ├── index.ts │ │ │ ├── home.route.ts │ │ │ ├── home.module.ts │ │ │ ├── home.scss │ │ │ └── home.component.ts │ │ ├── layouts │ │ │ ├── footer │ │ │ │ ├── footer.component.html │ │ │ │ └── footer.component.ts │ │ │ ├── profiles │ │ │ │ ├── profile-info.model.ts │ │ │ │ ├── page-ribbon.component.ts │ │ │ │ ├── profile.service.ts │ │ │ │ └── page-ribbon.scss │ │ │ ├── main │ │ │ │ ├── main.component.html │ │ │ │ └── main.component.ts │ │ │ ├── index.ts │ │ │ ├── layout-routing.module.ts │ │ │ ├── error │ │ │ │ ├── error.component.html │ │ │ │ ├── error.route.ts │ │ │ │ └── error.component.ts │ │ │ └── navbar │ │ │ │ ├── active-menu.directive.ts │ │ │ │ └── navbar.scss │ │ ├── polyfills.ts │ │ ├── admin │ │ │ ├── logs │ │ │ │ ├── log.model.ts │ │ │ │ ├── logs.route.ts │ │ │ │ ├── logs.service.ts │ │ │ │ ├── logs.component.ts │ │ │ │ └── logs.component.html │ │ │ ├── docs │ │ │ │ ├── docs.component.html │ │ │ │ ├── docs.component.ts │ │ │ │ └── docs.route.ts │ │ │ ├── audits │ │ │ │ ├── audit-data.model.ts │ │ │ │ ├── audit.model.ts │ │ │ │ ├── audits.route.ts │ │ │ │ └── audits.service.ts │ │ │ ├── health │ │ │ │ ├── health.route.ts │ │ │ │ ├── health-modal.component.ts │ │ │ │ ├── health.component.html │ │ │ │ └── health-modal.component.html │ │ │ ├── metrics │ │ │ │ ├── metrics.route.ts │ │ │ │ ├── metrics.service.ts │ │ │ │ └── metrics-modal.component.ts │ │ │ ├── configuration │ │ │ │ ├── configuration.route.ts │ │ │ │ ├── configuration.component.ts │ │ │ │ └── configuration.service.ts │ │ │ ├── admin.route.ts │ │ │ ├── user-management │ │ │ │ ├── user-management-detail.component.ts │ │ │ │ ├── user-management-delete-dialog.component.html │ │ │ │ ├── user-modal.service.ts │ │ │ │ └── user-management-delete-dialog.component.ts │ │ │ └── index.ts │ │ ├── vendor.ts │ │ ├── app.route.ts │ │ ├── blocks │ │ │ ├── config │ │ │ │ ├── prod.config.ts │ │ │ │ └── uib-pagination.config.ts │ │ │ └── interceptor │ │ │ │ ├── errorhandler.interceptor.ts │ │ │ │ ├── auth-expired.interceptor.ts │ │ │ │ ├── auth.interceptor.ts │ │ │ │ ├── http.provider.ts │ │ │ │ └── notification.interceptor.ts │ │ ├── account │ │ │ ├── register │ │ │ │ ├── register.service.ts │ │ │ │ └── register.route.ts │ │ │ ├── password │ │ │ │ ├── password.service.ts │ │ │ │ ├── password.route.ts │ │ │ │ ├── password-strength-bar.scss │ │ │ │ └── password.component.ts │ │ │ ├── password-reset │ │ │ │ ├── init │ │ │ │ │ ├── password-reset-init.service.ts │ │ │ │ │ ├── password-reset-init.route.ts │ │ │ │ │ └── password-reset-init.component.ts │ │ │ │ └── finish │ │ │ │ │ ├── password-reset-finish.service.ts │ │ │ │ │ └── password-reset-finish.route.ts │ │ │ ├── activate │ │ │ │ ├── activate.route.ts │ │ │ │ ├── activate.service.ts │ │ │ │ ├── activate.component.html │ │ │ │ └── activate.component.ts │ │ │ ├── settings │ │ │ │ └── settings.route.ts │ │ │ ├── account.route.ts │ │ │ ├── index.ts │ │ │ └── account.module.ts │ │ ├── entities │ │ │ ├── video │ │ │ │ ├── index.ts │ │ │ │ ├── video.model.ts │ │ │ │ ├── video-play.component.html │ │ │ │ ├── video-delete-dialog.component.html │ │ │ │ └── video.module.ts │ │ │ └── entity.module.ts │ │ ├── app.main-aot.ts │ │ ├── app.main.ts │ │ └── app.constants.ts │ ├── favicon.ico │ ├── content │ │ ├── images │ │ │ ├── hipster.png │ │ │ ├── hipster2x.png │ │ │ └── logo-jhipster.png │ │ └── scss │ │ │ └── vendor.scss │ ├── i18n │ │ ├── zh-cn │ │ │ ├── error.json │ │ │ ├── configuration.json │ │ │ ├── activate.json │ │ │ ├── logs.json │ │ │ ├── password.json │ │ │ ├── gateway.json │ │ │ ├── sessions.json │ │ │ ├── login.json │ │ │ ├── home.json │ │ │ ├── health.json │ │ │ ├── audits.json │ │ │ ├── register.json │ │ │ ├── reset.json │ │ │ ├── user-management.json │ │ │ ├── settings.json │ │ │ └── video.json │ │ └── en │ │ │ ├── error.json │ │ │ ├── configuration.json │ │ │ ├── logs.json │ │ │ ├── activate.json │ │ │ ├── password.json │ │ │ ├── gateway.json │ │ │ ├── sessions.json │ │ │ ├── login.json │ │ │ ├── home.json │ │ │ ├── health.json │ │ │ ├── audits.json │ │ │ ├── reset.json │ │ │ ├── register.json │ │ │ ├── user-management.json │ │ │ ├── video.json │ │ │ └── settings.json │ ├── swagger-ui │ │ └── images │ │ │ └── throbber.gif │ ├── robots.txt │ ├── manifest.webapp │ ├── sw.js │ └── 404.html │ ├── java │ └── com │ │ └── caosg │ │ └── ytbdl │ │ ├── domain │ │ ├── package-info.java │ │ ├── StringSetConverter.java │ │ ├── String2SetDeserializer.java │ │ └── Authority.java │ │ ├── service │ │ ├── package-info.java │ │ ├── dto │ │ │ └── package-info.java │ │ ├── mapper │ │ │ ├── package-info.java │ │ │ └── VideoMapper.java │ │ └── util │ │ │ ├── StreamGobbler.java │ │ │ └── RandomUtil.java │ │ ├── config │ │ ├── audit │ │ │ └── package-info.java │ │ ├── package-info.java │ │ ├── ApplicationProperties.java │ │ ├── Constants.java │ │ ├── LoggingAspectConfiguration.java │ │ ├── DateTimeFormatConfiguration.java │ │ ├── CloudDatabaseConfiguration.java │ │ ├── JacksonConfiguration.java │ │ ├── ThymeleafConfiguration.java │ │ ├── LocaleConfiguration.java │ │ └── DefaultProfileUtil.java │ │ ├── security │ │ ├── package-info.java │ │ ├── AuthoritiesConstants.java │ │ ├── UserNotActivatedException.java │ │ ├── SpringSecurityAuditorAware.java │ │ └── jwt │ │ │ └── JWTConfigurer.java │ │ ├── web │ │ └── rest │ │ │ ├── package-info.java │ │ │ ├── vm │ │ │ ├── package-info.java │ │ │ ├── KeyAndPasswordVM.java │ │ │ ├── LoggerVM.java │ │ │ ├── LoginVM.java │ │ │ └── ManagedUserVM.java │ │ │ ├── errors │ │ │ ├── ErrorConstants.java │ │ │ ├── ParameterizedErrorVM.java │ │ │ ├── FieldErrorVM.java │ │ │ ├── ErrorVM.java │ │ │ └── CustomParameterizedException.java │ │ │ ├── LogsResource.java │ │ │ └── util │ │ │ ├── HeaderUtil.java │ │ │ └── PaginationUtil.java │ │ ├── repository │ │ ├── package-info.java │ │ ├── AuthorityRepository.java │ │ ├── VideoRepository.java │ │ ├── PersistenceAuditEventRepository.java │ │ └── UserRepository.java │ │ ├── crawler │ │ ├── YoutubeDLException.java │ │ ├── dto │ │ │ └── ThumbnailsBean.java │ │ └── YoutubeDLResponse.java │ │ └── ApplicationWebXml.java │ └── docker │ ├── sonar.yml │ ├── Dockerfile │ ├── mysql.yml │ └── app.yml ├── webpack ├── logo-jhipster.png └── utils.js ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── proxy.conf.json ├── .editorconfig ├── tsconfig.json ├── tsconfig-aot.json ├── .yo-rc.json └── .angular-cli.json /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [] 3 | } 4 | -------------------------------------------------------------------------------- /src/test/resources/i18n/messages_en.properties: -------------------------------------------------------------------------------- 1 | email.test.title=test title 2 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/authorities.csv: -------------------------------------------------------------------------------- 1 | name 2 | ROLE_ADMIN 3 | ROLE_USER 4 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/constants/pagination.constants.ts: -------------------------------------------------------------------------------- 1 | export const ITEMS_PER_PAGE = 20; 2 | -------------------------------------------------------------------------------- /webpack/logo-jhipster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caosg/youtube-dl-java/HEAD/webpack/logo-jhipster.png -------------------------------------------------------------------------------- /src/main/webapp/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caosg/youtube-dl-java/HEAD/src/main/webapp/favicon.ico -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caosg/youtube-dl-java/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/domain/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JPA domain objects. 3 | */ 4 | package com.caosg.ytbdl.domain; 5 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/service/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Service layer beans. 3 | */ 4 | package com.caosg.ytbdl.service; 5 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/model/base-entity.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | ; 4 | -------------------------------------------------------------------------------- /src/main/webapp/app/home/index.ts: -------------------------------------------------------------------------------- 1 | export * from './home.component'; 2 | export * from './home.route'; 3 | export * from './home.module'; 4 | -------------------------------------------------------------------------------- /src/main/webapp/content/images/hipster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caosg/youtube-dl-java/HEAD/src/main/webapp/content/images/hipster.png -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/error.json: -------------------------------------------------------------------------------- 1 | { 2 | "error": { 3 | "title": "错误页面!", 4 | "403": "您没有权限访问此页面." 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/config/audit/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Audit specific code. 3 | */ 4 | package com.caosg.ytbdl.config.audit; 5 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/security/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring Security configuration. 3 | */ 4 | package com.caosg.ytbdl.security; 5 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/service/dto/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Data Transfer Objects. 3 | */ 4 | package com.caosg.ytbdl.service.dto; 5 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/web/rest/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring MVC REST controllers. 3 | */ 4 | package com.caosg.ytbdl.web.rest; 5 | -------------------------------------------------------------------------------- /src/main/webapp/content/images/hipster2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caosg/youtube-dl-java/HEAD/src/main/webapp/content/images/hipster2x.png -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip 2 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/config/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring Framework configuration files. 3 | */ 4 | package com.caosg.ytbdl.config; 5 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/repository/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring Data JPA repositories. 3 | */ 4 | package com.caosg.ytbdl.repository; 5 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/footer/footer.component.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/main/webapp/content/images/logo-jhipster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caosg/youtube-dl-java/HEAD/src/main/webapp/content/images/logo-jhipster.png -------------------------------------------------------------------------------- /src/main/webapp/swagger-ui/images/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/caosg/youtube-dl-java/HEAD/src/main/webapp/swagger-ui/images/throbber.gif -------------------------------------------------------------------------------- /src/test/resources/mails/testEmail.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /proxy.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "*": { 3 | "target": "http://localhost:8080", 4 | "secure": false, 5 | "loglevel": "debug" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/users_authorities.csv: -------------------------------------------------------------------------------- 1 | user_id;authority_name 2 | 1;ROLE_ADMIN 3 | 1;ROLE_USER 4 | 3;ROLE_ADMIN 5 | 3;ROLE_USER 6 | 4;ROLE_USER 7 | -------------------------------------------------------------------------------- /src/main/webapp/app/polyfills.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | import 'reflect-metadata/Reflect'; 3 | import 'zone.js/dist/zone'; 4 | 5 | require('../manifest.webapp'); 6 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/web/rest/vm/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * View Models used by Spring MVC REST controllers. 3 | */ 4 | package com.caosg.ytbdl.web.rest.vm; 5 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/logs/log.model.ts: -------------------------------------------------------------------------------- 1 | export class Log { 2 | constructor( 3 | public name: string, 4 | public level: string 5 | ) { } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/constants/pagination.constants.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.ITEMS_PER_PAGE = 20; 4 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/model/base-entity.ts: -------------------------------------------------------------------------------- 1 | export interface BaseEntity { 2 | // using type any to avoid methods complaining of invalid type 3 | id?: any; 4 | }; 5 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/error.json: -------------------------------------------------------------------------------- 1 | { 2 | "error": { 3 | "title": "Error page!", 4 | "403": "You are not authorized to access the page." 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/docs/docs.component.html: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /src/main/docker/sonar.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | youtubedl-sonar: 4 | image: sonarqube:6.4-alpine 5 | ports: 6 | - 9000:9000 7 | - 9092:9092 8 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/service/mapper/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MapStruct mappers for mapping domain objects and Data Transfer Objects. 3 | */ 4 | package com.caosg.ytbdl.service.mapper; 5 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/audits/audit-data.model.ts: -------------------------------------------------------------------------------- 1 | export class AuditData { 2 | constructor( 3 | public remoteAddress: string, 4 | public sessionId: string 5 | ) { } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/.h2.server.properties: -------------------------------------------------------------------------------- 1 | #H2 Server Properties 2 | 0=JHipster H2 (Disk)|org.h2.Driver|jdbc\:h2\:file\:./target/h2db/db/youtubedl|youtubedl 3 | webAllowOthers=true 4 | webPort=8082 5 | webSSL=false 6 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/profiles/profile-info.model.ts: -------------------------------------------------------------------------------- 1 | export class ProfileInfo { 2 | activeProfiles: string[]; 3 | ribbonEnv: string; 4 | inProduction: boolean; 5 | swaggerEnabled: boolean; 6 | } 7 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/footer/footer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'jhi-footer', 5 | templateUrl: './footer.component.html' 6 | }) 7 | export class FooterComponent {} 8 | -------------------------------------------------------------------------------- /src/main/webapp/app/vendor.ts: -------------------------------------------------------------------------------- 1 | /* after changing this file run 'yarn run webpack:build' */ 2 | /* tslint:disable */ 3 | import '../content/scss/vendor.scss'; 4 | // jhipster-needle-add-element-to-vendor - JHipster will add new menu items here 5 | -------------------------------------------------------------------------------- /src/main/webapp/app/app.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { NavbarComponent } from './layouts'; 4 | 5 | export const navbarRoute: Route = { 6 | path: '', 7 | component: NavbarComponent, 8 | outlet: 'navbar' 9 | }; 10 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "configuration": { 3 | "title": "配置", 4 | "filter": "过滤 (按前缀)", 5 | "table": { 6 | "prefix": "前缀", 7 | "properties": "属性" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/activate.json: -------------------------------------------------------------------------------- 1 | { 2 | "activate": { 3 | "title": "启用", 4 | "messages": { 5 | "success": "您的账号已启用. 请 ", 6 | "error": "您的账号无法启用. 请重新注册." 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/logs.json: -------------------------------------------------------------------------------- 1 | { 2 | "logs": { 3 | "title": "日志", 4 | "nbloggers": "共有 {{ total }} 条日志.", 5 | "filter": "筛选", 6 | "table": { 7 | "name": "名称", 8 | "level": "等级" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/docs/docs.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'jhi-docs', 5 | templateUrl: './docs.component.html' 6 | }) 7 | export class JhiDocsComponent { 8 | constructor( 9 | ) { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/model/response-wrapper.model.ts: -------------------------------------------------------------------------------- 1 | import { Headers } from '@angular/http'; 2 | 3 | export class ResponseWrapper { 4 | constructor( 5 | public headers: Headers, 6 | public json: any, 7 | public status: number 8 | ) { } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "configuration": { 3 | "title": "Configuration", 4 | "filter": "Filter (by prefix)", 5 | "table": { 6 | "prefix": "Prefix", 7 | "properties": "Properties" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/logs.json: -------------------------------------------------------------------------------- 1 | { 2 | "logs": { 3 | "title": "Logs", 4 | "nbloggers": "There are {{ total }} loggers.", 5 | "filter": "Filter", 6 | "table": { 7 | "name": "Name", 8 | "level": "Level" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/webapp/robots.txt: -------------------------------------------------------------------------------- 1 | # robotstxt.org/ 2 | 3 | User-agent: * 4 | Disallow: /api/account 5 | Disallow: /api/account/change_password 6 | Disallow: /api/account/sessions 7 | Disallow: /api/audits/ 8 | Disallow: /api/logs/ 9 | Disallow: /api/users/ 10 | Disallow: /management/ 11 | Disallow: /v2/api-docs/ 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/audits/audit.model.ts: -------------------------------------------------------------------------------- 1 | import { AuditData } from './audit-data.model'; 2 | 3 | export class Audit { 4 | constructor( 5 | public data: AuditData, 6 | public principal: string, 7 | public timestamp: string, 8 | public type: string 9 | ) { } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/logs/logs.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { LogsComponent } from './logs.component'; 4 | 5 | export const logsRoute: Route = { 6 | path: 'logs', 7 | component: LogsComponent, 8 | data: { 9 | pageTitle: 'logs.title' 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/audits/audits.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { AuditsComponent } from './audits.component'; 4 | 5 | export const auditsRoute: Route = { 6 | path: 'audits', 7 | component: AuditsComponent, 8 | data: { 9 | pageTitle: 'audits.title' 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/docs/docs.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { JhiDocsComponent } from './docs.component'; 4 | 5 | export const docsRoute: Route = { 6 | path: 'docs', 7 | component: JhiDocsComponent, 8 | data: { 9 | pageTitle: 'global.menu.admin.apidocs' 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/blocks/config/prod.config.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { DEBUG_INFO_ENABLED } from '../../app.constants'; 3 | 4 | export function ProdConfig() { 5 | // disable debug data on prod profile to improve performance 6 | if (!DEBUG_INFO_ENABLED) { 7 | enableProdMode(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/health/health.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { JhiHealthCheckComponent } from './health.component'; 4 | 5 | export const healthRoute: Route = { 6 | path: 'jhi-health', 7 | component: JhiHealthCheckComponent, 8 | data: { 9 | pageTitle: 'health.title' 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/password.json: -------------------------------------------------------------------------------- 1 | { 2 | "password": { 3 | "title": "[{{username}}] 的密码", 4 | "form": { 5 | "button": "保存" 6 | }, 7 | "messages": { 8 | "error": "发生错误! 密码无法被修改.", 9 | "success": "密码修改成功!" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/metrics/metrics.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { JhiMetricsMonitoringComponent } from './metrics.component'; 4 | 5 | export const metricsRoute: Route = { 6 | path: 'jhi-metrics', 7 | component: JhiMetricsMonitoringComponent, 8 | data: { 9 | pageTitle: 'metrics.title' 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/activate.json: -------------------------------------------------------------------------------- 1 | { 2 | "activate": { 3 | "title": "Activation", 4 | "messages": { 5 | "success": "Your user account has been activated. Please ", 6 | "error": "Your user could not be activated. Please use the registration form to sign up." 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/webapp/app/home/home.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { UserRouteAccessService } from '../shared'; 4 | import { HomeComponent } from './'; 5 | 6 | export const HOME_ROUTE: Route = { 7 | path: '', 8 | component: HomeComponent, 9 | data: { 10 | authorities: [], 11 | pageTitle: 'home.title' 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/repository/AuthorityRepository.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.repository; 2 | 3 | import com.caosg.ytbdl.domain.Authority; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | /** 8 | * Spring Data JPA repository for the Authority entity. 9 | */ 10 | public interface AuthorityRepository extends JpaRepository { 11 | } 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/configuration/configuration.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { JhiConfigurationComponent } from './configuration.component'; 4 | 5 | export const configurationRoute: Route = { 6 | path: 'jhi-configuration', 7 | component: JhiConfigurationComponent, 8 | data: { 9 | pageTitle: 'configuration.title' 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/main/main.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 |
6 |
7 | 8 | 9 |
10 | 11 |
12 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/gateway.json: -------------------------------------------------------------------------------- 1 | { 2 | "gateway": { 3 | "title": "网关", 4 | "routes": { 5 | "title": "当前可用路由", 6 | "url": "映射路径", 7 | "service": "服务名称", 8 | "servers": "服务实例地址", 9 | "error": "警告: 没有可用服务实例!" 10 | }, 11 | "refresh": { 12 | "button": "刷新" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/register/register.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http } from '@angular/http'; 3 | import { Observable } from 'rxjs/Rx'; 4 | 5 | @Injectable() 6 | export class Register { 7 | 8 | constructor(private http: Http) {} 9 | 10 | save(account: any): Observable { 11 | return this.http.post('api/register', account); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/user/account.model.ts: -------------------------------------------------------------------------------- 1 | export class Account { 2 | constructor( 3 | public activated: boolean, 4 | public authorities: string[], 5 | public email: string, 6 | public firstName: string, 7 | public langKey: string, 8 | public lastName: string, 9 | public login: string, 10 | public imageUrl: string 11 | ) { } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | 3 | ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \ 4 | JHIPSTER_SLEEP=0 \ 5 | JAVA_OPTS="" 6 | 7 | # add directly the war 8 | ADD *.war /app.war 9 | 10 | EXPOSE 8080 11 | CMD echo "The application will start in ${JHIPSTER_SLEEP}s..." && \ 12 | sleep ${JHIPSTER_SLEEP} && \ 13 | java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /app.war 14 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/video/index.ts: -------------------------------------------------------------------------------- 1 | export * from './video.model'; 2 | export * from './video-popup.service'; 3 | export * from './video.service'; 4 | export * from './video-dialog.component'; 5 | export * from './video-delete-dialog.component'; 6 | export * from './video-detail.component'; 7 | export * from './video.component'; 8 | export * from './video-play.component'; 9 | export * from './video.route'; 10 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/auth/csrf.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { CookieService } from 'ngx-cookie'; 3 | 4 | @Injectable() 5 | export class CSRFService { 6 | 7 | constructor(private cookieService: CookieService) {} 8 | 9 | getCSRF(name?: string) { 10 | name = `${name ? name : 'XSRF-TOKEN'}`; 11 | return this.cookieService.get(name); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/password.json: -------------------------------------------------------------------------------- 1 | { 2 | "password": { 3 | "title": "Password for [{{username}}]", 4 | "form": { 5 | "button": "Save" 6 | }, 7 | "messages": { 8 | "error": "An error has occurred! The password could not be changed.", 9 | "success": "Password changed!" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/model/response-wrapper.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var ResponseWrapper = (function () { 4 | function ResponseWrapper(headers, json, status) { 5 | this.headers = headers; 6 | this.json = json; 7 | this.status = status; 8 | } 9 | return ResponseWrapper; 10 | }()); 11 | exports.ResponseWrapper = ResponseWrapper; 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/language/language.constants.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Languages codes are ISO_639-1 codes, see http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes 3 | They are written in English to avoid character encoding issues (not a perfect solution) 4 | */ 5 | export const LANGUAGES: string[] = [ 6 | 'zh-cn', 7 | 'en' 8 | // jhipster-needle-i18n-language-constant - JHipster will add/remove languages in this array 9 | ]; 10 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/gateway.json: -------------------------------------------------------------------------------- 1 | { 2 | "gateway": { 3 | "title": "Gateway", 4 | "routes": { 5 | "title": "Current routes", 6 | "url": "URL", 7 | "service": "service", 8 | "servers": "Available servers", 9 | "error": "Warning: no server available!" 10 | }, 11 | "refresh": { 12 | "button": "Refresh" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password/password.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http } from '@angular/http'; 3 | import { Observable } from 'rxjs/Rx'; 4 | 5 | @Injectable() 6 | export class PasswordService { 7 | 8 | constructor(private http: Http) {} 9 | 10 | save(newPassword: string): Observable { 11 | return this.http.post('api/account/change_password', newPassword); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/config/ApplicationProperties.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.config; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | /** 6 | * Properties specific to JHipster. 7 | *

8 | * Properties are configured in the application.yml file. 9 | */ 10 | @ConfigurationProperties(prefix = "application", ignoreUnknownFields = false) 11 | public class ApplicationProperties { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password-reset/init/password-reset-init.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http } from '@angular/http'; 3 | import { Observable } from 'rxjs/Rx'; 4 | 5 | @Injectable() 6 | export class PasswordResetInitService { 7 | 8 | constructor(private http: Http) {} 9 | 10 | save(mail: string): Observable { 11 | return this.http.post('api/account/reset_password/init', mail); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/config/Constants.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.config; 2 | 3 | /** 4 | * Application constants. 5 | */ 6 | public final class Constants { 7 | 8 | //Regex for acceptable logins 9 | public static final String LOGIN_REGEX = "^[_'.@A-Za-z0-9-]*$"; 10 | 11 | public static final String SYSTEM_ACCOUNT = "system"; 12 | public static final String ANONYMOUS_USER = "anonymoususer"; 13 | 14 | private Constants() { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/security/AuthoritiesConstants.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.security; 2 | 3 | /** 4 | * Constants for Spring Security authorities. 5 | */ 6 | public final class AuthoritiesConstants { 7 | 8 | public static final String ADMIN = "ROLE_ADMIN"; 9 | 10 | public static final String USER = "ROLE_USER"; 11 | 12 | public static final String ANONYMOUS = "ROLE_ANONYMOUS"; 13 | 14 | private AuthoritiesConstants() { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/webapp/app/app.main-aot.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowser } from '@angular/platform-browser'; 2 | import { ProdConfig } from './blocks/config/prod.config'; 3 | import { YoutubedlAppModuleNgFactory } from '../../../../target/aot/src/main/webapp/app/app.module.ngfactory'; 4 | 5 | ProdConfig(); 6 | 7 | platformBrowser().bootstrapModuleFactory(YoutubedlAppModuleNgFactory) 8 | .then((success) => console.log(`Application started`)) 9 | .catch((err) => console.error(err)); 10 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/activate/activate.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { UserRouteAccessService } from '../../shared'; 4 | import { ActivateComponent } from './activate.component'; 5 | 6 | export const activateRoute: Route = { 7 | path: 'activate', 8 | component: ActivateComponent, 9 | data: { 10 | authorities: [], 11 | pageTitle: 'activate.title' 12 | }, 13 | canActivate: [UserRouteAccessService] 14 | }; 15 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/register/register.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { UserRouteAccessService } from '../../shared'; 4 | import { RegisterComponent } from './register.component'; 5 | 6 | export const registerRoute: Route = { 7 | path: 'register', 8 | component: RegisterComponent, 9 | data: { 10 | authorities: [], 11 | pageTitle: 'register.title' 12 | }, 13 | canActivate: [UserRouteAccessService] 14 | }; 15 | -------------------------------------------------------------------------------- /src/main/webapp/app/app.main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | import { ProdConfig } from './blocks/config/prod.config'; 3 | import { YoutubedlAppModule } from './app.module'; 4 | 5 | ProdConfig(); 6 | 7 | if (module['hot']) { 8 | module['hot'].accept(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(YoutubedlAppModule) 12 | .then((success) => console.log(`Application started`)) 13 | .catch((err) => console.error(err)); 14 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/sessions.json: -------------------------------------------------------------------------------- 1 | { 2 | "sessions": { 3 | "title": "[{{username}} 使用中的 Sessions]", 4 | "table": { 5 | "ipaddress": "IP 位址", 6 | "useragent": "用户代理", 7 | "date": "日期", 8 | "button": "失效" 9 | }, 10 | "messages": { 11 | "success": "Session 已失效!", 12 | "error": "发生错误! 无法使 Session 失效." 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password-reset/finish/password-reset-finish.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http } from '@angular/http'; 3 | import { Observable } from 'rxjs/Rx'; 4 | 5 | @Injectable() 6 | export class PasswordResetFinishService { 7 | 8 | constructor(private http: Http) {} 9 | 10 | save(keyAndPassword: any): Observable { 11 | return this.http.post('api/account/reset_password/finish', keyAndPassword); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/javascript/spec/helpers/mock-route.service.ts: -------------------------------------------------------------------------------- 1 | import { ActivatedRoute } from '@angular/router'; 2 | import { Observable } from 'rxjs'; 3 | 4 | export class MockActivatedRoute extends ActivatedRoute { 5 | 6 | constructor(parameters?: any) { 7 | super(); 8 | this.queryParams = Observable.of(parameters); 9 | this.params = Observable.of(parameters); 10 | } 11 | } 12 | 13 | export class MockRouter { 14 | navigate = jasmine.createSpy('navigate'); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/app/app.constants.ts: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE, EDIT THE WEBPACK COMMON CONFIG INSTEAD, WHICH WILL MODIFY THIS FILE 2 | /* tslint:disable */ 3 | let _VERSION = '0.0.1-SNAPSHOT'; // This value will be overwritten by webpack 4 | let _DEBUG_INFO_ENABLED = true; // This value will be overwritten by webpack 5 | /* @toreplace VERSION */ 6 | /* @toreplace DEBUG_INFO_ENABLED */ 7 | /* tslint:enable */ 8 | export const VERSION = _VERSION; 9 | export const DEBUG_INFO_ENABLED = _DEBUG_INFO_ENABLED; 10 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/index.ts: -------------------------------------------------------------------------------- 1 | export * from './error/error.component'; 2 | export * from './error/error.route'; 3 | export * from './main/main.component'; 4 | export * from './footer/footer.component'; 5 | export * from './navbar/navbar.component'; 6 | export * from './navbar/active-menu.directive'; 7 | export * from './profiles/page-ribbon.component'; 8 | export * from './profiles/profile.service'; 9 | export * from './profiles/profile-info.model'; 10 | export * from './layout-routing.module'; 11 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password/password.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { UserRouteAccessService } from '../../shared'; 4 | import { PasswordComponent } from './password.component'; 5 | 6 | export const passwordRoute: Route = { 7 | path: 'password', 8 | component: PasswordComponent, 9 | data: { 10 | authorities: ['ROLE_USER'], 11 | pageTitle: 'global.menu.account.password' 12 | }, 13 | canActivate: [UserRouteAccessService] 14 | }; 15 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/settings/settings.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { UserRouteAccessService } from '../../shared'; 4 | import { SettingsComponent } from './settings.component'; 5 | 6 | export const settingsRoute: Route = { 7 | path: 'settings', 8 | component: SettingsComponent, 9 | data: { 10 | authorities: ['ROLE_USER'], 11 | pageTitle: 'global.menu.account.settings' 12 | }, 13 | canActivate: [UserRouteAccessService] 14 | }; 15 | -------------------------------------------------------------------------------- /src/main/webapp/app/blocks/config/uib-pagination.config.ts: -------------------------------------------------------------------------------- 1 | import { ITEMS_PER_PAGE } from '../../shared'; 2 | import { Injectable } from '@angular/core'; 3 | import { NgbPaginationConfig} from '@ng-bootstrap/ng-bootstrap'; 4 | 5 | @Injectable() 6 | export class PaginationConfig { 7 | constructor(private config: NgbPaginationConfig) { 8 | config.boundaryLinks = true; 9 | config.maxSize = 5; 10 | config.pageSize = ITEMS_PER_PAGE; 11 | config.size = 'sm'; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/com/caosg/ytbdl/config/WebConfigurerTestController.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.config; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | @RestController 7 | public class WebConfigurerTestController { 8 | 9 | @GetMapping("/api/test-cors") 10 | public void testCorsOnApiPath() { 11 | } 12 | 13 | @GetMapping("/test/test-cors") 14 | public void testCorsOnOtherPath() { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/language/language.constants.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | /* 4 | Languages codes are ISO_639-1 codes, see http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes 5 | They are written in English to avoid character encoding issues (not a perfect solution) 6 | */ 7 | exports.LANGUAGES = [ 8 | 'zh-cn', 9 | 'en' 10 | // jhipster-needle-i18n-language-constant - JHipster will add/remove languages in this array 11 | ]; 12 | -------------------------------------------------------------------------------- /src/main/docker/mysql.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | youtubedl-mysql: 4 | image: mysql:5.7.18 5 | # volumes: 6 | # - ~/volumes/jhipster/youtubedl/mysql/:/var/lib/mysql/ 7 | environment: 8 | - MYSQL_USER=root 9 | - MYSQL_ALLOW_EMPTY_PASSWORD=yes 10 | - MYSQL_DATABASE=youtubedl 11 | ports: 12 | - 3306:3306 13 | command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8 --explicit_defaults_for_timestamp 14 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/login.json: -------------------------------------------------------------------------------- 1 | { 2 | "login": { 3 | "title": "登录", 4 | "form": { 5 | "password": "密码", 6 | "password.placeholder": "您的密码", 7 | "rememberme": "自动登录", 8 | "button": "登录" 9 | }, 10 | "messages": { 11 | "error": { 12 | "authentication": "登录失败! 请检查您的登录信息, 并重试一次." 13 | } 14 | }, 15 | "password" : { 16 | "forgot": "忘记密码?" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/layout-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule } from '@angular/router'; 3 | 4 | import { navbarRoute } from '../app.route'; 5 | import { errorRoute } from './'; 6 | 7 | const LAYOUT_ROUTES = [ 8 | navbarRoute, 9 | ...errorRoute 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [ 14 | RouterModule.forRoot(LAYOUT_ROUTES, { useHash: true }) 15 | ], 16 | exports: [ 17 | RouterModule 18 | ] 19 | }) 20 | export class LayoutRoutingModule {} 21 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/sessions.json: -------------------------------------------------------------------------------- 1 | { 2 | "sessions": { 3 | "title": "Active sessions for [{{username}}]", 4 | "table": { 5 | "ipaddress": "IP address", 6 | "useragent": "User Agent", 7 | "date": "Date", 8 | "button": "Invalidate" 9 | }, 10 | "messages": { 11 | "success": "Session invalidated!", 12 | "error": "An error has occurred! The session could not be invalidated." 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/auth/account.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http, Response } from '@angular/http'; 3 | import { Observable } from 'rxjs/Rx'; 4 | 5 | @Injectable() 6 | export class AccountService { 7 | constructor(private http: Http) { } 8 | 9 | get(): Observable { 10 | return this.http.get('api/account').map((res: Response) => res.json()); 11 | } 12 | 13 | save(account: any): Observable { 14 | return this.http.post('api/account', account); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password-reset/init/password-reset-init.route.ts: -------------------------------------------------------------------------------- 1 | import { Route } from '@angular/router'; 2 | 3 | import { UserRouteAccessService } from '../../../shared'; 4 | import { PasswordResetInitComponent } from './password-reset-init.component'; 5 | 6 | export const passwordResetInitRoute: Route = { 7 | path: 'reset/request', 8 | component: PasswordResetInitComponent, 9 | data: { 10 | authorities: [], 11 | pageTitle: 'global.menu.account.password' 12 | }, 13 | canActivate: [UserRouteAccessService] 14 | }; 15 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/repository/VideoRepository.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.repository; 2 | 3 | import com.caosg.ytbdl.domain.Video; 4 | import org.springframework.stereotype.Repository; 5 | 6 | import org.springframework.data.jpa.repository.*; 7 | 8 | import java.util.Optional; 9 | 10 | 11 | /** 12 | * Spring Data JPA repository for the Video entity. 13 | */ 14 | @SuppressWarnings("unused") 15 | @Repository 16 | public interface VideoRepository extends JpaRepository { 17 | Optional

2 |
3 |
4 | 5 |
6 |
7 |

Error Page!

8 | 9 |
10 |
{{errorMessage}} 11 |
12 |
13 |
You are not authorized to access the page. 14 |
15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/home.json: -------------------------------------------------------------------------------- 1 | { 2 | "home": { 3 | "title": "欢迎, Java Hipster!", 4 | "subtitle": "这里是首页", 5 | "logged": { 6 | "message": "您目前是以 \"{{username}}\" 账号登录." 7 | }, 8 | "question": "如果您有任何有关 JHipster 的问题, 可以查阅下列资源:", 9 | "link": { 10 | "homepage": "JHipster 首頁", 11 | "stackoverflow": "Stack Overflow 上关于 JHipster 的讨论", 12 | "bugtracker": "JHipster 的缺陷追踪", 13 | "chat": "JHipster public chat room", 14 | "follow": "在 Twitter 上联络 @java_hipster" 15 | }, 16 | "like": "如果您喜欢 JHipster, 请记得给我们加星在", 17 | "github": "GitHub" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/error/error.route.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | import { UserRouteAccessService } from '../../shared'; 4 | import { ErrorComponent } from './error.component'; 5 | 6 | export const errorRoute: Routes = [ 7 | { 8 | path: 'error', 9 | component: ErrorComponent, 10 | data: { 11 | authorities: [], 12 | pageTitle: 'error.title' 13 | }, 14 | }, 15 | { 16 | path: 'accessdenied', 17 | component: ErrorComponent, 18 | data: { 19 | authorities: [], 20 | pageTitle: 'error.title', 21 | error403: true 22 | }, 23 | } 24 | ]; 25 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/service/mapper/VideoMapper.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.service.mapper; 2 | 3 | import com.caosg.ytbdl.crawler.dto.VideoInfo; 4 | import com.caosg.ytbdl.domain.Video; 5 | import org.mapstruct.Mapper; 6 | import org.mapstruct.Mapping; 7 | import org.mapstruct.Mappings; 8 | import org.mapstruct.factory.Mappers; 9 | 10 | /** 11 | * Created by shuguangcao on 2017/7/10. 12 | */ 13 | @Mapper 14 | public interface VideoMapper { 15 | 16 | VideoMapper MAPPER = Mappers.getMapper(VideoMapper.class); 17 | 18 | @Mappings({ 19 | @Mapping(target = "id",ignore = true), 20 | @Mapping(source = "id",target = "vid") 21 | }) 22 | Video toVideo(VideoInfo videoInfo); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/health.json: -------------------------------------------------------------------------------- 1 | { 2 | "health": { 3 | "title": "服务状态", 4 | "refresh.button": "刷新", 5 | "stacktrace": "堆栈调用", 6 | "details": { 7 | "details": "详细情况", 8 | "properties": "属性", 9 | "name": "名称", 10 | "value": "值", 11 | "error": "错误" 12 | }, 13 | "indicator": { 14 | "diskSpace": "硬盘空间", 15 | "mail": "电子邮件", 16 | "db": "数据库" 17 | }, 18 | "table": { 19 | "service": "服务名称", 20 | "status": "状态" 21 | }, 22 | "status": { 23 | "UP": "正常", 24 | "DOWN": "异常" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/audits.json: -------------------------------------------------------------------------------- 1 | { 2 | "audits": { 3 | "title": "审核", 4 | "filter": { 5 | "title": "根据日期筛选", 6 | "from": "从", 7 | "to": "至", 8 | "button": { 9 | "weeks": "周", 10 | "today": "今天", 11 | "clear": "清除", 12 | "close": "关闭" 13 | } 14 | }, 15 | "table": { 16 | "header": { 17 | "principal": "用户", 18 | "date": "日期", 19 | "status": "状态", 20 | "data": "其它" 21 | }, 22 | "data": { 23 | "remoteAddress": "远程地址:" 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/javascript/spec/helpers/mock-language.service.ts: -------------------------------------------------------------------------------- 1 | import { SpyObject } from './spyobject'; 2 | import { JhiLanguageService } from 'ng-jhipster'; 3 | import Spy = jasmine.Spy; 4 | 5 | export class MockLanguageService extends SpyObject { 6 | 7 | getCurrentSpy: Spy; 8 | fakeResponse: any; 9 | 10 | constructor() { 11 | super(JhiLanguageService); 12 | 13 | this.fakeResponse = 'zh-cn'; 14 | this.getCurrentSpy = this.spy('getCurrent').andReturn(Promise.resolve(this.fakeResponse)); 15 | } 16 | 17 | init() {} 18 | 19 | changeLanguage(languageKey: string) {} 20 | 21 | setLocations(locations: string[]) {} 22 | 23 | addLocation(location: string) {} 24 | 25 | reload() {} 26 | } 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true, 12 | "outDir": "target/www/app", 13 | "lib": ["es6", "dom"], 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ] 17 | }, 18 | "include": [ 19 | "src/main/webapp/app", 20 | "src/test/javascript/" 21 | ], 22 | "exclude": [ 23 | "src/main/webapp/app/app.main-aot.ts" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/home.json: -------------------------------------------------------------------------------- 1 | { 2 | "home": { 3 | "title": "Welcome, Java Hipster!", 4 | "subtitle": "This is your homepage", 5 | "logged": { 6 | "message": "You are logged in as user \"{{username}}\"." 7 | }, 8 | "question": "If you have any question on JHipster:", 9 | "link": { 10 | "homepage": "JHipster homepage", 11 | "stackoverflow": "JHipster on Stack Overflow", 12 | "bugtracker": "JHipster bug tracker", 13 | "chat": "JHipster public chat room", 14 | "follow": "follow @java_hipster on Twitter" 15 | }, 16 | "like": "If you like JHipster, don't forget to give us a star on", 17 | "github": "GitHub" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/video/video.model.ts: -------------------------------------------------------------------------------- 1 | import { BaseEntity } from './../../shared'; 2 | 3 | export class Video implements BaseEntity { 4 | constructor( 5 | public id?: number, 6 | public extractor?: string, 7 | public protocol?: string, 8 | public uploader?: string, 9 | public duration?: number, 10 | public vid?: string, 11 | public format?: string, 12 | public title?: string, 13 | public url?: string, 14 | public width?: number, 15 | public height?: number, 16 | public ext?: string, 17 | public filesize?: number, 18 | public thumbnail?: string, 19 | public tags?: string, 20 | public webpageUrl?: string, 21 | ) { 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/config/DateTimeFormatConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.format.FormatterRegistry; 5 | import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar; 6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 7 | 8 | @Configuration 9 | public class DateTimeFormatConfiguration extends WebMvcConfigurerAdapter { 10 | 11 | @Override 12 | public void addFormatters(FormatterRegistry registry) { 13 | DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar(); 14 | registrar.setUseIsoFormat(true); 15 | registrar.registerFormatters(registry); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/health.json: -------------------------------------------------------------------------------- 1 | { 2 | "health": { 3 | "title": "Health Checks", 4 | "refresh.button": "Refresh", 5 | "stacktrace": "Stacktrace", 6 | "details": { 7 | "details": "Details", 8 | "properties": "Properties", 9 | "name": "Name", 10 | "value": "Value", 11 | "error": "Error" 12 | }, 13 | "indicator": { 14 | "diskSpace": "Disk space", 15 | "mail": "Email", 16 | "db": "Database" 17 | }, 18 | "table": { 19 | "service": "Service name", 20 | "status": "Status" 21 | }, 22 | "status": { 23 | "UP": "UP", 24 | "DOWN": "DOWN" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/video/video-play.component.html: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/audits.json: -------------------------------------------------------------------------------- 1 | { 2 | "audits": { 3 | "title": "Audits", 4 | "filter": { 5 | "title": "Filter per date", 6 | "from": "from", 7 | "to": "to", 8 | "button": { 9 | "weeks": "Weeks", 10 | "today": "today", 11 | "clear": "clear", 12 | "close": "close" 13 | } 14 | }, 15 | "table": { 16 | "header": { 17 | "principal": "User", 18 | "date": "Date", 19 | "status": "State", 20 | "data": "Extra data" 21 | }, 22 | "data": { 23 | "remoteAddress": "Remote Address:" 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/javascript/spec/helpers/mock-account.service.ts: -------------------------------------------------------------------------------- 1 | import { SpyObject } from './spyobject'; 2 | import { AccountService } from '../../../../main/webapp/app/shared/auth/account.service'; 3 | import Spy = jasmine.Spy; 4 | 5 | export class MockAccountService extends SpyObject { 6 | 7 | getSpy: Spy; 8 | saveSpy: Spy; 9 | fakeResponse: any; 10 | 11 | constructor() { 12 | super(AccountService); 13 | 14 | this.fakeResponse = null; 15 | this.getSpy = this.spy('get').andReturn(this); 16 | this.saveSpy = this.spy('save').andReturn(this); 17 | } 18 | 19 | subscribe(callback: any) { 20 | callback(this.fakeResponse); 21 | } 22 | 23 | setResponse(json: any): void { 24 | this.fakeResponse = json; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/admin.route.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | import { 4 | auditsRoute, 5 | configurationRoute, 6 | docsRoute, 7 | healthRoute, 8 | logsRoute, 9 | metricsRoute, 10 | userMgmtRoute, 11 | userDialogRoute 12 | } from './'; 13 | 14 | import { UserRouteAccessService } from '../shared'; 15 | 16 | const ADMIN_ROUTES = [ 17 | auditsRoute, 18 | configurationRoute, 19 | docsRoute, 20 | healthRoute, 21 | logsRoute, 22 | ...userMgmtRoute, 23 | metricsRoute 24 | ]; 25 | 26 | export const adminState: Routes = [{ 27 | path: '', 28 | data: { 29 | authorities: ['ROLE_ADMIN'] 30 | }, 31 | canActivate: [UserRouteAccessService], 32 | children: ADMIN_ROUTES 33 | }, 34 | ...userDialogRoute 35 | ]; 36 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/audits/audits.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http, Response, URLSearchParams } from '@angular/http'; 3 | import { Observable } from 'rxjs/Rx'; 4 | 5 | @Injectable() 6 | export class AuditsService { 7 | constructor(private http: Http) { } 8 | 9 | query(req: any): Observable { 10 | const params: URLSearchParams = new URLSearchParams(); 11 | params.set('fromDate', req.fromDate); 12 | params.set('toDate', req.toDate); 13 | params.set('page', req.page); 14 | params.set('size', req.size); 15 | params.set('sort', req.sort); 16 | 17 | const options = { 18 | search: params 19 | }; 20 | 21 | return this.http.get('management/audits', options); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tsconfig-aot.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "es2015", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "removeComments": false, 10 | "noImplicitAny": false, 11 | "suppressImplicitAnyIndexErrors": true, 12 | "outDir": "target/www/app", 13 | "lib": ["es2015", "dom"], 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ] 17 | }, 18 | "files": [ 19 | "src/main/webapp/app/app.module.ts", 20 | "src/main/webapp/app/app.main-aot.ts" 21 | ], 22 | "angularCompilerOptions": { 23 | "genDir": "target/aot", 24 | "skipMetadataEmit" : true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/error/error.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { ActivatedRoute } from '@angular/router'; 3 | 4 | @Component({ 5 | selector: 'jhi-error', 6 | templateUrl: './error.component.html' 7 | }) 8 | export class ErrorComponent implements OnInit { 9 | errorMessage: string; 10 | error403: boolean; 11 | 12 | constructor( 13 | private route: ActivatedRoute 14 | ) { 15 | } 16 | 17 | ngOnInit() { 18 | this.route.data.subscribe((routeData) => { 19 | if (routeData.error403) { 20 | this.error403 = routeData.error403; 21 | } 22 | if (routeData.errorMessage) { 23 | this.errorMessage = routeData.errorMessage; 24 | } 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/service/util/StreamGobbler.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.service.util; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | /** 7 | * Created by csg on 2017/7/9. 8 | */ 9 | public class StreamGobbler extends Thread { 10 | 11 | private InputStream stream; 12 | private StringBuffer buffer; 13 | 14 | public StreamGobbler(StringBuffer buffer, InputStream stream) { 15 | this.stream = stream; 16 | this.buffer = buffer; 17 | start(); 18 | } 19 | 20 | public void run() { 21 | try { 22 | int nextChar; 23 | while((nextChar = this.stream.read()) != -1) { 24 | this.buffer.append((char) nextChar); 25 | } 26 | } 27 | catch (IOException e) { 28 | 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/web/rest/errors/ParameterizedErrorVM.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.web.rest.errors; 2 | 3 | import java.io.Serializable; 4 | import java.util.Map; 5 | 6 | /** 7 | * View Model for sending a parameterized error message. 8 | */ 9 | public class ParameterizedErrorVM implements Serializable { 10 | 11 | private static final long serialVersionUID = 1L; 12 | 13 | private final String message; 14 | private final Map paramMap; 15 | 16 | public ParameterizedErrorVM(String message, Map paramMap) { 17 | this.message = message; 18 | this.paramMap = paramMap; 19 | } 20 | 21 | public String getMessage() { 22 | return message; 23 | } 24 | 25 | public Map getParams() { 26 | return paramMap; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "register": { 3 | "title": "注册", 4 | "form": { 5 | "button": "注册" 6 | }, 7 | "messages": { 8 | "validate": { 9 | "login": { 10 | "required": "您的账号是必填项.", 11 | "minlength": "您的账号长度至少要有1个字符", 12 | "maxlength": "您的账号长度不能超过50个字符", 13 | "pattern": "你的账号只能使用小写英文以及数字" 14 | } 15 | }, 16 | "success": "注册成功! 请检查您的邮箱.", 17 | "error": { 18 | "fail": "注册失败! 请稍后再试.", 19 | "userexists": "账号已被注册! 请选择其它账号.", 20 | "emailexists": "邮件已经被注册! 请选择其它邮件." 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/config/CloudDatabaseConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.config; 2 | 3 | import io.github.jhipster.config.JHipsterConstants; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.cloud.config.java.AbstractCloudConfig; 8 | import org.springframework.context.annotation.*; 9 | 10 | import javax.sql.DataSource; 11 | 12 | @Configuration 13 | @Profile(JHipsterConstants.SPRING_PROFILE_CLOUD) 14 | public class CloudDatabaseConfiguration extends AbstractCloudConfig { 15 | 16 | private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class); 17 | 18 | @Bean 19 | public DataSource dataSource() { 20 | log.info("Configuring JDBC datasource from a cloud provider"); 21 | return connectionFactory().dataSource(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/web/rest/errors/FieldErrorVM.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.web.rest.errors; 2 | 3 | import java.io.Serializable; 4 | 5 | public class FieldErrorVM implements Serializable { 6 | 7 | private static final long serialVersionUID = 1L; 8 | 9 | private final String objectName; 10 | 11 | private final String field; 12 | 13 | private final String message; 14 | 15 | public FieldErrorVM(String dto, String field, String message) { 16 | this.objectName = dto; 17 | this.field = field; 18 | this.message = message; 19 | } 20 | 21 | public String getObjectName() { 22 | return objectName; 23 | } 24 | 25 | public String getField() { 26 | return field; 27 | } 28 | 29 | public String getMessage() { 30 | return message; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/activate/activate.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Activation

5 | 6 |
7 | Your user account has been activated. Please 8 | sign in. 9 |
10 | 11 |
12 | Your user could not be activated. Please use the registration form to sign up. 13 |
14 | 15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/config/JacksonConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.config; 2 | 3 | import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module; 4 | import com.fasterxml.jackson.module.afterburner.AfterburnerModule; 5 | 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | @Configuration 10 | public class JacksonConfiguration { 11 | 12 | /** 13 | * Support for Hibernate types in Jackson. 14 | */ 15 | @Bean 16 | public Hibernate5Module hibernate5Module() { 17 | return new Hibernate5Module(); 18 | } 19 | 20 | /** 21 | * Jackson Afterburner module to speed up serialization/deserialization. 22 | */ 23 | @Bean 24 | public AfterburnerModule afterburnerModule() { 25 | return new AfterburnerModule(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/master.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/shared-common.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Title } from '@angular/platform-browser'; 3 | 4 | import { 5 | YoutubedlSharedLibsModule, 6 | JhiLanguageHelper, 7 | FindLanguageFromKeyPipe, 8 | JhiAlertComponent, 9 | JhiAlertErrorComponent 10 | } from './'; 11 | 12 | @NgModule({ 13 | imports: [ 14 | YoutubedlSharedLibsModule 15 | ], 16 | declarations: [ 17 | FindLanguageFromKeyPipe, 18 | JhiAlertComponent, 19 | JhiAlertErrorComponent 20 | ], 21 | providers: [ 22 | JhiLanguageHelper, 23 | Title 24 | ], 25 | exports: [ 26 | YoutubedlSharedLibsModule, 27 | FindLanguageFromKeyPipe, 28 | JhiAlertComponent, 29 | JhiAlertErrorComponent 30 | ] 31 | }) 32 | export class YoutubedlSharedCommonModule {} 33 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/reset.json: -------------------------------------------------------------------------------- 1 | { 2 | "reset": { 3 | "request": { 4 | "title": "重置您的密码", 5 | "form": { 6 | "button": "重置密码" 7 | }, 8 | "messages": { 9 | "info": "请输入您注册时使用的邮件地址", 10 | "success": "已将重置密码的操作说明发送到您的邮箱,请检查邮件.", 11 | "notfound": "没有与该邮件地址关联的账号. 请使用其他邮件地址" 12 | } 13 | }, 14 | "finish" : { 15 | "title": "重置密码", 16 | "form": { 17 | "button": "确定" 18 | }, 19 | "messages": { 20 | "info": "请设置新密码", 21 | "success": "您的密码已被重置. 请 ", 22 | "keymissing": "无效的重置密码请求.", 23 | "error": "无法重置密码. 您必须在请求重置密码后24小时内完成重置." 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | ${AnsiColor.GREEN} ██╗${AnsiColor.RED} ██╗ ██╗ ████████╗ ███████╗ ██████╗ ████████╗ ████████╗ ███████╗ 3 | ${AnsiColor.GREEN} ██║${AnsiColor.RED} ██║ ██║ ╚══██╔══╝ ██╔═══██╗ ██╔════╝ ╚══██╔══╝ ██╔═════╝ ██╔═══██╗ 4 | ${AnsiColor.GREEN} ██║${AnsiColor.RED} ████████║ ██║ ███████╔╝ ╚█████╗ ██║ ██████╗ ███████╔╝ 5 | ${AnsiColor.GREEN}██╗ ██║${AnsiColor.RED} ██╔═══██║ ██║ ██╔════╝ ╚═══██╗ ██║ ██╔═══╝ ██╔══██║ 6 | ${AnsiColor.GREEN}╚██████╔╝${AnsiColor.RED} ██║ ██║ ████████╗ ██║ ██████╔╝ ██║ ████████╗ ██║ ╚██╗ 7 | ${AnsiColor.GREEN} ╚═════╝ ${AnsiColor.RED} ╚═╝ ╚═╝ ╚═══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══════╝ ╚═╝ ╚═╝ 8 | 9 | ${AnsiColor.BRIGHT_BLUE}:: JHipster 🤓 :: Running Spring Boot ${spring-boot.version} :: 10 | :: http://jhipster.github.io ::${AnsiColor.DEFAULT} 11 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/login/login-modal.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; 3 | 4 | import { JhiLoginModalComponent } from './login.component'; 5 | 6 | @Injectable() 7 | export class LoginModalService { 8 | private isOpen = false; 9 | constructor( 10 | private modalService: NgbModal, 11 | ) {} 12 | 13 | open(): NgbModalRef { 14 | if (this.isOpen) { 15 | return; 16 | } 17 | this.isOpen = true; 18 | const modalRef = this.modalService.open(JhiLoginModalComponent, { 19 | container: 'nav' 20 | }); 21 | modalRef.result.then((result) => { 22 | this.isOpen = false; 23 | }, (reason) => { 24 | this.isOpen = false; 25 | }); 26 | return modalRef; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/javascript/spec/entry.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import 'core-js'; 3 | import 'zone.js/dist/zone'; 4 | import 'zone.js/dist/long-stack-trace-zone'; 5 | import 'zone.js/dist/async-test'; 6 | import 'zone.js/dist/fake-async-test'; 7 | import 'zone.js/dist/sync-test'; 8 | import 'zone.js/dist/proxy'; 9 | import 'zone.js/dist/jasmine-patch'; 10 | import 'rxjs'; 11 | import 'intl/locale-data/jsonp/en-US.js'; 12 | import { TestBed } from '@angular/core/testing'; 13 | import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; 14 | 15 | TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); 16 | 17 | declare let require: any; 18 | const testsContext: any = require.context('./', true, /\.spec/); 19 | testsContext.keys().forEach(testsContext); 20 | -------------------------------------------------------------------------------- /src/main/webapp/manifest.webapp: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Youtubedl", 3 | "short_name": "Youtubedl", 4 | "icons": [ 5 | { 6 | "src": "./content/images/logo-jhipster.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "./content/images/logo-jhipster.png", 12 | "sizes": "256x256", 13 | "type": "image/png" 14 | }, 15 | { 16 | "src": "./content/images/logo-jhipster.png", 17 | "sizes": "384x384", 18 | "type": "image/png" 19 | }, 20 | { 21 | "src": "./content/images/logo-jhipster.png", 22 | "sizes": "512x512", 23 | "type": "image/png" 24 | } 25 | ], 26 | "theme_color": "#000000", 27 | "background_color": "#e0e0e0", 28 | "start_url": "/index.html", 29 | "display": "standalone", 30 | "orientation": "portrait" 31 | } 32 | -------------------------------------------------------------------------------- /src/test/javascript/spec/test.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { MockBackend } from '@angular/http/testing'; 3 | import { Http, BaseRequestOptions } from '@angular/http'; 4 | import { JhiLanguageService } from 'ng-jhipster'; 5 | import { MockLanguageService } from './helpers/mock-language.service'; 6 | 7 | @NgModule({ 8 | providers: [ 9 | MockBackend, 10 | BaseRequestOptions, 11 | { 12 | provide: JhiLanguageService, 13 | useClass: MockLanguageService 14 | }, 15 | { 16 | provide: Http, 17 | useFactory: (backendInstance: MockBackend, defaultOptions: BaseRequestOptions) => { 18 | return new Http(backendInstance, defaultOptions); 19 | }, 20 | deps: [MockBackend, BaseRequestOptions] 21 | } 22 | ] 23 | }) 24 | export class YoutubedlTestModule {} 25 | -------------------------------------------------------------------------------- /src/main/resources/i18n/messages.properties: -------------------------------------------------------------------------------- 1 | # Error page 2 | error.title=Your request cannot be processed 3 | error.subtitle=Sorry, an error has occurred. 4 | error.status=Status: 5 | error.message=Message: 6 | 7 | # Activation email 8 | email.activation.title=youtubedl account activation 9 | email.activation.greeting=Dear {0} 10 | email.activation.text1=Your youtubedl account has been created, please click on the URL below to activate it: 11 | email.activation.text2=Regards, 12 | email.signature=youtubedl Team. 13 | 14 | # Creation email 15 | email.creation.text1=Your youtubedl account has been created, please click on the URL below to access it: 16 | 17 | # Reset email 18 | email.reset.title=youtubedl password reset 19 | email.reset.greeting=Dear {0} 20 | email.reset.text1=For your youtubedl account a password reset was requested, please click on the URL below to reset it: 21 | email.reset.text2=Regards, 22 | 23 | -------------------------------------------------------------------------------- /src/main/resources/i18n/messages_en.properties: -------------------------------------------------------------------------------- 1 | # Error page 2 | error.title=Your request cannot be processed 3 | error.subtitle=Sorry, an error has occurred. 4 | error.status=Status: 5 | error.message=Message: 6 | 7 | # Activation email 8 | email.activation.title=youtubedl account activation 9 | email.activation.greeting=Dear {0} 10 | email.activation.text1=Your youtubedl account has been created, please click on the URL below to activate it: 11 | email.activation.text2=Regards, 12 | email.signature=youtubedl Team. 13 | 14 | # Creation email 15 | email.creation.text1=Your youtubedl account has been created, please click on the URL below to access it: 16 | 17 | # Reset email 18 | email.reset.title=youtubedl password reset 19 | email.reset.greeting=Dear {0} 20 | email.reset.text1=For your youtubedl account a password reset was requested, please click on the URL below to reset it: 21 | email.reset.text2=Regards, 22 | 23 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/profiles/page-ribbon.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { ProfileService } from './profile.service'; 3 | import { ProfileInfo } from './profile-info.model'; 4 | 5 | @Component({ 6 | selector: 'jhi-page-ribbon', 7 | template: ``, 8 | styleUrls: [ 9 | 'page-ribbon.scss' 10 | ] 11 | }) 12 | export class PageRibbonComponent implements OnInit { 13 | 14 | profileInfo: ProfileInfo; 15 | ribbonEnv: string; 16 | 17 | constructor(private profileService: ProfileService) {} 18 | 19 | ngOnInit() { 20 | this.profileService.getProfileInfo().subscribe((profileInfo) => { 21 | this.profileInfo = profileInfo; 22 | this.ribbonEnv = profileInfo.ribbonEnv; 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/crawler/YoutubeDLException.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.crawler; 2 | 3 | /** 4 | * Created by csg on 2017/7/9. 5 | */ 6 | public class YoutubeDLException extends Exception { 7 | 8 | /** 9 | * Exception message 10 | */ 11 | private String message; 12 | 13 | /** 14 | * Construct YoutubeDLException with a message 15 | * @param message 16 | */ 17 | public YoutubeDLException(String message) { 18 | this.message = message; 19 | } 20 | 21 | /** 22 | * Construct YoutubeDLException from another exception 23 | * @param e Any exception 24 | */ 25 | public YoutubeDLException(Exception e) { 26 | message = e.getMessage(); 27 | } 28 | 29 | /** 30 | * Get exception message 31 | * @return exception message 32 | */ 33 | @Override 34 | public String getMessage() { 35 | return message; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/user-management.json: -------------------------------------------------------------------------------- 1 | { 2 | "userManagement": { 3 | "home": { 4 | "title": "用户", 5 | "createLabel": "创建新用户", 6 | "createOrEditLabel": "创建或编辑用户" 7 | }, 8 | "created": "用户 {{ param }} 创建成功", 9 | "updated": "用户 {{ param }} 更新成功", 10 | "deleted": "用户 {{ param }} 删除成功", 11 | "delete": { 12 | "question": "你确定要删除用户 {{ login }} ?" 13 | }, 14 | "detail": { 15 | "title": "用户" 16 | }, 17 | "login": "登录", 18 | "firstName": "名字", 19 | "lastName": "姓氏", 20 | "email": "邮箱", 21 | "activated": "已激活", 22 | "deactivated": "失效", 23 | "profiles": "角色", 24 | "langKey": "语言", 25 | "createdBy": "创建人", 26 | "createdDate": "创建时间", 27 | "lastModifiedBy": "最近修改人", 28 | "lastModifiedDate": "最近修改时间" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/ApplicationWebXml.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl; 2 | 3 | import com.caosg.ytbdl.config.DefaultProfileUtil; 4 | import org.springframework.boot.builder.SpringApplicationBuilder; 5 | import org.springframework.boot.web.support.SpringBootServletInitializer; 6 | 7 | /** 8 | * This is a helper Java class that provides an alternative to creating a web.xml. 9 | * This will be invoked only when the application is deployed to a servlet container like Tomcat, JBoss etc. 10 | */ 11 | public class ApplicationWebXml extends SpringBootServletInitializer { 12 | 13 | @Override 14 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 15 | /** 16 | * set a default to use when no profile is configured. 17 | */ 18 | DefaultProfileUtil.addDefaultProfile(application.application()); 19 | return application.sources(YoutubedlApp.class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/alert/alert.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnDestroy, OnInit } from '@angular/core'; 2 | import { JhiAlertService } from 'ng-jhipster'; 3 | 4 | @Component({ 5 | selector: 'jhi-alert', 6 | template: ` 7 | ` 14 | }) 15 | export class JhiAlertComponent implements OnInit, OnDestroy { 16 | alerts: any[]; 17 | 18 | constructor(private alertService: JhiAlertService) { } 19 | 20 | ngOnInit() { 21 | this.alerts = this.alertService.get(); 22 | } 23 | 24 | ngOnDestroy() { 25 | this.alerts = []; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/domain/StringSetConverter.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.domain; 2 | 3 | import org.apache.commons.collections.CollectionUtils; 4 | import org.springframework.util.StringUtils; 5 | 6 | import javax.persistence.AttributeConverter; 7 | import javax.persistence.Convert; 8 | import java.util.*; 9 | 10 | /** 11 | * Created by shuguangcao on 2017/7/10. 12 | */ 13 | @Convert 14 | public class StringSetConverter implements AttributeConverter, String> { 15 | 16 | @Override 17 | public String convertToDatabaseColumn(Set set) { 18 | if(CollectionUtils.isEmpty(set)) 19 | return ""; 20 | return String.join(",", set); 21 | 22 | } 23 | 24 | @Override 25 | public Set convertToEntityAttribute(String joined) { 26 | if(StringUtils.isEmpty(joined)) 27 | return null; 28 | Set set = new HashSet<>(Arrays.asList(joined.split(","))) ; 29 | return set; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/crawler/dto/ThumbnailsBean.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.crawler.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | /** 6 | * Created by csg on 2017/7/9. 7 | */ 8 | @JsonIgnoreProperties(ignoreUnknown = true) 9 | public class ThumbnailsBean { 10 | /** 11 | * url : https://r1.ykimg.com/0541040859073A661F8869289B0A987B 12 | * id : 0 13 | */ 14 | 15 | private String url; 16 | private String id; 17 | 18 | public String getUrl() { 19 | return url; 20 | } 21 | 22 | public void setUrl(String url) { 23 | this.url = url; 24 | } 25 | 26 | public String getId() { 27 | return id; 28 | } 29 | 30 | public void setId(String id) { 31 | this.id = id; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "ThumbnailsBean{" + 37 | "url='" + url + '\'' + 38 | ", id='" + id + '\'' + 39 | '}'; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/profiles/profile.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http, Response } from '@angular/http'; 3 | import { Observable } from 'rxjs/Rx'; 4 | 5 | import { ProfileInfo } from './profile-info.model'; 6 | 7 | @Injectable() 8 | export class ProfileService { 9 | 10 | private profileInfoUrl = 'api/profile-info'; 11 | 12 | constructor(private http: Http) { } 13 | 14 | getProfileInfo(): Observable { 15 | return this.http.get(this.profileInfoUrl) 16 | .map((res: Response) => { 17 | const data = res.json(); 18 | const pi = new ProfileInfo(); 19 | pi.activeProfiles = data.activeProfiles; 20 | pi.ribbonEnv = data.ribbonEnv; 21 | pi.inProduction = data.activeProfiles.indexOf('prod') !== -1; 22 | pi.swaggerEnabled = data.activeProfiles.indexOf('swagger') !== -1; 23 | return pi; 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/profiles/page-ribbon.scss: -------------------------------------------------------------------------------- 1 | 2 | /* ========================================================================== 3 | Developement Ribbon 4 | ========================================================================== */ 5 | .ribbon { 6 | background-color: rgba(170, 0, 0, 0.5); 7 | left: -3.5em; 8 | moz-transform: rotate(-45deg); 9 | ms-transform: rotate(-45deg); 10 | o-transform: rotate(-45deg); 11 | webkit-transform: rotate(-45deg); 12 | transform: rotate(-45deg); 13 | overflow: hidden; 14 | position: absolute; 15 | top: 40px; 16 | white-space: nowrap; 17 | width: 15em; 18 | z-index: 9999; 19 | pointer-events: none; 20 | opacity: 0.75; 21 | a { 22 | color: #fff; 23 | display: block; 24 | font-weight: 400; 25 | margin: 1px 0; 26 | padding: 10px 50px; 27 | text-align: center; 28 | text-decoration: none; 29 | text-shadow: 0 0 5px #444; 30 | pointer-events: none; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/domain/String2SetDeserializer.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.domain; 2 | 3 | import com.fasterxml.jackson.core.JsonParser; 4 | import com.fasterxml.jackson.core.JsonProcessingException; 5 | import com.fasterxml.jackson.databind.DeserializationContext; 6 | import com.fasterxml.jackson.databind.JsonDeserializer; 7 | import org.mapstruct.ap.internal.util.Collections; 8 | import org.springframework.util.StringUtils; 9 | 10 | import java.io.IOException; 11 | import java.util.Set; 12 | 13 | /** 14 | * Created by shuguangcao on 2017/7/10. 15 | */ 16 | public class String2SetDeserializer extends JsonDeserializer> { 17 | @Override 18 | public Set deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { 19 | String tagString = jsonParser.getValueAsString(); 20 | if(StringUtils.isEmpty(tagString)) return null; 21 | Set tags = Collections.asSet(tagString.split(",")) ; 22 | return tags; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/webapp/app/blocks/interceptor/errorhandler.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { JhiHttpInterceptor, JhiEventManager } from 'ng-jhipster'; 2 | import { RequestOptionsArgs, Response } from '@angular/http'; 3 | import { Observable } from 'rxjs/Observable'; 4 | 5 | export class ErrorHandlerInterceptor extends JhiHttpInterceptor { 6 | 7 | constructor(private eventManager: JhiEventManager) { 8 | super(); 9 | } 10 | 11 | requestIntercept(options?: RequestOptionsArgs): RequestOptionsArgs { 12 | return options; 13 | } 14 | 15 | responseIntercept(observable: Observable): Observable { 16 | return > observable.catch((error) => { 17 | if (!(error.status === 401 && (error.text() === '' || 18 | (error.json().path && error.json().path.indexOf('/api/account') === 0 )))) { 19 | this.eventManager.broadcast( {name: 'youtubedlApp.httpError', content: error}); 20 | } 21 | return Observable.throw(error); 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/webapp/app/home/home.scss: -------------------------------------------------------------------------------- 1 | 2 | /* ========================================================================== 3 | Main page styles 4 | ========================================================================== */ 5 | 6 | .hipster { 7 | display: inline-block; 8 | width: 347px; 9 | height: 497px; 10 | background: url("../../content/images/hipster.png") no-repeat center top; 11 | background-size: contain; 12 | } 13 | 14 | /* wait autoprefixer update to allow simple generation of high pixel density media query */ 15 | @media 16 | only screen and (-webkit-min-device-pixel-ratio: 2), 17 | only screen and ( min--moz-device-pixel-ratio: 2), 18 | only screen and ( -o-min-device-pixel-ratio: 2/1), 19 | only screen and ( min-device-pixel-ratio: 2), 20 | only screen and ( min-resolution: 192dpi), 21 | only screen and ( min-resolution: 2dppx) { 22 | .hipster { 23 | background: url("../../content/images/hipster2x.png") no-repeat center top; 24 | background-size: contain; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/logs/logs.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { Log } from './log.model'; 4 | import { LogsService } from './logs.service'; 5 | 6 | @Component({ 7 | selector: 'jhi-logs', 8 | templateUrl: './logs.component.html', 9 | }) 10 | export class LogsComponent implements OnInit { 11 | 12 | loggers: Log[]; 13 | filter: string; 14 | orderProp: string; 15 | reverse: boolean; 16 | 17 | constructor( 18 | private logsService: LogsService 19 | ) { 20 | this.filter = ''; 21 | this.orderProp = 'name'; 22 | this.reverse = false; 23 | } 24 | 25 | ngOnInit() { 26 | this.logsService.findAll().subscribe((loggers) => this.loggers = loggers); 27 | } 28 | 29 | changeLevel(name: string, level: string) { 30 | const log = new Log(name, level); 31 | this.logsService.changeLevel(log).subscribe(() => { 32 | this.logsService.findAll().subscribe((loggers) => this.loggers = loggers); 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { JhiHttpInterceptor } from 'ng-jhipster'; 2 | import { RequestOptionsArgs, Response } from '@angular/http'; 3 | import { Observable } from 'rxjs/Observable'; 4 | import { Injector } from '@angular/core'; 5 | import { LoginService } from '../../shared/login/login.service'; 6 | 7 | export class AuthExpiredInterceptor extends JhiHttpInterceptor { 8 | 9 | constructor(private injector: Injector) { 10 | super(); 11 | } 12 | 13 | requestIntercept(options?: RequestOptionsArgs): RequestOptionsArgs { 14 | return options; 15 | } 16 | 17 | responseIntercept(observable: Observable): Observable { 18 | return > observable.catch((error, source) => { 19 | if (error.status === 401) { 20 | const loginService: LoginService = this.injector.get(LoginService); 21 | loginService.logout(); 22 | } 23 | return Observable.throw(error); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/security/jwt/JWTConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.security.jwt; 2 | 3 | import org.springframework.security.config.annotation.SecurityConfigurerAdapter; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.web.DefaultSecurityFilterChain; 6 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 7 | 8 | public class JWTConfigurer extends SecurityConfigurerAdapter { 9 | 10 | public static final String AUTHORIZATION_HEADER = "Authorization"; 11 | 12 | private TokenProvider tokenProvider; 13 | 14 | public JWTConfigurer(TokenProvider tokenProvider) { 15 | this.tokenProvider = tokenProvider; 16 | } 17 | 18 | @Override 19 | public void configure(HttpSecurity http) throws Exception { 20 | JWTFilter customFilter = new JWTFilter(tokenProvider); 21 | http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/webapp/app/blocks/interceptor/auth.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs/Observable'; 2 | import { RequestOptionsArgs, Response } from '@angular/http'; 3 | import { LocalStorageService, SessionStorageService } from 'ng2-webstorage'; 4 | import { JhiHttpInterceptor } from 'ng-jhipster'; 5 | 6 | export class AuthInterceptor extends JhiHttpInterceptor { 7 | 8 | constructor( 9 | private localStorage: LocalStorageService, 10 | private sessionStorage: SessionStorageService 11 | ) { 12 | super(); 13 | } 14 | 15 | requestIntercept(options?: RequestOptionsArgs): RequestOptionsArgs { 16 | const token = this.localStorage.retrieve('authenticationToken') || this.sessionStorage.retrieve('authenticationToken'); 17 | if (!!token) { 18 | options.headers.append('Authorization', 'Bearer ' + token); 19 | } 20 | return options; 21 | } 22 | 23 | responseIntercept(observable: Observable): Observable { 24 | return observable; // by pass 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/navbar/active-menu.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, OnInit, ElementRef, Renderer, Input} from '@angular/core'; 2 | import { TranslateService, LangChangeEvent } from '@ngx-translate/core'; 3 | 4 | @Directive({ 5 | selector: '[jhiActiveMenu]' 6 | }) 7 | export class ActiveMenuDirective implements OnInit { 8 | @Input() jhiActiveMenu: string; 9 | 10 | constructor(private el: ElementRef, private renderer: Renderer, private translateService: TranslateService) {} 11 | 12 | ngOnInit() { 13 | this.translateService.onLangChange.subscribe((event: LangChangeEvent) => { 14 | this.updateActiveFlag(event.lang); 15 | }); 16 | this.updateActiveFlag(this.translateService.currentLang); 17 | } 18 | 19 | updateActiveFlag(selectedLanguage) { 20 | if (this.jhiActiveMenu === selectedLanguage) { 21 | this.renderer.setElementClass(this.el.nativeElement, 'active', true); 22 | } else { 23 | this.renderer.setElementClass(this.el.nativeElement, 'active', false); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/resources/mails/creationEmail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JHipster creation 5 | 6 | 7 | 8 | 9 |

10 | Dear 11 |

12 |

13 | Your JHipster account has been created, please click on the URL below to access it: 14 |

15 |

16 | Login link 18 |

19 |

20 | Regards, 21 |
22 | JHipster. 23 |

24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/resources/mails/passwordResetEmail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JHipster password reset 5 | 6 | 7 | 8 | 9 |

10 | Dear 11 |

12 |

13 | For your JHipster account a password reset was requested, please click on the URL below to reset it: 14 |

15 |

16 | Reset Link 18 |

19 |

20 | Regards, 21 |
22 | JHipster. 23 |

24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/shared-libs.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { FormsModule } from '@angular/forms'; 3 | import { HttpModule } from '@angular/http'; 4 | import { CommonModule } from '@angular/common'; 5 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 6 | import { NgJhipsterModule } from 'ng-jhipster'; 7 | import { InfiniteScrollModule } from 'ngx-infinite-scroll'; 8 | import { CookieModule } from 'ngx-cookie'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | NgbModule.forRoot(), 13 | NgJhipsterModule.forRoot({ 14 | // set below to true to make alerts look like toast 15 | alertAsToast: false, 16 | i18nEnabled: true, 17 | defaultI18nLang: 'zh-cn' 18 | }), 19 | InfiniteScrollModule, 20 | CookieModule.forRoot() 21 | ], 22 | exports: [ 23 | FormsModule, 24 | HttpModule, 25 | CommonModule, 26 | NgbModule, 27 | NgJhipsterModule, 28 | InfiniteScrollModule 29 | ] 30 | }) 31 | export class YoutubedlSharedLibsModule {} 32 | -------------------------------------------------------------------------------- /src/main/resources/i18n/messages_zh_cn.properties: -------------------------------------------------------------------------------- 1 | # Error page 2 | error.title=\u60a8\u7684\u8bf7\u6c42\u65e0\u6cd5\u88ab\u5904\u7406 3 | error.subtitle=\u62b1\u6b49\u002c\u53d1\u751f\u4e86\u4e00\u4e2a\u9519\u8bef\u002e 4 | error.status=\u72b6\u6001: 5 | error.message=\u6d88\u606f: 6 | 7 | # Activation email 8 | email.activation.title=youtubedl \u6fc0\u6d3b\u8d26\u53f7 9 | email.activation.greeting=\u4eb2\u7231\u7684 {0} 10 | email.activation.text1=\u60A8\u7684 youtubedl \u8d26\u53f7\u5df2\u521b\u5efa\u6210\u529f, \u8bf7\u70b9\u51fb\u4e0b\u5217\u94fe\u63a5\u542f\u7528\u4f60\u7684\u8d26\u53f7: 11 | email.activation.text2=\u795D\u60A8\u4F7F\u7528\u6109\u5FEB, 12 | email.signature=youtubedl \u56e2\u961f. 13 | 14 | # Creation email 15 | email.creation.text1=Your youtubedl account has been created, please click on the URL below to access it: 16 | 17 | # Reset email 18 | email.reset.title=youtubedl password reset 19 | email.reset.greeting=Dear {0} 20 | email.reset.text1=For your youtubedl account a password reset was requested, please click on the URL below to reset it: 21 | email.reset.text2=Regards, 22 | 23 | -------------------------------------------------------------------------------- /src/main/resources/mails/activationEmail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JHipster activation 5 | 6 | 7 | 8 | 9 |

10 | Dear 11 |

12 |

13 | Your JHipster account has been created, please click on the URL below to activate it: 14 |

15 |

16 | Activation Link 18 |

19 |

20 | Regards, 21 |
22 | JHipster. 23 |

24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/index.ts: -------------------------------------------------------------------------------- 1 | export * from './activate/activate.component'; 2 | export * from './activate/activate.service'; 3 | export * from './activate/activate.route'; 4 | export * from './password/password.component'; 5 | export * from './password/password-strength-bar.component'; 6 | export * from './password/password.service'; 7 | export * from './password/password.route'; 8 | export * from './password-reset/finish/password-reset-finish.component'; 9 | export * from './password-reset/finish/password-reset-finish.service'; 10 | export * from './password-reset/finish/password-reset-finish.route'; 11 | export * from './password-reset/init/password-reset-init.component'; 12 | export * from './password-reset/init/password-reset-init.service'; 13 | export * from './password-reset/init/password-reset-init.route'; 14 | export * from './register/register.component'; 15 | export * from './register/register.service'; 16 | export * from './register/register.route'; 17 | export * from './settings/settings.component'; 18 | export * from './settings/settings.route'; 19 | export * from './account.route'; 20 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/service/util/RandomUtil.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.service.util; 2 | 3 | import org.apache.commons.lang3.RandomStringUtils; 4 | 5 | /** 6 | * Utility class for generating random Strings. 7 | */ 8 | public final class RandomUtil { 9 | 10 | private static final int DEF_COUNT = 20; 11 | 12 | private RandomUtil() { 13 | } 14 | 15 | /** 16 | * Generate a password. 17 | * 18 | * @return the generated password 19 | */ 20 | public static String generatePassword() { 21 | return RandomStringUtils.randomAlphanumeric(DEF_COUNT); 22 | } 23 | 24 | /** 25 | * Generate an activation key. 26 | * 27 | * @return the generated activation key 28 | */ 29 | public static String generateActivationKey() { 30 | return RandomStringUtils.randomNumeric(DEF_COUNT); 31 | } 32 | 33 | /** 34 | * Generate a reset key. 35 | * 36 | * @return the generated reset key 37 | */ 38 | public static String generateResetKey() { 39 | return RandomStringUtils.randomNumeric(DEF_COUNT); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/user-management/user-management-detail.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnDestroy } from '@angular/core'; 2 | import { ActivatedRoute } from '@angular/router'; 3 | import { Subscription } from 'rxjs/Rx'; 4 | 5 | import { User, UserService } from '../../shared'; 6 | 7 | @Component({ 8 | selector: 'jhi-user-mgmt-detail', 9 | templateUrl: './user-management-detail.component.html' 10 | }) 11 | export class UserMgmtDetailComponent implements OnInit, OnDestroy { 12 | 13 | user: User; 14 | private subscription: Subscription; 15 | 16 | constructor( 17 | private userService: UserService, 18 | private route: ActivatedRoute 19 | ) { 20 | } 21 | 22 | ngOnInit() { 23 | this.subscription = this.route.params.subscribe((params) => { 24 | this.load(params['login']); 25 | }); 26 | } 27 | 28 | load(login) { 29 | this.userService.find(login).subscribe((user) => { 30 | this.user = user; 31 | }); 32 | } 33 | 34 | ngOnDestroy() { 35 | this.subscription.unsubscribe(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/reset.json: -------------------------------------------------------------------------------- 1 | { 2 | "reset": { 3 | "request": { 4 | "title": "Reset your password", 5 | "form": { 6 | "button": "Reset password" 7 | }, 8 | "messages": { 9 | "info": "Enter the email address you used to register", 10 | "success": "Check your emails for details on how to reset your password.", 11 | "notfound": "Email address isn't registered! Please check and try again" 12 | } 13 | }, 14 | "finish" : { 15 | "title": "Reset password", 16 | "form": { 17 | "button": "Validate new password" 18 | }, 19 | "messages": { 20 | "info": "Choose a new password", 21 | "success": "Your password has been reset. Please ", 22 | "keymissing": "The reset key is missing.", 23 | "error": "Your password couldn't be reset. Remember a password request is only valid for 24 hours." 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/repository/PersistenceAuditEventRepository.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.repository; 2 | 3 | import com.caosg.ytbdl.domain.PersistentAuditEvent; 4 | import org.springframework.data.domain.Page; 5 | import org.springframework.data.domain.Pageable; 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | 8 | import java.time.Instant; 9 | import java.util.List; 10 | 11 | /** 12 | * Spring Data JPA repository for the PersistentAuditEvent entity. 13 | */ 14 | public interface PersistenceAuditEventRepository extends JpaRepository { 15 | 16 | List findByPrincipal(String principal); 17 | 18 | List findByAuditEventDateAfter(Instant after); 19 | 20 | List findByPrincipalAndAuditEventDateAfter(String principal, Instant after); 21 | 22 | List findByPrincipalAndAuditEventDateAfterAndAuditEventType(String principle, Instant after, String type); 23 | 24 | Page findAllByAuditEventDateBetween(Instant fromDate, Instant toDate, Pageable pageable); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/web/rest/vm/LoggerVM.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.web.rest.vm; 2 | 3 | import ch.qos.logback.classic.Logger; 4 | 5 | /** 6 | * View Model object for storing a Logback logger. 7 | */ 8 | public class LoggerVM { 9 | 10 | private String name; 11 | 12 | private String level; 13 | 14 | public LoggerVM(Logger logger) { 15 | this.name = logger.getName(); 16 | this.level = logger.getEffectiveLevel().toString(); 17 | } 18 | 19 | public LoggerVM() { 20 | // Empty public constructor used by Jackson. 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public void setName(String name) { 28 | this.name = name; 29 | } 30 | 31 | public String getLevel() { 32 | return level; 33 | } 34 | 35 | public void setLevel(String level) { 36 | this.level = level; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "LoggerVM{" + 42 | "name='" + name + '\'' + 43 | ", level='" + level + '\'' + 44 | '}'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/user/user.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var User = (function () { 4 | function User(id, login, firstName, lastName, email, activated, langKey, authorities, createdBy, createdDate, lastModifiedBy, lastModifiedDate, password) { 5 | this.id = id ? id : null; 6 | this.login = login ? login : null; 7 | this.firstName = firstName ? firstName : null; 8 | this.lastName = lastName ? lastName : null; 9 | this.email = email ? email : null; 10 | this.activated = activated ? activated : false; 11 | this.langKey = langKey ? langKey : null; 12 | this.authorities = authorities ? authorities : null; 13 | this.createdBy = createdBy ? createdBy : null; 14 | this.createdDate = createdDate ? createdDate : null; 15 | this.lastModifiedBy = lastModifiedBy ? lastModifiedBy : null; 16 | this.lastModifiedDate = lastModifiedDate ? lastModifiedDate : null; 17 | this.password = password ? password : null; 18 | } 19 | return User; 20 | }()); 21 | exports.User = User; 22 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/register.json: -------------------------------------------------------------------------------- 1 | { 2 | "register": { 3 | "title": "Registration", 4 | "form": { 5 | "button": "Register" 6 | }, 7 | "messages": { 8 | "validate": { 9 | "login": { 10 | "required": "Your username is required.", 11 | "minlength": "Your username is required to be at least 1 character.", 12 | "maxlength": "Your username cannot be longer than 50 characters.", 13 | "pattern": "Your username can only contain lower-case letters and digits." 14 | } 15 | }, 16 | "success": "Registration saved! Please check your email for confirmation.", 17 | "error": { 18 | "fail": "Registration failed! Please try again later.", 19 | "userexists": "Login name already registered! Please choose another one.", 20 | "emailexists": "Email is already in use! Please choose another one." 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/config/ThymeleafConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.config; 2 | 3 | import org.apache.commons.lang3.CharEncoding; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.context.annotation.*; 7 | import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; 8 | 9 | @Configuration 10 | public class ThymeleafConfiguration { 11 | 12 | @SuppressWarnings("unused") 13 | private final Logger log = LoggerFactory.getLogger(ThymeleafConfiguration.class); 14 | 15 | @Bean 16 | @Description("Thymeleaf template resolver serving HTML 5 emails") 17 | public ClassLoaderTemplateResolver emailTemplateResolver() { 18 | ClassLoaderTemplateResolver emailTemplateResolver = new ClassLoaderTemplateResolver(); 19 | emailTemplateResolver.setPrefix("mails/"); 20 | emailTemplateResolver.setSuffix(".html"); 21 | emailTemplateResolver.setTemplateMode("HTML5"); 22 | emailTemplateResolver.setCharacterEncoding(CharEncoding.UTF_8); 23 | emailTemplateResolver.setOrder(1); 24 | return emailTemplateResolver; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/video/video-delete-dialog.component.html: -------------------------------------------------------------------------------- 1 |
2 | 7 | 11 | 19 |
20 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/user-management.json: -------------------------------------------------------------------------------- 1 | { 2 | "userManagement": { 3 | "home": { 4 | "title": "Users", 5 | "createLabel": "Create a new user", 6 | "createOrEditLabel": "Create or edit a user" 7 | }, 8 | "created": "A new user is created with identifier {{ param }}", 9 | "updated": "An user is updated with identifier {{ param }}", 10 | "deleted": "An user is deleted with identifier {{ param }}", 11 | "delete": { 12 | "question": "Are you sure you want to delete user {{ login }}?" 13 | }, 14 | "detail": { 15 | "title": "User" 16 | }, 17 | "login": "Login", 18 | "firstName": "First name", 19 | "lastName": "Last name", 20 | "email": "Email", 21 | "activated": "Activated", 22 | "deactivated": "Deactivated", 23 | "profiles": "Profiles", 24 | "langKey": "Language", 25 | "createdBy": "Created by", 26 | "createdDate": "Created date", 27 | "lastModifiedBy": "Modified by", 28 | "lastModifiedDate": "Modified date" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.html: -------------------------------------------------------------------------------- 1 |
2 | 7 | 11 | 19 |
20 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "title": "[{{username}}] 的用户设置", 4 | "form": { 5 | "firstname": "名字", 6 | "firstname.placeholder": "您的名字", 7 | "lastname": "姓氏", 8 | "lastname.placeholder": "您的姓氏", 9 | "language": "语言", 10 | "button": "保存" 11 | }, 12 | "messages": { 13 | "error": { 14 | "fail": "发生错误! 设置无法保存.", 15 | "emailexists": "该邮件地址已被使用! 请使用另外的邮件地址." 16 | }, 17 | "success": "设置保存成功!", 18 | "validate": { 19 | "firstname": { 20 | "required": "您的名字是必填项.", 21 | "minlength": "您的名字长度至少要有1个字符", 22 | "maxlength": "您的名字长度不能超过50个字符" 23 | }, 24 | "lastname": { 25 | "required": "您的姓氏是必填项.", 26 | "minlength": "您的姓氏长度至少要有1个字符", 27 | "maxlength": "您的姓氏长度不能超过50个字符" 28 | } 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-jhipster": { 3 | "promptValues": { 4 | "packageName": "com.caosg.ytbdl", 5 | "nativeLanguage": "zh-cn" 6 | }, 7 | "jhipsterVersion": "4.6.0", 8 | "baseName": "youtubedl", 9 | "packageName": "com.caosg.ytbdl", 10 | "packageFolder": "com/caosg/ytbdl", 11 | "serverPort": "8080", 12 | "authenticationType": "jwt", 13 | "hibernateCache": "ehcache", 14 | "clusteredHttpSession": false, 15 | "websocket": false, 16 | "databaseType": "sql", 17 | "devDatabaseType": "h2Disk", 18 | "prodDatabaseType": "mysql", 19 | "searchEngine": false, 20 | "messageBroker": false, 21 | "serviceDiscoveryType": false, 22 | "buildTool": "maven", 23 | "enableSocialSignIn": false, 24 | "jwtSecretKey": "d65b524005028491b7862aced20378f6ed427717", 25 | "clientFramework": "angularX", 26 | "useSass": true, 27 | "clientPackageManager": "yarn", 28 | "applicationType": "monolith", 29 | "testFrameworks": [], 30 | "jhiPrefix": "jhi", 31 | "enableTranslation": true, 32 | "nativeLanguage": "zh-cn", 33 | "languages": [ 34 | "zh-cn", 35 | "en" 36 | ] 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/webapp/app/shared/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants/pagination.constants'; 2 | export * from './alert/alert.component'; 3 | export * from './alert/alert-error.component'; 4 | export * from './auth/csrf.service'; 5 | export * from './auth/state-storage.service'; 6 | export * from './auth/account.service'; 7 | export * from './auth/auth-jwt.service'; 8 | export * from './auth/principal.service'; 9 | export * from './auth/has-any-authority.directive'; 10 | export * from './auth/user-route-access-service'; 11 | export * from './language/language.constants'; 12 | export * from './language/language.helper'; 13 | export * from './language/find-language-from-key.pipe'; 14 | export * from './login/login.component'; 15 | export * from './login/login.service'; 16 | export * from './login/login-modal.service'; 17 | export * from './user/account.model'; 18 | export * from './user/user.model'; 19 | export * from './user/user.service'; 20 | export * from './model/response-wrapper.model'; 21 | export * from './model/request-util'; 22 | export * from './model/base-entity'; 23 | export * from './shared-libs.module'; 24 | export * from './shared-common.module'; 25 | export * from './shared.module'; 26 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/health/health-modal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; 3 | 4 | import { JhiHealthService } from './health.service'; 5 | 6 | @Component({ 7 | selector: 'jhi-health-modal', 8 | templateUrl: './health-modal.component.html' 9 | }) 10 | export class JhiHealthModalComponent { 11 | 12 | currentHealth: any; 13 | 14 | constructor(private healthService: JhiHealthService, public activeModal: NgbActiveModal) {} 15 | 16 | baseName(name) { 17 | return this.healthService.getBaseName(name); 18 | } 19 | 20 | subSystemName(name) { 21 | return this.healthService.getSubSystemName(name); 22 | } 23 | 24 | readableValue(value: number) { 25 | if (this.currentHealth.name !== 'diskSpace') { 26 | return value.toString(); 27 | } 28 | 29 | // Should display storage space in an human readable unit 30 | const val = value / 1073741824; 31 | if (val > 1) { // Value 32 | return val.toFixed(2) + ' GB'; 33 | } else { 34 | return (value / 1048576).toFixed(2) + ' MB'; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/auth/csrf.service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | Object.defineProperty(exports, "__esModule", { value: true }); 9 | var core_1 = require("@angular/core"); 10 | var CSRFService = (function () { 11 | function CSRFService(cookieService) { 12 | this.cookieService = cookieService; 13 | } 14 | CSRFService.prototype.getCSRF = function (name) { 15 | name = "" + (name ? name : 'XSRF-TOKEN'); 16 | return this.cookieService.get(name); 17 | }; 18 | return CSRFService; 19 | }()); 20 | CSRFService = __decorate([ 21 | core_1.Injectable() 22 | ], CSRFService); 23 | exports.CSRFService = CSRFService; 24 | -------------------------------------------------------------------------------- /src/main/webapp/content/scss/vendor.scss: -------------------------------------------------------------------------------- 1 | /* after changing this file run 'yarn run 'yarn run webpack:build' */ 2 | $fa-font-path: '~font-awesome/fonts'; 3 | 4 | /*************************** 5 | put Sass variables here: 6 | eg $input-color: red; 7 | ****************************/ 8 | 9 | @import 'node_modules/bootstrap/scss/bootstrap'; 10 | @import 'node_modules/font-awesome/scss/font-awesome'; 11 | 12 | .card-margin { 13 | margin-left: 1rem; 14 | margin-bottom: 1rem; 15 | width: 350px; 16 | } 17 | .album { 18 | padding-top: 1rem; 19 | background-color: #f7f7f7; 20 | } 21 | .video-img { 22 | opacity: 1; 23 | display: block; 24 | width: 100%; 25 | height: auto; 26 | transition: .5s ease; 27 | backface-visibility: hidden; 28 | } 29 | .play { 30 | transition: .5s ease; 31 | opacity: 0; 32 | position: absolute; 33 | top: 40%; 34 | left: 50%; 35 | transform: translate(-50%, -50%); 36 | -ms-transform: translate(-50%, -50%) 37 | } 38 | .card-img-top:hover .video-img{ 39 | opacity: 0.6; 40 | } 41 | .card-img-top:hover .play { 42 | opacity: 1; 43 | } 44 | .start { 45 | background-color: #41af11; 46 | color: white; 47 | font-size: 16px; 48 | padding: 16px 32px; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/activate/activate.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; 3 | import { ActivatedRoute } from '@angular/router'; 4 | 5 | import { ActivateService } from './activate.service'; 6 | import { LoginModalService } from '../../shared'; 7 | 8 | @Component({ 9 | selector: 'jhi-activate', 10 | templateUrl: './activate.component.html' 11 | }) 12 | export class ActivateComponent implements OnInit { 13 | error: string; 14 | success: string; 15 | modalRef: NgbModalRef; 16 | 17 | constructor( 18 | private activateService: ActivateService, 19 | private loginModalService: LoginModalService, 20 | private route: ActivatedRoute 21 | ) { 22 | } 23 | 24 | ngOnInit() { 25 | this.route.queryParams.subscribe((params) => { 26 | this.activateService.get(params['key']).subscribe(() => { 27 | this.error = null; 28 | this.success = 'OK'; 29 | }, () => { 30 | this.success = null; 31 | this.error = 'ERROR'; 32 | }); 33 | }); 34 | } 35 | 36 | login() { 37 | this.modalRef = this.loginModalService.open(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/main/main.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Router, ActivatedRouteSnapshot, NavigationEnd, RoutesRecognized } from '@angular/router'; 3 | 4 | import { JhiLanguageHelper, StateStorageService } from '../../shared'; 5 | 6 | @Component({ 7 | selector: 'jhi-main', 8 | templateUrl: './main.component.html' 9 | }) 10 | export class JhiMainComponent implements OnInit { 11 | 12 | constructor( 13 | private jhiLanguageHelper: JhiLanguageHelper, 14 | private router: Router, 15 | private $storageService: StateStorageService, 16 | ) {} 17 | 18 | private getPageTitle(routeSnapshot: ActivatedRouteSnapshot) { 19 | let title: string = (routeSnapshot.data && routeSnapshot.data['pageTitle']) ? routeSnapshot.data['pageTitle'] : 'youtubedlApp'; 20 | if (routeSnapshot.firstChild) { 21 | title = this.getPageTitle(routeSnapshot.firstChild) || title; 22 | } 23 | return title; 24 | } 25 | 26 | ngOnInit() { 27 | this.router.events.subscribe((event) => { 28 | if (event instanceof NavigationEnd) { 29 | this.jhiLanguageHelper.updateTitle(this.getPageTitle(this.router.routerState.snapshot.root)); 30 | } 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/video.json: -------------------------------------------------------------------------------- 1 | { 2 | "youtubedlApp": { 3 | "video" : { 4 | "home": { 5 | "title": "Videos", 6 | "createLabel": "Create a new Video", 7 | "createOrEditLabel": "Create or edit a Video" 8 | }, 9 | "created": "A new Video is created with identifier {{ param }}", 10 | "updated": "A Video is updated with identifier {{ param }}", 11 | "deleted": "A Video is deleted with identifier {{ param }}", 12 | "delete": { 13 | "question": "Are you sure you want to delete Video {{ id }}?" 14 | }, 15 | "detail": { 16 | "title": "Video" 17 | }, 18 | "extractor": "Extractor", 19 | "protocol": "Protocol", 20 | "uploader": "Uploader", 21 | "duration": "Duration", 22 | "vid": "Vid", 23 | "format": "Format", 24 | "title": "Title", 25 | "url": "Url", 26 | "width": "Width", 27 | "height": "Height", 28 | "ext": "Ext", 29 | "filesize": "Filesize", 30 | "thumbnail": "Thumbnail", 31 | "tags": "Tags", 32 | "webpageUrl": "Webpage Url" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.repository; 2 | 3 | import com.caosg.ytbdl.domain.User; 4 | import org.springframework.data.domain.Page; 5 | import org.springframework.data.domain.Pageable; 6 | import org.springframework.data.jpa.repository.EntityGraph; 7 | import org.springframework.data.jpa.repository.JpaRepository; 8 | import org.springframework.stereotype.Repository; 9 | import java.util.List; 10 | import java.util.Optional; 11 | import java.time.Instant; 12 | 13 | /** 14 | * Spring Data JPA repository for the User entity. 15 | */ 16 | @Repository 17 | public interface UserRepository extends JpaRepository { 18 | 19 | Optional findOneByActivationKey(String activationKey); 20 | 21 | List findAllByActivatedIsFalseAndCreatedDateBefore(Instant dateTime); 22 | 23 | Optional findOneByResetKey(String resetKey); 24 | 25 | Optional findOneByEmail(String email); 26 | 27 | Optional findOneByLogin(String login); 28 | 29 | @EntityGraph(attributePaths = "authorities") 30 | User findOneWithAuthoritiesById(Long id); 31 | 32 | @EntityGraph(attributePaths = "authorities") 33 | Optional findOneWithAuthoritiesByLogin(String login); 34 | 35 | Page findAllByLoginNot(Pageable pageable, String login); 36 | } 37 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/auth/account.service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | Object.defineProperty(exports, "__esModule", { value: true }); 9 | var core_1 = require("@angular/core"); 10 | var AccountService = (function () { 11 | function AccountService(http) { 12 | this.http = http; 13 | } 14 | AccountService.prototype.get = function () { 15 | return this.http.get('api/account').map(function (res) { return res.json(); }); 16 | }; 17 | AccountService.prototype.save = function (account) { 18 | return this.http.post('api/account', account); 19 | }; 20 | return AccountService; 21 | }()); 22 | AccountService = __decorate([ 23 | core_1.Injectable() 24 | ], AccountService); 25 | exports.AccountService = AccountService; 26 | -------------------------------------------------------------------------------- /src/main/webapp/sw.js: -------------------------------------------------------------------------------- 1 | var dataCacheName = 'Youtubedl-v1'; 2 | var cacheName = 'Youtubedl-1'; 3 | var filesToCache = [ 4 | '/', 5 | '/index.html' 6 | ]; 7 | 8 | self.addEventListener('install', function(e) { 9 | console.log('[ServiceWorker] Install'); 10 | e.waitUntil( 11 | caches.open(cacheName).then(function(cache) { 12 | console.log('[ServiceWorker] Caching app shell'); 13 | return cache.addAll(filesToCache); 14 | }) 15 | ); 16 | }); 17 | 18 | self.addEventListener('activate', function(e) { 19 | console.log('[ServiceWorker] Activate'); 20 | e.waitUntil( 21 | caches.keys().then(function(keyList) { 22 | return Promise.all(keyList.map(function(key) { 23 | if (key !== cacheName && key !== dataCacheName) { 24 | console.log('[ServiceWorker] Removing old cache', key); 25 | return caches.delete(key); 26 | } 27 | })); 28 | }) 29 | ); 30 | return self.clients.claim(); 31 | }); 32 | 33 | self.addEventListener('fetch', function(e) { 34 | console.log('[Service Worker] Fetch', e.request.url); 35 | e.respondWith( 36 | caches.match(e.request).then(function(response) { 37 | return response || fetch(e.request); 38 | }) 39 | ); 40 | }); 41 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/account.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; 2 | import { RouterModule } from '@angular/router'; 3 | 4 | import { YoutubedlSharedModule } from '../shared'; 5 | 6 | import { 7 | Register, 8 | ActivateService, 9 | PasswordService, 10 | PasswordResetInitService, 11 | PasswordResetFinishService, 12 | PasswordStrengthBarComponent, 13 | RegisterComponent, 14 | ActivateComponent, 15 | PasswordComponent, 16 | PasswordResetInitComponent, 17 | PasswordResetFinishComponent, 18 | SettingsComponent, 19 | accountState 20 | } from './'; 21 | 22 | @NgModule({ 23 | imports: [ 24 | YoutubedlSharedModule, 25 | RouterModule.forRoot(accountState, { useHash: true }) 26 | ], 27 | declarations: [ 28 | ActivateComponent, 29 | RegisterComponent, 30 | PasswordComponent, 31 | PasswordStrengthBarComponent, 32 | PasswordResetInitComponent, 33 | PasswordResetFinishComponent, 34 | SettingsComponent 35 | ], 36 | providers: [ 37 | Register, 38 | ActivateService, 39 | PasswordService, 40 | PasswordResetInitService, 41 | PasswordResetFinishService 42 | ], 43 | schemas: [CUSTOM_ELEMENTS_SCHEMA] 44 | }) 45 | export class YoutubedlAccountModule {} 46 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; 2 | import { DatePipe } from '@angular/common'; 3 | 4 | import { 5 | YoutubedlSharedLibsModule, 6 | YoutubedlSharedCommonModule, 7 | CSRFService, 8 | AuthServerProvider, 9 | AccountService, 10 | UserService, 11 | StateStorageService, 12 | LoginService, 13 | LoginModalService, 14 | Principal, 15 | HasAnyAuthorityDirective, 16 | JhiLoginModalComponent 17 | } from './'; 18 | 19 | @NgModule({ 20 | imports: [ 21 | YoutubedlSharedLibsModule, 22 | YoutubedlSharedCommonModule 23 | ], 24 | declarations: [ 25 | JhiLoginModalComponent, 26 | HasAnyAuthorityDirective 27 | ], 28 | providers: [ 29 | LoginService, 30 | LoginModalService, 31 | AccountService, 32 | StateStorageService, 33 | Principal, 34 | CSRFService, 35 | AuthServerProvider, 36 | UserService, 37 | DatePipe 38 | ], 39 | entryComponents: [JhiLoginModalComponent], 40 | exports: [ 41 | YoutubedlSharedCommonModule, 42 | JhiLoginModalComponent, 43 | HasAnyAuthorityDirective, 44 | DatePipe 45 | ], 46 | schemas: [CUSTOM_ELEMENTS_SCHEMA] 47 | 48 | }) 49 | export class YoutubedlSharedModule {} 50 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/web/rest/LogsResource.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.web.rest; 2 | 3 | import com.caosg.ytbdl.web.rest.vm.LoggerVM; 4 | 5 | import ch.qos.logback.classic.Level; 6 | import ch.qos.logback.classic.LoggerContext; 7 | import com.codahale.metrics.annotation.Timed; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.http.HttpStatus; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import java.util.List; 13 | import java.util.stream.Collectors; 14 | 15 | /** 16 | * Controller for view and managing Log Level at runtime. 17 | */ 18 | @RestController 19 | @RequestMapping("/management") 20 | public class LogsResource { 21 | 22 | @GetMapping("/logs") 23 | @Timed 24 | public List getList() { 25 | LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); 26 | return context.getLoggerList() 27 | .stream() 28 | .map(LoggerVM::new) 29 | .collect(Collectors.toList()); 30 | } 31 | 32 | @PutMapping("/logs") 33 | @ResponseStatus(HttpStatus.NO_CONTENT) 34 | @Timed 35 | public void changeLevel(@RequestBody LoggerVM jsonLogger) { 36 | LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); 37 | context.getLogger(jsonLogger.getName()).setLevel(Level.valueOf(jsonLogger.getLevel())); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /webpack/utils.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | module.exports = { 5 | parseVersion, 6 | root, 7 | isExternalLib 8 | }; 9 | 10 | const parseString = require('xml2js').parseString; 11 | // return the version number from `pom.xml` file 12 | function parseVersion() { 13 | let version = null; 14 | const pomXml = fs.readFileSync('pom.xml', 'utf8'); 15 | parseString(pomXml, (err, result) => { 16 | if (result.project.version && result.project.version[0]) { 17 | version = result.project.version[0]; 18 | } else if (result.project.parent && result.project.parent[0] && result.project.parent[0].version && result.project.parent[0].version[0]) { 19 | version = result.project.parent[0].version[0]; 20 | } 21 | }); 22 | if (version === null) { 23 | throw new Error('pom.xml is malformed. No version is defined'); 24 | } 25 | return version; 26 | } 27 | 28 | const _root = path.resolve(__dirname, '..'); 29 | 30 | function root(args) { 31 | args = Array.prototype.slice.call(arguments, 0); 32 | return path.join.apply(path, [_root].concat(args)); 33 | } 34 | 35 | function isExternalLib(module, check = /node_modules/) { 36 | const req = module.userRequest; 37 | if (typeof req !== 'string') { 38 | return false; 39 | } 40 | return req.search(check) >= 0; 41 | } 42 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password/password.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { Principal } from '../../shared'; 4 | import { PasswordService } from './password.service'; 5 | 6 | @Component({ 7 | selector: 'jhi-password', 8 | templateUrl: './password.component.html' 9 | }) 10 | export class PasswordComponent implements OnInit { 11 | doNotMatch: string; 12 | error: string; 13 | success: string; 14 | account: any; 15 | password: string; 16 | confirmPassword: string; 17 | 18 | constructor( 19 | private passwordService: PasswordService, 20 | private principal: Principal 21 | ) { 22 | } 23 | 24 | ngOnInit() { 25 | this.principal.identity().then((account) => { 26 | this.account = account; 27 | }); 28 | } 29 | 30 | changePassword() { 31 | if (this.password !== this.confirmPassword) { 32 | this.error = null; 33 | this.success = null; 34 | this.doNotMatch = 'ERROR'; 35 | } else { 36 | this.doNotMatch = null; 37 | this.passwordService.save(this.password).subscribe(() => { 38 | this.error = null; 39 | this.success = 'OK'; 40 | }, () => { 41 | this.success = null; 42 | this.error = 'ERROR'; 43 | }); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/zh-cn/video.json: -------------------------------------------------------------------------------- 1 | { 2 | "youtubedlApp": { 3 | "video" : { 4 | "home": { 5 | "title": "Videos", 6 | "createLabel": "Create a new Video", 7 | "createOrEditLabel": "Create or edit a Video" 8 | }, 9 | "created": "A new Video is created with identifier {{ param }}", 10 | "updated": "A Video is updated with identifier {{ param }}", 11 | "deleted": "A Video is deleted with identifier {{ param }}", 12 | "delete": { 13 | "question": "Are you sure you want to delete Video {{ id }}?" 14 | }, 15 | "detail": { 16 | "title": "视频" 17 | }, 18 | "play": "播放", 19 | "extractor": "来源", 20 | "protocol": "协议", 21 | "uploader": "上传者", 22 | "duration": "时长", 23 | "vid": "Vid", 24 | "format": "格式", 25 | "title": "标题", 26 | "url": "播放地址", 27 | "width": "长度", 28 | "height": "宽度", 29 | "ext": "格式", 30 | "filesize": "大小", 31 | "thumbnail": "封面", 32 | "tags": "标签", 33 | "webpageUrl": "视频地址", 34 | "error": { 35 | "webpageUrl": "视频网址不能为空", 36 | "playIsNull": "暂不支持播放" 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/crawler/YoutubeDLResponse.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.crawler; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * Created by csg on 2017/7/9. 7 | */ 8 | public class YoutubeDLResponse { 9 | private Map options; 10 | private String command; 11 | private int exitCode; 12 | private String out; 13 | private String err; 14 | private String directory; 15 | private int elapsedTime; 16 | 17 | public YoutubeDLResponse(String command, Map options, String directory, int exitCode, int elapsedTime, String out, String err) { 18 | this.command = command; 19 | this.options = options; 20 | this.directory = directory; 21 | this.elapsedTime = elapsedTime; 22 | this.exitCode = exitCode; 23 | this.out = out; 24 | this.err = err; 25 | } 26 | 27 | public String getCommand() { 28 | return command; 29 | } 30 | 31 | public int getExitCode() { 32 | return exitCode; 33 | } 34 | 35 | public String getOut() { 36 | return out; 37 | } 38 | 39 | public String getErr() { 40 | return err; 41 | } 42 | 43 | public Map getOptions() { 44 | return options; 45 | } 46 | 47 | public String getDirectory() { 48 | return directory; 49 | } 50 | 51 | public int getElapsedTime() { 52 | return elapsedTime; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function __export(m) { 3 | for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; 4 | } 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | __export(require("./constants/pagination.constants")); 7 | __export(require("./alert/alert.component")); 8 | __export(require("./alert/alert-error.component")); 9 | __export(require("./auth/csrf.service")); 10 | __export(require("./auth/state-storage.service")); 11 | __export(require("./auth/account.service")); 12 | __export(require("./auth/auth-jwt.service")); 13 | __export(require("./auth/principal.service")); 14 | __export(require("./auth/has-any-authority.directive")); 15 | __export(require("./auth/user-route-access-service")); 16 | __export(require("./language/language.constants")); 17 | __export(require("./language/language.helper")); 18 | __export(require("./language/find-language-from-key.pipe")); 19 | __export(require("./login/login.component")); 20 | __export(require("./login/login.service")); 21 | __export(require("./login/login-modal.service")); 22 | __export(require("./user/account.model")); 23 | __export(require("./user/user.model")); 24 | __export(require("./user/user.service")); 25 | __export(require("./model/response-wrapper.model")); 26 | __export(require("./model/request-util")); 27 | __export(require("./shared-libs.module")); 28 | __export(require("./shared-common.module")); 29 | __export(require("./shared.module")); 30 | -------------------------------------------------------------------------------- /src/main/webapp/i18n/en/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "title": "User settings for [{{username}}]", 4 | "form": { 5 | "firstname": "First Name", 6 | "firstname.placeholder": "Your first name", 7 | "lastname": "Last Name", 8 | "lastname.placeholder": "Your last name", 9 | "language": "Language", 10 | "button": "Save" 11 | }, 12 | "messages": { 13 | "error": { 14 | "fail": "An error has occurred! Settings could not be saved.", 15 | "emailexists": "Email is already in use! Please choose another one." 16 | }, 17 | "success": "Settings saved!", 18 | "validate": { 19 | "firstname": { 20 | "required": "Your first name is required.", 21 | "minlength": "Your first name is required to be at least 1 character", 22 | "maxlength": "Your first name cannot be longer than 50 characters" 23 | }, 24 | "lastname": { 25 | "required": "Your last name is required.", 26 | "minlength": "Your last name is required to be at least 1 character", 27 | "maxlength": "Your last name cannot be longer than 50 characters" 28 | } 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/index.ts: -------------------------------------------------------------------------------- 1 | export * from './audits/audits.component'; 2 | export * from './audits/audits.service'; 3 | export * from './audits/audits.route'; 4 | export * from './audits/audit.model'; 5 | export * from './audits/audit-data.model'; 6 | export * from './configuration/configuration.component'; 7 | export * from './configuration/configuration.service'; 8 | export * from './configuration/configuration.route'; 9 | export * from './docs/docs.component'; 10 | export * from './docs/docs.route'; 11 | export * from './health/health.component'; 12 | export * from './health/health-modal.component'; 13 | export * from './health/health.service'; 14 | export * from './health/health.route'; 15 | export * from './logs/logs.component'; 16 | export * from './logs/logs.service'; 17 | export * from './logs/logs.route'; 18 | export * from './logs/log.model'; 19 | export * from './metrics/metrics.component'; 20 | export * from './metrics/metrics-modal.component'; 21 | export * from './metrics/metrics.service'; 22 | export * from './metrics/metrics.route'; 23 | export * from './user-management/user-management-dialog.component'; 24 | export * from './user-management/user-management-delete-dialog.component'; 25 | export * from './user-management/user-management-detail.component'; 26 | export * from './user-management/user-management.component'; 27 | export * from './user-management/user-management.route'; 28 | export * from './user-management/user-modal.service'; 29 | export * from './admin.route'; 30 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/configuration/configuration.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { JhiConfigurationService } from './configuration.service'; 4 | 5 | @Component({ 6 | selector: 'jhi-configuration', 7 | templateUrl: './configuration.component.html' 8 | }) 9 | export class JhiConfigurationComponent implements OnInit { 10 | allConfiguration: any = null; 11 | configuration: any = null; 12 | configKeys: any[]; 13 | filter: string; 14 | orderProp: string; 15 | reverse: boolean; 16 | 17 | constructor( 18 | private configurationService: JhiConfigurationService 19 | ) { 20 | this.configKeys = []; 21 | this.filter = ''; 22 | this.orderProp = 'prefix'; 23 | this.reverse = false; 24 | } 25 | 26 | keys(dict): Array { 27 | return (dict === undefined) ? [] : Object.keys(dict); 28 | } 29 | 30 | ngOnInit() { 31 | this.configurationService.get().subscribe((configuration) => { 32 | this.configuration = configuration; 33 | 34 | for (const config of configuration) { 35 | if (config.properties !== undefined) { 36 | this.configKeys.push(Object.keys(config.properties)); 37 | } 38 | } 39 | }); 40 | 41 | this.configurationService.getEnv().subscribe((configuration) => { 42 | this.allConfiguration = configuration; 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/web/rest/vm/LoginVM.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.web.rest.vm; 2 | 3 | import com.caosg.ytbdl.config.Constants; 4 | import javax.validation.constraints.NotNull; 5 | import javax.validation.constraints.Pattern; 6 | import javax.validation.constraints.Size; 7 | 8 | /** 9 | * View Model object for storing a user's credentials. 10 | */ 11 | public class LoginVM { 12 | 13 | @Pattern(regexp = Constants.LOGIN_REGEX) 14 | @NotNull 15 | @Size(min = 1, max = 50) 16 | private String username; 17 | 18 | @NotNull 19 | @Size(min = ManagedUserVM.PASSWORD_MIN_LENGTH, max = ManagedUserVM.PASSWORD_MAX_LENGTH) 20 | private String password; 21 | 22 | private Boolean rememberMe; 23 | 24 | public String getUsername() { 25 | return username; 26 | } 27 | 28 | public void setUsername(String username) { 29 | this.username = username; 30 | } 31 | 32 | public String getPassword() { 33 | return password; 34 | } 35 | 36 | public void setPassword(String password) { 37 | this.password = password; 38 | } 39 | 40 | public Boolean isRememberMe() { 41 | return rememberMe; 42 | } 43 | 44 | public void setRememberMe(Boolean rememberMe) { 45 | this.rememberMe = rememberMe; 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return "LoginVM{" + 51 | "username='" + username + '\'' + 52 | ", rememberMe=" + rememberMe + 53 | '}'; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /.angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "project": { 4 | "name": "youtubedl" 5 | }, 6 | "apps": [{ 7 | "root": "src/main/webapp/", 8 | "outDir": "target/www/app", 9 | "assets": [ 10 | "content", 11 | "i18n", 12 | "favicon.ico" 13 | ], 14 | "index": "index.html", 15 | "main": "app/app.main.ts", 16 | "polyfills": "app/polyfills.ts", 17 | "test": "", 18 | "tsconfig": "../../../tsconfig.json", 19 | "prefix": "jhi", 20 | "mobile": false, 21 | "styles": [ 22 | "content/scss/vendor.scss", 23 | "content/scss/global.scss" 24 | ], 25 | "scripts": [] 26 | }], 27 | "lint": [{ 28 | "project": "../../../tsconfig.json" 29 | }, 30 | { 31 | "project": "../../../tsconfig-aot.json" 32 | } 33 | ], 34 | "test": { 35 | "karma": { 36 | "config": "src/test/javascript/karma.conf.js" 37 | } 38 | }, 39 | "defaults": { 40 | "styleExt": "scss", 41 | "prefixInterfaces": false, 42 | "component" : { 43 | "inlineStyle" : true, 44 | "inlineTemplate": false 45 | }, 46 | "spec": { 47 | "component": false, 48 | "directive": false, 49 | "pipe": false, 50 | "service": false 51 | } 52 | }, 53 | "packageManager": "yarn" 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/web/rest/errors/ErrorVM.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.web.rest.errors; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | /** 8 | * View Model for transferring error message with a list of field errors. 9 | */ 10 | public class ErrorVM implements Serializable { 11 | 12 | private static final long serialVersionUID = 1L; 13 | 14 | private final String message; 15 | private final String description; 16 | 17 | private List fieldErrors; 18 | 19 | public ErrorVM(String message) { 20 | this(message, null); 21 | } 22 | 23 | public ErrorVM(String message, String description) { 24 | this.message = message; 25 | this.description = description; 26 | } 27 | 28 | public ErrorVM(String message, String description, List fieldErrors) { 29 | this.message = message; 30 | this.description = description; 31 | this.fieldErrors = fieldErrors; 32 | } 33 | 34 | public void add(String objectName, String field, String message) { 35 | if (fieldErrors == null) { 36 | fieldErrors = new ArrayList<>(); 37 | } 38 | fieldErrors.add(new FieldErrorVM(objectName, field, message)); 39 | } 40 | 41 | public String getMessage() { 42 | return message; 43 | } 44 | 45 | public String getDescription() { 46 | return description; 47 | } 48 | 49 | public List getFieldErrors() { 50 | return fieldErrors; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/config/LocaleConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.config; 2 | 3 | import io.github.jhipster.config.locale.AngularCookieLocaleResolver; 4 | 5 | import org.springframework.context.EnvironmentAware; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.core.env.Environment; 9 | import org.springframework.web.servlet.LocaleResolver; 10 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 11 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 12 | import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; 13 | 14 | @Configuration 15 | public class LocaleConfiguration extends WebMvcConfigurerAdapter implements EnvironmentAware { 16 | 17 | @Override 18 | public void setEnvironment(Environment environment) { 19 | // unused 20 | } 21 | 22 | @Bean(name = "localeResolver") 23 | public LocaleResolver localeResolver() { 24 | AngularCookieLocaleResolver cookieLocaleResolver = new AngularCookieLocaleResolver(); 25 | cookieLocaleResolver.setCookieName("NG_TRANSLATE_LANG_KEY"); 26 | return cookieLocaleResolver; 27 | } 28 | 29 | @Override 30 | public void addInterceptors(InterceptorRegistry registry) { 31 | LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); 32 | localeChangeInterceptor.setParamName("language"); 33 | registry.addInterceptor(localeChangeInterceptor); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/user-management/user-modal.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Component } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; 4 | 5 | import { User, UserService } from '../../shared'; 6 | 7 | @Injectable() 8 | export class UserModalService { 9 | private isOpen = false; 10 | constructor( 11 | private modalService: NgbModal, 12 | private router: Router, 13 | private userService: UserService 14 | ) {} 15 | 16 | open(component: Component, login?: string): NgbModalRef { 17 | if (this.isOpen) { 18 | return; 19 | } 20 | this.isOpen = true; 21 | 22 | if (login) { 23 | this.userService.find(login).subscribe((user) => this.userModalRef(component, user)); 24 | } else { 25 | return this.userModalRef(component, new User()); 26 | } 27 | } 28 | 29 | userModalRef(component: Component, user: User): NgbModalRef { 30 | const modalRef = this.modalService.open(component, { size: 'lg', backdrop: 'static'}); 31 | modalRef.componentInstance.user = user; 32 | modalRef.result.then((result) => { 33 | this.router.navigate([{ outlets: { popup: null }}], { replaceUrl: true }); 34 | this.isOpen = false; 35 | }, (reason) => { 36 | this.router.navigate([{ outlets: { popup: null }}], { replaceUrl: true }); 37 | this.isOpen = false; 38 | }); 39 | return modalRef; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/webapp/app/account/password-reset/init/password-reset-init.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, AfterViewInit, Renderer, ElementRef } from '@angular/core'; 2 | 3 | import { PasswordResetInitService } from './password-reset-init.service'; 4 | 5 | @Component({ 6 | selector: 'jhi-password-reset-init', 7 | templateUrl: './password-reset-init.component.html' 8 | }) 9 | export class PasswordResetInitComponent implements OnInit, AfterViewInit { 10 | error: string; 11 | errorEmailNotExists: string; 12 | resetAccount: any; 13 | success: string; 14 | 15 | constructor( 16 | private passwordResetInitService: PasswordResetInitService, 17 | private elementRef: ElementRef, 18 | private renderer: Renderer 19 | ) { 20 | } 21 | 22 | ngOnInit() { 23 | this.resetAccount = {}; 24 | } 25 | 26 | ngAfterViewInit() { 27 | this.renderer.invokeElementMethod(this.elementRef.nativeElement.querySelector('#email'), 'focus', []); 28 | } 29 | 30 | requestReset() { 31 | this.error = null; 32 | this.errorEmailNotExists = null; 33 | 34 | this.passwordResetInitService.save(this.resetAccount.email).subscribe(() => { 35 | this.success = 'OK'; 36 | }, (response) => { 37 | this.success = null; 38 | if (response.status === 400 && response.data === 'email address not registered') { 39 | this.errorEmailNotExists = 'ERROR'; 40 | } else { 41 | this.error = 'ERROR'; 42 | } 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/auth/has-any-authority.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; 2 | import { Principal } from './principal.service'; 3 | 4 | /** 5 | * @whatItDoes Conditionally includes an HTML element if current user has any 6 | * of the authorities passed as the `expression`. 7 | * 8 | * @howToUse 9 | * ``` 10 | * ... 11 | * 12 | * ... 13 | * ``` 14 | */ 15 | @Directive({ 16 | selector: '[jhiHasAnyAuthority]' 17 | }) 18 | export class HasAnyAuthorityDirective { 19 | 20 | private authorities: string[]; 21 | 22 | constructor(private principal: Principal, private templateRef: TemplateRef, private viewContainerRef: ViewContainerRef) { 23 | } 24 | 25 | @Input() 26 | set jhiHasAnyAuthority(value: string|string[]) { 27 | this.authorities = typeof value === 'string' ? [ value ] : value; 28 | this.updateView(); 29 | // Get notified each time authentication state changes. 30 | this.principal.getAuthenticationState().subscribe((identity) => this.updateView()); 31 | } 32 | 33 | private updateView(): void { 34 | this.principal.hasAnyAuthority(this.authorities).then((result) => { 35 | this.viewContainerRef.clear(); 36 | if (result) { 37 | this.viewContainerRef.createEmbeddedView(this.templateRef); 38 | } 39 | }); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/web/rest/vm/ManagedUserVM.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.web.rest.vm; 2 | 3 | import com.caosg.ytbdl.service.dto.UserDTO; 4 | import javax.validation.constraints.Size; 5 | 6 | import java.time.Instant; 7 | import java.util.Set; 8 | 9 | /** 10 | * View Model extending the UserDTO, which is meant to be used in the user management UI. 11 | */ 12 | public class ManagedUserVM extends UserDTO { 13 | 14 | public static final int PASSWORD_MIN_LENGTH = 4; 15 | 16 | public static final int PASSWORD_MAX_LENGTH = 100; 17 | 18 | @Size(min = PASSWORD_MIN_LENGTH, max = PASSWORD_MAX_LENGTH) 19 | private String password; 20 | 21 | public ManagedUserVM() { 22 | // Empty constructor needed for Jackson. 23 | } 24 | 25 | public ManagedUserVM(Long id, String login, String password, String firstName, String lastName, 26 | String email, boolean activated, String imageUrl, String langKey, 27 | String createdBy, Instant createdDate, String lastModifiedBy, Instant lastModifiedDate, 28 | Set authorities) { 29 | 30 | super(id, login, firstName, lastName, email, activated, imageUrl, langKey, 31 | createdBy, createdDate, lastModifiedBy, lastModifiedDate, authorities); 32 | 33 | this.password = password; 34 | } 35 | 36 | public String getPassword() { 37 | return password; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return "ManagedUserVM{" + 43 | "} " + super.toString(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/webapp/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Page Not Found 6 | 7 | 8 | 55 | 56 | 57 |

Page Not Found

58 |

Sorry, but the page you were trying to view does not exist.

59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/web/rest/errors/CustomParameterizedException.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.web.rest.errors; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * Custom, parameterized exception, which can be translated on the client side. 8 | * For example: 9 | * 10 | *
11 |  * throw new CustomParameterizedException("myCustomError", "hello", "world");
12 |  * 
13 | * 14 | * Can be translated with: 15 | * 16 | *
17 |  * "error.myCustomError" :  "The server says {{param0}} to {{param1}}"
18 |  * 
19 | */ 20 | public class CustomParameterizedException extends RuntimeException { 21 | 22 | private static final long serialVersionUID = 1L; 23 | 24 | private static final String PARAM = "param"; 25 | 26 | private final String message; 27 | 28 | private final Map paramMap = new HashMap<>(); 29 | 30 | public CustomParameterizedException(String message, String... params) { 31 | super(message); 32 | this.message = message; 33 | if (params != null && params.length > 0) { 34 | for (int i = 0; i < params.length; i++) { 35 | paramMap.put(PARAM + i, params[i]); 36 | } 37 | } 38 | } 39 | 40 | public CustomParameterizedException(String message, Map paramMap) { 41 | super(message); 42 | this.message = message; 43 | this.paramMap.putAll(paramMap); 44 | } 45 | 46 | public ParameterizedErrorVM getErrorVM() { 47 | return new ParameterizedErrorVM(message, paramMap); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/auth/state-storage.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { SessionStorageService } from 'ng2-webstorage'; 3 | 4 | @Injectable() 5 | export class StateStorageService { 6 | constructor( 7 | private $sessionStorage: SessionStorageService 8 | ) {} 9 | 10 | getPreviousState() { 11 | return this.$sessionStorage.retrieve('previousState'); 12 | } 13 | 14 | resetPreviousState() { 15 | this.$sessionStorage.clear('previousState'); 16 | } 17 | 18 | storePreviousState(previousStateName, previousStateParams) { 19 | const previousState = { 'name': previousStateName, 'params': previousStateParams }; 20 | this.$sessionStorage.store('previousState', previousState); 21 | } 22 | 23 | getDestinationState() { 24 | return this.$sessionStorage.retrieve('destinationState'); 25 | } 26 | 27 | storeUrl(url: string) { 28 | this.$sessionStorage.store('previousUrl', url); 29 | } 30 | 31 | getUrl() { 32 | return this.$sessionStorage.retrieve('previousUrl'); 33 | } 34 | 35 | storeDestinationState(destinationState, destinationStateParams, fromState) { 36 | const destinationInfo = { 37 | 'destination': { 38 | 'name': destinationState.name, 39 | 'data': destinationState.data, 40 | }, 41 | 'params': destinationStateParams, 42 | 'from': { 43 | 'name': fromState.name, 44 | } 45 | }; 46 | this.$sessionStorage.store('destinationState', destinationInfo); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/webapp/app/blocks/interceptor/http.provider.ts: -------------------------------------------------------------------------------- 1 | import { Injector } from '@angular/core'; 2 | import { Http, XHRBackend, RequestOptions } from '@angular/http'; 3 | import { JhiEventManager, JhiInterceptableHttp } from 'ng-jhipster'; 4 | 5 | import { AuthInterceptor } from './auth.interceptor'; 6 | import { LocalStorageService, SessionStorageService } from 'ng2-webstorage'; 7 | import { AuthExpiredInterceptor } from './auth-expired.interceptor'; 8 | import { ErrorHandlerInterceptor } from './errorhandler.interceptor'; 9 | import { NotificationInterceptor } from './notification.interceptor'; 10 | 11 | export function interceptableFactory( 12 | backend: XHRBackend, 13 | defaultOptions: RequestOptions, 14 | localStorage: LocalStorageService, 15 | sessionStorage: SessionStorageService, 16 | injector: Injector, 17 | eventManager: JhiEventManager 18 | ) { 19 | return new JhiInterceptableHttp( 20 | backend, 21 | defaultOptions, 22 | [ 23 | new AuthInterceptor(localStorage, sessionStorage), 24 | new AuthExpiredInterceptor(injector), 25 | // Other interceptors can be added here 26 | new ErrorHandlerInterceptor(eventManager), 27 | new NotificationInterceptor(injector) 28 | ] 29 | ); 30 | }; 31 | 32 | export function customHttpProvider() { 33 | return { 34 | provide: Http, 35 | useFactory: interceptableFactory, 36 | deps: [ 37 | XHRBackend, 38 | RequestOptions, 39 | LocalStorageService, 40 | SessionStorageService, 41 | Injector, 42 | JhiEventManager 43 | ] 44 | }; 45 | }; 46 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/video/video.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; 2 | import { RouterModule } from '@angular/router'; 3 | 4 | import { YoutubedlSharedModule } from '../../shared'; 5 | import { 6 | VideoService, 7 | VideoPopupService, 8 | VideoComponent, 9 | VideoDetailComponent, 10 | VideoDialogComponent, 11 | VideoPopupComponent, 12 | VideoDeletePopupComponent, 13 | VideoDeleteDialogComponent, 14 | videoRoute, 15 | videoPopupRoute, 16 | VideoResolvePagingParams, 17 | VideoPlayComponent, 18 | VideoPlayPopupComponent 19 | } from './'; 20 | 21 | const ENTITY_STATES = [ 22 | ...videoRoute, 23 | ...videoPopupRoute, 24 | ]; 25 | 26 | @NgModule({ 27 | imports: [ 28 | YoutubedlSharedModule, 29 | RouterModule.forRoot(ENTITY_STATES, { useHash: true }) 30 | ], 31 | declarations: [ 32 | VideoComponent, 33 | VideoDetailComponent, 34 | VideoDialogComponent, 35 | VideoDeleteDialogComponent, 36 | VideoPopupComponent, 37 | VideoDeletePopupComponent, 38 | VideoPlayComponent, 39 | VideoPlayPopupComponent 40 | ], 41 | entryComponents: [ 42 | VideoComponent, 43 | VideoDialogComponent, 44 | VideoPopupComponent, 45 | VideoDeleteDialogComponent, 46 | VideoDeletePopupComponent, 47 | VideoPlayComponent, 48 | VideoPlayPopupComponent 49 | ], 50 | providers: [ 51 | VideoService, 52 | VideoPopupService, 53 | VideoResolvePagingParams, 54 | ], 55 | schemas: [CUSTOM_ELEMENTS_SCHEMA] 56 | }) 57 | export class YoutubedlVideoModule {} 58 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/login/login.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { JhiLanguageService } from 'ng-jhipster'; 3 | 4 | import { Principal } from '../auth/principal.service'; 5 | import { AuthServerProvider } from '../auth/auth-jwt.service'; 6 | 7 | @Injectable() 8 | export class LoginService { 9 | 10 | constructor( 11 | private languageService: JhiLanguageService, 12 | private principal: Principal, 13 | private authServerProvider: AuthServerProvider 14 | ) {} 15 | 16 | login(credentials, callback?) { 17 | const cb = callback || function() {}; 18 | 19 | return new Promise((resolve, reject) => { 20 | this.authServerProvider.login(credentials).subscribe((data) => { 21 | this.principal.identity(true).then((account) => { 22 | // After the login the language will be changed to 23 | // the language selected by the user during his registration 24 | if (account !== null) { 25 | this.languageService.changeLanguage(account.langKey); 26 | } 27 | resolve(data); 28 | }); 29 | return cb(); 30 | }, (err) => { 31 | this.logout(); 32 | reject(err); 33 | return cb(err); 34 | }); 35 | }); 36 | } 37 | 38 | loginWithToken(jwt, rememberMe) { 39 | return this.authServerProvider.loginWithToken(jwt, rememberMe); 40 | } 41 | 42 | logout() { 43 | this.authServerProvider.logout().subscribe(); 44 | this.principal.authenticate(null); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/language/find-language-from-key.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({name: 'findLanguageFromKey'}) 4 | export class FindLanguageFromKeyPipe implements PipeTransform { 5 | private languages: any = { 6 | 'ca': { name: 'Català' }, 7 | 'cs': { name: 'Český' }, 8 | 'da': { name: 'Dansk' }, 9 | 'de': { name: 'Deutsch' }, 10 | 'el': { name: 'Ελληνικά' }, 11 | 'en': { name: 'English' }, 12 | 'es': { name: 'Español' }, 13 | 'et': { name: 'Eesti' }, 14 | 'fa': { name: 'فارسی', rtl: true }, 15 | 'fr': { name: 'Français' }, 16 | 'gl': { name: 'Galego' }, 17 | 'hu': { name: 'Magyar' }, 18 | 'hi': { name: 'हिंदी' }, 19 | 'hy': { name: 'Հայերեն' }, 20 | 'it': { name: 'Italiano' }, 21 | 'ja': { name: '日本語' }, 22 | 'ko': { name: '한국어' }, 23 | 'mr': { name: 'मराठी' }, 24 | 'nl': { name: 'Nederlands' }, 25 | 'pl': { name: 'Polski' }, 26 | 'pt-br': { name: 'Português (Brasil)' }, 27 | 'pt-pt': { name: 'Português' }, 28 | 'ro': { name: 'Română' }, 29 | 'ru': { name: 'Русский' }, 30 | 'sk': { name: 'Slovenský' }, 31 | 'sr': { name: 'Srpski' }, 32 | 'sv': { name: 'Svenska' }, 33 | 'ta': { name: 'தமிழ்' }, 34 | 'th': { name: 'ไทย' }, 35 | 'tr': { name: 'Türkçe' }, 36 | 'ua': { name: 'Українська' }, 37 | 'vi': { name: 'Tiếng Việt' }, 38 | 'zh-cn': { name: '中文(简体)' }, 39 | 'zh-tw': { name: '繁體中文' } 40 | }; 41 | transform(lang: string): string { 42 | return this.languages[lang].name; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/health/health.component.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | Health Checks 4 | 7 |

8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 25 | 30 | 31 | 32 |
Service NameStatusDetails
{{'health.indicator.' + baseName(health.name) | translate}} {{subSystemName(health.name)}} 21 | 22 | {{health.status}} 23 | 24 | 26 | 27 | 28 | 29 |
33 |
34 |
35 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/user/user.model.ts: -------------------------------------------------------------------------------- 1 | export class User { 2 | public id?: any; 3 | public login?: string; 4 | public firstName?: string; 5 | public lastName?: string; 6 | public email?: string; 7 | public activated?: Boolean; 8 | public langKey?: string; 9 | public authorities?: any[]; 10 | public createdBy?: string; 11 | public createdDate?: Date; 12 | public lastModifiedBy?: string; 13 | public lastModifiedDate?: Date; 14 | public password?: string; 15 | 16 | constructor( 17 | id?: any, 18 | login?: string, 19 | firstName?: string, 20 | lastName?: string, 21 | email?: string, 22 | activated?: Boolean, 23 | langKey?: string, 24 | authorities?: any[], 25 | createdBy?: string, 26 | createdDate?: Date, 27 | lastModifiedBy?: string, 28 | lastModifiedDate?: Date, 29 | password?: string 30 | ) { 31 | this.id = id ? id : null; 32 | this.login = login ? login : null; 33 | this.firstName = firstName ? firstName : null; 34 | this.lastName = lastName ? lastName : null; 35 | this.email = email ? email : null; 36 | this.activated = activated ? activated : false; 37 | this.langKey = langKey ? langKey : null; 38 | this.authorities = authorities ? authorities : null; 39 | this.createdBy = createdBy ? createdBy : null; 40 | this.createdDate = createdDate ? createdDate : null; 41 | this.lastModifiedBy = lastModifiedBy ? lastModifiedBy : null; 42 | this.lastModifiedDate = lastModifiedDate ? lastModifiedDate : null; 43 | this.password = password ? password : null; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/login/login-modal.service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | Object.defineProperty(exports, "__esModule", { value: true }); 9 | var core_1 = require("@angular/core"); 10 | var login_component_1 = require("./login.component"); 11 | var LoginModalService = (function () { 12 | function LoginModalService(modalService) { 13 | this.modalService = modalService; 14 | this.isOpen = false; 15 | } 16 | LoginModalService.prototype.open = function () { 17 | var _this = this; 18 | if (this.isOpen) { 19 | return; 20 | } 21 | this.isOpen = true; 22 | var modalRef = this.modalService.open(login_component_1.JhiLoginModalComponent, { 23 | container: 'nav' 24 | }); 25 | modalRef.result.then(function (result) { 26 | _this.isOpen = false; 27 | }, function (reason) { 28 | _this.isOpen = false; 29 | }); 30 | return modalRef; 31 | }; 32 | return LoginModalService; 33 | }()); 34 | LoginModalService = __decorate([ 35 | core_1.Injectable() 36 | ], LoginModalService); 37 | exports.LoginModalService = LoginModalService; 38 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/health/health-modal.component.html: -------------------------------------------------------------------------------- 1 | 9 | 34 | 37 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/domain/Authority.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.domain; 2 | 3 | import org.hibernate.annotations.Cache; 4 | import org.hibernate.annotations.CacheConcurrencyStrategy; 5 | import javax.persistence.Entity; 6 | import javax.persistence.Id; 7 | import javax.persistence.Table; 8 | import javax.persistence.Column; 9 | import javax.validation.constraints.NotNull; 10 | import javax.validation.constraints.Size; 11 | import java.io.Serializable; 12 | 13 | /** 14 | * An authority (a security role) used by Spring Security. 15 | */ 16 | @Entity 17 | @Table(name = "jhi_authority") 18 | @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 19 | public class Authority implements Serializable { 20 | 21 | private static final long serialVersionUID = 1L; 22 | 23 | @NotNull 24 | @Size(min = 0, max = 50) 25 | @Id 26 | @Column(length = 50) 27 | private String name; 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | @Override 38 | public boolean equals(Object o) { 39 | if (this == o) { 40 | return true; 41 | } 42 | if (o == null || getClass() != o.getClass()) { 43 | return false; 44 | } 45 | 46 | Authority authority = (Authority) o; 47 | 48 | return !(name != null ? !name.equals(authority.name) : authority.name != null); 49 | } 50 | 51 | @Override 52 | public int hashCode() { 53 | return name != null ? name.hashCode() : 0; 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | return "Authority{" + 59 | "name='" + name + '\'' + 60 | "}"; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/shared-common.module.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | Object.defineProperty(exports, "__esModule", { value: true }); 9 | var core_1 = require("@angular/core"); 10 | var platform_browser_1 = require("@angular/platform-browser"); 11 | var _1 = require("./"); 12 | var YoutubedlSharedCommonModule = (function () { 13 | function YoutubedlSharedCommonModule() { 14 | } 15 | return YoutubedlSharedCommonModule; 16 | }()); 17 | YoutubedlSharedCommonModule = __decorate([ 18 | core_1.NgModule({ 19 | imports: [ 20 | _1.YoutubedlSharedLibsModule 21 | ], 22 | declarations: [ 23 | _1.FindLanguageFromKeyPipe, 24 | _1.JhiAlertComponent, 25 | _1.JhiAlertErrorComponent 26 | ], 27 | providers: [ 28 | _1.JhiLanguageHelper, 29 | platform_browser_1.Title 30 | ], 31 | exports: [ 32 | _1.YoutubedlSharedLibsModule, 33 | _1.FindLanguageFromKeyPipe, 34 | _1.JhiAlertComponent, 35 | _1.JhiAlertErrorComponent 36 | ] 37 | }) 38 | ], YoutubedlSharedCommonModule); 39 | exports.YoutubedlSharedCommonModule = YoutubedlSharedCommonModule; 40 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/alert/alert.component.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | Object.defineProperty(exports, "__esModule", { value: true }); 9 | var core_1 = require("@angular/core"); 10 | var JhiAlertComponent = (function () { 11 | function JhiAlertComponent(alertService) { 12 | this.alertService = alertService; 13 | } 14 | JhiAlertComponent.prototype.ngOnInit = function () { 15 | this.alerts = this.alertService.get(); 16 | }; 17 | JhiAlertComponent.prototype.ngOnDestroy = function () { 18 | this.alerts = []; 19 | }; 20 | return JhiAlertComponent; 21 | }()); 22 | JhiAlertComponent = __decorate([ 23 | core_1.Component({ 24 | selector: 'jhi-alert', 25 | template: "\n
\n
\n \n
\n                
\n
\n
" 26 | }) 27 | ], JhiAlertComponent); 28 | exports.JhiAlertComponent = JhiAlertComponent; 29 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/metrics/metrics-modal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; 3 | 4 | @Component({ 5 | selector: 'jhi-metrics-modal', 6 | templateUrl: './metrics-modal.component.html' 7 | }) 8 | export class JhiMetricsMonitoringModalComponent implements OnInit { 9 | 10 | threadDumpFilter: any; 11 | threadDump: any; 12 | threadDumpAll = 0; 13 | threadDumpBlocked = 0; 14 | threadDumpRunnable = 0; 15 | threadDumpTimedWaiting = 0; 16 | threadDumpWaiting = 0; 17 | 18 | constructor(public activeModal: NgbActiveModal) {} 19 | 20 | ngOnInit() { 21 | this.threadDump.forEach((value) => { 22 | if (value.threadState === 'RUNNABLE') { 23 | this.threadDumpRunnable += 1; 24 | } else if (value.threadState === 'WAITING') { 25 | this.threadDumpWaiting += 1; 26 | } else if (value.threadState === 'TIMED_WAITING') { 27 | this.threadDumpTimedWaiting += 1; 28 | } else if (value.threadState === 'BLOCKED') { 29 | this.threadDumpBlocked += 1; 30 | } 31 | }); 32 | 33 | this.threadDumpAll = this.threadDumpRunnable + this.threadDumpWaiting + 34 | this.threadDumpTimedWaiting + this.threadDumpBlocked; 35 | } 36 | 37 | getBadgeClass(threadState) { 38 | if (threadState === 'RUNNABLE') { 39 | return 'badge-success'; 40 | } else if (threadState === 'WAITING') { 41 | return 'badge-info'; 42 | } else if (threadState === 'TIMED_WAITING') { 43 | return 'badge-warning'; 44 | } else if (threadState === 'BLOCKED') { 45 | return 'badge-danger'; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/auth/user-route-access-service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; 3 | 4 | import { Principal } from '../'; 5 | import { LoginModalService } from '../login/login-modal.service'; 6 | import { StateStorageService } from './state-storage.service'; 7 | 8 | @Injectable() 9 | export class UserRouteAccessService implements CanActivate { 10 | 11 | constructor(private router: Router, 12 | private loginModalService: LoginModalService, 13 | private principal: Principal, 14 | private stateStorageService: StateStorageService) { 15 | } 16 | 17 | canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Promise { 18 | 19 | const authorities = route.data['authorities']; 20 | if (!authorities || authorities.length === 0) { 21 | return true; 22 | } 23 | 24 | return this.checkLogin(authorities, state.url); 25 | } 26 | 27 | checkLogin(authorities: string[], url: string): Promise { 28 | const principal = this.principal; 29 | return Promise.resolve(principal.identity().then((account) => { 30 | 31 | if (account && principal.hasAnyAuthorityDirect(authorities)) { 32 | return true; 33 | } 34 | 35 | this.stateStorageService.storeUrl(url); 36 | this.router.navigate(['accessdenied']).then(() => { 37 | // only show the login dialog, if the user hasn't logged in yet 38 | if (!account) { 39 | this.loginModalService.open(); 40 | } 41 | }); 42 | return false; 43 | })); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/web/rest/util/HeaderUtil.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.web.rest.util; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.http.HttpHeaders; 6 | /** 7 | * Utility class for HTTP headers creation. 8 | */ 9 | public final class HeaderUtil { 10 | 11 | private static final Logger log = LoggerFactory.getLogger(HeaderUtil.class); 12 | 13 | private static final String APPLICATION_NAME = "youtubedlApp"; 14 | 15 | private HeaderUtil() { 16 | } 17 | 18 | public static HttpHeaders createAlert(String message, String param) { 19 | HttpHeaders headers = new HttpHeaders(); 20 | headers.add("X-youtubedlApp-alert", message); 21 | headers.add("X-youtubedlApp-params", param); 22 | return headers; 23 | } 24 | 25 | public static HttpHeaders createEntityCreationAlert(String entityName, String param) { 26 | return createAlert(APPLICATION_NAME + "." + entityName + ".created", param); 27 | } 28 | 29 | public static HttpHeaders createEntityUpdateAlert(String entityName, String param) { 30 | return createAlert(APPLICATION_NAME + "." + entityName + ".updated", param); 31 | } 32 | 33 | public static HttpHeaders createEntityDeletionAlert(String entityName, String param) { 34 | return createAlert(APPLICATION_NAME + "." + entityName + ".deleted", param); 35 | } 36 | 37 | public static HttpHeaders createFailureAlert(String entityName, String errorKey, String defaultMessage) { 38 | log.error("Entity processing failed, {}", defaultMessage); 39 | HttpHeaders headers = new HttpHeaders(); 40 | headers.add("X-youtubedlApp-error", "error." + errorKey); 41 | headers.add("X-youtubedlApp-params", entityName); 42 | return headers; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/webapp/app/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; 4 | import { JhiEventManager, JhiAlertService } from 'ng-jhipster'; 5 | 6 | import { Account, LoginModalService, Principal } from '../shared'; 7 | 8 | @Component({ 9 | selector: 'jhi-home', 10 | templateUrl: './home.component.html', 11 | styleUrls: [ 12 | 'home.scss' 13 | ] 14 | 15 | }) 16 | export class HomeComponent implements OnInit { 17 | account: Account; 18 | modalRef: NgbModalRef; 19 | videoUrl: ''; 20 | constructor( 21 | private principal: Principal, 22 | private loginModalService: LoginModalService, 23 | private eventManager: JhiEventManager, 24 | private alertService: JhiAlertService, 25 | private router: Router 26 | ) { 27 | } 28 | 29 | ngOnInit() { 30 | this.principal.identity().then((account) => { 31 | this.account = account; 32 | }); 33 | this.registerAuthenticationSuccess(); 34 | } 35 | 36 | registerAuthenticationSuccess() { 37 | this.eventManager.subscribe('authenticationSuccess', (message) => { 38 | this.principal.identity().then((account) => { 39 | this.account = account; 40 | }); 41 | }); 42 | } 43 | 44 | isAuthenticated() { 45 | return this.principal.isAuthenticated(); 46 | } 47 | 48 | login() { 49 | this.modalRef = this.loginModalService.open(); 50 | } 51 | 52 | parseVideo() { 53 | if (this.videoUrl.length === 0) { 54 | this.alertService.error('youtubedlApp.video.error.webpageUrl'); 55 | } 56 | this.router.navigate(['/video/parse', this.videoUrl]); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/webapp/app/blocks/interceptor/notification.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { JhiAlertService, JhiHttpInterceptor } from 'ng-jhipster'; 2 | import { RequestOptionsArgs, Response } from '@angular/http'; 3 | import { Injector } from '@angular/core'; 4 | import { Observable } from 'rxjs/Observable'; 5 | 6 | export class NotificationInterceptor extends JhiHttpInterceptor { 7 | 8 | private alertService: JhiAlertService; 9 | 10 | constructor(private injector: Injector) { 11 | super(); 12 | setTimeout(() => this.alertService = injector.get(JhiAlertService)); 13 | } 14 | 15 | requestIntercept(options?: RequestOptionsArgs): RequestOptionsArgs { 16 | return options; 17 | } 18 | 19 | responseIntercept(observable: Observable): Observable { 20 | return observable.map((response: Response) => { 21 | const headers = []; 22 | response.headers.forEach((value, name) => { 23 | if (name.toLowerCase().endsWith('app-alert') || name.toLowerCase().endsWith('app-params')) { 24 | headers.push(name); 25 | } 26 | }); 27 | if (headers.length > 1) { 28 | headers.sort(); 29 | const alertKey = response.headers.get(headers[ 0 ]); 30 | if (typeof alertKey === 'string') { 31 | if (this.alertService) { 32 | const alertParam = headers.length >= 2 ? response.headers.get(headers[ 1 ]) : null; 33 | this.alertService.success(alertKey, { param : alertParam }, null); 34 | } 35 | } 36 | } 37 | return response; 38 | }).catch((error) => { 39 | return Observable.throw(error); // here, response is an error 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/webapp/app/shared/user/user.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http, Response } from '@angular/http'; 3 | import { Observable } from 'rxjs/Rx'; 4 | 5 | import { User } from './user.model'; 6 | import { ResponseWrapper } from '../model/response-wrapper.model'; 7 | import { createRequestOption } from '../model/request-util'; 8 | 9 | @Injectable() 10 | export class UserService { 11 | private resourceUrl = 'api/users'; 12 | 13 | constructor(private http: Http) { } 14 | 15 | create(user: User): Observable { 16 | return this.http.post(this.resourceUrl, user) 17 | .map((res: Response) => this.convertResponse(res)); 18 | } 19 | 20 | update(user: User): Observable { 21 | return this.http.put(this.resourceUrl, user) 22 | .map((res: Response) => this.convertResponse(res)); 23 | } 24 | 25 | find(login: string): Observable { 26 | return this.http.get(`${this.resourceUrl}/${login}`).map((res: Response) => res.json()); 27 | } 28 | 29 | query(req?: any): Observable { 30 | const options = createRequestOption(req); 31 | return this.http.get(this.resourceUrl, options) 32 | .map((res: Response) => this.convertResponse(res)); 33 | } 34 | 35 | delete(login: string): Observable { 36 | return this.http.delete(`${this.resourceUrl}/${login}`); 37 | } 38 | 39 | authorities(): Observable { 40 | return this.http.get('api/users/authorities').map((res: Response) => { 41 | const json = res.json(); 42 | return json; 43 | }); 44 | } 45 | 46 | private convertResponse(res: Response): ResponseWrapper { 47 | const jsonResponse = res.json(); 48 | return new ResponseWrapper(res.headers, jsonResponse, res.status); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/configuration/configuration.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http, Response } from '@angular/http'; 3 | import { Observable } from 'rxjs/Rx'; 4 | 5 | @Injectable() 6 | export class JhiConfigurationService { 7 | 8 | constructor(private http: Http) { 9 | } 10 | 11 | get(): Observable { 12 | return this.http.get('management/configprops').map((res: Response) => { 13 | const properties: any[] = []; 14 | 15 | const propertiesObject = res.json(); 16 | 17 | for (const key in propertiesObject) { 18 | if (propertiesObject.hasOwnProperty(key)) { 19 | properties.push(propertiesObject[key]); 20 | } 21 | } 22 | 23 | return properties.sort((propertyA, propertyB) => { 24 | return (propertyA.prefix === propertyB.prefix) ? 0 : 25 | (propertyA.prefix < propertyB.prefix) ? -1 : 1; 26 | }); 27 | }); 28 | } 29 | 30 | getEnv(): Observable { 31 | return this.http.get('management/env').map((res: Response) => { 32 | const properties: any = {}; 33 | 34 | const propertiesObject = res.json(); 35 | 36 | for (const key in propertiesObject) { 37 | if (propertiesObject.hasOwnProperty(key)) { 38 | const valsObject = propertiesObject[key]; 39 | const vals: any[] = []; 40 | 41 | for (const valKey in valsObject) { 42 | if (valsObject.hasOwnProperty(valKey)) { 43 | vals.push({key: valKey, val: valsObject[valKey]}); 44 | } 45 | } 46 | properties[key] = vals; 47 | } 48 | } 49 | 50 | return properties; 51 | }); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/logs/logs.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Logs

3 | 4 |

There are {{ loggers.length }} loggers.

5 | 6 | Filter 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 25 | 26 |
NameLevel
{{logger.name | slice:0:140}} 19 | 20 | 21 | 22 | 23 | 24 |
27 |
28 | -------------------------------------------------------------------------------- /src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnDestroy } from '@angular/core'; 2 | import { ActivatedRoute } from '@angular/router'; 3 | import { NgbActiveModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; 4 | import { JhiEventManager } from 'ng-jhipster'; 5 | 6 | import { User, UserService } from '../../shared'; 7 | import { UserModalService } from './user-modal.service'; 8 | 9 | @Component({ 10 | selector: 'jhi-user-mgmt-delete-dialog', 11 | templateUrl: './user-management-delete-dialog.component.html' 12 | }) 13 | export class UserMgmtDeleteDialogComponent { 14 | 15 | user: User; 16 | 17 | constructor( 18 | private userService: UserService, 19 | public activeModal: NgbActiveModal, 20 | private eventManager: JhiEventManager 21 | ) { 22 | } 23 | 24 | clear() { 25 | this.activeModal.dismiss('cancel'); 26 | } 27 | 28 | confirmDelete(login) { 29 | this.userService.delete(login).subscribe((response) => { 30 | this.eventManager.broadcast({ name: 'userListModification', 31 | content: 'Deleted a user'}); 32 | this.activeModal.dismiss(true); 33 | }); 34 | } 35 | } 36 | 37 | @Component({ 38 | selector: 'jhi-user-delete-dialog', 39 | template: '' 40 | }) 41 | export class UserDeleteDialogComponent implements OnInit, OnDestroy { 42 | 43 | modalRef: NgbModalRef; 44 | routeSub: any; 45 | 46 | constructor( 47 | private route: ActivatedRoute, 48 | private userModalService: UserModalService 49 | ) {} 50 | 51 | ngOnInit() { 52 | this.routeSub = this.route.params.subscribe((params) => { 53 | this.modalRef = this.userModalService.open(UserMgmtDeleteDialogComponent, params['login']); 54 | }); 55 | } 56 | 57 | ngOnDestroy() { 58 | this.routeSub.unsubscribe(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/webapp/app/layouts/navbar/navbar.scss: -------------------------------------------------------------------------------- 1 | 2 | /* ========================================================================== 3 | Navbar 4 | ========================================================================== */ 5 | .navbar-version { 6 | font-size: 10px; 7 | color: #ccc 8 | } 9 | 10 | .jh-navbar { 11 | background-color: #353d47; 12 | padding: .2em 1em; 13 | .profile-image { 14 | margin: -10px 0px; 15 | height: 40px; 16 | width: 40px; 17 | border-radius: 50%; 18 | } 19 | .dropdown-item.active, .dropdown-item.active:focus, .dropdown-item.active:hover { 20 | background-color: #353d47; 21 | } 22 | .dropdown-toggle::after { 23 | margin-left: 0.15em; 24 | } 25 | ul.navbar-nav { 26 | padding: 0.5em; 27 | .nav-item { 28 | margin-left: 1.5rem; 29 | } 30 | } 31 | a.nav-link { 32 | font-weight: 400; 33 | } 34 | .jh-navbar-toggler { 35 | color: #ccc; 36 | font-size: 1.5em; 37 | padding: 10px; 38 | &:hover { 39 | color: #fff; 40 | } 41 | } 42 | } 43 | 44 | @media screen and (max-width: 992px) { 45 | .jh-logo-container { 46 | width: 100%; 47 | } 48 | } 49 | 50 | .navbar-title { 51 | display: inline-block; 52 | vertical-align: middle; 53 | } 54 | 55 | /* ========================================================================== 56 | Logo styles 57 | ========================================================================== */ 58 | .navbar-brand { 59 | &.logo { 60 | padding: 5px 15px; 61 | .logo-img { 62 | height: 45px; 63 | width: 70px; 64 | display: inline-block; 65 | vertical-align: middle; 66 | background: url("../../../content/images/logo-jhipster.png") no-repeat center center; 67 | background-size: contain; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/config/DefaultProfileUtil.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.config; 2 | 3 | import io.github.jhipster.config.JHipsterConstants; 4 | 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.core.env.Environment; 7 | 8 | import java.util.*; 9 | 10 | /** 11 | * Utility class to load a Spring profile to be used as default 12 | * when there is no spring.profiles.active set in the environment or as command line argument. 13 | * If the value is not available in application.yml then dev profile will be used as default. 14 | */ 15 | public final class DefaultProfileUtil { 16 | 17 | private static final String SPRING_PROFILE_DEFAULT = "spring.profiles.default"; 18 | 19 | private DefaultProfileUtil() { 20 | } 21 | 22 | /** 23 | * Set a default to use when no profile is configured. 24 | * 25 | * @param app the Spring application 26 | */ 27 | public static void addDefaultProfile(SpringApplication app) { 28 | Map defProperties = new HashMap<>(); 29 | /* 30 | * The default profile to use when no other profiles are defined 31 | * This cannot be set in the application.yml file. 32 | * See https://github.com/spring-projects/spring-boot/issues/1219 33 | */ 34 | defProperties.put(SPRING_PROFILE_DEFAULT, JHipsterConstants.SPRING_PROFILE_DEVELOPMENT); 35 | app.setDefaultProperties(defProperties); 36 | } 37 | 38 | /** 39 | * Get the profiles that are applied else get default profiles. 40 | * 41 | * @param env spring environment 42 | * @return profiles 43 | */ 44 | public static String[] getActiveProfiles(Environment env) { 45 | String[] profiles = env.getActiveProfiles(); 46 | if (profiles.length == 0) { 47 | return env.getDefaultProfiles(); 48 | } 49 | return profiles; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/caosg/ytbdl/web/rest/util/PaginationUtil.java: -------------------------------------------------------------------------------- 1 | package com.caosg.ytbdl.web.rest.util; 2 | 3 | import org.springframework.data.domain.Page; 4 | import org.springframework.http.HttpHeaders; 5 | import org.springframework.web.util.UriComponentsBuilder; 6 | 7 | /** 8 | * Utility class for handling pagination. 9 | * 10 | *

11 | * Pagination uses the same principles as the Github API, 12 | * and follow RFC 5988 (Link header). 13 | */ 14 | public final class PaginationUtil { 15 | 16 | private PaginationUtil() { 17 | } 18 | 19 | public static HttpHeaders generatePaginationHttpHeaders(Page page, String baseUrl) { 20 | 21 | HttpHeaders headers = new HttpHeaders(); 22 | headers.add("X-Total-Count", Long.toString(page.getTotalElements())); 23 | String link = ""; 24 | if ((page.getNumber() + 1) < page.getTotalPages()) { 25 | link = "<" + generateUri(baseUrl, page.getNumber() + 1, page.getSize()) + ">; rel=\"next\","; 26 | } 27 | // prev link 28 | if ((page.getNumber()) > 0) { 29 | link += "<" + generateUri(baseUrl, page.getNumber() - 1, page.getSize()) + ">; rel=\"prev\","; 30 | } 31 | // last and first link 32 | int lastPage = 0; 33 | if (page.getTotalPages() > 0) { 34 | lastPage = page.getTotalPages() - 1; 35 | } 36 | link += "<" + generateUri(baseUrl, lastPage, page.getSize()) + ">; rel=\"last\","; 37 | link += "<" + generateUri(baseUrl, 0, page.getSize()) + ">; rel=\"first\""; 38 | headers.add(HttpHeaders.LINK, link); 39 | return headers; 40 | } 41 | 42 | private static String generateUri(String baseUrl, int page, int size) { 43 | return UriComponentsBuilder.fromUriString(baseUrl).queryParam("page", page).queryParam("size", size).toUriString(); 44 | } 45 | } 46 | --------------------------------------------------------------------------------