허진호

first commit

1 +# Byte-compiled / optimized / DLL files
2 +__pycache__/
3 +*.py[cod]
4 +*$py.class
5 +
6 +# C extensions
7 +*.so
8 +
9 +# Distribution / packaging
10 +credential.py
11 +.Python
12 +build/
13 +develop-eggs/
14 +dist/
15 +downloads/
16 +eggs/
17 +.eggs/
18 +lib/
19 +lib64/
20 +parts/
21 +sdist/
22 +var/
23 +wheels/
24 +*.egg-info/
25 +.installed.cfg
26 +*.egg
27 +MANIFEST
28 +
29 +# PyInstaller
30 +# Usually these files are written by a python script from a template
31 +# before PyInstaller builds the exe, so as to inject date/other infos into it.
32 +*.manifest
33 +*.spec
34 +
35 +# Installer logs
36 +pip-log.txt
37 +pip-delete-this-directory.txt
38 +
39 +# Unit test / coverage reports
40 +htmlcov/
41 +.tox/
42 +.coverage
43 +.coverage.*
44 +.cache
45 +nosetests.xml
46 +coverage.xml
47 +*.cover
48 +.hypothesis/
49 +.pytest_cache/
50 +
51 +# Translations
52 +*.mo
53 +*.pot
54 +
55 +# Django stuff:
56 +*.log
57 +local_settings.py
58 +db.sqlite3
59 +
60 +# Flask stuff:
61 +instance/
62 +.webassets-cache
63 +
64 +# Scrapy stuff:
65 +.scrapy
66 +
67 +# Sphinx documentation
68 +docs/_build/
69 +
70 +# PyBuilder
71 +target/
72 +
73 +# Jupyter Notebook
74 +.ipynb_checkpoints
75 +
76 +# pyenv
77 +.python-version
78 +
79 +# celery beat schedule file
80 +celerybeat-schedule
81 +
82 +# SageMath parsed files
83 +*.sage.py
84 +
85 +# Environments
86 +.env
87 +.venv
88 +env/
89 +venv/
90 +ENV/
91 +env.bak/
92 +venv.bak/
93 +
94 +# Spyder project settings
95 +.spyderproject
96 +.spyproject
97 +
98 +# Rope project settings
99 +.ropeproject
100 +
101 +# mkdocs documentation
102 +/site
103 +
104 +# mypy
105 +.mypy_cache/
106 +
107 +*.pyc
108 +*~
109 +__pycache__
110 +venv
111 +db.sqlite3
112 +.DS_Store
113 +
114 +# User-specific stuff:
115 +**/.idea/workspace.xml
116 +**/.idea/tasks.xml
117 +**/.idea/dictionaries
118 +**/.idea/vcs.xml
119 +**/.idea/jsLibraryMappings.xml
120 +
121 +# Sensitive or high-churn files:
122 +**/.idea/dataSources.ids
123 +**/.idea/dataSources.xml
124 +**/.idea/dataSources.local.xml
125 +**/.idea/sqlDataSources.xml
126 +**/.idea/dynamic.xml
127 +**/.idea/uiDesigner.xml
128 +
129 +## File-based project format:
130 +*.iws
131 +
132 +# IntelliJ
133 +/out/
134 +
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<module type="PYTHON_MODULE" version="4">
3 + <component name="FacetManager">
4 + <facet type="django" name="Django">
5 + <configuration>
6 + <option name="rootFolder" value="$MODULE_DIR$" />
7 + <option name="settingsModule" value="fileshell/settings.py" />
8 + <option name="manageScript" value="$MODULE_DIR$/manage.py" />
9 + <option name="environment" value="&lt;map/&gt;" />
10 + <option name="doNotUseTestRunner" value="false" />
11 + <option name="trackFilePattern" value="migrations" />
12 + </configuration>
13 + </facet>
14 + </component>
15 + <component name="NewModuleRootManager">
16 + <content url="file://$MODULE_DIR$">
17 + <excludeFolder url="file://$MODULE_DIR$/venv" />
18 + </content>
19 + <orderEntry type="inheritedJdk" />
20 + <orderEntry type="sourceFolder" forTests="false" />
21 + </component>
22 + <component name="TemplatesService">
23 + <option name="TEMPLATE_CONFIGURATION" value="Django" />
24 + <option name="TEMPLATE_FOLDERS">
25 + <list>
26 + <option value="$MODULE_DIR$/../fileshell\templates" />
27 + </list>
28 + </option>
29 + </component>
30 + <component name="TestRunnerService">
31 + <option name="PROJECT_TEST_RUNNER" value="Unittests" />
32 + </component>
33 +</module>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project version="4">
3 + <component name="JavaScriptSettings">
4 + <option name="languageLevel" value="ES6" />
5 + </component>
6 + <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (fileshell)" project-jdk-type="Python SDK" />
7 +</project>
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project version="4">
3 + <component name="ProjectModuleManager">
4 + <modules>
5 + <module fileurl="file://$PROJECT_DIR$/.idea/fileshell.iml" filepath="$PROJECT_DIR$/.idea/fileshell.iml" />
6 + </modules>
7 + </component>
8 +</project>
...\ No newline at end of file ...\ No newline at end of file
File mode changed
File mode changed
1 +from django.contrib import admin
2 +from .models import *
3 +
4 +admin.site.register(File)
5 +admin.site.register(Folder)
...\ No newline at end of file ...\ No newline at end of file
1 +from django import forms
2 +from django.contrib.auth.models import User
3 +from .models import *
4 +
5 +class UserForm(forms.ModelForm):
6 + class Meta:
7 + model = User
8 + fields = ['username', 'password', 'email']
9 +
10 +
11 +class FolderForm(forms.ModelForm):
12 + class Meta:
13 + model = Folder
14 + fields = ['dir_name', 'parent']
15 +
16 + def __init__(self, *args, **kwargs):
17 + super(FolderForm, self).__init__(*args, **kwargs)
18 + self.fields['folder'].required = False
...\ No newline at end of file ...\ No newline at end of file
1 +# -*- coding: utf-8 -*-
2 +# Generated by Django 1.11.13 on 2018-06-07 01:36
3 +from __future__ import unicode_literals
4 +
5 +from django.db import migrations, models
6 +import django.db.models.deletion
7 +
8 +
9 +class Migration(migrations.Migration):
10 +
11 + initial = True
12 +
13 + dependencies = [
14 + ]
15 +
16 + operations = [
17 + migrations.CreateModel(
18 + name='File',
19 + fields=[
20 + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21 + ('title', models.CharField(max_length=100)),
22 + ('user', models.CharField(max_length=20)),
23 + ('uploaded_TM', models.DateTimeField(auto_now_add=True)),
24 + ('last_view_TM', models.DateTimeField()),
25 + ('isFavor', models.BooleanField()),
26 + ('bucketPath', models.CharField(max_length=50)),
27 + ('fileSize', models.IntegerField()),
28 + ('localPath', models.CharField(max_length=100)),
29 + ],
30 + ),
31 + migrations.CreateModel(
32 + name='Folder',
33 + fields=[
34 + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
35 + ('dir_name', models.CharField(max_length=30)),
36 + ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child', to='fileshell.Folder')),
37 + ],
38 + ),
39 + migrations.AddField(
40 + model_name='file',
41 + name='folder',
42 + field=models.ManyToManyField(blank=True, null=True, related_name='datas', to='fileshell.Folder'),
43 + ),
44 + ]
1 +# -*- coding: utf-8 -*-
2 +# Generated by Django 1.11.13 on 2018-06-07 13:33
3 +from __future__ import unicode_literals
4 +
5 +from django.db import migrations, models
6 +
7 +
8 +class Migration(migrations.Migration):
9 +
10 + dependencies = [
11 + ('fileshell', '0001_initial'),
12 + ]
13 +
14 + operations = [
15 + migrations.RemoveField(
16 + model_name='file',
17 + name='localPath',
18 + ),
19 + migrations.AlterField(
20 + model_name='file',
21 + name='last_view_TM',
22 + field=models.DateTimeField(auto_now_add=True),
23 + ),
24 + ]
1 +# -*- coding: utf-8 -*-
2 +# Generated by Django 1.11.13 on 2018-06-07 14:43
3 +from __future__ import unicode_literals
4 +
5 +from django.db import migrations, models
6 +import django.db.models.deletion
7 +
8 +
9 +class Migration(migrations.Migration):
10 +
11 + dependencies = [
12 + ('fileshell', '0002_auto_20180607_1333'),
13 + ]
14 +
15 + operations = [
16 + migrations.RemoveField(
17 + model_name='file',
18 + name='folder',
19 + ),
20 + migrations.AddField(
21 + model_name='file',
22 + name='folder',
23 + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='datas', to='fileshell.Folder'),
24 + ),
25 + ]
1 +# -*- coding: utf-8 -*-
2 +# Generated by Django 1.11.13 on 2018-06-08 02:08
3 +from __future__ import unicode_literals
4 +
5 +from django.db import migrations, models
6 +
7 +
8 +class Migration(migrations.Migration):
9 +
10 + dependencies = [
11 + ('fileshell', '0003_auto_20180607_1443'),
12 + ]
13 +
14 + operations = [
15 + migrations.AddField(
16 + model_name='folder',
17 + name='user',
18 + field=models.CharField(default='', max_length=20),
19 + ),
20 + ]
1 +from django.db import models
2 +
3 +class File(models.Model):
4 + title = models.CharField(max_length=100)
5 + user = models.CharField(max_length=20)
6 + uploaded_TM = models.DateTimeField(auto_now_add=True)
7 + last_view_TM = models.DateTimeField(auto_now_add=True)
8 + isFavor = models.BooleanField(default=False)
9 + bucketPath = models.CharField(max_length=50)
10 + fileSize = models.IntegerField()
11 + folder = models.ForeignKey('Folder', null=True, blank=True, related_name='datas')
12 +
13 +class Folder(models.Model):
14 + dir_name = models.CharField(max_length=30)
15 + user = models.CharField(max_length=20, default='')
16 + parent = models.ForeignKey('self', related_name='child', null=True, blank=True)
...\ No newline at end of file ...\ No newline at end of file
1 +"""
2 +Django settings for fileshell project.
3 +
4 +Generated by 'django-admin startproject' using Django 2.0.5.
5 +
6 +For more information on this file, see
7 +https://docs.djangoproject.com/en/2.0/topics/settings/
8 +
9 +For the full list of settings and their values, see
10 +https://docs.djangoproject.com/en/2.0/ref/settings/
11 +"""
12 +
13 +import os
14 +from .credential import *
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/2.0/howto/deployment/checklist/
22 +
23 +# SECURITY WARNING: don't run with debug turned on in production!
24 +DEBUG = True
25 +
26 +ALLOWED_HOSTS = []
27 +
28 +
29 +# Application definition
30 +
31 +INSTALLED_APPS = [
32 + 'django.contrib.admin',
33 + 'django.contrib.auth',
34 + 'django.contrib.contenttypes',
35 + 'django.contrib.sessions',
36 + 'django.contrib.messages',
37 + 'django.contrib.staticfiles',
38 + 'fileshell',
39 + 'storages',
40 +]
41 +
42 +MIDDLEWARE = [
43 + 'django.middleware.security.SecurityMiddleware',
44 + 'django.contrib.sessions.middleware.SessionMiddleware',
45 + 'django.middleware.common.CommonMiddleware',
46 + 'django.middleware.csrf.CsrfViewMiddleware',
47 + 'django.contrib.auth.middleware.AuthenticationMiddleware',
48 + 'django.contrib.messages.middleware.MessageMiddleware',
49 + 'django.middleware.clickjacking.XFrameOptionsMiddleware',
50 +]
51 +
52 +ROOT_URLCONF = 'fileshell.urls'
53 +
54 +TEMPLATES = [
55 + {
56 + 'BACKEND': 'django.template.backends.django.DjangoTemplates',
57 + 'DIRS': [os.path.join(BASE_DIR, 'templates')]
58 + ,
59 + 'APP_DIRS': True,
60 + 'OPTIONS': {
61 + 'context_processors': [
62 + 'django.template.context_processors.debug',
63 + 'django.template.context_processors.request',
64 + 'django.contrib.auth.context_processors.auth',
65 + 'django.contrib.messages.context_processors.messages',
66 + ],
67 + },
68 + },
69 +]
70 +
71 +WSGI_APPLICATION = 'fileshell.wsgi.application'
72 +
73 +
74 +# Database
75 +# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
76 +
77 +DATABASES = {
78 + 'default': {
79 + 'ENGINE': 'django.db.backends.sqlite3',
80 + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
81 + }
82 +}
83 +
84 +
85 +# Password validation
86 +# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
87 +
88 +AUTH_PASSWORD_VALIDATORS = [
89 + {
90 + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
91 + },
92 + {
93 + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
94 + },
95 + {
96 + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
97 + },
98 + {
99 + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
100 + },
101 +]
102 +
103 +
104 +# Internationalization
105 +# https://docs.djangoproject.com/en/2.0/topics/i18n/
106 +
107 +LANGUAGE_CODE = 'en-us'
108 +
109 +
110 +TIME_ZONE = 'Asia/Seoul'
111 +
112 +USE_I18N = True
113 +
114 +USE_L10N = True
115 +
116 +USE_TZ = False
117 +
118 +
119 +
120 +# Static files (CSS, JavaScript, Images)
121 +# https://docs.djangoproject.com/en/2.0/howto/static-files/
122 +
123 +STATIC_URL = '/static/'
124 +LOGIN_REDIRECT_URL = '/'
125 +LOGOUT_REDIRECT_URL = '/account_login'
126 +
127 +#S3 Storage
128 +DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
129 +MEDIAFILES_LOCATION = 'storages.backends.s3boto3.S3Boto3Storage'
130 +LOCAL_DOWNLOAD_PATH = 'C:\\Users\\USER\\Downloads\\'
131 +
132 +# SECURITY WARNING: keep the secret key used in production secret!
133 +SECRET_KEY = secret_key
134 +
135 +#AWS Access
136 +AWS_ACCESS_KEY_ID = key_id
137 +AWS_SECRET_ACCESS_KEY =secret_access_key
138 +AWS_STORAGE_BUCKET_NAME ='fileshell-test'
1 +body {
2 + font-family: "Roboto", sans-serif;
3 +}
4 +.search_form{
5 + float:right;
6 +}
7 +.left_bar {
8 + float:left;
9 + width:200px;
10 + height:900px;
11 + background-color: #2b2d3d;
12 +}
13 +.nav {
14 +}
15 +.nav-list {
16 + list-style: none;
17 + margin: 10px;
18 +}
19 +.nav-item {
20 + font-size: 30px;
21 + color:#ffffff;
22 + margin: 10px;
23 +}
24 +.nav-item1 {
25 + font-size: 30px;
26 + color:#ffffff;
27 + margin: 10px;
28 +}
29 +.nav-link {
30 + list-style: none;
31 + text-decoration: none;
32 + color:#ffffff;
33 +}
34 +.nav-link-right {
35 + list-style: none;
36 + text-decoration: none;
37 + color:#ffffff;
38 +}
39 +.nav-link:hover {
40 +}
41 +.frame {
42 + width: 1800px;
43 + margin: 0 auto;
44 + border: 1px solid #aaa;
45 +}
46 +.header {
47 + height : 60px;
48 + padding:40px 10px;
49 + text-align: center;
50 + background: #eee;
51 + margin-bottom: 20px;
52 +}
53 +.profile_icon {
54 + float:right;
55 + padding-right: 10px;
56 + margin-right: 10px;
57 +}
58 +.logout_icon {
59 + float:right;
60 +}
61 +.logo {
62 + font-size: 2em;
63 + font-weight: bold;
64 + background: #5457de;
65 + color: #fff;
66 + display: inline-block;
67 + padding: 0 8px;
68 +}
69 +.container {
70 + overflow: hidden;
71 +}
72 +
73 +.content {
74 + float: left;
75 + width: 1600px;
76 +}
77 +.right_bar {
78 + float:right;
79 + width:200px;
80 + height:800px;
81 + background: #FFFFFF;
82 +}
83 +.upload-btn {
84 + width:180px;
85 + height:60px;
86 + text-align: center;
87 + background-color: #2b2d3d;
88 + margin : 10px;
89 +}
90 +.upload-link {
91 + font-size: 17px;
92 + font-weight: bold;
93 + color: #fff;
94 + text-decoration: none;
95 + text-decoration-color: #FFF;
96 +}
97 +.nav-link-right {
98 + font-size: 15px;
99 + font-weight: bold;
100 + color: #fff;
101 + text-decoration: none;
102 + color:#2b2d3d;
103 +}
104 +.footer {
105 + text-align: center;
106 + border-top: 1px solid #aaa;
107 + margin: 20px 20px 0;
108 + font-size: 12px;
109 +}
110 +.switch {
111 + position: relative;
112 + display: inline-block;
113 + width: 60px;
114 + height: 34px;
115 +}
116 +
117 +/* Hide default HTML checkbox */
118 +.switch input {display:none;}
119 +
120 +/* The slider */
121 +.slider {
122 + position: absolute;
123 + cursor: pointer;
124 + top: 0;
125 + left: 0;
126 + right: 0;
127 + bottom: 0;
128 + background-color: #ccc;
129 + -webkit-transition: .4s;
130 + transition: .4s;
131 +}
132 +
133 +.slider:before {
134 + position: absolute;
135 + content: "";
136 + height: 26px;
137 + width: 26px;
138 + left: 4px;
139 + bottom: 4px;
140 + background-color: white;
141 + -webkit-transition: .4s;
142 + transition: .4s;
143 +}
144 +
145 +input:checked + .slider {
146 + background-color: #2196F3;
147 +}
148 +
149 +input:focus + .slider {
150 + box-shadow: 0 0 1px #2196F3;
151 +}
152 +
153 +input:checked + .slider:before {
154 + -webkit-transform: translateX(26px);
155 + -ms-transform: translateX(26px);
156 + transform: translateX(26px);
157 +}
158 +
159 +/* Rounded sliders */
160 +.slider.round {
161 + border-radius: 34px;
162 +}
163 +
164 +.slider.round:before {
165 + border-radius: 50%;
166 +}
1 +
2 +@import url(https://fonts.googleapis.com/css?family=Lato:400,700);
3 +* {
4 + -moz-box-sizing: border-box;
5 + -webkit-box-sizing: border-box;
6 + box-sizing: border-box;
7 +}
8 +html {
9 + width: 100%;
10 + height: 100%;
11 +}
12 +
13 +body {
14 + width:100%;
15 + height:100%;
16 + background: -webkit-linear-gradient(45deg, rgba(245, 242, 126, 0.8) 0%, rgba(43, 237, 61, 0.4) 100%);
17 + background: linear-gradient(45deg, rgba(245, 227, 100, 0.8) 0%, rgba(66, 245, 189, 0.4) 100%);
18 +}
19 +body .header{
20 + background: white;
21 + margin-left : 20%;
22 + width:50%;
23 + height:100px;
24 + -moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
25 + -webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
26 + box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
27 +}
28 +body .header h1 {
29 + font-family: "Roboto", sans-serif;
30 + font-size: 50px;
31 + text-align: center;
32 + display: inline;
33 + -webkit-font-smoothing: antialiased;
34 + -moz-osx-font-smoothing: grayscale;
35 +}
36 +body .header .search_bar {
37 + margin-right: 10px;
38 + margin-top: 20px;
39 + float:right;
40 +}
41 +.profile_icon {
42 + width:50px;
43 + height:50px;
44 + float:right;
45 + margin-right: 15px;
46 + align : right;
47 + display: inline;
48 +}
49 +.logout_icon {
50 + width:50px;
51 + height:50px;
52 + float:right;
53 + align : right;
54 + display: inline;
55 +}
56 +body .left_bar{
57 + float:left;
58 + width:230px;
59 + height: 100%;
60 + background: white;
61 + -moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
62 + -webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
63 + box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
64 +}
65 +.left_bar .nav {
66 +
67 +}
68 +.left_bar .nav-list {
69 + list-style: none;
70 +}
71 +.left_bar .nav-item {
72 + font-size: 20px;
73 + font-weight: 700;
74 + margin-bottom: 23px;
75 + letter-spacing: 7px;
76 + text-transform: uppercase;
77 + color: #263238;
78 +}
79 +.left_bar .nav-link {
80 + list-style: none;
81 + text-decoration: none;
82 + color:#000000;
83 +}
84 +.left_bar .nav-link:hover {
85 +}
86 +body .right_bar{
87 + float:right;
88 + width:200px;
89 + height:600px;
90 + background: white;
91 + margin-top: 100px;
92 + -moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
93 + -webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
94 + box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
95 +}
96 +.right_bar .nav {
97 +
98 +}
99 +.right_bar .nav-list {
100 + list-style: none;
101 +}
102 +.right_bar .nav-item {
103 + font-size: 18px;
104 + font-weight: 700;
105 + margin-bottom: 23px;
106 + letter-spacing: 7px;
107 + text-transform: uppercase;
108 + color: #263238;
109 +}
110 +.right_bar .nav-link {
111 + list-style: none;
112 + text-decoration: none;
113 + color:#000000;
114 +}
115 +.right_bar .nav-link:hover {
116 +}
117 +body .container {
118 + position: relative;
119 + overflow: hidden;
120 + width: 700px;
121 + height: 800px;
122 + margin: 80px auto 0;
123 + background-color: #ffffff;
124 + -moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
125 + -webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
126 + box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
127 +}
128 +body .container .half {
129 + float: left;
130 + width: 100%;
131 + height: 100%;
132 + padding: 58px 40px 0;
133 +}
134 +body .container h1 {
135 + font-size: 18px;
136 + font-weight: 700;
137 + margin-bottom: 23px;
138 + text-align: center;
139 + text-indent: 6px;
140 + letter-spacing: 7px;
141 + text-transform: uppercase;
142 + color: #263238;
143 +}
144 +body .container .tabs {
145 + width: 54%;
146 + margin-bottom: 29px;
147 + border-bottom: 1px solid #d9d9d9;
148 + flaot :left;
149 + position: relative;
150 + left:22%;
151 +}
152 +body .container .tabs .tab {
153 + display: inline-block;
154 + margin-bottom: -1px;
155 + padding: 20px 15px 10px;
156 + cursor: pointer;
157 + letter-spacing: 0;
158 + border-bottom: 1px solid #d9d9d9;
159 + -moz-user-select: -moz-none;
160 + -ms-user-select: none;
161 + -webkit-user-select: none;
162 + user-select: none;
163 + transition: all 0.1s ease-in-out
164 +}
165 +body .container .tabs .tab a {
166 + font-size: 11px;
167 + text-decoration: none;
168 + text-transform: uppercase;
169 + color: #d9d9d9;
170 + transition: all 0.1s ease-in-out;
171 +}
172 +body .container .tabs .tab.active a, body .container .tabs .tab:hover a {
173 + color: #263238;
174 +}
175 +body .container .tabs .tab.active {
176 + border-bottom: 1px solid #263238;
177 +}
178 +body .container .content form {
179 + position: relative;
180 + height: 287px;
181 +}
182 +body .container .content label:first-of-type, body .container .content input:first-of-type, body .container .content .more:first-of-type {
183 + -moz-animation: slideIn 0.4s cubic-bezier(0.37, 0.82, 0.2, 1);
184 + -webkit-animation: slideIn 0.4s cubic-bezier(0.37, 0.82, 0.2, 1);
185 + animation: slideIn 0.4s cubic-bezier(0.37, 0.82, 0.2, 1);
186 +}
187 +body .container .content label:nth-of-type(2), body .container .content input:nth-of-type(2), body .container .content .more:nth-of-type(2) {
188 + -moz-animation: slideIn 0.5s cubic-bezier(0.37, 0.82, 0.2, 1);
189 + -webkit-animation: slideIn 0.5s cubic-bezier(0.37, 0.82, 0.2, 1);
190 + animation: slideIn 0.5s cubic-bezier(0.37, 0.82, 0.2, 1);
191 +}
192 +body .container .content label:nth-of-type(3), body .container .content input:nth-of-type(3), body .container .content .more:nth-of-type(3) {
193 + -moz-animation: slideIn 0.6s cubic-bezier(0.37, 0.82, 0.2, 1);
194 + -webkit-animation: slideIn 0.6s cubic-bezier(0.37, 0.82, 0.2, 1);
195 + animation: slideIn 0.6s cubic-bezier(0.37, 0.82, 0.2, 1);
196 +}
197 +body .container .content label {
198 + font-size: 12px;
199 + color: #263238;
200 + -moz-user-select: -moz-none;
201 + -ms-user-select: none;
202 + -webkit-user-select: none;
203 + user-select: none;
204 +}
205 +body .container .content label:not([for='remember']) {
206 + display: none;
207 +}
208 +body .container .content input.inpt {
209 + font-size: 14px;
210 + display: block;
211 + width: 100%;
212 + height: 42px;
213 + margin-bottom: 12px;
214 + padding: 16px 13px;
215 + color: #999999;
216 + border: 1px solid #d9d9d9;
217 + background: transparent;
218 + -moz-border-radius: 2px;
219 + -webkit-border-radius: 2px;
220 + border-radius: 2px;
221 +}
222 +body .container .content input.inpt::-webkit-input-placeholder {
223 + font-size: 14px;
224 + color: #999999;
225 + font-family: 'Lato', sans-serif;
226 +}
227 +body .container .content input.inpt:-moz-placeholder {
228 + font-size: 14px;
229 + color: #999999;
230 + font-family: 'Lato', sans-serif;
231 +}
232 +body .container .content input.inpt::-moz-placeholder {
233 + font-size: 14px;
234 + color: #999999;
235 + font-family: 'Lato', sans-serif;
236 +}
237 +body .container .content input.inpt:-ms-input-placeholder {
238 + font-size: 14px;
239 + color: #999999;
240 + font-family: 'Lato', sans-serif;
241 +}
242 +body .container .content input.inpt:focus {
243 + border-color: #999999;
244 +}
245 +body .container .content input.submit {
246 + font-size: 12px;
247 + line-height: 42px;
248 + display: block;
249 + width: 100%;
250 + height: 42px;
251 + cursor: pointer;
252 + vertical-align: middle;
253 + letter-spacing: 2px;
254 + text-transform: uppercase;
255 + color: #263238;
256 + border: 1px solid #263238;
257 + background: transparent;
258 + -moz-border-radius: 2px;
259 + -webkit-border-radius: 2px;
260 + border-radius: 2px;
261 +}
262 +body .container .content input.submit:hover {
263 + background-color: #263238;
264 + color: #ffffff;
265 + -moz-transition: all 0.2s;
266 + -o-transition: all 0.2s;
267 + -webkit-transition: all 0.2s;
268 + transition: all 0.2s;
269 +}
270 +body .container .content input:focus {
271 + outline: none;
272 +}
273 +body .container .content .checkbox {
274 + margin-top: 4px;
275 + overflow: hidden;
276 + clip: rect(0 0 0 0);
277 + width: 0;
278 + height: 0;
279 + margin: 17px -1px;
280 + padding: 0;
281 + border: 0;
282 +}
283 +body .container .content .checkbox + label {
284 + vertical-align: middle;
285 + display: inline-block;
286 + width: 50%;
287 +}
288 +body .container .content .checkbox + label:before {
289 + content: "\A";
290 + color: #999999;
291 + font-family: Verdana;
292 + font-weight: bold;
293 + font-size: 8px;
294 + line-height: 10px;
295 + text-align: center;
296 + display: inline-block;
297 + vertical-align: middle;
298 + position: relative;
299 + -moz-border-radius: 2px;
300 + -webkit-border-radius: 2px;
301 + border-radius: 2px;
302 + background: transparent;
303 + border: 1px solid #d9d9d9;
304 + width: 11px;
305 + height: 11px;
306 + margin: -2px 8px 0 0;
307 +}
308 +body .container .content .checkbox:checked + label:before {
309 + content: "✓";
310 +}
311 +body .container .content .submit-wrap {
312 + position: absolute;
313 + bottom: 0;
314 + width: 100%;
315 +}
316 +body .container .content .submit-wrap a {
317 + font-size: 12px;
318 + display: block;
319 + margin-top: 20px;
320 + text-align: center;
321 + text-decoration: none;
322 + color: #999999;
323 +}
324 +body .container .content .submit-wrap a:hover {
325 + text-decoration: underline;
326 +}
327 +body .container .content .signup-cont {
328 + display: none;
329 +}
330 +
331 +@keyframes slideIn {
332 + 0% {
333 + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
334 + opacity: 0;
335 + margin-left: -320px;
336 + }
337 + 100% {
338 + filter: progid:DXImageTransform.Microsoft.Alpha(enabled=false);
339 + opacity: 1;
340 + margin-left: 0px;
341 + }
342 +}
343 +@-webkit-keyframes slideIn {
344 + 0% {
345 + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
346 + opacity: 0;
347 + margin-left: -320px;
348 + }
349 + 100% {
350 + filter: progid:DXImageTransform.Microsoft.Alpha(enabled=false);
351 + opacity: 1;
352 + margin-left: 0px;
353 + }
354 +}
355 +.credits {
356 + display: block;
357 + position: absolute;
358 + right: 0;
359 + bottom: 0;
360 + color: #999999;
361 + font-size: 14px;
362 + margin: 0 10px 10px 0;
363 +}
364 +.credits a {
365 + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
366 + opacity: 0.8;
367 + color: inherit;
368 + font-weight: 700;
369 + text-decoration: none;
370 +}
1 +@import url(https://fonts.googleapis.com/css?family=Lato:400,700);
2 +* {
3 + -moz-box-sizing: border-box;
4 + -webkit-box-siing: border-box;
5 + box-sizing: border-box;
6 +}
7 +html {
8 + width: 100%;
9 + height: 100%;
10 +}
11 +
12 +body {
13 + background: -webkit-linear-gradient(45deg, rgba(245, 242, 126, 0.8) 0%, rgba(66, 245, 189, 0.4) 100%);
14 + background: linear-gradient(45deg, rgba(245, 227, 100, 0.8) 0%, rgba(66, 245, 189, 0.4) 100%);
15 + color: rgba(0, 0, 0, 0.6);
16 + font-family: "Roboto", sans-serif;
17 + font-size: 14px;
18 + line-height: 1.6em;
19 + -webkit-font-smoothing: antialiased;
20 + -moz-osx-font-smoothing: grayscale;
21 +}
22 +body .container {
23 + position: relative;
24 + overflow: hidden;
25 + width: 700px;
26 + height: 800px;
27 + margin: 80px auto 0;
28 + background-color: #ffffff;
29 + -moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
30 + -webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
31 + box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
32 +}
33 +body .container .half {
34 + float: left;
35 + width: 100%;
36 + height: 100%;
37 + padding: 58px 40px 0;
38 +}
39 +body .container h1 {
40 + font-size: 18px;
41 + font-weight: 700;
42 + margin-bottom: 23px;
43 + text-align: center;
44 + text-indent: 6px;
45 + letter-spacing: 7px;
46 + text-transform: uppercase;
47 + color: #263238;
48 +}
49 +body .container .tabs {
50 + width: 54%;
51 + margin-bottom: 29px;
52 + border-bottom: 1px solid #d9d9d9;
53 + flaot :left;
54 + position: relative;
55 + left:22%;
56 +}
57 +body .container .tabs .tab {
58 + display: inline-block;
59 + margin-bottom: -1px;
60 + padding: 20px 15px 10px;
61 + cursor: pointer;
62 + letter-spacing: 0;
63 + border-bottom: 1px solid #d9d9d9;
64 + -moz-user-select: -moz-none;
65 + -ms-user-select: none;
66 + -webkit-user-select: none;
67 + user-select: none;
68 + transition: all 0.1s ease-in-out
69 +}
70 +body .container .tabs .tab a {
71 + font-size: 11px;
72 + text-decoration: none;
73 + text-transform: uppercase;
74 + color: #d9d9d9;
75 + transition: all 0.1s ease-in-out;
76 +}
77 +body .container .tabs .tab.active a, body .container .tabs .tab:hover a {
78 + color: #263238;
79 +}
80 +body .container .tabs .tab.active {
81 + border-bottom: 1px solid #263238;
82 +}
83 +body .container .content form {
84 + position: relative;
85 + height: 287px;
86 +}
87 +body .container .content label:first-of-type, body .container .content input:first-of-type, body .container .content .more:first-of-type {
88 + -moz-animation: slideIn 0.4s cubic-bezier(0.37, 0.82, 0.2, 1);
89 + -webkit-animation: slideIn 0.4s cubic-bezier(0.37, 0.82, 0.2, 1);
90 + animation: slideIn 0.4s cubic-bezier(0.37, 0.82, 0.2, 1);
91 +}
92 +body .container .content label:nth-of-type(2), body .container .content input:nth-of-type(2), body .container .content .more:nth-of-type(2) {
93 + -moz-animation: slideIn 0.5s cubic-bezier(0.37, 0.82, 0.2, 1);
94 + -webkit-animation: slideIn 0.5s cubic-bezier(0.37, 0.82, 0.2, 1);
95 + animation: slideIn 0.5s cubic-bezier(0.37, 0.82, 0.2, 1);
96 +}
97 +body .container .content label:nth-of-type(3), body .container .content input:nth-of-type(3), body .container .content .more:nth-of-type(3) {
98 + -moz-animation: slideIn 0.6s cubic-bezier(0.37, 0.82, 0.2, 1);
99 + -webkit-animation: slideIn 0.6s cubic-bezier(0.37, 0.82, 0.2, 1);
100 + animation: slideIn 0.6s cubic-bezier(0.37, 0.82, 0.2, 1);
101 +}
102 +body .container .content label {
103 + font-size: 12px;
104 + color: #263238;
105 + -moz-user-select: -moz-none;
106 + -ms-user-select: none;
107 + -webkit-user-select: none;
108 + user-select: none;
109 +}
110 +body .container .content label:not([for='remember']) {
111 + display: none;
112 +}
113 +body .container .content input.inpt {
114 + font-size: 14px;
115 + display: block;
116 + width: 100%;
117 + height: 42px;
118 + margin-bottom: 12px;
119 + padding: 16px 13px;
120 + color: #999999;
121 + border: 1px solid #d9d9d9;
122 + background: transparent;
123 + -moz-border-radius: 2px;
124 + -webkit-border-radius: 2px;
125 + border-radius: 2px;
126 +}
127 +body .container .content input.inpt::-webkit-input-placeholder {
128 + font-size: 14px;
129 + color: #999999;
130 + font-family: 'Lato', sans-serif;
131 +}
132 +body .container .content input.inpt:-moz-placeholder {
133 + font-size: 14px;
134 + color: #999999;
135 + font-family: 'Lato', sans-serif;
136 +}
137 +body .container .content input.inpt::-moz-placeholder {
138 + font-size: 14px;
139 + color: #999999;
140 + font-family: 'Lato', sans-serif;
141 +}
142 +body .container .content input.inpt:-ms-input-placeholder {
143 + font-size: 14px;
144 + color: #999999;
145 + font-family: 'Lato', sans-serif;
146 +}
147 +body .container .content input.inpt:focus {
148 + border-color: #999999;
149 +}
150 +body .container .content input.submit {
151 + font-size: 12px;
152 + line-height: 42px;
153 + display: block;
154 + width: 100%;
155 + height: 42px;
156 + cursor: pointer;
157 + vertical-align: middle;
158 + letter-spacing: 2px;
159 + text-transform: uppercase;
160 + color: #263238;
161 + border: 1px solid #263238;
162 + background: transparent;
163 + -moz-border-radius: 2px;
164 + -webkit-border-radius: 2px;
165 + border-radius: 2px;
166 +}
167 +body .container .content input.submit:hover {
168 + background-color: #263238;
169 + color: #ffffff;
170 + -moz-transition: all 0.2s;
171 + -o-transition: all 0.2s;
172 + -webkit-transition: all 0.2s;
173 + transition: all 0.2s;
174 +}
175 +body .container .content input:focus {
176 + outline: none;
177 +}
178 +body .container .content .checkbox {
179 + margin-top: 4px;
180 + overflow: hidden;
181 + clip: rect(0 0 0 0);
182 + width: 0;
183 + height: 0;
184 + margin: 17px -1px;
185 + padding: 0;
186 + border: 0;
187 +}
188 +body .container .content .checkbox + label {
189 + vertical-align: middle;
190 + display: inline-block;
191 + width: 50%;
192 +}
193 +body .container .content .checkbox + label:before {
194 + content: "\A";
195 + color: #999999;
196 + font-family: Verdana;
197 + font-weight: bold;
198 + font-size: 8px;
199 + line-height: 10px;
200 + text-align: center;
201 + display: inline-block;
202 + vertical-align: middle;
203 + position: relative;
204 + -moz-border-radius: 2px;
205 + -webkit-border-radius: 2px;
206 + border-radius: 2px;
207 + background: transparent;
208 + border: 1px solid #d9d9d9;
209 + width: 11px;
210 + height: 11px;
211 + margin: -2px 8px 0 0;
212 +}
213 +body .container .content .checkbox:checked + label:before {
214 + content: "✓";
215 +}
216 +body .container .content .submit-wrap {
217 + position: absolute;
218 + bottom: 0;
219 + width: 100%;
220 +}
221 +body .container .content .submit-wrap a {
222 + font-size: 12px;
223 + display: block;
224 + margin-top: 20px;
225 + text-align: center;
226 + text-decoration: none;
227 + color: #999999;
228 +}
229 +body .container .content .submit-wrap a:hover {
230 + text-decoration: underline;
231 +}
232 +body .container .content .signup-cont {
233 + display: none;
234 +}
235 +
236 +@keyframes slideIn {
237 + 0% {
238 + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
239 + opacity: 0;
240 + margin-left: -320px;
241 + }
242 + 100% {
243 + filter: progid:DXImageTransform.Microsoft.Alpha(enabled=false);
244 + opacity: 1;
245 + margin-left: 0px;
246 + }
247 +}
248 +@-webkit-keyframes slideIn {
249 + 0% {
250 + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
251 + opacity: 0;
252 + margin-left: -320px;
253 + }
254 + 100% {
255 + filter: progid:DXImageTransform.Microsoft.Alpha(enabled=false);
256 + opacity: 1;
257 + margin-left: 0px;
258 + }
259 +}
260 +.credits a {
261 + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
262 + opacity: 0.8;
263 + color: inherit;
264 + font-weight: 700;
265 + text-decoration: none;
266 +}
1 +from django.conf import settings
2 +from storages.backends.s3boto3 import S3Boto3Storage
3 +from .settings import AWS_STORAGE_BUCKET_NAME, LOCAL_DOWNLOAD_PATH
4 +import boto3
5 +import os
6 +
7 +class MediaStorage(S3Boto3Storage):
8 + location = settings.MEDIAFILES_LOCATION
9 +
10 + def create_dir(dir_name):
11 + client = boto3.client('s3')
12 + client.put_object(Bucket= AWS_STORAGE_BUCKET_NAME, Key=dir_name+'/')
13 +
14 + def upload_file(file, user, dir):
15 + client = boto3.client('s3')
16 + data = file
17 + f = open('tempfile', 'wb')
18 + for chunk in data.chunks():
19 + f.write(chunk)
20 + f.close()
21 +
22 + nf = open('tempfile', 'rb')
23 + # client.Bucket(AWS_STORAGE_BUCKET_NAME).put_object(Key=file_name, body= nf)
24 + client.upload_fileobj(nf, AWS_STORAGE_BUCKET_NAME, user.username + '/' + dir + file.name)
25 + os.remove('tempfile')
26 + # putResponse = client.put_object(Bucket=AWS_STORAGE_BUCKET_NAME, Key= file_name)
27 +
28 + def download_file(file_name, dir):
29 + client = boto3.resource('s3')
30 + client.Bucket(AWS_STORAGE_BUCKET_NAME).download_file(Key= dir, Filename=LOCAL_DOWNLOAD_PATH+file_name)
31 +
32 + def delete_file(file_name, dir):
33 + client = boto3.resource('s3')
34 + client.Bucket(AWS_STORAGE_BUCKET_NAME).objects.filter(Prefix=dir).delete()
35 +
36 +
37 +
38 +
39 +
40 +
41 +
42 +
43 +
44 +
45 +
46 +
47 +
48 +
49 +
50 +
51 +
52 +
53 +
54 +
55 +
56 +
57 +
58 +
59 +
60 +
61 +
62 +
63 +
64 +
65 +
66 +
67 +
68 +
69 +
70 +
71 +
72 +
73 +
74 +
75 +
76 +
77 +
78 +
79 +
80 +
81 +
82 +
83 +
84 +
85 +
86 +
87 +
88 +
89 +
90 +
91 +
92 +
93 +
94 +
95 +
96 +
97 + def print_dir(dir_name):
98 + s3 = boto3.resource('s3')
99 + mybucket = s3.Bucket('fileshell-test')
100 + return(mybucket.objects.all())
101 +
102 +
1 +"""fileshell URL Configuration
2 +
3 +The `urlpatterns` list routes URLs to views. For more information please see:
4 + https://docs.djangoproject.com/en/2.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.conf.urls import url, include
18 +from fileshell import views
19 +
20 +urlpatterns = [
21 + url('admin/', admin.site.urls),
22 +
23 + url(r'^$', views.home, name='home'),
24 + url('search/(?P<search_name>.+)', views.search, name='search'),
25 +
26 + url('profile/', views.profile, name='profile'), ## 프로필 화면
27 + url(r'^accounts/', include('django.contrib.auth.urls')), ## 기본 유저
28 + url('account_login/', views.account_login, name='account_login'), ## 로그인 화면
29 +
30 + url(r'^download/(?P<bucketPath>.+)//(?P<filename>.+)//(?P<dir>.+)$', views.download, name='download'), ## 다운로드 기능
31 + url(r'^delete/(?P<bucketPath>.+)//(?P<filename>.+)//(?P<dir>.+)$', views.delete, name='delete'), ## 삭제 기능
32 + url(r'^changeFavor/(?P<bucketPath>.+)/(?P<filename>.+)$', views.changeFavor, name='changeFavor'), ## 즐겨찾기 on/off 기능
33 + url('add_folder/', views.add_folder, name='add_folder'), ## 폴더 추가 기능
34 + url('signup/', views.signup, name='signup'), ## 회원가입 기능
35 + url('upload/', views.upload, name='upload'), ## 파일 업로드 기능
36 +
37 + url('home/', views.file, name='file'), ## 모든 file 경로 화면 (home/으로 시작하는 모든 경로)
38 +
39 + url(r'^', views.home, name='home'), ## 이외의 모든 화면 홈으로 이동
40 +]
1 +from django.db.models import Case, Value, When
2 +from django.shortcuts import render, redirect
3 +from django.contrib.auth import login
4 +from django.http import *
5 +from .storages import *
6 +from .forms import *
7 +from .models import *
8 +import time
9 +import datetime
10 +
11 +
12 +def home(request):
13 +
14 + # user가 로그인 되어 있을 때
15 + if request.user.is_authenticated:
16 + # user가 갖고 있는 파일 중 즐겨찾기 True인 파일 필터링
17 + favorList = File.objects.filter(isFavor=True, user=request.user.username)
18 +
19 + # user가 갖고 있는 파일 중 일주일 안에 다운로드 된 파일 필터링
20 + endTime = datetime.datetime.now()
21 + startTime = endTime - datetime.timedelta(days=7) # 최근 날짜 기준 (현재: 7일)
22 + recentList = File.objects.filter(last_view_TM__range=[startTime, endTime], user=request.user.username)
23 +
24 + return render(request, 'home.html', {'favorList': favorList, 'recentList': recentList})
25 + # user가 로그인 되어 있지 않을 때 로그인 화면 출력
26 + else:
27 + return render(request, 'login.html')
28 +
29 +def file(request):
30 +
31 + # user가 로그인 되어 있을 때
32 + if request.user.is_authenticated:
33 + pass
34 + # user가 로그인 되어 있지 않을때 home으로 이동(로그인 화면 출력)
35 + else:
36 + return redirect('/')
37 +
38 +
39 + this_path = request.path
40 + dir = this_path[1:]
41 +
42 + type = this_path.split('/')
43 + type.pop(0)
44 + type = type.pop(0)
45 + print(type)
46 +
47 + # user가 갖고 있는 폴더 중 현재 url을 parent로 갖는 폴더 필터링
48 + folderList = Folder.objects.filter(parent__dir_name=dir, user=request.user.username)
49 + # user가 갖고 있는 파일 중 현재 url을 폴더 dir로 갖는 폴더 필터링
50 + fileList = File.objects.filter(folder__dir_name=dir, user=request.user.username)
51 +
52 + return render(request, 'file.html', {'folderList': folderList, 'fileList': fileList})
53 +
54 +def search(request, search_name):
55 +
56 + # user가 로그인 되어 있을 때
57 + if request.user.is_authenticated:
58 + pass
59 + # user가 로그인 되어 있지 않을때 home으로 이동(로그인 화면 출력)
60 + else:
61 + return redirect('/')
62 +
63 +
64 + this_path = request.path
65 + dir = this_path[1:]
66 +
67 + type = this_path.split('/')
68 + type.pop(0)
69 + type = type.pop(0)
70 + print(type)
71 +
72 +
73 + name = request
74 + print(name)
75 + # user가 갖고 있는 폴더 중 현재 url을 parent로 갖는 폴더 필터링
76 + folderList = Folder.objects.filter(dir_name__contains=search_name, user=request.user.username)
77 + # user가 갖고 있는 파일 중 현재 url을 폴더 dir로 갖는 폴더 필터링
78 + fileList = File.objects.filter(title__contains=search_name, user=request.user.username)
79 +
80 + return render(request, 'search.html', {'folderList': folderList, 'fileList': fileList})
81 +
82 +def profile(request):
83 +
84 + # 유저 정보 출력
85 + return render(request, 'profile.html')
86 +
87 +def account_login(request):
88 +
89 + # 로그인 화면 출력
90 + return render(request, 'login.html')
91 +
92 +def signup(request):
93 +
94 + # requst가 POST일 때
95 + if request.method == "POST":
96 + # user 폼 지정
97 + form = UserForm(request.POST)
98 +
99 + # form이 유효할 때
100 + if form.is_valid():
101 + # 로컬 DB에 user 저장
102 + new_user = User.objects.create_user(**form.cleaned_data)
103 + # 유저 정보로 로그인
104 + login(request, new_user)
105 +
106 + # 로컬 DB에 디폴트 경로 저장
107 + Folder.objects.create(dir_name='home/', user=request.user.username)
108 +
109 + # s3 main bucket에 userid/ 디렉토리와 userid/home/ 디렉토리 생성
110 + MediaStorage.create_dir(new_user.username)
111 + MediaStorage.create_dir(new_user.username + '/home')
112 +
113 + # home 화면으로 이동
114 + return redirect('/')
115 +
116 + # form이 유효하지 않을 때
117 + else:
118 + ########################### 사용자 폼 부적합 알림 #######################
119 + print("사용자 폼 부적합")
120 +
121 + # home 화면으로 이동(로그인 화면)
122 + return redirect('/')
123 +
124 +def add_folder(request):
125 +
126 + # requst가 POST일 때
127 + if request.method == 'POST':
128 +
129 + ## 파일 model 변수 초기화
130 + user = request.user.username
131 + dir_name = request.POST.get('dir_name')
132 + temp = request.META.get('HTTP_REFERER', '/')
133 + dir = url_convert(temp)
134 + parent = Folder.objects.get(dir_name=dir, user=user)
135 +
136 + # 로컬 DB에 저장
137 + Folder.objects.create(dir_name=dir+dir_name+'/', parent=parent, user=user)
138 + # s3 main bucket에 dir/ 디렉토리에 dir_name/ 디렉토리 생성
139 + MediaStorage.create_dir(user + '/' +dir + dir_name)
140 +
141 + return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
142 +
143 +def upload(request):
144 + if request.method == 'POST':
145 +
146 + ## 파일 model 변수 초기화
147 + filedata = request.FILES['source-file']
148 + title = request.FILES.get('source-file')
149 + user = request.user
150 + user_name = request.user.username
151 + now = time.localtime()
152 + uploadde_TM = "%04d-%02d-%02d %02d:%02d:%02d" % (
153 + now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec)
154 + filesize = filedata.size
155 + temp = request.META.get('HTTP_REFERER', '/')
156 + dir = url_convert(temp)
157 + folder = Folder.objects.get(dir_name=dir, user=request.user.username)
158 +
159 + # 로컬 DB에 저장
160 + File.objects.create(title=title, user=user, isFavor=False, bucketPath=user_name+'/'+dir,
161 + fileSize=filesize, folder=folder)
162 + # s3 버킷에 저장
163 + MediaStorage.upload_file(filedata, user, dir)
164 + else:
165 + pass
166 +
167 + return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
168 +
169 +def download(request, bucketPath, filename, dir):
170 +
171 + # 경로와 이름이 같은 파일을 필터링
172 + #### 같은 이름을 가진 파일에 경우 겹칠 수 있음 ####
173 +
174 + # 필터링 된 파일 최근 열람 시간 갱신
175 + File.objects.filter(title=filename, bucketPath=dir).update(last_view_TM=datetime.datetime.now())
176 +
177 + # s3에서 해당 파일을 정해진 경로로 다운로드
178 + MediaStorage.download_file(filename, bucketPath)
179 +
180 + return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
181 +
182 +def delete(request, bucketPath, filename, dir):
183 +
184 + # 경로와 이름이 같은 파일을 필터링
185 + #### 같은 이름을 가진 파일에 경우 겹칠 수 있음 ####
186 +
187 + # 필터링 된 파일 로컬 DB에서 삭제
188 + File.objects.filter(title=filename, bucketPath=dir).delete()
189 +
190 + # s3에서 해당 파일을 정해진 경로로 삭제
191 + MediaStorage.delete_file(filename, bucketPath)
192 +
193 + return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
194 +
195 +def changeFavor(request, bucketPath, filename):
196 +
197 + # 경로와 이름이 같은 파일을 필터링
198 + #### 같은 이름을 가진 파일에 경우 겹칠 수 있음 ####
199 +
200 + # 해당 파일 즐겨찾기 값을 True면 False로 False면 True로 수정
201 + File.objects.filter(title=filename, bucketPath=bucketPath).update(isFavor=Case(
202 + When(isFavor=True, then=Value(False)),
203 + default=Value(True))
204 + )
205 +
206 + return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
207 +
208 +# url 원하는 형식으로 바꿔주기 위함
209 +def url_convert(url):
210 + url = str(url)
211 + temp = url.split('/')
212 + temp.pop(0);temp.pop(0);temp.pop(0)
213 + dir = ''
214 + for i in temp:
215 + dir += i + '/'
216 + dir = dir[:-1]
217 + return dir
218 +
219 +
1 +"""
2 +WSGI config for fileshell 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/2.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", "fileshell.settings")
15 +
16 +application = get_wsgi_application()
1 +#!/usr/bin/env python
2 +import os
3 +import sys
4 +
5 +if __name__ == "__main__":
6 + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "fileshell.settings")
7 + try:
8 + from django.core.management import execute_from_command_line
9 + except ImportError as exc:
10 + raise ImportError(
11 + "Couldn't import Django. Are you sure it's installed and "
12 + "available on your PYTHONPATH environment variable? Did you "
13 + "forget to activate a virtual environment?"
14 + ) from exc
15 + execute_from_command_line(sys.argv)
1 +{% load staticfiles %}
2 +<!DOCTYPE html>
3 +<html lang="en" dir="ltr">
4 +<head>
5 + <meta charset="utf-8">
6 + <title> FileShell</title>
7 + <link rel="stylesheet" href="{% static 'css/layout_base.css' %}">
8 +</head>
9 +<body>
10 +
11 +<div class="left_bar">
12 + <a href=/> <img class = 'shell_icon' src= "{% static 'resources/shell.png' %}" width="200" height="200"/></a>
13 + <div class="nav">
14 + <ul class="nav-list">
15 + <li class="nav-item"><a href="/" class="nav-link">Home</a></li>
16 + <li class="nav-item"><a href="/home/" class="nav-link">File</a></li>
17 + </ul>
18 + </div>
19 +
20 +</div>
21 +<div class="header">
22 + <a href="{% url 'logout' %}"> <img class = 'logout_icon' src= "{% static 'resources/logout.png' %}" width="50" height="50" align="right"/></a>
23 + <a href="{% url 'profile' %}"> <img class = 'profile_icon' src= "{% static 'resources/profile.png' %}" width="50" height="50" align="right"/></a>
24 + <div class="search_form">
25 + <form id='search' action="" onsubmit="yourFunction()" method="post" enctype="multipart/form-data">{% csrf_token %}
26 + <input type="dir_name" name="dir_name" id="dir_name" required="required" placeholder="검색할 파일이나 폴더 이름">
27 + <input type = "submit">
28 + </form>
29 + </div>
30 + <h1> FileShell</h1>
31 +</div>
32 +{% block content %}
33 +{% endblock %}
34 +</div>
35 +
36 +<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
37 +<script type="text/javascript">
38 + function yourFunction(){
39 + var action_src = "/search/" + document.getElementsByName("dir_name")[0].value;
40 + var your_form = document.getElementById('search');
41 + your_form.action = action_src ;
42 + }
43 +</script>
44 +</body>
45 +</html>
1 +{% load staticfiles %}
2 +<!DOCTYPE html>
3 +<html lang="en" dir="ltr">
4 +<head>
5 + <meta charset="utf-8">
6 + <title> FileShell</title>
7 + <link rel="stylesheet" href="{% static 'css/layout_base_demo.css' %}">
8 +</head>
9 +<body>
10 +<div class="left_bar">
11 + <div class="nav">
12 + <a href="../home"> <img class = 'shell_icon' src= "{% static 'resources/shell.png' %}" width="100" height="100"/></a>
13 + <ul class="nav-list">
14 + <li class="nav-item"><a href="../home" class="nav-link">Home</a></li>
15 + <li class="nav-item"><a href="../file" class="nav-link">File</a></li>
16 + </ul>
17 + </div>
18 +
19 +</div>
20 +<div class="header">
21 + <h1> FileShell</h1>
22 + <a href="{% url 'logout' %}"> <img class = 'logout_icon' src= "{% static 'resources/logout.png' %}"/></a>
23 + <a href="{% url 'profile' %}"> <img class = 'profile_icon' src= "{% static 'resources/profile.png' %}" /></a>
24 + <input type="search" name="search" id="search" class="search_bar" placeholder="Your search">
25 +</div>
26 +<div>
27 + {% block content %}
28 + {% endblock %}
29 + <div class="right_bar">
30 + <button class="upload-btn"><a href="../home" class="upload-link">파일 업로드</a></button>
31 + <div class="nav">
32 + <ul class="nav-list">
33 + <li class="nav-item1"><a href="../file" class="nav-link-right"> <img class = 'add_folder_icon' src= "{% static 'resources/add_folder.png' %}" width="30" height="30"/> 새 폴더</a></li>
34 + </ul>
35 + </div>
36 + </div>
37 +
38 +</div>
39 +
40 +</body>
41 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +{% extends 'base.html'%}
2 +{% load staticfiles %}
3 +{% block content %}
4 + <div>
5 + <div class="right_bar">
6 + <li class="nav-item1"><a href="" class="nav-link-right"> <img class = 'add_folder_icon' src= "{% static 'resources/upload.png' %}" width="30" height="30"/> 파일 업로드</a></li>
7 + <form action={% url 'upload' %} method="post" enctype="multipart/form-data" novalidate>
8 + {% csrf_token %}
9 +
10 + <input type ="file" name = "source-file">
11 + <input type = "submit">
12 + </form>
13 + <li class="nav-item1"><a href="" class="nav-link-right"> <img class = 'add_folder_icon' src= "{% static 'resources/add_folder.png' %}" width="30" height="30"/> 새 폴더</a></li>
14 + <form action="{% url 'add_folder' %}" method="post" enctype="multipart/form-data">{% csrf_token %}
15 + <input type="dir_name" name="dir_name" id="dir_name" required="required" placeholder="New Folder Name">
16 + <input type = "submit">
17 + </form>
18 + </div>
19 + </div>
20 + <div class="frame">
21 + <!-- //header -->
22 + <div class="container">
23 + <!-- //nav -->
24 + <div class="content">
25 + <table cellspacing=1 width=700 border=1>
26 + <tr>
27 + <td width=300><p align=center>제목</p></td>
28 + <td width=350><p align=center>등록 시간</p></td>
29 + <td width=350><p align=center>최근 열람 시간</p></td>
30 + <td width=200><p align=center>즐겨찾기</p></td>
31 + <td width=200><p align=center>파일 크기</p></td>
32 + <td width=200><p align=center>파일 삭제</p></td>
33 + </tr>
34 + {% if folderList %}
35 + <ul>
36 + {% for folderRow in folderList %}
37 + <tr>
38 + <td width=50><a href="/{{ folderRow.dir_name }}", align=center>{{ folderRow.dir_name }}</a></td>
39 + <td width=100><p href="", align=center>{{ folderRow.uploaded_TM }}</p></td>
40 + <td width=100><p href="", align=center>{{ folderRow.last_view_TM }}</p></td>
41 + <td width=100><p href="", align=center>{{ folderRow.isFavor }}</p></td>
42 + <td width=100><p href="", align=center>{{ folderRow.fileSize }}</p></td>
43 + </tr>
44 + {% endfor %}
45 + </ul>
46 + {% else %}
47 + <p>No Folder.</p>
48 + {% endif %}
49 + {% if fileList %}
50 + <ul>
51 + {% for fileRow in fileList %}
52 + <tr>
53 + <td width=50><a href="/download/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>{{ fileRow.title }}</a></td>
54 + <td width=100><p href="", align=center>{{ fileRow.uploaded_TM }}</p></td>
55 + <td width=100><p href="", align=center>{{ fileRow.last_view_TM }}</p></td>
56 + <td width=100><a href="/changeFavor/{{ fileRow.bucketPath }}/{{ fileRow.title }}" align=center>{{ fileRow.isFavor }}</a></td>
57 + <td width=100><p href="", align=center>{{ fileRow.fileSize }}</p></td>
58 + <td width=100><a href="/delete/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>파일 삭제</a></td>
59 +
60 + </tr>
61 + {% endfor %}
62 + </ul>
63 + {% else %}
64 + <p>No File.</p>
65 + {% endif %}
66 +
67 + </table>
68 + </div>
69 + </div>
70 + <!-- //container -->
71 + </div>
72 + <!-- //frame -->
73 +
74 +{% endblock %}
1 +{% extends 'base.html'%}
2 +{% load staticfiles %}
3 +{% block content %}
4 + <div class="frame">
5 + <!-- //header -->
6 + <div class="container">
7 + <!-- //nav -->
8 + <div class="content">
9 + <div class="well text-muted text-center" style="padding-top: 4rem; padding-bottom: 4rem;">
10 + <span class="glyphicon glyphicon-arrow-down" style="font-size: 4rem;"></span>
11 + <h3>Drop Photos Here to Upload</h3>
12 + </div>
13 + <h2>즐겨찾기</h2>
14 + <table cellspacing=1 width=700 border=1>
15 + <tr>
16 + <td width=300><p align=center>제목</p></td>
17 + <td width=350><p align=center>등록 시간</p></td>
18 + <td width=350><p align=center>최근 열람 시간</p></td>
19 + <td width=200><p align=center>즐겨찾기</p></td>
20 + <td width=200><p align=center>파일 크기</p></td>
21 + <td width=200><p align=center>파일 삭제</p></td>
22 + </tr>
23 + {% if favorList %}
24 + <ul>
25 + {% for fileRow in favorList %}
26 + <tr>
27 + <td width=50><a href="/download/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>{{ fileRow.title }}</a></td>
28 + <td width=100><p href="", align=center>{{ fileRow.uploaded_TM }}</p></td>
29 + <td width=100><p href="", align=center>{{ fileRow.last_view_TM }}</p></td>
30 + <td width=100><a href="/changeFavor/{{ fileRow.bucketPath }}/{{ fileRow.title }}" align=center>{{ fileRow.isFavor }}</a></td>
31 + <td width=100><p href="", align=center>{{ fileRow.fileSize }}</p></td>
32 + <td width=100><a href="/delete/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>파일 삭제</a></td>
33 +
34 + </tr>
35 + {% endfor %}
36 + </ul>
37 + {% else %}
38 + <p>No File.</p>
39 + {% endif %}
40 + </table>
41 +
42 + <h2>최근 항목</h2>
43 + <table cellspacing=1 width=700 border=1>
44 + <tr>
45 + <td width=300><p align=center>제목</p></td>
46 + <td width=350><p align=center>등록 시간</p></td>
47 + <td width=350><p align=center>최근 열람 시간</p></td>
48 + <td width=100><p align=center>즐겨찾기</p></td>
49 + <td width=100><p align=center>파일 크기</p></td>
50 + <td width=100><p align=center>파일 삭제</p></td>
51 + </tr>
52 + {% if recentList %}
53 + <ul>
54 + {% for fileRow in recentList %}
55 + <tr>
56 + <td width=50><a href="/download/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>{{ fileRow.title }}</a></td>
57 + <td width=100><p href="", align=center>{{ fileRow.uploaded_TM }}</p></td>
58 + <td width=100><p href="", align=center>{{ fileRow.last_view_TM }}</p></td>
59 + <td width=100><a href="/changeFavor/{{ fileRow.bucketPath }}/{{ fileRow.title }}" align=center>{{ fileRow.isFavor }}</a></td>
60 + <td width=100><p href="", align=center>{{ fileRow.fileSize }}</p></td>
61 + <td width=100><a href="/delete/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>파일 삭제</a></td>
62 +
63 + </tr>
64 + {% endfor %}
65 + </ul>
66 + {% else %}
67 + <p>No File.</p>
68 + {% endif %}
69 + </table>
70 + </div>
71 + </div>
72 + <!-- //container -->
73 + </div>
74 + <!-- //frame -->
75 +{% endblock %}
1 +<!DOCTYPE html>
2 +<html lang="en">
3 +<head>
4 + <meta charset="UTF-8">
5 + <title>Title</title>
6 +</head>
7 +<body>
8 + <h1>TEST!</h1>
9 + <form action="" method="post" enctype="multipart/form-data">
10 + {% csrf_token %}
11 + <input type="file" name="img-file">
12 + <input type="submit">
13 + </form>
14 +{% if object.img %}
15 + <img src="{{ object.img.url }}" alt="">
16 +{% else %}
17 +{% endif %}
18 +</body>
19 +</html>
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +{% extends 'base.html'%}
2 +{% load staticfiles %}
3 +{% block content %}
4 + <div>
5 + <div class="right_bar">
6 + <li class="nav-item1"><a href="" class="nav-link-right"> <img class = 'add_folder_icon' src= "{% static 'resources/upload.png' %}" width="30" height="30"/> 파일 업로드</a></li>
7 + <form action={% url 'upload' %} method="post" enctype="multipart/form-data" novalidate>
8 + {% csrf_token %}
9 +
10 + <input type ="file" name = "source-file">
11 + <input type = "submit">
12 + </form>
13 + <li class="nav-item1"><a href="" class="nav-link-right"> <img class = 'add_folder_icon' src= "{% static 'resources/add_folder.png' %}" width="30" height="30"/> 새 폴더</a></li>
14 + <form action="{% url 'add_folder' %}" method="post" enctype="multipart/form-data">{% csrf_token %}
15 + <input type="dir_name" name="dir_name" id="dir_name" required="required" placeholder="New Folder Name">
16 + <input type = "submit">
17 + </form>
18 + </div>
19 + </div>
20 + <div class="frame">
21 + <!-- //header -->
22 + <div class="container">
23 + <!-- //nav -->
24 + <div class="content">
25 + <table cellspacing=1 width=700 border=1>
26 + <tr>
27 + <td width=300><p align=center>제목</p></td>
28 + <td width=350><p align=center>등록 시간</p></td>
29 + <td width=350><p align=center>최근 열람 시간</p></td>
30 + <td width=200><p align=center>즐겨찾기</p></td>
31 + <td width=200><p align=center>파일 크기</p></td>
32 + <td width=200><p align=center>파일 삭제</p></td>
33 + </tr>
34 + {% if folderList %}
35 + <ul>
36 + {% for folderRow in folderList %}
37 + <tr>
38 + <td width=50><a href="/{{ folderRow.dir_name }}", align=center>{{ folderRow.dir_name }}</a></td>
39 + <td width=100><p href="", align=center>{{ folderRow.uploaded_TM }}</p></td>
40 + <td width=100><p href="", align=center>{{ folderRow.last_view_TM }}</p></td>
41 + <td width=100><p href="", align=center>{{ folderRow.isFavor }}</p></td>
42 + <td width=100><p href="", align=center>{{ folderRow.fileSize }}</p></td>
43 + </tr>
44 + {% endfor %}
45 + </ul>
46 + {% else %}
47 + <p>No Folder.</p>
48 + {% endif %}
49 + {% if fileList %}
50 + <ul>
51 + {% for fileRow in fileList %}
52 + <tr>
53 + <td width=50><a href="/download/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>{{ fileRow.title }}</a></td>
54 + <td width=100><p href="", align=center>{{ fileRow.uploaded_TM }}</p></td>
55 + <td width=100><p href="", align=center>{{ fileRow.last_view_TM }}</p></td>
56 + <td width=100><a href="/changeFavor/{{ fileRow.bucketPath }}/{{ fileRow.title }}" align=center>{{ fileRow.isFavor }}</a></td>
57 + <td width=100><p href="", align=center>{{ fileRow.fileSize }}</p></td>
58 + <td width=100><a href="/delete/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>파일 삭제</a></td>
59 + </tr>
60 + {% endfor %}
61 + </ul>
62 + {% else %}
63 + <p>No File.</p>
64 + {% endif %}
65 +
66 + </table>
67 + </div>
68 + </div>
69 + <!-- //container -->
70 + </div>
71 + <!-- //frame -->
72 +
73 +{% endblock %}