허진호

first commit

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
credential.py
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
*.pyc
*~
__pycache__
venv
db.sqlite3
.DS_Store
# User-specific stuff:
**/.idea/workspace.xml
**/.idea/tasks.xml
**/.idea/dictionaries
**/.idea/vcs.xml
**/.idea/jsLibraryMappings.xml
# Sensitive or high-churn files:
**/.idea/dataSources.ids
**/.idea/dataSources.xml
**/.idea/dataSources.local.xml
**/.idea/sqlDataSources.xml
**/.idea/dynamic.xml
**/.idea/uiDesigner.xml
## File-based project format:
*.iws
# IntelliJ
/out/
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="FacetManager">
<facet type="django" name="Django">
<configuration>
<option name="rootFolder" value="$MODULE_DIR$" />
<option name="settingsModule" value="fileshell/settings.py" />
<option name="manageScript" value="$MODULE_DIR$/manage.py" />
<option name="environment" value="&lt;map/&gt;" />
<option name="doNotUseTestRunner" value="false" />
<option name="trackFilePattern" value="migrations" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Django" />
<option name="TEMPLATE_FOLDERS">
<list>
<option value="$MODULE_DIR$/../fileshell\templates" />
</list>
</option>
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (fileshell)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/fileshell.iml" filepath="$PROJECT_DIR$/.idea/fileshell.iml" />
</modules>
</component>
</project>
\ No newline at end of file
File mode changed
File mode changed
from django.contrib import admin
from .models import *
admin.site.register(File)
admin.site.register(Folder)
\ No newline at end of file
from django import forms
from django.contrib.auth.models import User
from .models import *
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'password', 'email']
class FolderForm(forms.ModelForm):
class Meta:
model = Folder
fields = ['dir_name', 'parent']
def __init__(self, *args, **kwargs):
super(FolderForm, self).__init__(*args, **kwargs)
self.fields['folder'].required = False
\ No newline at end of file
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-06-07 01:36
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='File',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=100)),
('user', models.CharField(max_length=20)),
('uploaded_TM', models.DateTimeField(auto_now_add=True)),
('last_view_TM', models.DateTimeField()),
('isFavor', models.BooleanField()),
('bucketPath', models.CharField(max_length=50)),
('fileSize', models.IntegerField()),
('localPath', models.CharField(max_length=100)),
],
),
migrations.CreateModel(
name='Folder',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('dir_name', models.CharField(max_length=30)),
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child', to='fileshell.Folder')),
],
),
migrations.AddField(
model_name='file',
name='folder',
field=models.ManyToManyField(blank=True, null=True, related_name='datas', to='fileshell.Folder'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-06-07 13:33
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('fileshell', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='file',
name='localPath',
),
migrations.AlterField(
model_name='file',
name='last_view_TM',
field=models.DateTimeField(auto_now_add=True),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-06-07 14:43
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('fileshell', '0002_auto_20180607_1333'),
]
operations = [
migrations.RemoveField(
model_name='file',
name='folder',
),
migrations.AddField(
model_name='file',
name='folder',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='datas', to='fileshell.Folder'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-06-08 02:08
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('fileshell', '0003_auto_20180607_1443'),
]
operations = [
migrations.AddField(
model_name='folder',
name='user',
field=models.CharField(default='', max_length=20),
),
]
from django.db import models
class File(models.Model):
title = models.CharField(max_length=100)
user = models.CharField(max_length=20)
uploaded_TM = models.DateTimeField(auto_now_add=True)
last_view_TM = models.DateTimeField(auto_now_add=True)
isFavor = models.BooleanField(default=False)
bucketPath = models.CharField(max_length=50)
fileSize = models.IntegerField()
folder = models.ForeignKey('Folder', null=True, blank=True, related_name='datas')
class Folder(models.Model):
dir_name = models.CharField(max_length=30)
user = models.CharField(max_length=20, default='')
parent = models.ForeignKey('self', related_name='child', null=True, blank=True)
\ No newline at end of file
"""
Django settings for fileshell project.
Generated by 'django-admin startproject' using Django 2.0.5.
For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""
import os
from .credential import *
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'fileshell',
'storages',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'fileshell.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'fileshell.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Asia/Seoul'
USE_I18N = True
USE_L10N = True
USE_TZ = False
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL = '/static/'
LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/account_login'
#S3 Storage
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
MEDIAFILES_LOCATION = 'storages.backends.s3boto3.S3Boto3Storage'
LOCAL_DOWNLOAD_PATH = 'C:\\Users\\USER\\Downloads\\'
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = secret_key
#AWS Access
AWS_ACCESS_KEY_ID = key_id
AWS_SECRET_ACCESS_KEY =secret_access_key
AWS_STORAGE_BUCKET_NAME ='fileshell-test'
body {
font-family: "Roboto", sans-serif;
}
.search_form{
float:right;
}
.left_bar {
float:left;
width:200px;
height:900px;
background-color: #2b2d3d;
}
.nav {
}
.nav-list {
list-style: none;
margin: 10px;
}
.nav-item {
font-size: 30px;
color:#ffffff;
margin: 10px;
}
.nav-item1 {
font-size: 30px;
color:#ffffff;
margin: 10px;
}
.nav-link {
list-style: none;
text-decoration: none;
color:#ffffff;
}
.nav-link-right {
list-style: none;
text-decoration: none;
color:#ffffff;
}
.nav-link:hover {
}
.frame {
width: 1800px;
margin: 0 auto;
border: 1px solid #aaa;
}
.header {
height : 60px;
padding:40px 10px;
text-align: center;
background: #eee;
margin-bottom: 20px;
}
.profile_icon {
float:right;
padding-right: 10px;
margin-right: 10px;
}
.logout_icon {
float:right;
}
.logo {
font-size: 2em;
font-weight: bold;
background: #5457de;
color: #fff;
display: inline-block;
padding: 0 8px;
}
.container {
overflow: hidden;
}
.content {
float: left;
width: 1600px;
}
.right_bar {
float:right;
width:200px;
height:800px;
background: #FFFFFF;
}
.upload-btn {
width:180px;
height:60px;
text-align: center;
background-color: #2b2d3d;
margin : 10px;
}
.upload-link {
font-size: 17px;
font-weight: bold;
color: #fff;
text-decoration: none;
text-decoration-color: #FFF;
}
.nav-link-right {
font-size: 15px;
font-weight: bold;
color: #fff;
text-decoration: none;
color:#2b2d3d;
}
.footer {
text-align: center;
border-top: 1px solid #aaa;
margin: 20px 20px 0;
font-size: 12px;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {display:none;}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
@import url(https://fonts.googleapis.com/css?family=Lato:400,700);
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
html {
width: 100%;
height: 100%;
}
body {
width:100%;
height:100%;
background: -webkit-linear-gradient(45deg, rgba(245, 242, 126, 0.8) 0%, rgba(43, 237, 61, 0.4) 100%);
background: linear-gradient(45deg, rgba(245, 227, 100, 0.8) 0%, rgba(66, 245, 189, 0.4) 100%);
}
body .header{
background: white;
margin-left : 20%;
width:50%;
height:100px;
-moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
-webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
}
body .header h1 {
font-family: "Roboto", sans-serif;
font-size: 50px;
text-align: center;
display: inline;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body .header .search_bar {
margin-right: 10px;
margin-top: 20px;
float:right;
}
.profile_icon {
width:50px;
height:50px;
float:right;
margin-right: 15px;
align : right;
display: inline;
}
.logout_icon {
width:50px;
height:50px;
float:right;
align : right;
display: inline;
}
body .left_bar{
float:left;
width:230px;
height: 100%;
background: white;
-moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
-webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
}
.left_bar .nav {
}
.left_bar .nav-list {
list-style: none;
}
.left_bar .nav-item {
font-size: 20px;
font-weight: 700;
margin-bottom: 23px;
letter-spacing: 7px;
text-transform: uppercase;
color: #263238;
}
.left_bar .nav-link {
list-style: none;
text-decoration: none;
color:#000000;
}
.left_bar .nav-link:hover {
}
body .right_bar{
float:right;
width:200px;
height:600px;
background: white;
margin-top: 100px;
-moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
-webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
}
.right_bar .nav {
}
.right_bar .nav-list {
list-style: none;
}
.right_bar .nav-item {
font-size: 18px;
font-weight: 700;
margin-bottom: 23px;
letter-spacing: 7px;
text-transform: uppercase;
color: #263238;
}
.right_bar .nav-link {
list-style: none;
text-decoration: none;
color:#000000;
}
.right_bar .nav-link:hover {
}
body .container {
position: relative;
overflow: hidden;
width: 700px;
height: 800px;
margin: 80px auto 0;
background-color: #ffffff;
-moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
-webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
}
body .container .half {
float: left;
width: 100%;
height: 100%;
padding: 58px 40px 0;
}
body .container h1 {
font-size: 18px;
font-weight: 700;
margin-bottom: 23px;
text-align: center;
text-indent: 6px;
letter-spacing: 7px;
text-transform: uppercase;
color: #263238;
}
body .container .tabs {
width: 54%;
margin-bottom: 29px;
border-bottom: 1px solid #d9d9d9;
flaot :left;
position: relative;
left:22%;
}
body .container .tabs .tab {
display: inline-block;
margin-bottom: -1px;
padding: 20px 15px 10px;
cursor: pointer;
letter-spacing: 0;
border-bottom: 1px solid #d9d9d9;
-moz-user-select: -moz-none;
-ms-user-select: none;
-webkit-user-select: none;
user-select: none;
transition: all 0.1s ease-in-out
}
body .container .tabs .tab a {
font-size: 11px;
text-decoration: none;
text-transform: uppercase;
color: #d9d9d9;
transition: all 0.1s ease-in-out;
}
body .container .tabs .tab.active a, body .container .tabs .tab:hover a {
color: #263238;
}
body .container .tabs .tab.active {
border-bottom: 1px solid #263238;
}
body .container .content form {
position: relative;
height: 287px;
}
body .container .content label:first-of-type, body .container .content input:first-of-type, body .container .content .more:first-of-type {
-moz-animation: slideIn 0.4s cubic-bezier(0.37, 0.82, 0.2, 1);
-webkit-animation: slideIn 0.4s cubic-bezier(0.37, 0.82, 0.2, 1);
animation: slideIn 0.4s cubic-bezier(0.37, 0.82, 0.2, 1);
}
body .container .content label:nth-of-type(2), body .container .content input:nth-of-type(2), body .container .content .more:nth-of-type(2) {
-moz-animation: slideIn 0.5s cubic-bezier(0.37, 0.82, 0.2, 1);
-webkit-animation: slideIn 0.5s cubic-bezier(0.37, 0.82, 0.2, 1);
animation: slideIn 0.5s cubic-bezier(0.37, 0.82, 0.2, 1);
}
body .container .content label:nth-of-type(3), body .container .content input:nth-of-type(3), body .container .content .more:nth-of-type(3) {
-moz-animation: slideIn 0.6s cubic-bezier(0.37, 0.82, 0.2, 1);
-webkit-animation: slideIn 0.6s cubic-bezier(0.37, 0.82, 0.2, 1);
animation: slideIn 0.6s cubic-bezier(0.37, 0.82, 0.2, 1);
}
body .container .content label {
font-size: 12px;
color: #263238;
-moz-user-select: -moz-none;
-ms-user-select: none;
-webkit-user-select: none;
user-select: none;
}
body .container .content label:not([for='remember']) {
display: none;
}
body .container .content input.inpt {
font-size: 14px;
display: block;
width: 100%;
height: 42px;
margin-bottom: 12px;
padding: 16px 13px;
color: #999999;
border: 1px solid #d9d9d9;
background: transparent;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
}
body .container .content input.inpt::-webkit-input-placeholder {
font-size: 14px;
color: #999999;
font-family: 'Lato', sans-serif;
}
body .container .content input.inpt:-moz-placeholder {
font-size: 14px;
color: #999999;
font-family: 'Lato', sans-serif;
}
body .container .content input.inpt::-moz-placeholder {
font-size: 14px;
color: #999999;
font-family: 'Lato', sans-serif;
}
body .container .content input.inpt:-ms-input-placeholder {
font-size: 14px;
color: #999999;
font-family: 'Lato', sans-serif;
}
body .container .content input.inpt:focus {
border-color: #999999;
}
body .container .content input.submit {
font-size: 12px;
line-height: 42px;
display: block;
width: 100%;
height: 42px;
cursor: pointer;
vertical-align: middle;
letter-spacing: 2px;
text-transform: uppercase;
color: #263238;
border: 1px solid #263238;
background: transparent;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
}
body .container .content input.submit:hover {
background-color: #263238;
color: #ffffff;
-moz-transition: all 0.2s;
-o-transition: all 0.2s;
-webkit-transition: all 0.2s;
transition: all 0.2s;
}
body .container .content input:focus {
outline: none;
}
body .container .content .checkbox {
margin-top: 4px;
overflow: hidden;
clip: rect(0 0 0 0);
width: 0;
height: 0;
margin: 17px -1px;
padding: 0;
border: 0;
}
body .container .content .checkbox + label {
vertical-align: middle;
display: inline-block;
width: 50%;
}
body .container .content .checkbox + label:before {
content: "\A";
color: #999999;
font-family: Verdana;
font-weight: bold;
font-size: 8px;
line-height: 10px;
text-align: center;
display: inline-block;
vertical-align: middle;
position: relative;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
background: transparent;
border: 1px solid #d9d9d9;
width: 11px;
height: 11px;
margin: -2px 8px 0 0;
}
body .container .content .checkbox:checked + label:before {
content: "✓";
}
body .container .content .submit-wrap {
position: absolute;
bottom: 0;
width: 100%;
}
body .container .content .submit-wrap a {
font-size: 12px;
display: block;
margin-top: 20px;
text-align: center;
text-decoration: none;
color: #999999;
}
body .container .content .submit-wrap a:hover {
text-decoration: underline;
}
body .container .content .signup-cont {
display: none;
}
@keyframes slideIn {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
margin-left: -320px;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(enabled=false);
opacity: 1;
margin-left: 0px;
}
}
@-webkit-keyframes slideIn {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
margin-left: -320px;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(enabled=false);
opacity: 1;
margin-left: 0px;
}
}
.credits {
display: block;
position: absolute;
right: 0;
bottom: 0;
color: #999999;
font-size: 14px;
margin: 0 10px 10px 0;
}
.credits a {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
opacity: 0.8;
color: inherit;
font-weight: 700;
text-decoration: none;
}
@import url(https://fonts.googleapis.com/css?family=Lato:400,700);
* {
-moz-box-sizing: border-box;
-webkit-box-siing: border-box;
box-sizing: border-box;
}
html {
width: 100%;
height: 100%;
}
body {
background: -webkit-linear-gradient(45deg, rgba(245, 242, 126, 0.8) 0%, rgba(66, 245, 189, 0.4) 100%);
background: linear-gradient(45deg, rgba(245, 227, 100, 0.8) 0%, rgba(66, 245, 189, 0.4) 100%);
color: rgba(0, 0, 0, 0.6);
font-family: "Roboto", sans-serif;
font-size: 14px;
line-height: 1.6em;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body .container {
position: relative;
overflow: hidden;
width: 700px;
height: 800px;
margin: 80px auto 0;
background-color: #ffffff;
-moz-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
-webkit-box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px;
}
body .container .half {
float: left;
width: 100%;
height: 100%;
padding: 58px 40px 0;
}
body .container h1 {
font-size: 18px;
font-weight: 700;
margin-bottom: 23px;
text-align: center;
text-indent: 6px;
letter-spacing: 7px;
text-transform: uppercase;
color: #263238;
}
body .container .tabs {
width: 54%;
margin-bottom: 29px;
border-bottom: 1px solid #d9d9d9;
flaot :left;
position: relative;
left:22%;
}
body .container .tabs .tab {
display: inline-block;
margin-bottom: -1px;
padding: 20px 15px 10px;
cursor: pointer;
letter-spacing: 0;
border-bottom: 1px solid #d9d9d9;
-moz-user-select: -moz-none;
-ms-user-select: none;
-webkit-user-select: none;
user-select: none;
transition: all 0.1s ease-in-out
}
body .container .tabs .tab a {
font-size: 11px;
text-decoration: none;
text-transform: uppercase;
color: #d9d9d9;
transition: all 0.1s ease-in-out;
}
body .container .tabs .tab.active a, body .container .tabs .tab:hover a {
color: #263238;
}
body .container .tabs .tab.active {
border-bottom: 1px solid #263238;
}
body .container .content form {
position: relative;
height: 287px;
}
body .container .content label:first-of-type, body .container .content input:first-of-type, body .container .content .more:first-of-type {
-moz-animation: slideIn 0.4s cubic-bezier(0.37, 0.82, 0.2, 1);
-webkit-animation: slideIn 0.4s cubic-bezier(0.37, 0.82, 0.2, 1);
animation: slideIn 0.4s cubic-bezier(0.37, 0.82, 0.2, 1);
}
body .container .content label:nth-of-type(2), body .container .content input:nth-of-type(2), body .container .content .more:nth-of-type(2) {
-moz-animation: slideIn 0.5s cubic-bezier(0.37, 0.82, 0.2, 1);
-webkit-animation: slideIn 0.5s cubic-bezier(0.37, 0.82, 0.2, 1);
animation: slideIn 0.5s cubic-bezier(0.37, 0.82, 0.2, 1);
}
body .container .content label:nth-of-type(3), body .container .content input:nth-of-type(3), body .container .content .more:nth-of-type(3) {
-moz-animation: slideIn 0.6s cubic-bezier(0.37, 0.82, 0.2, 1);
-webkit-animation: slideIn 0.6s cubic-bezier(0.37, 0.82, 0.2, 1);
animation: slideIn 0.6s cubic-bezier(0.37, 0.82, 0.2, 1);
}
body .container .content label {
font-size: 12px;
color: #263238;
-moz-user-select: -moz-none;
-ms-user-select: none;
-webkit-user-select: none;
user-select: none;
}
body .container .content label:not([for='remember']) {
display: none;
}
body .container .content input.inpt {
font-size: 14px;
display: block;
width: 100%;
height: 42px;
margin-bottom: 12px;
padding: 16px 13px;
color: #999999;
border: 1px solid #d9d9d9;
background: transparent;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
}
body .container .content input.inpt::-webkit-input-placeholder {
font-size: 14px;
color: #999999;
font-family: 'Lato', sans-serif;
}
body .container .content input.inpt:-moz-placeholder {
font-size: 14px;
color: #999999;
font-family: 'Lato', sans-serif;
}
body .container .content input.inpt::-moz-placeholder {
font-size: 14px;
color: #999999;
font-family: 'Lato', sans-serif;
}
body .container .content input.inpt:-ms-input-placeholder {
font-size: 14px;
color: #999999;
font-family: 'Lato', sans-serif;
}
body .container .content input.inpt:focus {
border-color: #999999;
}
body .container .content input.submit {
font-size: 12px;
line-height: 42px;
display: block;
width: 100%;
height: 42px;
cursor: pointer;
vertical-align: middle;
letter-spacing: 2px;
text-transform: uppercase;
color: #263238;
border: 1px solid #263238;
background: transparent;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
}
body .container .content input.submit:hover {
background-color: #263238;
color: #ffffff;
-moz-transition: all 0.2s;
-o-transition: all 0.2s;
-webkit-transition: all 0.2s;
transition: all 0.2s;
}
body .container .content input:focus {
outline: none;
}
body .container .content .checkbox {
margin-top: 4px;
overflow: hidden;
clip: rect(0 0 0 0);
width: 0;
height: 0;
margin: 17px -1px;
padding: 0;
border: 0;
}
body .container .content .checkbox + label {
vertical-align: middle;
display: inline-block;
width: 50%;
}
body .container .content .checkbox + label:before {
content: "\A";
color: #999999;
font-family: Verdana;
font-weight: bold;
font-size: 8px;
line-height: 10px;
text-align: center;
display: inline-block;
vertical-align: middle;
position: relative;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
background: transparent;
border: 1px solid #d9d9d9;
width: 11px;
height: 11px;
margin: -2px 8px 0 0;
}
body .container .content .checkbox:checked + label:before {
content: "✓";
}
body .container .content .submit-wrap {
position: absolute;
bottom: 0;
width: 100%;
}
body .container .content .submit-wrap a {
font-size: 12px;
display: block;
margin-top: 20px;
text-align: center;
text-decoration: none;
color: #999999;
}
body .container .content .submit-wrap a:hover {
text-decoration: underline;
}
body .container .content .signup-cont {
display: none;
}
@keyframes slideIn {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
margin-left: -320px;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(enabled=false);
opacity: 1;
margin-left: 0px;
}
}
@-webkit-keyframes slideIn {
0% {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
margin-left: -320px;
}
100% {
filter: progid:DXImageTransform.Microsoft.Alpha(enabled=false);
opacity: 1;
margin-left: 0px;
}
}
.credits a {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
opacity: 0.8;
color: inherit;
font-weight: 700;
text-decoration: none;
}
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage
from .settings import AWS_STORAGE_BUCKET_NAME, LOCAL_DOWNLOAD_PATH
import boto3
import os
class MediaStorage(S3Boto3Storage):
location = settings.MEDIAFILES_LOCATION
def create_dir(dir_name):
client = boto3.client('s3')
client.put_object(Bucket= AWS_STORAGE_BUCKET_NAME, Key=dir_name+'/')
def upload_file(file, user, dir):
client = boto3.client('s3')
data = file
f = open('tempfile', 'wb')
for chunk in data.chunks():
f.write(chunk)
f.close()
nf = open('tempfile', 'rb')
# client.Bucket(AWS_STORAGE_BUCKET_NAME).put_object(Key=file_name, body= nf)
client.upload_fileobj(nf, AWS_STORAGE_BUCKET_NAME, user.username + '/' + dir + file.name)
os.remove('tempfile')
# putResponse = client.put_object(Bucket=AWS_STORAGE_BUCKET_NAME, Key= file_name)
def download_file(file_name, dir):
client = boto3.resource('s3')
client.Bucket(AWS_STORAGE_BUCKET_NAME).download_file(Key= dir, Filename=LOCAL_DOWNLOAD_PATH+file_name)
def delete_file(file_name, dir):
client = boto3.resource('s3')
client.Bucket(AWS_STORAGE_BUCKET_NAME).objects.filter(Prefix=dir).delete()
def print_dir(dir_name):
s3 = boto3.resource('s3')
mybucket = s3.Bucket('fileshell-test')
return(mybucket.objects.all())
"""fileshell URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.conf.urls import url, include
from fileshell import views
urlpatterns = [
url('admin/', admin.site.urls),
url(r'^$', views.home, name='home'),
url('search/(?P<search_name>.+)', views.search, name='search'),
url('profile/', views.profile, name='profile'), ## 프로필 화면
url(r'^accounts/', include('django.contrib.auth.urls')), ## 기본 유저
url('account_login/', views.account_login, name='account_login'), ## 로그인 화면
url(r'^download/(?P<bucketPath>.+)//(?P<filename>.+)//(?P<dir>.+)$', views.download, name='download'), ## 다운로드 기능
url(r'^delete/(?P<bucketPath>.+)//(?P<filename>.+)//(?P<dir>.+)$', views.delete, name='delete'), ## 삭제 기능
url(r'^changeFavor/(?P<bucketPath>.+)/(?P<filename>.+)$', views.changeFavor, name='changeFavor'), ## 즐겨찾기 on/off 기능
url('add_folder/', views.add_folder, name='add_folder'), ## 폴더 추가 기능
url('signup/', views.signup, name='signup'), ## 회원가입 기능
url('upload/', views.upload, name='upload'), ## 파일 업로드 기능
url('home/', views.file, name='file'), ## 모든 file 경로 화면 (home/으로 시작하는 모든 경로)
url(r'^', views.home, name='home'), ## 이외의 모든 화면 홈으로 이동
]
from django.db.models import Case, Value, When
from django.shortcuts import render, redirect
from django.contrib.auth import login
from django.http import *
from .storages import *
from .forms import *
from .models import *
import time
import datetime
def home(request):
# user가 로그인 되어 있을 때
if request.user.is_authenticated:
# user가 갖고 있는 파일 중 즐겨찾기 True인 파일 필터링
favorList = File.objects.filter(isFavor=True, user=request.user.username)
# user가 갖고 있는 파일 중 일주일 안에 다운로드 된 파일 필터링
endTime = datetime.datetime.now()
startTime = endTime - datetime.timedelta(days=7) # 최근 날짜 기준 (현재: 7일)
recentList = File.objects.filter(last_view_TM__range=[startTime, endTime], user=request.user.username)
return render(request, 'home.html', {'favorList': favorList, 'recentList': recentList})
# user가 로그인 되어 있지 않을 때 로그인 화면 출력
else:
return render(request, 'login.html')
def file(request):
# user가 로그인 되어 있을 때
if request.user.is_authenticated:
pass
# user가 로그인 되어 있지 않을때 home으로 이동(로그인 화면 출력)
else:
return redirect('/')
this_path = request.path
dir = this_path[1:]
type = this_path.split('/')
type.pop(0)
type = type.pop(0)
print(type)
# user가 갖고 있는 폴더 중 현재 url을 parent로 갖는 폴더 필터링
folderList = Folder.objects.filter(parent__dir_name=dir, user=request.user.username)
# user가 갖고 있는 파일 중 현재 url을 폴더 dir로 갖는 폴더 필터링
fileList = File.objects.filter(folder__dir_name=dir, user=request.user.username)
return render(request, 'file.html', {'folderList': folderList, 'fileList': fileList})
def search(request, search_name):
# user가 로그인 되어 있을 때
if request.user.is_authenticated:
pass
# user가 로그인 되어 있지 않을때 home으로 이동(로그인 화면 출력)
else:
return redirect('/')
this_path = request.path
dir = this_path[1:]
type = this_path.split('/')
type.pop(0)
type = type.pop(0)
print(type)
name = request
print(name)
# user가 갖고 있는 폴더 중 현재 url을 parent로 갖는 폴더 필터링
folderList = Folder.objects.filter(dir_name__contains=search_name, user=request.user.username)
# user가 갖고 있는 파일 중 현재 url을 폴더 dir로 갖는 폴더 필터링
fileList = File.objects.filter(title__contains=search_name, user=request.user.username)
return render(request, 'search.html', {'folderList': folderList, 'fileList': fileList})
def profile(request):
# 유저 정보 출력
return render(request, 'profile.html')
def account_login(request):
# 로그인 화면 출력
return render(request, 'login.html')
def signup(request):
# requst가 POST일 때
if request.method == "POST":
# user 폼 지정
form = UserForm(request.POST)
# form이 유효할 때
if form.is_valid():
# 로컬 DB에 user 저장
new_user = User.objects.create_user(**form.cleaned_data)
# 유저 정보로 로그인
login(request, new_user)
# 로컬 DB에 디폴트 경로 저장
Folder.objects.create(dir_name='home/', user=request.user.username)
# s3 main bucket에 userid/ 디렉토리와 userid/home/ 디렉토리 생성
MediaStorage.create_dir(new_user.username)
MediaStorage.create_dir(new_user.username + '/home')
# home 화면으로 이동
return redirect('/')
# form이 유효하지 않을 때
else:
########################### 사용자 폼 부적합 알림 #######################
print("사용자 폼 부적합")
# home 화면으로 이동(로그인 화면)
return redirect('/')
def add_folder(request):
# requst가 POST일 때
if request.method == 'POST':
## 파일 model 변수 초기화
user = request.user.username
dir_name = request.POST.get('dir_name')
temp = request.META.get('HTTP_REFERER', '/')
dir = url_convert(temp)
parent = Folder.objects.get(dir_name=dir, user=user)
# 로컬 DB에 저장
Folder.objects.create(dir_name=dir+dir_name+'/', parent=parent, user=user)
# s3 main bucket에 dir/ 디렉토리에 dir_name/ 디렉토리 생성
MediaStorage.create_dir(user + '/' +dir + dir_name)
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
def upload(request):
if request.method == 'POST':
## 파일 model 변수 초기화
filedata = request.FILES['source-file']
title = request.FILES.get('source-file')
user = request.user
user_name = request.user.username
now = time.localtime()
uploadde_TM = "%04d-%02d-%02d %02d:%02d:%02d" % (
now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec)
filesize = filedata.size
temp = request.META.get('HTTP_REFERER', '/')
dir = url_convert(temp)
folder = Folder.objects.get(dir_name=dir, user=request.user.username)
# 로컬 DB에 저장
File.objects.create(title=title, user=user, isFavor=False, bucketPath=user_name+'/'+dir,
fileSize=filesize, folder=folder)
# s3 버킷에 저장
MediaStorage.upload_file(filedata, user, dir)
else:
pass
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
def download(request, bucketPath, filename, dir):
# 경로와 이름이 같은 파일을 필터링
#### 같은 이름을 가진 파일에 경우 겹칠 수 있음 ####
# 필터링 된 파일 최근 열람 시간 갱신
File.objects.filter(title=filename, bucketPath=dir).update(last_view_TM=datetime.datetime.now())
# s3에서 해당 파일을 정해진 경로로 다운로드
MediaStorage.download_file(filename, bucketPath)
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
def delete(request, bucketPath, filename, dir):
# 경로와 이름이 같은 파일을 필터링
#### 같은 이름을 가진 파일에 경우 겹칠 수 있음 ####
# 필터링 된 파일 로컬 DB에서 삭제
File.objects.filter(title=filename, bucketPath=dir).delete()
# s3에서 해당 파일을 정해진 경로로 삭제
MediaStorage.delete_file(filename, bucketPath)
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
def changeFavor(request, bucketPath, filename):
# 경로와 이름이 같은 파일을 필터링
#### 같은 이름을 가진 파일에 경우 겹칠 수 있음 ####
# 해당 파일 즐겨찾기 값을 True면 False로 False면 True로 수정
File.objects.filter(title=filename, bucketPath=bucketPath).update(isFavor=Case(
When(isFavor=True, then=Value(False)),
default=Value(True))
)
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
# url 원하는 형식으로 바꿔주기 위함
def url_convert(url):
url = str(url)
temp = url.split('/')
temp.pop(0);temp.pop(0);temp.pop(0)
dir = ''
for i in temp:
dir += i + '/'
dir = dir[:-1]
return dir
"""
WSGI config for fileshell project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "fileshell.settings")
application = get_wsgi_application()
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "fileshell.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title> FileShell</title>
<link rel="stylesheet" href="{% static 'css/layout_base.css' %}">
</head>
<body>
<div class="left_bar">
<a href=/> <img class = 'shell_icon' src= "{% static 'resources/shell.png' %}" width="200" height="200"/></a>
<div class="nav">
<ul class="nav-list">
<li class="nav-item"><a href="/" class="nav-link">Home</a></li>
<li class="nav-item"><a href="/home/" class="nav-link">File</a></li>
</ul>
</div>
</div>
<div class="header">
<a href="{% url 'logout' %}"> <img class = 'logout_icon' src= "{% static 'resources/logout.png' %}" width="50" height="50" align="right"/></a>
<a href="{% url 'profile' %}"> <img class = 'profile_icon' src= "{% static 'resources/profile.png' %}" width="50" height="50" align="right"/></a>
<div class="search_form">
<form id='search' action="" onsubmit="yourFunction()" method="post" enctype="multipart/form-data">{% csrf_token %}
<input type="dir_name" name="dir_name" id="dir_name" required="required" placeholder="검색할 파일이나 폴더 이름">
<input type = "submit">
</form>
</div>
<h1> FileShell</h1>
</div>
{% block content %}
{% endblock %}
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
function yourFunction(){
var action_src = "/search/" + document.getElementsByName("dir_name")[0].value;
var your_form = document.getElementById('search');
your_form.action = action_src ;
}
</script>
</body>
</html>
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title> FileShell</title>
<link rel="stylesheet" href="{% static 'css/layout_base_demo.css' %}">
</head>
<body>
<div class="left_bar">
<div class="nav">
<a href="../home"> <img class = 'shell_icon' src= "{% static 'resources/shell.png' %}" width="100" height="100"/></a>
<ul class="nav-list">
<li class="nav-item"><a href="../home" class="nav-link">Home</a></li>
<li class="nav-item"><a href="../file" class="nav-link">File</a></li>
</ul>
</div>
</div>
<div class="header">
<h1> FileShell</h1>
<a href="{% url 'logout' %}"> <img class = 'logout_icon' src= "{% static 'resources/logout.png' %}"/></a>
<a href="{% url 'profile' %}"> <img class = 'profile_icon' src= "{% static 'resources/profile.png' %}" /></a>
<input type="search" name="search" id="search" class="search_bar" placeholder="Your search">
</div>
<div>
{% block content %}
{% endblock %}
<div class="right_bar">
<button class="upload-btn"><a href="../home" class="upload-link">파일 업로드</a></button>
<div class="nav">
<ul class="nav-list">
<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>
</ul>
</div>
</div>
</div>
</body>
</html>
\ No newline at end of file
{% extends 'base.html'%}
{% load staticfiles %}
{% block content %}
<div>
<div class="right_bar">
<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>
<form action={% url 'upload' %} method="post" enctype="multipart/form-data" novalidate>
{% csrf_token %}
<input type ="file" name = "source-file">
<input type = "submit">
</form>
<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>
<form action="{% url 'add_folder' %}" method="post" enctype="multipart/form-data">{% csrf_token %}
<input type="dir_name" name="dir_name" id="dir_name" required="required" placeholder="New Folder Name">
<input type = "submit">
</form>
</div>
</div>
<div class="frame">
<!-- //header -->
<div class="container">
<!-- //nav -->
<div class="content">
<table cellspacing=1 width=700 border=1>
<tr>
<td width=300><p align=center>제목</p></td>
<td width=350><p align=center>등록 시간</p></td>
<td width=350><p align=center>최근 열람 시간</p></td>
<td width=200><p align=center>즐겨찾기</p></td>
<td width=200><p align=center>파일 크기</p></td>
<td width=200><p align=center>파일 삭제</p></td>
</tr>
{% if folderList %}
<ul>
{% for folderRow in folderList %}
<tr>
<td width=50><a href="/{{ folderRow.dir_name }}", align=center>{{ folderRow.dir_name }}</a></td>
<td width=100><p href="", align=center>{{ folderRow.uploaded_TM }}</p></td>
<td width=100><p href="", align=center>{{ folderRow.last_view_TM }}</p></td>
<td width=100><p href="", align=center>{{ folderRow.isFavor }}</p></td>
<td width=100><p href="", align=center>{{ folderRow.fileSize }}</p></td>
</tr>
{% endfor %}
</ul>
{% else %}
<p>No Folder.</p>
{% endif %}
{% if fileList %}
<ul>
{% for fileRow in fileList %}
<tr>
<td width=50><a href="/download/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>{{ fileRow.title }}</a></td>
<td width=100><p href="", align=center>{{ fileRow.uploaded_TM }}</p></td>
<td width=100><p href="", align=center>{{ fileRow.last_view_TM }}</p></td>
<td width=100><a href="/changeFavor/{{ fileRow.bucketPath }}/{{ fileRow.title }}" align=center>{{ fileRow.isFavor }}</a></td>
<td width=100><p href="", align=center>{{ fileRow.fileSize }}</p></td>
<td width=100><a href="/delete/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>파일 삭제</a></td>
</tr>
{% endfor %}
</ul>
{% else %}
<p>No File.</p>
{% endif %}
</table>
</div>
</div>
<!-- //container -->
</div>
<!-- //frame -->
{% endblock %}
{% extends 'base.html'%}
{% load staticfiles %}
{% block content %}
<div class="frame">
<!-- //header -->
<div class="container">
<!-- //nav -->
<div class="content">
<div class="well text-muted text-center" style="padding-top: 4rem; padding-bottom: 4rem;">
<span class="glyphicon glyphicon-arrow-down" style="font-size: 4rem;"></span>
<h3>Drop Photos Here to Upload</h3>
</div>
<h2>즐겨찾기</h2>
<table cellspacing=1 width=700 border=1>
<tr>
<td width=300><p align=center>제목</p></td>
<td width=350><p align=center>등록 시간</p></td>
<td width=350><p align=center>최근 열람 시간</p></td>
<td width=200><p align=center>즐겨찾기</p></td>
<td width=200><p align=center>파일 크기</p></td>
<td width=200><p align=center>파일 삭제</p></td>
</tr>
{% if favorList %}
<ul>
{% for fileRow in favorList %}
<tr>
<td width=50><a href="/download/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>{{ fileRow.title }}</a></td>
<td width=100><p href="", align=center>{{ fileRow.uploaded_TM }}</p></td>
<td width=100><p href="", align=center>{{ fileRow.last_view_TM }}</p></td>
<td width=100><a href="/changeFavor/{{ fileRow.bucketPath }}/{{ fileRow.title }}" align=center>{{ fileRow.isFavor }}</a></td>
<td width=100><p href="", align=center>{{ fileRow.fileSize }}</p></td>
<td width=100><a href="/delete/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>파일 삭제</a></td>
</tr>
{% endfor %}
</ul>
{% else %}
<p>No File.</p>
{% endif %}
</table>
<h2>최근 항목</h2>
<table cellspacing=1 width=700 border=1>
<tr>
<td width=300><p align=center>제목</p></td>
<td width=350><p align=center>등록 시간</p></td>
<td width=350><p align=center>최근 열람 시간</p></td>
<td width=100><p align=center>즐겨찾기</p></td>
<td width=100><p align=center>파일 크기</p></td>
<td width=100><p align=center>파일 삭제</p></td>
</tr>
{% if recentList %}
<ul>
{% for fileRow in recentList %}
<tr>
<td width=50><a href="/download/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>{{ fileRow.title }}</a></td>
<td width=100><p href="", align=center>{{ fileRow.uploaded_TM }}</p></td>
<td width=100><p href="", align=center>{{ fileRow.last_view_TM }}</p></td>
<td width=100><a href="/changeFavor/{{ fileRow.bucketPath }}/{{ fileRow.title }}" align=center>{{ fileRow.isFavor }}</a></td>
<td width=100><p href="", align=center>{{ fileRow.fileSize }}</p></td>
<td width=100><a href="/delete/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>파일 삭제</a></td>
</tr>
{% endfor %}
</ul>
{% else %}
<p>No File.</p>
{% endif %}
</table>
</div>
</div>
<!-- //container -->
</div>
<!-- //frame -->
{% endblock %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>TEST!</h1>
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="img-file">
<input type="submit">
</form>
{% if object.img %}
<img src="{{ object.img.url }}" alt="">
{% else %}
{% endif %}
</body>
</html>
\ No newline at end of file
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
{% extends 'base.html'%}
{% load staticfiles %}
{% block content %}
<div>
<div class="right_bar">
<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>
<form action={% url 'upload' %} method="post" enctype="multipart/form-data" novalidate>
{% csrf_token %}
<input type ="file" name = "source-file">
<input type = "submit">
</form>
<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>
<form action="{% url 'add_folder' %}" method="post" enctype="multipart/form-data">{% csrf_token %}
<input type="dir_name" name="dir_name" id="dir_name" required="required" placeholder="New Folder Name">
<input type = "submit">
</form>
</div>
</div>
<div class="frame">
<!-- //header -->
<div class="container">
<!-- //nav -->
<div class="content">
<table cellspacing=1 width=700 border=1>
<tr>
<td width=300><p align=center>제목</p></td>
<td width=350><p align=center>등록 시간</p></td>
<td width=350><p align=center>최근 열람 시간</p></td>
<td width=200><p align=center>즐겨찾기</p></td>
<td width=200><p align=center>파일 크기</p></td>
<td width=200><p align=center>파일 삭제</p></td>
</tr>
{% if folderList %}
<ul>
{% for folderRow in folderList %}
<tr>
<td width=50><a href="/{{ folderRow.dir_name }}", align=center>{{ folderRow.dir_name }}</a></td>
<td width=100><p href="", align=center>{{ folderRow.uploaded_TM }}</p></td>
<td width=100><p href="", align=center>{{ folderRow.last_view_TM }}</p></td>
<td width=100><p href="", align=center>{{ folderRow.isFavor }}</p></td>
<td width=100><p href="", align=center>{{ folderRow.fileSize }}</p></td>
</tr>
{% endfor %}
</ul>
{% else %}
<p>No Folder.</p>
{% endif %}
{% if fileList %}
<ul>
{% for fileRow in fileList %}
<tr>
<td width=50><a href="/download/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>{{ fileRow.title }}</a></td>
<td width=100><p href="", align=center>{{ fileRow.uploaded_TM }}</p></td>
<td width=100><p href="", align=center>{{ fileRow.last_view_TM }}</p></td>
<td width=100><a href="/changeFavor/{{ fileRow.bucketPath }}/{{ fileRow.title }}" align=center>{{ fileRow.isFavor }}</a></td>
<td width=100><p href="", align=center>{{ fileRow.fileSize }}</p></td>
<td width=100><a href="/delete/{{ fileRow.bucketPath }}{{ fileRow.title }}//{{ fileRow.title }}//{{ fileRow.bucketPath }}" align=center>파일 삭제</a></td>
</tr>
{% endfor %}
</ul>
{% else %}
<p>No File.</p>
{% endif %}
</table>
</div>
</div>
<!-- //container -->
</div>
<!-- //frame -->
{% endblock %}