Flare-k

Modified Model and Serializers

Showing 61 changed files with 2041 additions and 92 deletions
1 +# editorconfig.org
2 +root = true
3 +
4 +[*]
5 +indent_style = space
6 +indent_size = 2
7 +end_of_line = lf
8 +charset = utf-8
9 +trim_trailing_whitespace = true
10 +insert_final_newline = true
11 +
12 +[*.md]
13 +trim_trailing_whitespace = false
1 +#Created by .ignore support plugin (hsz.mobi)
2 +### Node template
3 +# Logs
4 +/logs
5 +*.log
6 +npm-debug.log*
7 +yarn-debug.log*
8 +yarn-error.log*
9 +
10 +# Runtime data
11 +pids
12 +*.pid
13 +*.seed
14 +*.pid.lock
15 +
16 +# Directory for instrumented libs generated by jscoverage/JSCover
17 +lib-cov
18 +
19 +# Coverage directory used by tools like istanbul
20 +coverage
21 +
22 +# nyc test coverage
23 +.nyc_output
24 +
25 +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26 +.grunt
27 +
28 +# Bower dependency directory (https://bower.io/)
29 +bower_components
30 +
31 +# node-waf configuration
32 +.lock-wscript
33 +
34 +# Compiled binary addons (https://nodejs.org/api/addons.html)
35 +build/Release
36 +
37 +# Dependency directories
38 +node_modules/
39 +jspm_packages/
40 +
41 +# TypeScript v1 declaration files
42 +typings/
43 +
44 +# Optional npm cache directory
45 +.npm
46 +
47 +# Optional eslint cache
48 +.eslintcache
49 +
50 +# Optional REPL history
51 +.node_repl_history
52 +
53 +# Output of 'npm pack'
54 +*.tgz
55 +
56 +# Yarn Integrity file
57 +.yarn-integrity
58 +
59 +# dotenv environment variables file
60 +.env
61 +
62 +# parcel-bundler cache (https://parceljs.org/)
63 +.cache
64 +
65 +# next.js build output
66 +.next
67 +
68 +# nuxt.js build output
69 +.nuxt
70 +
71 +# Nuxt generate
72 +dist
73 +
74 +# vuepress build output
75 +.vuepress/dist
76 +
77 +# Serverless directories
78 +.serverless
79 +
80 +# IDE / Editor
81 +.idea
82 +
83 +# Service worker
84 +sw.*
85 +
86 +# macOS
87 +.DS_Store
88 +
89 +# Vim swap files
90 +*.swp
91 +
92 +node_modules/
1 +# frontend
2 +
3 +> My incredible Nuxt.js project
4 +
5 +## Build Setup
6 +
7 +```bash
8 +# install dependencies
9 +$ npm install
10 +
11 +# serve with hot reload at localhost:3000
12 +$ npm run dev
13 +
14 +# build for production and launch server
15 +$ npm run build
16 +$ npm run start
17 +
18 +# generate static project
19 +$ npm run generate
20 +```
21 +
22 +For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org).
1 +# ASSETS
2 +
3 +**This directory is not required, you can delete it if you don't want to use it.**
4 +
5 +This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
6 +
7 +More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked).
1 +// Ref: https://github.com/nuxt-community/vuetify-module#customvariables
2 +//
3 +// The variables you want to modify
4 +// $font-size-root: 20px;
1 +<template>
2 + <div>
3 + <v-btn class="pink white--text">click me</v-btn>
4 + <v-btn depressed class="pink">click me</v-btn>
5 + <v-btn flat class="pink">click me</v-btn>
6 +
7 + <v-btn depressed class="pink white--text">
8 + <v-icon left>email</v-icon>
9 + <span>email me</span>
10 + </v-btn>
11 +
12 + <v-btn depressed small class="pink white--text">
13 + <v-icon left small>email</v-icon>
14 + <span>email me</span>
15 + </v-btn>
16 +
17 + <v-btn fab small dark class="purple">
18 + <v-icon>favorite</v-icon>
19 + </v-btn>
20 +
21 +
22 + <h1>HomePage</h1>
23 + <v-btn class="hidden-md-and-down">click me</v-btn>
24 + <v-btn class="hidden-md-and-up">click me</v-btn>
25 + <v-btn class="hidden-sm-only">click me</v-btn>
26 +
27 + </div>
28 +</template>
29 +
30 +<script>
31 + export default {
32 + name: "ButtonIconVisibility"
33 + }
34 +</script>
35 +
36 +<style scoped>
37 +
38 +</style>
1 +<template>
2 + <div>
3 + <v-btn
4 + text
5 + @click="$refs.fileInput.click()">
6 + <v-icon>vertical_align_top</v-icon>
7 + <span class="caption">업로드</span>
8 + </v-btn>
9 + <input
10 + v-show="false"
11 + type="file"
12 + ref="fileInput"
13 + multiple="multiple"
14 + @change="uploadFile">
15 + </div>
16 +</template>
17 +
18 +<script>
19 + import 'material-design-icons-iconfont/dist/material-design-icons.css'
20 +
21 + export default {
22 + name: "CreateFileFormComponent",
23 + data() {
24 + return {
25 + filepath: '',
26 + }
27 + },
28 + methods: {
29 + async uploadFile(e) {
30 + try {
31 + const formData = new FormData();
32 + const now = Date.now();
33 + Array.prototype.forEach.call(e.target.files, (file) => {
34 + formData.append('file', file);
35 + formData.append('name', file.name);
36 + formData.append('isFolder', true);
37 + formData.append('path', this.filepath);
38 + formData.append('fileSize', file.size);
39 + formData.append('createdDate', now);
40 + formData.append('updatedDate', now);
41 + formData.append('share', false);
42 + console.log(file);
43 + });
44 +
45 + await this.$store.dispatch('file/uploadFile', {formData});
46 + return this.$router.replace('/');
47 + } catch (e) {
48 + console.error(e);
49 + }
50 + }
51 + }
52 + }
53 +</script>
54 +
55 +<style scoped>
56 +
57 +</style>
1 +<template>
2 + <v-dialog max-width="400px">
3 + <template v-slot:activator="{on}">
4 + <v-btn
5 + flat slot="activator"
6 + text
7 + v-on="on">
8 + <v-icon>add</v-icon>
9 + <span overline class="caption">새로 만들기</span>
10 + </v-btn>
11 + </template>
12 + <v-card>
13 + <v-card-title>
14 + <p class="title font-weight-light">폴더</p>
15 + </v-card-title>
16 + <v-form class="px-3" @submit.prevent="uploadFolder">
17 + <v-card-text>
18 + <v-text-field
19 + outlined
20 + label="폴더 이름"
21 + v-model="folderName"
22 + color="blue"
23 + />
24 + </v-card-text>
25 + <v-card-actions>
26 + <v-spacer/>
27 + <v-btn
28 + depressed
29 + class="mr-3 mb-3 text-lowercase font-weight-light"
30 + type="submit">
31 + 만들기
32 + </v-btn>
33 + </v-card-actions>
34 + </v-form>
35 + </v-card>
36 + </v-dialog>
37 +</template>
38 +
39 +<script>
40 + export default {
41 + name: "CreateFolderFormComponent",
42 + data() {
43 + return {
44 + valid: false,
45 + folderName: '',
46 + folderPath: '/',
47 + }
48 + },
49 + methods: {
50 + async uploadFolder() {
51 + try {
52 + console.log('폴더이름 test', this.folderName);
53 +
54 + const now = Date.now();
55 + const formData = new FormData();
56 + formData.append('name', this.folderName);
57 + formData.append('owner', 'owner');
58 + formData.append('path', this.folderPath);
59 + formData.append('isFolder', true);
60 + formData.append('createdAt', now);
61 + formData.append('fileSize', 0);
62 + formData.append('share', false);
63 +
64 + console.log(now, this.folderPath);
65 +
66 + await this.$store.dispatch('file/uploadFolder', {formData});
67 + // await this.$router.replace('/');
68 + } catch (e) {
69 + console.error(e);
70 + }
71 + },
72 +
73 + }
74 + }
75 +</script>
76 +
77 +<style scoped>
78 +
79 +</style>
1 +<template>
2 + <v-layout justify-center="center" class="my-10">
3 + <v-flex
4 + xs12 md10>
5 + <v-data-table
6 + :headers="headers"
7 + :items="files"
8 + hide-actions
9 + hide-default-footer
10 + >
11 + <template slot="items" slot-scope="props">
12 + <td>
13 + <v-btn
14 + icon>
15 + <v-icon>folder</v-icon>
16 + </v-btn>
17 + </td>
18 + <td>
19 + {{ props.item.name }}
20 + </td>
21 + <td class="text-xs-right">{{ props.item.modifiedDate }}</td>
22 + <td class="text-xs-right">{{ props.item.owner }}</td>
23 + <td class="text-xs-right">{{ props.item.fileSize }}</td>
24 + <td class="text-xs-right">{{ props.item.share }}</td>
25 + </template>
26 + </v-data-table>
27 + </v-flex>
28 + </v-layout>
29 +</template>
30 +
31 +<script>
32 + import 'material-design-icons-iconfont/dist/material-design-icons.css'
33 +
34 + export default {
35 + name: 'DataTableComponent',
36 + data() {
37 + return {
38 + currentPath: 'root',
39 + fileTypeIcon: '',
40 + headers: [
41 + {text: '', value: 'icon'},
42 + {
43 + text: '이름',
44 + align: 'left',
45 + sortable: 'false',
46 + value: 'name'
47 + },
48 + {text: '수정한 날짜', value: 'modifiedDate'},
49 + {text: '수정한 사람', value: 'owner'},
50 + {text: '파일 크기', value: 'fileSize'},
51 + {text: '공유', value: 'share'}
52 + ],
53 + files: [
54 + {
55 + name: '90.944339.pdf',
56 + modifiedDate: '2020-02-08',
57 + owner: 'tjddus',
58 + fileSize: '1000',
59 + share: false
60 + }
61 + ]
62 + }
63 + }
64 + }
65 +</script>
1 +<template>
2 + <v-system-bar
3 + :height="55">
4 +
5 + <create-folder-form-component/>
6 +
7 + <create-file-form-component/>
8 +
9 + <v-spacer/>
10 + <v-menu offset-y>
11 + <template
12 + v-slot:activator="{on}">
13 + <v-btn
14 + text
15 + v-on="on"
16 + >
17 + <v-icon>sort</v-icon>
18 + <span class="caption">정렬</span>
19 + </v-btn>
20 + </template>
21 + <v-list>
22 + <v-list-item v-for="view in views" :key="view.title" @click="changeCurrentView(view.title)">
23 + <v-list-action>
24 + <v-icon small>{{view.icon}}</v-icon>
25 + </v-list-action>
26 + <v-list-title class="ml-1 body-2">{{view.title}}</v-list-title>
27 + </v-list-item>
28 + </v-list>
29 + </v-menu>
30 + </v-system-bar>
31 +</template>
32 +
33 +<script>
34 + import 'material-design-icons-iconfont/dist/material-design-icons.css'
35 + import CreateFolderFormComponent from "./CreateFolderFormComponent";
36 + import CreateFileFormComponent from "./CreateFileFormComponent";
37 +
38 + export default {
39 + name: "FileNavbarComponent",
40 + components: {CreateFolderFormComponent, CreateFileFormComponent},
41 + data() {
42 + return {
43 + currentView: 0,
44 + views: [
45 + {value: 0, icon: 'format_align_left', title: '목록'},
46 + {value: 1, icon: 'border_all', title: '타일'}
47 + ],
48 + }
49 + },
50 + methods: {
51 + changeCurrentView(value) {
52 + this.currentView = value;
53 + console.log(this.currentView);
54 + },
55 + }
56 + }
57 +</script>
58 +
59 +<style scoped>
60 +</style>
1 +<template>
2 + <div>
3 + <v-row
4 + align="center"
5 + justify="center">
6 + <v-col
7 + cols="12"
8 + sm="8"
9 + md="4"
10 + >
11 + <v-card>
12 + <v-form v-model="valid" @submit.prevent="login">
13 + <v-card-text>
14 + <v-text-field
15 + v-model="username"
16 + :rules="[rules.username]"
17 + label="username"
18 + prepend-icon="person">
19 + </v-text-field>
20 + <v-text-field
21 + v-model="password"
22 + :rules="[rules.password]"
23 + type="password"
24 + label="password"
25 + prepend-icon="lock">
26 + </v-text-field>
27 + </v-card-text>
28 + <v-card-actions>
29 + <v-spacer/>
30 + <v-btn
31 + color="grey"
32 + type="submit">
33 + 로그인
34 + </v-btn>
35 + </v-card-actions>
36 + </v-form>
37 + </v-card>
38 + </v-col>
39 + </v-row>
40 + </div>
41 +</template>
42 +
43 +
44 +<script>
45 + export default {
46 + name: "loginComponent",
47 + data() {
48 + return {
49 + valid: false,
50 + tryLogin: true,
51 + username: '',
52 + password: '',
53 + rules: {
54 + username: v => !!v || 'username is required',
55 + password: v => !!v || 'password is required',
56 + }
57 + }
58 + },
59 + methods: {
60 + async login() {
61 + try {
62 + console.log('login Method');
63 + await this.$store.dispatch('user/login', {
64 + username: this.username,
65 + password: this.password
66 + });
67 + await this.$router.replace('/');
68 + } catch (e) {
69 + console.error(e);
70 + }
71 + },
72 + changeTryLogin() {
73 + this.tryLogin = !this.tryLogin;
74 + }
75 + }
76 + }
77 +</script>
1 +<template>
2 + <div class="VueToNuxtLogo">
3 + <div class="Triangle Triangle--two" />
4 + <div class="Triangle Triangle--one" />
5 + <div class="Triangle Triangle--three" />
6 + <div class="Triangle Triangle--four" />
7 + </div>
8 +</template>
9 +
10 +<style>
11 +.VueToNuxtLogo {
12 + display: inline-block;
13 + animation: turn 2s linear forwards 1s;
14 + transform: rotateX(180deg);
15 + position: relative;
16 + overflow: hidden;
17 + height: 180px;
18 + width: 245px;
19 +}
20 +
21 +.Triangle {
22 + position: absolute;
23 + top: 0;
24 + left: 0;
25 + width: 0;
26 + height: 0;
27 +}
28 +
29 +.Triangle--one {
30 + border-left: 105px solid transparent;
31 + border-right: 105px solid transparent;
32 + border-bottom: 180px solid #41b883;
33 +}
34 +
35 +.Triangle--two {
36 + top: 30px;
37 + left: 35px;
38 + animation: goright 0.5s linear forwards 3.5s;
39 + border-left: 87.5px solid transparent;
40 + border-right: 87.5px solid transparent;
41 + border-bottom: 150px solid #3b8070;
42 +}
43 +
44 +.Triangle--three {
45 + top: 60px;
46 + left: 35px;
47 + animation: goright 0.5s linear forwards 3.5s;
48 + border-left: 70px solid transparent;
49 + border-right: 70px solid transparent;
50 + border-bottom: 120px solid #35495e;
51 +}
52 +
53 +.Triangle--four {
54 + top: 120px;
55 + left: 70px;
56 + animation: godown 0.5s linear forwards 3s;
57 + border-left: 35px solid transparent;
58 + border-right: 35px solid transparent;
59 + border-bottom: 60px solid #fff;
60 +}
61 +
62 +@keyframes turn {
63 + 100% {
64 + transform: rotateX(0deg);
65 + }
66 +}
67 +
68 +@keyframes godown {
69 + 100% {
70 + top: 180px;
71 + }
72 +}
73 +
74 +@keyframes goright {
75 + 100% {
76 + left: 70px;
77 + }
78 +}
79 +</style>
80 +
1 +<template>
2 + <div class="mx-4 mb-4">
3 + <h1 class="subheading grey--text">Team</h1>
4 +
5 + <v-container fluid class="my-5">
6 + <v-layout row wrap>
7 + <v-flex xs12 md6>
8 + <v-btn outline block class="primary">1</v-btn>
9 + </v-flex>
10 + <v-flex xs4 md2>
11 + <v-btn outline block class="primary">2</v-btn>
12 + </v-flex>
13 + <v-flex xs4 md2>
14 + <v-btn outline block class="primary">2</v-btn>
15 + </v-flex>
16 + <v-flex xs4 md2>
17 + <v-btn outline block class="primary">2</v-btn>
18 + </v-flex>
19 + </v-layout>
20 +
21 + <!-- justify-end, center, space-around-->
22 +
23 + <v-layout row wrap justify-end>
24 + <v-flex xs4 md3>
25 + <v-btn outline block class="success">1</v-btn>
26 + </v-flex>
27 + <v-flex xs4 md3>
28 + <v-btn outline block class="success">2</v-btn>
29 + </v-flex>
30 + </v-layout>
31 + </v-container>
32 +
33 +
34 + <v-container class="my-5">
35 +
36 + <v-layout row class="mb-3">
37 + <v-tooltip top>
38 + <template v-slot:activator="{ on }">
39 + <v-btn small flat color="grey" @click="sortBy('title')" v-on="on">
40 + <v-icon left small>folder</v-icon>
41 + <span class="caption text-lowercase">By project name</span>
42 + </v-btn>
43 + </template>
44 + <span>Sort projects by project name</span>
45 + </v-tooltip>
46 +
47 + <v-tooltip top>
48 + <template v-slot:activator="{ on }">
49 + <v-btn small flat color="grey" @click="sortBy('person')" v-on="on">
50 + <v-icon left small>person</v-icon>
51 + <span class="caption text-lowercase">By person</span>
52 + </v-btn>
53 + </template>
54 + <span>Sort projects by person</span>
55 + </v-tooltip>
56 + </v-layout>
57 +
58 +
59 + <v-card flat class="pa-3" v-for="project in projects" :key="project.title">
60 + <v-layout row wrap :class="`pa-3 project ${project.status}`">
61 + <v-flex xs12 md6>
62 + <div class="caption grey--text">project title</div>
63 + <div>{{project.title}}</div>
64 + </v-flex>
65 + <v-flex xs4 md2>
66 + <div class="caption grey--text">Person</div>
67 + <div>{{project.person}}</div>
68 + </v-flex>
69 + <v-flex xs4 md2>
70 + <div class="caption grey--text">Due by</div>
71 + <div>{{project.due}}</div>
72 + </v-flex>
73 + <v-flex xs4 md2>
74 + <v-chip small :class="`${project.status} white--text caption my-2`">{{project.status}}</v-chip>
75 + </v-flex>
76 + </v-layout>
77 + </v-card>
78 + </v-container>
79 + </div>
80 +</template>
81 +
82 +<script>
83 + export default {
84 + name: "PaddingMarginGrid",
85 + data() {
86 + return {
87 + projects: [
88 + {title: 'Design a new website', person: 'The Net Ninja', due: '1st Jan 2019', status: 'ongoing'},
89 + {title: 'Write a new website', person: 'Net Ninja', due: '1st Jan 2019', status: 'complete'},
90 + {title: 'Create a new website', person: 'Ninja', due: '1st Jan 2019', status: 'ongoing'},
91 + {title: 'Update a new website', person: 'tjddus', due: '1st Jan 2019', status: 'overdue'}
92 + ]
93 + }
94 + },
95 + methods: {
96 + sortBy(props) {
97 + this.projects.sort((a, b) => a[props] < b[props] ? -1 : 1);
98 + }
99 + }
100 + }
101 +</script>
102 +
103 +<style scoped>
104 + .project.complete {
105 + border-left: 4px solid #3cd1c2;
106 + }
107 +
108 + .project.ongoing {
109 + border-left: 4px solid orange;
110 + }
111 +
112 + .project.overdue {
113 + border-left: 4px solid tomato;
114 + }
115 +
116 + .v-chip.complete {
117 + background: #3cd1c2;
118 + }
119 +
120 + .v-chip.ongoing {
121 + background: orange;
122 + }
123 +
124 + .v-chip.overdue {
125 + background: tomato;
126 + }
127 +</style>
1 +# COMPONENTS
2 +
3 +**This directory is not required, you can delete it if you don't want to use it.**
4 +
5 +The components directory contains your Vue.js Components.
6 +
7 +_Nuxt.js doesn't supercharge these components._
1 +<template>
2 + <v-layout class="py-10" justify-center="center">
3 + <v-flex
4 + xs12 md10>
5 + <v-data-table
6 + :headers="headers"
7 + :items="files"
8 + hide-actions
9 + hide-default-footer
10 + >
11 + <template slot="items" slot-scope="props">
12 + <td>{{ props.item.name }}</td>
13 + <td class="text-xs-right">{{ props.item.shareDate }}</td>
14 + <td class="text-xs-right">{{ props.item.sharePerson }}</td>
15 + <td class="text-xs-right">{{ props.item.acitivity }}</td>
16 + </template>
17 + </v-data-table>
18 + </v-flex>
19 + </v-layout>
20 +</template>
21 +
22 +<script>
23 + export default {
24 + name: 'ShareTableComponent',
25 + // computed: {
26 + // files: this.$store.state.file.files
27 + // },
28 + data () {
29 + return {
30 + headers: [
31 + {
32 + text: '이름',
33 + align: 'left',
34 + sortable: 'false',
35 + value: 'name'
36 + },
37 + { text: '공유된 날짜', value: 'shareDate'},
38 + { text: '공유한 사람', value: 'sharePerson'},
39 + { text: '활동', value: 'activity'}
40 + ],
41 + files: [
42 + ]
43 + }
44 + }
45 + }
46 +</script>
1 +<template>
2 + <div>
3 + <v-row
4 + align="center"
5 + justify="center"
6 + >
7 + <v-col
8 + cols="12"
9 + sm="8"
10 + md="4"
11 + >
12 + <v-card>
13 + <v-form v-model="valid" @submit.prevent="signUp">
14 + <v-card-text>
15 + <v-text-field
16 + v-model="email"
17 + :rules="[rules.email]"
18 + prepend-icon="email"
19 + label="email">
20 + </v-text-field>
21 + <v-text-field
22 + v-model="username"
23 + :rules="[rules.username]"
24 + prepend-icon="person"
25 + label="username">
26 + </v-text-field>
27 + <v-text-field
28 + v-model="password"
29 + :rules="[rules.password]"
30 + prepend-icon="lock"
31 + type="password"
32 + label="password">
33 + </v-text-field>
34 + <v-text-field
35 + v-model="checkpassword"
36 + :rules="[rules.checkpassword]"
37 + prepend-icon="lock"
38 + type="password"
39 + label="checkpassword">
40 + </v-text-field>
41 + </v-card-text>
42 + <v-card-actions>
43 + <v-spacer/>
44 + <v-btn
45 + color="grey"
46 + type="submit">
47 + 회원가입
48 + </v-btn>
49 + </v-card-actions>
50 + </v-form>
51 + </v-card>
52 + </v-col>
53 + </v-row>
54 + </div>
55 +</template>
56 +
57 +<script>
58 + export default {
59 + name: "SignUpComponent",
60 + data() {
61 + return {
62 + valid: false,
63 + email: '',
64 + username: '',
65 + password: '',
66 + checkpassword: '',
67 + rules: {
68 + email: v => (v || '').match(/@/) || 'Please enter a valid email',
69 + username: v => !!v || 'username is required',
70 + password: v => !!v || 'password is required',
71 + checkpassword: v => v == this.password || 'checkpassword is incorrect'
72 + }
73 + }
74 + },
75 + methods: {
76 + async signUp() {
77 + try {
78 + console.log('signUp Method');
79 + //$store.dispatch -> action의 signUp 함수를 불러올 수 있음
80 + await this.$store.dispatch('user/signUp', {
81 + email: this.email,
82 + username: this.username,
83 + password: this.password
84 + });
85 + await this.$router.replace('/');
86 + } catch (e) {
87 + console.error(e);
88 + }
89 + }
90 + }
91 + }
92 +</script>
93 +
94 +<style scoped>
95 +
96 +</style>
97 +
98 +
1 +<template>
2 + <v-layout justify-center="center" class="my-10">
3 + <v-flex xs12 md10>
4 + <v-data-table :headers="headers" :items="files" hide-actions hide-default-footer>
5 + <template slot="items" slot-scope="props">
6 + <td>{{ props.item.name }}</td>
7 + <td class="text-xs-right">{{ props.item.deletedDate }}</td>
8 + <td class="text-xs-right">{{ props.item.deletePerson }}</td>
9 + <td class="text-xs-right">{{ props.item.makePerson }}</td>
10 + <td class="text-xs-right">{{ props.item.originalPath }}</td>
11 + </template>
12 + </v-data-table>
13 + </v-flex>
14 + </v-layout>
15 +
16 +</template>
17 +
18 +<script>
19 + export default {
20 + name: 'TrashTableComponent',
21 + data() {
22 + return {
23 + headers: [
24 + {
25 + text: '이름',
26 + align: 'left',
27 + sortable: 'false',
28 + value: 'name'
29 + },
30 + {text: '삭제된 날짜', value: 'deletedDate'},
31 + {text: '삭제한 사람', value: 'deletePerson'},
32 + {text: '만든 사람', value: 'makePerson'},
33 + {text: '원래 위치', value: 'originalPath'}
34 + ],
35 + files: []
36 + }
37 + }
38 + }
39 +</script>
1 +<template>
2 + <img
3 + class="VuetifyLogo"
4 + alt="Vuetify Logo"
5 + src="/vuetify-logo.svg"
6 + >
7 +</template>
8 +
9 +<style>
10 +.VuetifyLogo {
11 + height:180px;
12 + width: 180px;
13 + transform: rotateY(560deg);
14 + animation: turn 3.5s ease-out forwards 1s;
15 +}
16 +
17 +@keyframes turn {
18 + 100% {
19 + transform: rotateY(0deg);
20 + }
21 +}
22 +</style>
1 +# LAYOUTS
2 +
3 +**This directory is not required, you can delete it if you don't want to use it.**
4 +
5 +This directory contains your Application Layouts.
6 +
7 +More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts).
1 +<template>
2 + <v-app>
3 + <v-navigation-drawer
4 + v-model="drawer"
5 + app
6 + clipped
7 + >
8 + <v-list dense>
9 + <v-list-item v-for="item in items" :key="item.title" router :to="item.route">
10 + <v-list-item-action :to="item.to">
11 + <v-icon>{{item.icon}}</v-icon>
12 + </v-list-item-action>
13 + <v-list-item-content>
14 + <v-list-item-title>{{item.title}}</v-list-item-title>
15 + </v-list-item-content>
16 + </v-list-item>
17 + </v-list>
18 + </v-navigation-drawer>
19 +
20 + <v-app-bar
21 + app
22 + clipped-left
23 + :height="55"
24 + >
25 + <v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
26 + <v-toolbar-title small>KHULOUD</v-toolbar-title>
27 + <v-spacer/>
28 + <v-btn icon class="mr-2" nuxt to="inspire">
29 + <v-icon flat small>person</v-icon>
30 + </v-btn>
31 + </v-app-bar>
32 +
33 + <v-content>
34 + <nuxt/>
35 + </v-content>
36 +
37 + <v-footer app>
38 + <span>&copy; 2020</span>
39 + </v-footer>
40 + </v-app>
41 +</template>
42 +
43 +<script>
44 + import 'material-design-icons-iconfont/dist/material-design-icons.css'
45 +
46 + export default {
47 + props: {
48 + source: String,
49 + },
50 + data() {
51 + return {
52 + drawer: null,
53 + items: [
54 + {title: 'Khuloud', icon: 'school', route: '/'},
55 + {title: '내 파일', icon: 'folder', route: '/drive/file'},
56 + {title: '최근 항목', icon: 'list', route: '/'},
57 + {title: '사진', icon: 'image', route: '/inspire'},
58 + {title: '공유됨', icon: 'get_app', route: '/drive/shared-with-me'},
59 + {title: '휴지통', icon: 'delete', route: '/drive/trash'}
60 + ]
61 + }
62 + }
63 + }
64 +</script>
65 +
66 +<style scoped>
67 + #app {
68 + font-family: Avenir, Helvetica, Arial, sans-serif;
69 + -webkit-font-smoothing: antialiased;
70 + -moz-osx-font-smoothing: grayscale;
71 + color: #2c3e50;
72 + }
73 +</style>
1 +<template>
2 + <v-app dark>
3 + <h1 v-if="error.statusCode === 404">
4 + {{ pageNotFound }}
5 + </h1>
6 + <h1 v-else>
7 + {{ otherError }}
8 + </h1>
9 + <NuxtLink to="/">
10 + Home page
11 + </NuxtLink>
12 + </v-app>
13 +</template>
14 +
15 +<script>
16 +export default {
17 + layout: 'empty',
18 + props: {
19 + error: {
20 + type: Object,
21 + default: null
22 + }
23 + },
24 + data () {
25 + return {
26 + pageNotFound: '404 Not Found',
27 + otherError: 'An error occurred'
28 + }
29 + },
30 + head () {
31 + const title =
32 + this.error.statusCode === 404 ? this.pageNotFound : this.otherError
33 + return {
34 + title
35 + }
36 + }
37 +}
38 +</script>
39 +
40 +<style scoped>
41 +h1 {
42 + font-size: 20px;
43 +}
44 +</style>
1 +# MIDDLEWARE
2 +
3 +**This directory is not required, you can delete it if you don't want to use it.**
4 +
5 +This directory contains your application middleware.
6 +Middleware let you define custom functions that can be run before rendering either a page or a group of pages.
7 +
8 +More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware).
1 +// import colors from 'vuetify/es5/util/colors'
2 +//
3 +// export default {
4 +// mode: 'universal',
5 +// /*
6 +// ** Headers of the page
7 +// */
8 +// head: {
9 +// titleTemplate: '%s - ' + process.env.npm_package_name,
10 +// title: process.env.npm_package_name || '',
11 +// meta: [
12 +// { charset: 'utf-8' },
13 +// { name: 'viewport', content: 'width=device-width, initial-scale=1' },
14 +// { hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
15 +// ],
16 +// link: [
17 +// { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
18 +// ]
19 +// },
20 +// /*
21 +// ** Customize the progress-bar color
22 +// */
23 +// loading: { color: '#fff' },
24 +// /*
25 +// ** Global CSS
26 +// */
27 +// css: [
28 +// ],
29 +// /*
30 +// ** Plugins to load before mounting the App
31 +// */
32 +// plugins: [
33 +// ],
34 +// /*
35 +// ** Nuxt.js dev-modules
36 +// */
37 +// buildModules: [
38 +// '@nuxtjs/vuetify',
39 +// '@nuxtjs/moment',
40 +// ],
41 +// /*
42 +// ** Nuxt.js modules
43 +// */
44 +// modules: [
45 +// '@nuxtjs/axios',
46 +// '@nuxtjs/pwa'
47 +// ],
48 +// /*
49 +// ** Build configuration
50 +// */
51 +// build: {
52 +// /*
53 +// ** You can extend webpack config here
54 +// */
55 +// extend (config, ctx) {
56 +// }
57 +// }
58 +// }
59 +
60 +
61 +import webpack from 'webpack'
62 +
63 +module.exports = {
64 +
65 + server: {
66 + host: 'localhost',
67 + port: 3001
68 + },
69 + head: {
70 + meta: [{
71 + charset: 'utf-8',
72 + }, {
73 + name: 'viewport',
74 + content: 'width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no',
75 + }],
76 + cookie: {}
77 + },
78 + modules: [
79 + '@nuxtjs/axios',
80 + '@nuxtjs/pwa',
81 + ],
82 + buildModules: [
83 + '@nuxtjs/vuetify',
84 + '@nuxtjs/moment',
85 + ],
86 +
87 + // pwa: {
88 + // icon: {
89 + // iconSrc: 'static/icon.png'
90 + // },
91 + // manifest: {
92 + // name: 'node_express_study_final'
93 + // },
94 + // workbox: {
95 + // dev: true,
96 + // runtimeCaching: [{
97 + // urlPattern: 'http://localhost:4001/.*',
98 + // method: 'GET'
99 + // }, {
100 + // urlPattern: 'http://localhost:5001/.*',
101 + // method: 'GET'
102 + // }]
103 + // },
104 + // }
105 +};
This diff could not be displayed because it is too large.
1 +{
2 + "name": "frontend",
3 + "scripts": {
4 + "start": "nuxt"
5 + },
6 + "dependencies": {
7 + "@nuxtjs/axios": "^5.9.5",
8 + "@nuxtjs/moment": "^1.6.0",
9 + "@nuxtjs/pwa": "^3.0.0-beta.20",
10 + "@nuxtjs/vuetify": "^1.11.0",
11 + "jquery": "^3.4.1",
12 + "js-cookie": "^2.2.1",
13 + "loadsh": "0.0.4",
14 + "lodash.throttle": "^4.1.1",
15 + "material-design-icons-iconfont": "^5.0.1",
16 + "nuxt": "^2.11.0",
17 + "socket.io-client": "^2.3.0",
18 + "webpack": "^4.43.0"
19 + }
20 +}
1 +# PAGES
2 +
3 +This directory contains your Application Views and Routes.
4 +The framework reads all the `*.vue` files inside this directory and creates the router of your application.
5 +
6 +More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing).
1 +<template>
2 + <div>
3 + <file-navbar-component/>
4 + <data-table-component/>
5 + </div>
6 +</template>
7 +
8 +<script>
9 + import FileNavbarComponent from "../../components/FileNavbarComponent";
10 + import DataTableComponent from "../../components/DataTableComponent";
11 +
12 + export default {
13 + name: "file",
14 + components: {
15 + FileNavbarComponent,
16 + DataTableComponent,
17 + }
18 + }
19 +</script>
20 +
21 +<style scoped>
22 +
23 +</style>
1 +<template>
2 + <div>
3 + <file-navbar-component/>
4 + <share-table-component/>
5 + </div>
6 +</template>
7 +
8 +<script>
9 + import FileNavbarComponent from "../../components/FileNavbarComponent";
10 + import ShareTableComponent from "../../components/ShareTableComponent";
11 +
12 + export default {
13 + name: "shared-with-me.vue",
14 + components: {FileNavbarComponent, ShareTableComponent},
15 + }
16 +</script>
17 +
18 +<style scoped>
19 +
20 +</style>
1 +<template>
2 + <div>
3 + <trash-table-component/>
4 + </div>
5 +</template>
6 +
7 +<script>
8 + import TrashTableComponent from "../../components/TrashTableComponent";
9 + export default {
10 + name: 'trash',
11 + components: {
12 + TrashTableComponent
13 + }
14 + }
15 +</script>
1 +<template>
2 + <div>
3 + <div v-if="!me">
4 + Do login
5 + </div>
6 + <div v-else>
7 + {{me.username}}님 환영합니다
8 + </div>
9 +
10 + </div>
11 +</template>
12 +
13 +<script>
14 +
15 + export default {
16 + name: "home",
17 + data() {
18 + return {
19 + headers: [
20 + {
21 + text: '이름',
22 + }, {
23 + text: '수정한 날짜',
24 + }, {
25 + text: '공유',
26 + }, {
27 + text: '크기',
28 + }
29 + ],
30 + files: []
31 + }
32 + },
33 + computed: {
34 + me() {
35 + return this.$store.state.user.me;
36 + }
37 + }
38 + }
39 +</script>
40 +
1 +<template>
2 + <v-layout>
3 + <v-flex class="text-center">
4 + <div
5 + v-if="me">
6 + <v-btn @click="logout">로그아웃</v-btn>
7 + </div>
8 + <div
9 + v-else>
10 + <div
11 + v-if="tryLogin">
12 + <login-component/>
13 + <v-btn @click="changeTryLogin">회원가입</v-btn>
14 + </div>
15 + <div
16 + v-else>
17 + <sign-up-component/>
18 + <v-btn @click="changeTryLogin">로그인</v-btn>
19 + </div>
20 + </div>
21 +
22 + <PaddingMarginGrid/>
23 + </v-flex>
24 + </v-layout>
25 +</template>
26 +
27 +<script>
28 + import LoginComponent from "../components/LoginComponent";
29 + import SignUpComponent from "../components/SignUpComponent";
30 + import PaddingMarginGrid from "../components/PaddingMarginGrid";
31 +
32 +
33 + export default {
34 + data() {
35 + return {
36 + tryLogin: true,
37 + }
38 + },
39 + computed: {
40 + me() {
41 + return this.$store.state.user.me
42 + }
43 + },
44 + components: {
45 + LoginComponent,
46 + SignUpComponent,
47 + PaddingMarginGrid,
48 + },
49 + methods: {
50 + changeTryLogin() {
51 + this.tryLogin = !this.tryLogin
52 + },
53 + async logout() {
54 + try {
55 + await this.$store.dispatch('user/logout');
56 + await this.$router.replace('/');
57 + } catch (e) {
58 + console.error(e);
59 + }
60 + }
61 + }
62 + }
63 +
64 +</script>
1 +<template>
2 + <div>
3 + <PaddingMarginGrid/>
4 + </div>
5 +</template>
6 +
7 +<script>
8 + import PaddingMarginGrid from "../components/PaddingMarginGrid";
9 +
10 + export default {
11 + name: "vuetifyT",
12 + components: {PaddingMarginGrid}
13 + }
14 +</script>
15 +
16 +<style scoped>
17 +
18 +</style>
1 +# PLUGINS
2 +
3 +**This directory is not required, you can delete it if you don't want to use it.**
4 +
5 +This directory contains Javascript plugins that you want to run before mounting the root Vue.js application.
6 +
7 +More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins).
1 +# STATIC
2 +
3 +**This directory is not required, you can delete it if you don't want to use it.**
4 +
5 +This directory contains your static files.
6 +Each file inside this directory is mapped to `/`.
7 +Thus you'd want to delete this README.md before deploying to production.
8 +
9 +Example: `/static/robots.txt` is mapped as `/robots.txt`.
10 +
11 +More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static).
No preview for this file type
1 +<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>
1 +# STORE
2 +
3 +**This directory is not required, you can delete it if you don't want to use it.**
4 +
5 +This directory contains your Vuex Store files.
6 +Vuex Store option is implemented in the Nuxt.js framework.
7 +
8 +Creating a file in this directory automatically activates the option in the framework.
9 +
10 +More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store).
1 +export const state = () => ({
2 + files: [],
3 + file: null,
4 +});
5 +
6 +export const mutation = {
7 + loadFiles(state, payload) {
8 + const {files} = payload;
9 + state.files = files;
10 + },
11 + uploadFolder({commit}, payload) {
12 + const {file} = payload;
13 + state.files.push(file);
14 + },
15 + uploadFiles(state, payload) {
16 + const {files} = payload;
17 + state.files.concat(files);
18 + },
19 + deleteFile(state, payload) {
20 + const {fileId} = payload;
21 + state.file = null;
22 + state.files.splice(state.files.findIndex(file => file.id === fileId), 1);
23 + },
24 +};
25 +
26 +export const actions = {
27 + loadFiles({commit}, payload) {
28 + return new Promise(async (resolve, reject) => {
29 + try {
30 + const res = await this.$axios.get('http://127.0.0.1:8000/files/loadFiles', {
31 + withCredentials: true
32 + });
33 + const {files} = res.data;
34 + commit('loadFiles', {files});
35 + return resolve();
36 + } catch (e) {
37 + console.error(e);
38 + return reject(e);
39 + }
40 + })
41 + },
42 + uploadFolder({commit}, payload) {
43 + return new Promise(async (resolve, reject) => {
44 + try {
45 + const {formData} = payload;
46 + // const res = await this.$axios.post('http://127.0.0.1:8000/files/uploadFolder', formData, {
47 + // withCredentials: true
48 + // });
49 + let res = {
50 + file: {
51 + name: '90.944339.pdf',
52 + modifiedDate: '2020-02-08',
53 + owner: 'tjddus',
54 + fileSize: '1000',
55 + share: false
56 + }
57 + };
58 + const {file} = res;
59 + commit('uploadFiles', {file});
60 + return resolve();
61 +
62 + } catch (e) {
63 + console.error(e);
64 + return reject(e);
65 + }
66 + })
67 + },
68 + uploadFiles({commit}, payload) {
69 + return new Promise(async (resolve, reject) => {
70 + try {
71 + const {formData} = payload;
72 + const res = await this.$axios.post('http:/127.0.0.1:8000/files/uploadFiles', formData, {
73 + withCredentials: true
74 + });
75 + const {files} = res.data;
76 + commit('uploadFiles', files);
77 + return resolve();
78 +
79 + } catch (e) {
80 + console.error(e);
81 + return reject(e);
82 + }
83 + });
84 + },
85 + deleteFolder({commit}, payload) {
86 + return new Promise(async (resolve, reject) => {
87 + try {
88 + const {folderId} = payload;
89 + await this.$axios.get('http://127.0.0.1/files/deleteFile', {
90 + fileId: folderId
91 + }, {
92 + withCredentials: true
93 + });
94 + commit('deleteFile', {fileId: folderId});
95 +
96 + } catch (e) {
97 + console.error(e);
98 + return reject(e);
99 + }
100 + });
101 + },
102 + deleteFile({commit}, payload) {
103 + return new Promise(async (resolve, reject) => {
104 + try {
105 + const {fileId} = payload;
106 + await this.$axios.get('http://127.0.0.1/files/deleteFile', {
107 + fileId: fileId
108 + }, {
109 + withCredentials: true
110 + });
111 + commit('deleteFile', {fileId: fileId});
112 +
113 + } catch (e) {
114 + console.error(e);
115 + return reject(e);
116 + }
117 + })
118 + },
119 + // updateFolder({commit}, payload) {
120 + //
121 + // },
122 + // updateFile({commit}, payload) {
123 + //
124 + // }
125 +};
1 +import Cookie from 'js-cookie';
2 +
3 +export const state = () => ({});
4 +export const mutations = {};
5 +export const actions = {
6 + async nuxtServerInit({dispatch}, {req}) {
7 + try {
8 + const cookie = req.headers.cookie.split('=')[1];
9 + console.log(cookie);
10 + await dispatch('user/loadMe', {cookie});
11 + // await dispatch('post/loadPosts', {reset: true});
12 + // await dispatch('waitingRoom/loadChatMe');
13 + } catch (e) {
14 + console.error(e);
15 + }
16 + }
17 +};
1 +import Cookie from 'js-cookie';
2 +
3 +export const state = () => ({
4 + me: null,
5 +});
6 +
7 +export const mutations = {
8 + loadMe(state, payload) {
9 + const {user} = payload;
10 + state.me = user;
11 + },
12 + login(state, payload) {
13 + const {user} = payload;
14 + state.me = user;
15 + },
16 + logout(state) {
17 + state.me = null;
18 + }
19 +};
20 +
21 +export const actions = {
22 +//mutation{commit} 호출
23 + loadMe({commit}, payload) {
24 + return new Promise(async (resolve, reject) => {
25 + try {
26 + const {cookie} = payload;
27 + this.$axios.defaults.headers.common['Authorization'] = `Token ${cookie}`;
28 + const res = await this.$axios.get('http://localhost:8000/api/auth/loadMe', {
29 + withCredentials: true
30 + });
31 + commit('loadMe', {user: res.data});
32 + return resolve();
33 + } catch (e) {
34 + console.error(e);
35 + return reject(e);
36 + }
37 + })
38 + },
39 +
40 + /* signUp */
41 + signUp({commit}, payload) {
42 + return new Promise(async (resolve, reject) => {
43 + try {
44 + const {email, username, password} = payload;
45 + const res = await this.$axios.post('http://127.0.0.1:8000/api/auth/signUp', {
46 + email, username, password
47 + }, {
48 + withCredentials: true
49 + });
50 +
51 + const {user, token} = res.data;
52 + if (process.browser) {
53 + localStorage.setItem('accessToken', token);
54 + Cookie.set('accessToken', token);
55 + console.log(localStorage);
56 + }
57 +
58 + commit('login', {user});
59 + return resolve();
60 +
61 + } catch (e) {
62 + console.log(res.data);
63 + console.error(e);
64 + return reject(e);
65 + }
66 + })
67 + },
68 +
69 + /* login */
70 + login({commit}, payload) {
71 + return new Promise(async (resolve, reject) => {
72 + try {
73 + const {username, password} = payload;
74 + const res = await this.$axios.post('http://127.0.0.1:8000/api/auth/login', {
75 + username, password
76 + }, {
77 + withCredentials: true
78 + });
79 +
80 + console.log(res);
81 + const {user, token} = res.data;
82 + console.log(user, token);
83 + if (process.browser) {
84 + localStorage.setItem('accessToken', token);
85 + Cookie.set('accessToken', token);
86 + console.log(localStorage);
87 + }
88 +
89 +
90 + commit('login', {user});
91 + return resolve();
92 +
93 + } catch (e) {
94 + console.error(e);
95 + return reject(e);
96 + }
97 + });
98 + },
99 +
100 + /* logout */
101 + logout({commit}) {
102 + return new Promise(async (resolve, reject) => {
103 + try {
104 + // await this.$axios.get('http://127.0.0.1:8000/user/logout', {
105 + // withCredentials: true
106 + // });
107 + if (process.browser) {
108 + localStorage.removeItem('accessToken');
109 + Cookie.remove('accessToken');
110 + }
111 + commit('logout');
112 + return resolve();
113 +
114 + } catch (e) {
115 + console.error(e);
116 + return reject(e);
117 + }
118 + })
119 + }
120 +
121 +
122 +};
1 -'''
2 -import boto3
3 -import sys
4 -from django.conf import settings
5 -import configparser
6 -
7 -config = configparser.ConfigParser()
8 -config.read('config.ini')
9 -
10 -s3_client = boto3.client(
11 - 's3',
12 - aws_access_key_id=config['aws']['AWS_ACCESS_KEY_ID'],
13 - aws_secret_access_key=config['aws']['AWS_SECRET_ACCESS_KEY']
14 -)
15 -s3 = boto3.resource('s3', aws_access_key_id=config['aws']['AWS_ACCESS_KEY_ID'],
16 - aws_secret_access_key=config['aws']['AWS_SECRET_ACCESS_KEY'])
17 -
18 -
19 -def get_folder_with_items(self, main_folder):
20 - print("HI~~~~")
21 -
22 - try:
23 - result = self.s3_client.list_objects(
24 - Bucket="opijaeclouds", Prefix=main_folder[1:], Delimiter="/")
25 - result_files = get_files(main_folder, result.get(
26 - 'Contents')) if result.get('Contents') else []
27 - result_folders = get_folders(main_folder, result.get('CommonPrefixes')) if result.get(
28 - 'CommonPrefixes') else []
29 - return result_folders + result_files # return files and folders
30 - except Exception as e:
31 - print('Error on line {}'.format(
32 - sys.exc_info()[-1].tb_lineno), type(e).__name__, e)
33 -
34 -
35 -def get_files(main_folder, result):
36 - try:
37 - files_list = []
38 - for obj in result:
39 - # main_folder[1:] exp; -folder1/folder2 => delete "-"
40 - if main_folder[1:] != obj.get('Key'): # if obj is not folder item
41 - object_url = "https://s3.console.amazonaws.com/s3/buckets/{0}/{1}".format(
42 - "opijaeclouds", obj.get('Key'))
43 - # for template file icon
44 - icon_list = [
45 - 'ai.png', 'audition.png', 'avi.png', 'bridge.png', 'css.png', 'csv.png', 'dbf.png', 'doc.png',
46 - 'dreamweaver.png', 'dwg.png', 'exe.png', 'file.png', 'fireworks.png', 'fla.png', 'flash.png',
47 - 'folder_icon.png', 'html.png', 'illustrator.png', 'indesign.png', 'iso.png', 'javascript.png',
48 - 'jpg.png', 'json-file.png', 'mp3.png', 'mp4.png', 'pdf.png', 'photoshop.png', 'png.png',
49 - 'ppt.png', 'prelude.png', 'premiere.png', 'psd.png', 'rtf.png', 'search.png', 'svg.png',
50 - 'txt.png', 'xls.png', 'xml.png', 'zip.png', 'zip-1.png']
51 - img_file_list = ['ani', 'bmp', 'cal', 'fax', 'gif', 'img', 'jbg', 'jpg', 'jpe', 'mac', 'pbm',
52 - 'pcd', 'pcx', 'pct', 'pgm', 'png', 'jpeg', 'ppm', 'psd', 'ras', 'tag', 'tif',
53 - 'wmf']
54 - extension, icon = str(obj['Key'].split('.')[-1]).lower(), None
55 - if extension in img_file_list:
56 - icon = object_url if extension in ['bmp', 'jpg', 'jpeg', 'png',
57 - 'gif'] else "/static/images/jpg.png"
58 - if not icon:
59 - icon = "/static/images/" + extension + ".png" if extension + \
60 - ".png" in icon_list else "/static/images/file.png"
61 - item_type = "folder" if obj.get(
62 - 'Key')[-1] == "/" else "other" # for show template
63 - files_list.append(
64 - {'key': obj.get('Key'), 'url': object_url, 'icon': icon,
65 - 'text': obj.get('Key')[len(main_folder) - 1:], 'type': item_type})
66 - return sorted(files_list, key=lambda k: str(k['key']).lower(), reverse=no)
67 - except Exception as e:
68 - print('Error on line {}'.format(
69 - sys.exc_info()[-1].tb_lineno), type(e).__name__, e)
70 -
71 -
72 -def get_folders(main_folder, result):
73 - try:
74 - files_list = []
75 - for obj in result:
76 - icon = "/static/images/folder_icon.png"
77 - item_type = "folder" # for show template
78 - url = obj.get('Prefix')
79 - files_list.append(
80 - {'key': obj.get('Prefix'), 'url': url, 'icon': icon,
81 - 'text': obj.get('Prefix')[len(main_folder) - 1:], 'type': item_type})
82 - return sorted(files_list, key=lambda k: str(k['key']).lower(), reverse=no)
83 - except Exception as e:
84 - print('Error on line {}'.format(
85 - sys.exc_info()[-1].tb_lineno), type(e).__name__, e)
86 -'''
...@@ -2,7 +2,18 @@ from django.db import models ...@@ -2,7 +2,18 @@ from django.db import models
2 from django.utils import timezone 2 from django.utils import timezone
3 3
4 # Create your models here. 4 # Create your models here.
5 +
6 +
5 class File(models.Model): 7 class File(models.Model):
6 - path=models.CharField(max_length=300)
7 - created_date = models.DateTimeField(default=timezone.now)
8 - modified_date = models.DateTimeField(blank=True, null=True)
...\ No newline at end of file ...\ No newline at end of file
8 + file = models.FileField(upload_to=None, max_length=100, )
9 + name = models.CharField(max_length=50)
10 + isFolder = models.BooleanField(default=False)
11 + path = models.FilePathField(
12 + path=None, match=None, recursive=False, max_length=100)
13 + owner = models.CharField(max_length=30)
14 + fileSize = models.IntegerField()
15 + createdDate = models.DateTimeField(auto_now_add=True)
16 + modifiedDate = models.DateTimeField(blank=True, null=True)
17 +
18 + class Meta:
19 + ordering = ['createdDate']
......
1 +from rest_framework import serializers
2 +from .models import File
3 +
4 +
5 +class FileSerializer(serializers.FileSerializer):
6 + class Meta:
7 + model = File
8 + fields = ['file', 'name', 'isFolder', 'path', 'owner',
9 + 'fileSize', 'createdDate', 'modifiedDate']
...@@ -14,6 +14,7 @@ import configparser ...@@ -14,6 +14,7 @@ import configparser
14 14
15 config = configparser.ConfigParser() 15 config = configparser.ConfigParser()
16 config.read('config.ini') 16 config.read('config.ini')
17 +
17 # class FileToURL(View): 18 # class FileToURL(View):
18 # s3_client = boto3.client( 19 # s3_client = boto3.client(
19 # 's3', 20 # 's3',
...@@ -89,9 +90,6 @@ class FileList(View): ...@@ -89,9 +90,6 @@ class FileList(View):
89 bucket = "opijaeclouds" 90 bucket = "opijaeclouds"
90 91
91 bucketMy = self.s3.Bucket(bucket) 92 bucketMy = self.s3.Bucket(bucket)
92 - # Iterates through all the objects, doing the pagination for you. Each obj
93 - # is an ObjectSummary, so it doesn't contain the body. You'll need to call
94 - # get to get the whole body.
95 for obj in bucketMy.objects.all(): 93 for obj in bucketMy.objects.all():
96 key = obj.key 94 key = obj.key
97 body = obj.get()['Body'].read() 95 body = obj.get()['Body'].read()
......
1 +*.pyc
2 +*~
3 +__pycache__
4 +myvenv
5 +db.sqlite3
6 +/static
7 +.DS_Store
1 +from django.contrib import admin
2 +
3 +# Register your models here.
1 +from django.apps import AppConfig
2 +
3 +
4 +class AccountsConfig(AppConfig):
5 + name = 'accounts'
1 +from django.contrib.auth.models import User
2 +from django.contrib.auth import authenticate
3 +from rest_framework import serializers
4 +
5 +# 접속 유지 확인 및 사용자 확인
6 +class UserSerializer(serializers.ModelSerializer):
7 + class Meta:
8 + model = User
9 + fields = ['id', 'username', 'email']
10 +
11 +# 회원가입
12 +class SignUpSerializer(serializers.ModelSerializer):
13 + class Meta:
14 + model = User
15 + fields = ["username", "email", "password"]
16 +
17 + def create(self, validated_data):
18 + user = User.objects.create_user(
19 + validated_data['username'], validated_data['email'], validated_data['password']
20 + )
21 + return user
22 +
23 +
24 +# 로그인 (커스터마이징 => Serializer)
25 +class LoginSerializer(serializers.Serializer):
26 + username = serializers.CharField()
27 + password = serializers.CharField()
28 +
29 + def validate(self, data):
30 + print('validate data',data)
31 + user = authenticate(**data)
32 + if user and user.is_active:
33 + return user
34 + raise serializers.validationError('Unable to log in with provided credentials.')
...\ No newline at end of file ...\ No newline at end of file
1 +from django.test import TestCase
2 +
3 +# Create your tests here.
1 +from django.urls import path, include
2 +from rest_framework import routers
3 +from accounts.views import LoginAPI, UserAPI, SignUpAPI
4 +
5 +# router = routers.DefaultRouter()
6 +# router.register(r'user', views.login)
7 +
8 +urlpatterns = [
9 + path("api/auth/signUp", SignUpAPI.as_view()),
10 + path("api/auth/login", LoginAPI.as_view()),
11 + path("api/auth/loadMe", UserAPI.as_view()),
12 +]
1 +from django.shortcuts import render
2 +from rest_framework.authtoken.models import Token
3 +from accounts.serializers import (
4 + UserSerializer,
5 + LoginSerializer,
6 + SignUpSerializer,
7 +)
8 +from rest_framework import viewsets, permissions, generics, status
9 +from rest_framework.response import Response
10 +from django.contrib.auth.models import User
11 +
12 +# LoadUserAPI
13 +# ssr user loading
14 +# used for read_only endpoints to represent a single model instance.
15 +class UserAPI(generics.RetrieveAPIView):
16 + permission_classes = [
17 + permissions.IsAuthenticated,
18 + ]
19 + serializer_class = UserSerializer
20 +
21 + def get_object(self):
22 + print('Load Me 인증 성공', self.request.user)
23 + user = UserSerializer(self.request.user).data
24 + return self.request.user
25 +
26 +# SignUpAPI
27 +# 회원가입 API
28 +class SignUpAPI(generics.GenericAPIView):
29 + serializer_class = SignUpSerializer
30 +
31 + def post(self, request, *args, **kwargs):
32 + print(request.data)
33 + serializer = self.get_serializer(data=request.data)
34 + print(serializer)
35 + serializer.is_valid(raise_exception=True)
36 + user = serializer.save()
37 + print(user)
38 + token, created = Token.objects.get_or_create(user=user)
39 + return Response({
40 + 'user': UserSerializer(
41 + user, context = self.get_serializer_context()
42 + ).data,
43 + 'token': token.key
44 + })
45 +
46 +
47 +# LoginAPI: req.data(username, password)=>deserializer=>valid(authenticate)=>serializer
48 +# 로그인 API
49 +class LoginAPI(generics.GenericAPIView):
50 + # field : username, password
51 + serializer_class = LoginSerializer
52 +
53 + def post(self, request, *args, **kwargs):
54 + print('login request가 들어왔으면 말좀 해줘', request.data)
55 + serializer = self.get_serializer(data=request.data)
56 + serializer.is_valid(raise_exception=True)
57 + user = serializer.validated_data # complex type data
58 + token, created = Token.objects.get_or_create(user=user)
59 + print(user, token)
60 + return Response({
61 + 'user': UserSerializer(
62 + user, context = self.get_serializer_context()
63 + ).data,
64 + 'token': token.key
65 + })
...\ No newline at end of file ...\ No newline at end of file
1 +#!/usr/bin/env python
2 +"""Django's command-line utility for administrative tasks."""
3 +import os
4 +import sys
5 +
6 +
7 +def main():
8 + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
9 + try:
10 + from django.core.management import execute_from_command_line
11 + except ImportError as exc:
12 + raise ImportError(
13 + "Couldn't import Django. Are you sure it's installed and "
14 + "available on your PYTHONPATH environment variable? Did you "
15 + "forget to activate a virtual environment?"
16 + ) from exc
17 + execute_from_command_line(sys.argv)
18 +
19 +
20 +if __name__ == '__main__':
21 + main()
1 +"""
2 +ASGI config for mysite project.
3 +
4 +It exposes the ASGI callable as a module-level variable named ``application``.
5 +
6 +For more information on this file, see
7 +https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/
8 +"""
9 +
10 +import os
11 +
12 +from django.core.asgi import get_asgi_application
13 +
14 +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
15 +
16 +application = get_asgi_application()
1 +"""
2 +Django settings for mysite project.
3 +
4 +Generated by 'django-admin startproject' using Django 3.0.6.
5 +
6 +For more information on this file, see
7 +https://docs.djangoproject.com/en/3.0/topics/settings/
8 +
9 +For the full list of settings and their values, see
10 +https://docs.djangoproject.com/en/3.0/ref/settings/
11 +"""
12 +
13 +import os
14 +import datetime
15 +
16 +# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
17 +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
18 +
19 +
20 +# Quick-start development settings - unsuitable for production
21 +# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
22 +
23 +# SECURITY WARNING: keep the secret key used in production secret!
24 +SECRET_KEY = '&041&h2k89h+l=^#)0fgf*df-4crdid&fw_duhy5(i#-#g+xaj'
25 +
26 +# SECURITY WARNING: don't run with debug turned on in production!
27 +DEBUG = True
28 +
29 +ALLOWED_HOSTS = [
30 + 'localhost',
31 + '127.0.0.1',
32 +]
33 +
34 +
35 +# Application definition
36 +
37 +INSTALLED_APPS = [
38 + 'django.contrib.admin',
39 + 'django.contrib.auth',
40 + 'django.contrib.contenttypes',
41 + 'django.contrib.sessions',
42 + 'django.contrib.messages',
43 + 'django.contrib.staticfiles',
44 + 'rest_framework',
45 + 'rest_framework.authtoken',
46 + 'corsheaders',
47 + 'accounts',
48 +]
49 +
50 +MIDDLEWARE = [
51 + 'corsheaders.middleware.CorsMiddleware',
52 + 'django.middleware.common.CommonMiddleware',
53 + 'django.middleware.security.SecurityMiddleware',
54 + 'django.contrib.sessions.middleware.SessionMiddleware',
55 + 'django.middleware.common.CommonMiddleware',
56 + 'django.middleware.csrf.CsrfViewMiddleware',
57 + 'django.contrib.auth.middleware.AuthenticationMiddleware',
58 + 'django.contrib.messages.middleware.MessageMiddleware',
59 + 'django.middleware.clickjacking.XFrameOptionsMiddleware',
60 +]
61 +CORS_ORIGIN_ALLOWED_ALL = True
62 +CORS_ALLOW_CREDENTIALS = True
63 +
64 +CORS_ORIGIN_WHITELIST = [
65 +'http://localhost:3001',
66 +'http://127.0.0.1:3001',
67 +]
68 +
69 +ROOT_URLCONF = 'mysite.urls'
70 +
71 +TEMPLATES = [
72 + {
73 + 'BACKEND': 'django.template.backends.django.DjangoTemplates',
74 + 'DIRS': [],
75 + 'APP_DIRS': True,
76 + 'OPTIONS': {
77 + 'context_processors': [
78 + 'django.template.context_processors.debug',
79 + 'django.template.context_processors.request',
80 + 'django.contrib.auth.context_processors.auth',
81 + 'django.contrib.messages.context_processors.messages',
82 + ],
83 + },
84 + },
85 +]
86 +
87 +WSGI_APPLICATION = 'mysite.wsgi.application'
88 +
89 +
90 +# Database
91 +# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
92 +
93 +DATABASES = {
94 + 'default': {
95 + 'ENGINE': 'django.db.backends.sqlite3',
96 + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
97 + }
98 +}
99 +
100 +
101 +# Password validation
102 +# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
103 +
104 +AUTH_PASSWORD_VALIDATORS = [
105 + {
106 + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
107 + },
108 + {
109 + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
110 + },
111 + {
112 + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
113 + },
114 + {
115 + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
116 + },
117 +]
118 +
119 +
120 +# Internationalization
121 +# https://docs.djangoproject.com/en/3.0/topics/i18n/
122 +
123 +LANGUAGE_CODE = 'ko'
124 +
125 +TIME_ZONE = 'Asia/Seoul'
126 +
127 +USE_I18N = True
128 +
129 +USE_L10N = True
130 +
131 +USE_TZ = True
132 +
133 +
134 +# Static files (CSS, JavaScript, Images)
135 +# https://docs.djangoproject.com/en/3.0/howto/static-files/
136 +
137 +STATIC_URL = '/static/'
138 +
139 +REST_FRAMEWORK = {
140 + # 권한 인증
141 + 'DEFAULT_AUTHENTICATION_CLASSES': (
142 + 'rest_framework.authentication.TokenAuthentication',
143 + ),
144 +}
1 +"""mysite URL Configuration
2 +
3 +The `urlpatterns` list routes URLs to views. For more information please see:
4 + https://docs.djangoproject.com/en/3.0/topics/http/urls/
5 +Examples:
6 +Function views
7 + 1. Add an import: from my_app import views
8 + 2. Add a URL to urlpatterns: path('', views.home, name='home')
9 +Class-based views
10 + 1. Add an import: from other_app.views import Home
11 + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
12 +Including another URLconf
13 + 1. Import the include() function: from django.urls import include, path
14 + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15 +"""
16 +from django.contrib import admin
17 +from django.urls import path, include
18 +
19 +urlpatterns = [
20 + path('admin/', admin.site.urls),
21 + path('', include('accounts.urls')),
22 +]
1 +"""
2 +WSGI config for mysite project.
3 +
4 +It exposes the WSGI callable as a module-level variable named ``application``.
5 +
6 +For more information on this file, see
7 +https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/
8 +"""
9 +
10 +import os
11 +
12 +from django.core.wsgi import get_wsgi_application
13 +
14 +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
15 +
16 +application = get_wsgi_application()