Yoonjunhyeon

옛날 프론트엔드 삭제 및 yt8m 폴더 위치 변경

Showing 45 changed files with 0 additions and 688 deletions
......@@ -24,10 +24,6 @@ class VideoViewSet(viewsets.ModelViewSet):
queryset = Video.objects.all()
serializer_class = VideoSerializer
class VideoFileViewSet(viewsets.ModelViewSet):
queryset = VideoFile.objects.all()
serializer_class = VideoFileSerializer
......
# frontend
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn serve
```
### Compiles and minifies for production
```
yarn build
```
### Lints and fixes files
```
yarn lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"]
};
{
"name": "frontend",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@mdi/font": "^5.0.45",
"axios": "^0.19.2",
"core-js": "^3.6.4",
"filepond": "^4.13.0",
"filepond-plugin-file-validate-type": "^1.2.5",
"filepond-plugin-image-preview": "^4.6.1",
"moment": "^2.24.0",
"roboto-fontface": "*",
"vee-validate": "^3.2.5",
"vue": "^2.6.11",
"vue-filepond": "^6.0.2",
"vue-infinite-scroll": "^2.0.2",
"vue-router": "^3.1.5",
"vue-video-player": "^5.0.2",
"vuetify": "^2.2.11",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.2.0",
"@vue/cli-plugin-eslint": "~4.2.0",
"@vue/cli-plugin-router": "~4.2.0",
"@vue/cli-plugin-vuex": "~4.2.0",
"@vue/cli-service": "~4.2.0",
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.0.3",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-vue": "^6.1.2",
"node-sass": "^4.12.0",
"prettier": "^1.19.1",
"sass": "^1.19.0",
"sass-loader": "^8.0.2",
"vue-cli-plugin-vuetify": "~2.0.5",
"vue-template-compiler": "^2.6.11",
"vuetify-loader": "^1.3.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended",
"@vue/prettier"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
<template>
<v-app>
<v-app-bar app color="#ffffff" elevation="1">
<v-tabs grow v-model="tab">
<v-tab @click="$router.push('/')">Home</v-tab>
<v-tab @click="$router.push('/upload')">Upload</v-tab>
</v-tabs>
</v-app-bar>
<v-content>
<router-view />
</v-content>
<v-footer>
<v-row justify="center" @click="exDialog = true">
<v-avatar size="25" tile style="border-radius: 4px">
<v-img src="./assets/logo.png"></v-img>
</v-avatar>
<div>
<span
style="margin-left: 2px; font-size: 15px; color: #5a5a5a; font-weight: 400"
>
Profit-Hunter
</span>
<div
style="margin-left: 4px; margin-top: -1px; font-size: 10px; color: #888; font-weight: 400"
>
Used OpenSource
</div>
</div>
</v-row>
</v-footer>
</v-app>
</template>
<script>
export default {
name: "App",
data: () => ({
tab: null,
search: "",
exDialog: false
}),
mounted() {
console.log(window.location.href.substring(22));
if (window.location.href.substring(22) === "") {
this.tab = 0;
} else if (window.location.href.substring(22) === "upload") {
this.tab = 1;
} else {
this.tab = null;
}
}
};
</script>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 87.5 100"><defs><style>.cls-1{fill:#1697f6;}.cls-2{fill:#7bc6ff;}.cls-3{fill:#1867c0;}.cls-4{fill:#aeddff;}</style></defs><title>Artboard 46</title><polyline class="cls-1" points="43.75 0 23.31 0 43.75 48.32"/><polygon class="cls-2" points="43.75 62.5 43.75 100 0 14.58 22.92 14.58 43.75 62.5"/><polyline class="cls-3" points="43.75 0 64.19 0 43.75 48.32"/><polygon class="cls-4" points="64.58 14.58 87.5 14.58 43.75 100 43.75 62.5 64.58 14.58"/></svg>
<template>
<div>
<v-layout></v-layout>
<v-card></v-card>
</div>
</template>
<script>
export default {};
</script>
<style scoped></style>
<template>
<div>
<file-pond
name="bin"
ref="pond"
allow-multiple="false"
max-files="1"
:server="server"
v-bind:files="myFiles"
v-on:init="handleFilePondInit"
v-on:processfile="onload"
/>
</div>
</template>
<script>
// Import Vue FilePond
import vueFilePond from "vue-filepond";
// Import FilePond styles
import "filepond/dist/filepond.min.css";
// Import FilePond plugins
// Please note that you need to install these plugins separately
// Import image preview plugin styles
import "filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css";
// Import image preview and file type validation plugins
import FilePondPluginFileValidateType from "filepond-plugin-file-validate-type";
import FilePondPluginImagePreview from "filepond-plugin-image-preview";
// Create component
const FilePond = vueFilePond(
FilePondPluginFileValidateType,
FilePondPluginImagePreview
);
export default {
name: "app",
data() {
return {
myFiles: [],
server: {
url: `${this.$apiRootPath}upload/video`,
process: {}
}
};
},
methods: {
handleFilePondInit() {
console.log("FilePond has initialized");
// FilePond instance methods are available on `this.$refs.pond`
},
onload(e, r) {
console.log(r);
// this.$store.dispatch(r);
}
},
components: {
FilePond
}
};
</script>
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import vuetify from './plugins/vuetify';
import 'roboto-fontface/css/roboto/roboto-fontface.css';
import '@mdi/font/css/materialdesignicons.css';
import * as VeeValidate from 'vee-validate';
import './vee-validate';
import infiniteScroll from 'vue-infinite-scroll';
Vue.config.productionTip = false;
Vue.use(infiniteScroll);
Vue.use(VeeValidate);
new Vue({
router,
store,
vuetify,
render: (h) => h(App),
}).$mount('#app');
import Vue from "vue";
import Vuetify from "vuetify/lib";
import ko from "vuetify/es5/locale/ko";
Vue.use(Vuetify);
export default new Vuetify({
theme: {
options: {
customProperties: true
},
themes: {
light: {
primary: "#7DC1E8",
secondary: "#FFCE67",
accent: "#ddeefc",
error: "#FF5252",
info: "#2196F3",
blue: "#173f5f",
lightblue: "#72b1e4",
success: "#2779bd",
warning: "#12283a",
grey300: "#eceeef",
grey500: "#aaaaaa",
grey700: "#5a5a5a",
grey900: "#212529"
}
}
},
lang: {
locales: { ko },
current: "ko"
}
});
import Vue from "vue";
import VueRouter from "vue-router";
import axios from "axios";
Vue.prototype.$axios = axios;
const apiRootPath =
process.env.NODE_ENV !== "production"
? "http://localhost:8000/api/"
: "/api/";
Vue.prototype.$apiRootPath = apiRootPath;
axios.defaults.baseURL = apiRootPath;
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "Home",
component: () => import("../views/Home.vue")
},
{
path: "/upload",
name: "upload",
component: () => import("../views/Upload.vue")
}
];
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes
});
export default router;
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
tags: [],
videoList: [],
},
mutations: {
setTags(state, tags) {
state.tags = tags;
},
setVideoList(state, list) {
state.videoList = list;
},
},
getters: {
getTags: (state) => {
return state.tags;
},
getList: (state) => {
return state.videoList;
},
},
actions: {
LoadTags: (context) => {
return context.commit('setTags');
},
},
modules: {},
});
import { required, max, min } from "vee-validate/dist/rules";
import { extend } from "vee-validate";
extend("required", {
...required,
message: "This field is required"
});
extend("max", {
...max,
message: "This field must be {length} characters or less"
});
extend("min", {
...min,
message: "This field must have at least {length} characters"
});
<template>
<v-sheet>
<!-- autocomplete에 저장된 tag 넣어서(동영상 업로드 할 때마다 tag가 저장됨) 자동완성 되게끔.-->
<v-layout justify-center>
<v-flex xs12 sm8 md8 lg6>
<v-row class="mx-0 mt-10 mb-8" justify="center">
<v-icon color="lightblue">mdi-power-on</v-icon>
<div
style="text-align: center; font-size: 22px; font-weight: 400; color: #343a40; "
>Video List</div>
<v-icon color="lightblue">mdi-power-on</v-icon>
</v-row>
<v-autocomplete
class="mx-5"
v-model="params.tags"
:items="tagsList"
placeholder="Click to search Tags"
prepend-inner-icon="mdi-shape"
chips
multiple
deletable-chips
item-color="primary"
></v-autocomplete>
<!-- 동영상 리스트 -->
<div
v-infinite-scroll="getPost"
infinite-scroll-disabled="busy"
infinite-scroll-distance="10"
class="mb-2"
>
<v-row class="mx-5">
<v-flex xs12 md6 v-for="(post, index) in postList" :key="index" class="mx-0">
<v-card class="mx-1 my-1" elevation="0" outlined>
<div class="mx-2 my-1" style="font-size: 18px; color: #5a5a5a">{{ post.title }}</div>
<v-img height="250" style="border-top: 1px solid; solid;;border-color: #e0e0e0">
<div style="background-color: #7DC1E8; height: 250px">
<v-row justify="end" class="mx-0">
<v-avatar @click="delte()" size="30" color="#888" class="mt-1 mr-1">
<v-icon color="white">mdi-delete</v-icon>
</v-avatar>
</v-row>
<div
style="margin-left: 130px; margin-top: 70px; color: #ffff; font-size: 20px"
>Sample</div>
</div>
</v-img>
<v-divider></v-divider>
<v-chip-group column class="mx-1">
<v-chip color="secondary" v-for="(tag, index) in post.tags" :key="index">#{{ tag }}</v-chip>
</v-chip-group>
</v-card>
</v-flex>
</v-row>
</div>
</v-flex>
</v-layout>
</v-sheet>
</template>
<script>
// @ is an alias to /src
export default {
name: "Home",
components: {},
data() {
return {
postList: [],
tagsList: [],
busy: false,
params: {
tags: [],
skip: 0,
page: 1
}
};
},
watch: {
"params.tags"(newValue, oldValue) {
console.log(newValue, oldValue);
this.postList = [];
this.params.page = 1;
this.getPost();
}
},
computed: {
setSkip() {
if (this.params.page <= 0) return 0;
return (this.params.page - 1) * 10;
}
},
created() {
this.getPost();
this.getTags();
},
methods: {
getPost() {
this.busy = true;
this.params.skip = this.setSkip;
if (this.postList.length !== (this.params.page - 1) * 10) {
return;
}
this.$axios
.get("/video", { params: this.params })
.then(r => {
let tags = []
for (let i = 0; i < r.data.length; i++) {
tags = r.data[i].tags.split(',')
r.data[i].tags = tags
this.postList.push(r.data[i]);
}
this.busy = false;
this.params.page++;
})
.catch(e => {
console.log(e);
});
},
getTags() {
this.$axios
.get("/loadtag")
.then(r => {
let tags = []
for (let i = 0; i < r.data.length; i++) {
tags.push(r.data[i].tag)
}
this.tagsList = [...new Set(tags)]
})
.catch(e => {
console.log(e);
});
},
delete(atc) {
this.$axios
.delete(`/${atc._id}`)
.then(() => {
window.location.reload();
})
.catch(e => {
console.log(e);
});
}
}
};
</script>
<template>
<v-sheet>
<v-layout justify-center>
<v-overlay :value="loading">
<v-progress-circular indeterminate size="80"></v-progress-circular>
</v-overlay>
<v-flex xs12 sm8 md6>
<v-row justify="center" class="mx-0 my-12">
<v-icon color="lightblue">mdi-power-on</v-icon>
<div
style="text-align: center; font-size: 22px; font-weight: 400; color: #343a40; "
>Upload Video</div>
<v-icon color="lightblue">mdi-power-on</v-icon>
</v-row>
<v-card elevation="0">
<v-text-field
class="mx-10 mt-12 mb-6"
prepend-inner-icon="mdi-pen"
v-model="form.title"
:counter="40"
label="Title"
placeholder="Please input Title"
type="text"
></v-text-field>
<!-- file upload -->
<div class="mx-10 mb-12 mt-6">
<video-upload />
</div>
<v-dialog max-width="400" v-model="successDialog">
<v-card max-width="400" class="pt-3">
<div
style="text-align: center; font-size: 20px;color: #5a5a5a; font-weight: 400"
>Notice</div>
<v-divider class="mt-2 mb-3"></v-divider>
<div
style="margin-left: 10px; margin-right: 10px; text-align: center; font-size: 18px; font-weight: 400"
>Your Video's tags are successfully extracted</div>
<v-btn class="mt-4" elevation="0" block color="primary">Close</v-btn>
</v-card>
</v-dialog>
<v-card outlined class="pa-2 mx-10" elevation="0" min-height="67">
<div
style="margin-left: 5px; margin-top: -18px; background-color: #fff; width: 95px; text-align: center;font-size: 14px; color: #5a5a5a; font-weight: 500"
>Selected Tags</div>
<v-chip-group column>
<v-chip
color="secondary"
v-for="(tag, index) in form.tag"
:key="index"
@click="deleteTags(index)"
>
{{ tag }}
<v-icon small style="margin-left: 3px; margin-top: -2px">mdi-close-circle</v-icon>
</v-chip>
</v-chip-group>
</v-card>
<v-text-field
class="mx-10 my-12"
prepend-inner-icon="mdi-shape"
v-model="tag"
:counter="20"
label="Tag"
placeholder="Type to add Tag"
append-icon="mdi-arrow-up-bold"
@click:append="addTags(tag)"
@keydown.enter="addTags(tag)"
type="text"
></v-text-field>
</v-card>
<v-row justify="center" style="margin-top: 30px">
<v-btn elevation="0" large color="primary" @click="submit()">
<span style="font-size: 24px; font-weight: 300; letter-spacing: 2px">Upload</span>
</v-btn>
</v-row>
</v-flex>
</v-layout>
</v-sheet>
</template>
<script>
import videoUpload from "../components/uploadFile";
export default {
name: "Upload",
components: {
videoUpload
},
data() {
return {
myFiles: [],
tag: "",
form: {
title: "",
videoUrl: "",
tag: [
"Work",
"Home Improvement",
"Vacation",
"Food",
"Drawers",
"Shopping",
"Art",
"Tech",
"Creative Writing"
]
},
successDialog: false,
errorDialog: false,
loading: false
};
},
created() {
this.form.tag = [];
},
methods: {
submit() {
if (!(this.form.tag.length && this.form.title)) {
this.errorDialog = true;
return;
} else {
this.$axios
.post("/home", this.form)
.then(r => {
window.location.reload();
console.log(r);
this.successDialog = true;
})
.catch(e => {
console.log(e);
this.errorDialog = true;
});
}
},
deleteTags(index) {
for (let i = 0; i < this.form.tag.length; i++) {
const element = this.form.tag[i];
if (this.form.tag[index] === element) {
this.form.tag[i] = this.form.tag[this.form.tag.length - 1];
break;
}
}
this.form.tag.pop();
},
addTags(tag) {
let i;
let check = true;
for (i = 0; i < this.form.tag.length; i++) {
const element = this.form.tag[i];
if (tag === element) {
check = false;
}
}
if (tag && check) this.form.tag.push(tag);
this.tag = "";
}
}
};
</script>
module.exports = {
transpileDependencies: ['vuetify'],
transpileDependencies: ['vuex-persist'],
};
This diff could not be displayed because it is too large.