Showing
65 changed files
with
1139 additions
and
0 deletions
1.png
0 → 100644
701 KB
2.png
0 → 100644
2.45 MB
CVpage.db
0 → 100644
No preview for this file type
CVpage/__init__.py
0 → 100644
1 | +from flask import Flask | ||
2 | +from flask_migrate import Migrate | ||
3 | +from flask_sqlalchemy import SQLAlchemy | ||
4 | + | ||
5 | +import config | ||
6 | +db = SQLAlchemy() | ||
7 | +migrate = Migrate() | ||
8 | + | ||
9 | +def create_app(): | ||
10 | + app = Flask(__name__) | ||
11 | + from .views import workdetail_view,main_view,about_view | ||
12 | + #db 설정 등록 | ||
13 | + app.config.from_object(config) | ||
14 | + #ORM(db 코드 추상화) 등록 | ||
15 | + db.init_app(app) | ||
16 | + migrate.init_app(app, db) | ||
17 | + from . import models | ||
18 | + #블루 프린트 등록 | ||
19 | + app.register_blueprint(workdetail_view.bp) | ||
20 | + app.register_blueprint(main_view.bp) | ||
21 | + app.register_blueprint(about_view.bp) | ||
22 | + from .filter import format_datetime | ||
23 | + app.jinja_env.filters['datetime'] = format_datetime | ||
24 | + return app |
CVpage/__pycache__/__init__.cpython-36.pyc
0 → 100644
No preview for this file type
CVpage/__pycache__/__init__.cpython-38.pyc
0 → 100644
No preview for this file type
CVpage/__pycache__/filter.cpython-36.pyc
0 → 100644
No preview for this file type
CVpage/__pycache__/filter.cpython-38.pyc
0 → 100644
No preview for this file type
CVpage/__pycache__/form.cpython-36.pyc
0 → 100644
No preview for this file type
CVpage/__pycache__/form.cpython-38.pyc
0 → 100644
No preview for this file type
CVpage/__pycache__/forms.cpython-38.pyc
0 → 100644
No preview for this file type
CVpage/__pycache__/models.cpython-36.pyc
0 → 100644
No preview for this file type
CVpage/__pycache__/models.cpython-38.pyc
0 → 100644
No preview for this file type
CVpage/filter.py
0 → 100644
CVpage/form.py
0 → 100644
1 | +from flask_wtf import FlaskForm | ||
2 | +from wtforms import StringField, TextAreaField | ||
3 | +from wtforms.validators import DataRequired | ||
4 | + | ||
5 | +class ProjectForm(FlaskForm): | ||
6 | + projectName = StringField('프로젝트이름', validators=[DataRequired()]) | ||
7 | + projectType = StringField('타입', validators=[DataRequired()]) | ||
8 | + pictureName = StringField('video, pic이름', validators=[DataRequired()]) | ||
9 | + content = TextAreaField('내용', validators=[DataRequired()]) | ||
10 | + gitAddress = StringField('git주소', validators=[DataRequired()]) |
CVpage/models.py
0 → 100644
1 | +from CVpage import db | ||
2 | + | ||
3 | + | ||
4 | +class Project(db.Model): | ||
5 | + id = db.Column(db.Integer, primary_key=True) | ||
6 | + projectName = db.Column(db.String(200), nullable=False) | ||
7 | + projectType = db.Column(db.String(200), nullable=False) | ||
8 | + pictureName = db.Column(db.String(200), nullable=False) | ||
9 | + content = db.Column(db.Text(), nullable=False) | ||
10 | + gitAddress = db.Column(db.String(200), nullable=False) | ||
11 | + create_date = db.Column(db.DateTime(), nullable=False) | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
CVpage/static/css/about.css
0 → 100644
1 | +.jumbotron { | ||
2 | + padding-top: 3rem; | ||
3 | + padding-bottom: 3rem; | ||
4 | + margin-bottom: 0; | ||
5 | + background-color: #fff; | ||
6 | +} | ||
7 | +@media (min-width: 768px) { | ||
8 | + .jumbotron { | ||
9 | + padding-top: 6rem; | ||
10 | + padding-bottom: 6rem; | ||
11 | + } | ||
12 | +} | ||
13 | + | ||
14 | +.nooutline{ | ||
15 | + border:0; | ||
16 | +} | ||
17 | +.jumbotron p:last-child { | ||
18 | + margin-bottom: 0; | ||
19 | +} | ||
20 | + | ||
21 | +.jumbotron h1 { | ||
22 | + font-weight: 300; | ||
23 | +} | ||
24 | + | ||
25 | +.jumbotron .container { | ||
26 | + max-width: 40rem; | ||
27 | +} | ||
28 | + | ||
29 | +footer { | ||
30 | + padding-top: 3rem; | ||
31 | + padding-bottom: 3rem; | ||
32 | +} | ||
33 | + | ||
34 | +footer p { | ||
35 | + margin-bottom: .25rem; | ||
36 | +} | ||
37 | + | ||
38 | +header { position: fixed; z-index: 10; top: 0; left: 0; width: 100%; height: 0px; transition: top 0.2s ease-in-out; } | ||
39 | +.nav-up { top: -70px;} | ||
40 | + | ||
41 | +.bg-dark{ | ||
42 | + background-color: burlywood; | ||
43 | +} | ||
44 | +.textblack{ | ||
45 | + color:black; | ||
46 | + text-decoration:none; | ||
47 | +} | ||
48 | +.textblack:hover{ | ||
49 | + color:#808080; | ||
50 | + text-decoration:none; | ||
51 | +} | ||
52 | + | ||
53 | +.sub{ | ||
54 | + font-size:.5em; | ||
55 | + color:#000000; | ||
56 | +} | ||
57 | +.box{ | ||
58 | + position: static; | ||
59 | + height: 220px; | ||
60 | +} | ||
61 | +.front{ | ||
62 | + position: absolute; | ||
63 | + top:0; | ||
64 | + left:0; | ||
65 | + display: none; | ||
66 | +} | ||
67 | +.back{ | ||
68 | + position: absolute; | ||
69 | + top:0; | ||
70 | + left:0; | ||
71 | + display: none; | ||
72 | +} | ||
73 | +.box img:nth-child(2){ | ||
74 | + opacity: 0; | ||
75 | + transition:all 0.3s ease in ease-in-out; | ||
76 | +} | ||
77 | +.box:hover img:nth-child(2){ | ||
78 | + opacity: 1; | ||
79 | + transition:all 0.3s ease in ease-in-out; | ||
80 | +} | ||
81 | +.form{ | ||
82 | +} |
CVpage/static/css/bootstrap.min.css
0 → 100644
This diff could not be displayed because it is too large.
CVpage/static/css/detail.css
0 → 100644
1 | +.bgImage{ | ||
2 | + -webkit-filter: brightness(70%);filter: brightness(70%); | ||
3 | + position: absolute; | ||
4 | + top:0; | ||
5 | + left:0; | ||
6 | + z-index: -1; | ||
7 | + height: 100%; | ||
8 | + width:100%; | ||
9 | + animation: fadeIn 0.5s linear; | ||
10 | +} | ||
11 | +.bgImg{ | ||
12 | + -webkit-filter: brightness(70%);filter: brightness(70%); | ||
13 | + position: absolute; | ||
14 | + top:0; | ||
15 | + left:0; | ||
16 | + z-index: -1; | ||
17 | + height: 100%; | ||
18 | + width:100%; | ||
19 | +} | ||
20 | +@keyframes fadeIn{ | ||
21 | + from{ | ||
22 | + opacity:0; | ||
23 | + } | ||
24 | + to{ | ||
25 | + | ||
26 | + opacity:1; | ||
27 | + } | ||
28 | +} | ||
29 | +html, body { | ||
30 | + | ||
31 | + margin: 0; | ||
32 | + | ||
33 | + height: 100%; | ||
34 | + | ||
35 | + overflow: hidden; | ||
36 | + | ||
37 | +} | ||
38 | +.detail-container{ | ||
39 | + display:grid; | ||
40 | + grid-template-columns:10% 1fr; | ||
41 | + grid-template-rows:20% 60% 1fr; | ||
42 | + height:100%; | ||
43 | + grid-gap:10px; | ||
44 | + grid-template-areas: | ||
45 | + "header header" | ||
46 | + "side main" | ||
47 | + "side footer" | ||
48 | +} | ||
49 | +header{ | ||
50 | + grid-area:header; | ||
51 | +} | ||
52 | +.main{ | ||
53 | + grid-area:main; | ||
54 | + padding-left:3rem; | ||
55 | +} | ||
56 | +.side{ | ||
57 | + grid-area: side; | ||
58 | + display: flex; | ||
59 | + justify-content: center; | ||
60 | + padding-top:100%; | ||
61 | +} | ||
62 | +.footer{ | ||
63 | + grid-area:footer; | ||
64 | +} | ||
65 | +.textwhite{ | ||
66 | + color:rgb(255, 255, 255); | ||
67 | + text-decoration:none; | ||
68 | + border:2px solid white; | ||
69 | + padding:1px 5px 3px 5px; | ||
70 | + transition:all 0.2s; | ||
71 | + margin-right:0.5rem; | ||
72 | + } | ||
73 | +.textwhite:hover{ | ||
74 | + color:#cecece; | ||
75 | + text-decoration:none; | ||
76 | + border:4px solid #cecece; | ||
77 | + padding:1px 5px 3px 5px; | ||
78 | + margin-right:0.5rem; | ||
79 | + } | ||
80 | + | ||
81 | +.textwhitebx{ | ||
82 | + color:rgb(255, 255, 255); | ||
83 | + text-decoration:none; | ||
84 | + transition:all 0.2s; | ||
85 | + } | ||
86 | +.textwhitebx:hover{ | ||
87 | + color:#cecece; | ||
88 | + text-decoration:none; | ||
89 | + padding:1px 5px 3px 5px; | ||
90 | + margin-right:0.5rem; | ||
91 | +} | ||
92 | +.left-footer{ | ||
93 | + width:35%; | ||
94 | + float:left; | ||
95 | + box-sizing:border-box; | ||
96 | + margin-right:15%; | ||
97 | + text-align: right; | ||
98 | +} | ||
99 | + | ||
100 | +.right-footer{ | ||
101 | + width:35%; | ||
102 | + float:right; | ||
103 | + position: static; | ||
104 | + box-sizing:border-box; | ||
105 | + text-align: left; | ||
106 | + margin-right:15%; | ||
107 | +} | ||
108 | +.bottomBorderL a,.bottomBorderR a{ | ||
109 | + -webkit-transition: all 0.3s ease; | ||
110 | + transition: all 0.3s ease; | ||
111 | +} | ||
112 | +.bottomBorderL a:hover{ | ||
113 | + border-bottom: solid 2px white; | ||
114 | + border-left:solid 2px white; | ||
115 | + width: 100%; | ||
116 | +} | ||
117 | +.bottomBorderR a:hover{ | ||
118 | + border-bottom: solid 2px white; | ||
119 | + border-right:solid 2px white; | ||
120 | + width: 100%; | ||
121 | +} | ||
122 | + |
CVpage/static/img/distortion.jpg
0 → 100644
33.2 KB
CVpage/static/img/plus.png
0 → 100644
983 Bytes
CVpage/static/js/about.js
0 → 100644
1 | +//nav바 추적 | ||
2 | +var lastScrollTop = 0; | ||
3 | +var delta = 5; // 동작의 구현이 시작되는 위치 | ||
4 | +var navbarHeight = 70; // 영향을 받을 요소를 선택 | ||
5 | +var didScroll; // 스크롤시에 사용자가 스크롤했다는 것을 알림 | ||
6 | +$(window).scroll(function(event){ didScroll = true; }); // hasScrolled()를 실행하고 didScroll 상태를 재설정 | ||
7 | +setInterval(function() { if (didScroll) { hasScrolled(); didScroll = false; } }, 250); | ||
8 | +function hasScrolled() { | ||
9 | + var st = $(this).scrollTop(); | ||
10 | + if (Math.abs(lastScrollTop - st) <= delta) return; | ||
11 | + // If current position > last position AND scrolled past navbar... | ||
12 | + if (st > lastScrollTop && st > navbarHeight){ | ||
13 | + // Scroll Down | ||
14 | + if($(`#navbarHeader`).hasClass(`show`)) | ||
15 | + { | ||
16 | + n=$(`#navbarHeader`); | ||
17 | + n.removeClass(`show`); | ||
18 | + | ||
19 | + } | ||
20 | + $(`header`).removeClass(`nav-down`).addClass(`nav-up`); | ||
21 | + } | ||
22 | + else { // Scroll Up | ||
23 | + // If did not scroll past the document (possible on mac)... | ||
24 | + if($(`#navbarHeader`).hasClass(`show`)) | ||
25 | + { | ||
26 | + n=$(`#navbarHeader`) | ||
27 | + n.removeClass(`show`) | ||
28 | + return | ||
29 | + } | ||
30 | + if(st + $(window).height() < $(document).height()) | ||
31 | + { | ||
32 | + $(`header`).removeClass(`nav-up`).addClass(`nav-down`); | ||
33 | + } | ||
34 | + } | ||
35 | + lastScrollTop = st; | ||
36 | + | ||
37 | +} | ||
38 | +const navbutton=document.querySelector('.navButton') | ||
39 | +const maindiv=document.querySelector('.belowHeader') | ||
40 | +navbutton.addEventListener('onclick',pushMain) | ||
41 | +function pushMain(){ | ||
42 | + maindiv.style.transform="translate3d(0px, px, 0px)"; | ||
43 | +} | ||
44 | +function zoomIn(event) { | ||
45 | + event.target.style.transform = "scale(1.1)"; | ||
46 | + event.target.style.zIndex = 1; | ||
47 | + event.target.style.transition = "all 0.5s"; | ||
48 | + div=event.target.parentNode.parentNode; | ||
49 | + content=div.querySelector(`.card-body`); | ||
50 | + content.style.transform = "translate3d(0px, -150px, 0px)"; | ||
51 | + content.style.transition = "all 0.5s"; | ||
52 | +} | ||
53 | + | ||
54 | +function zoomOut(event) { | ||
55 | + event.target.style.transform = "scale(1)"; | ||
56 | + event.target.style.zIndex = 1; | ||
57 | + event.target.style.transition = "all 0.5s"; | ||
58 | + div=event.target.parentNode.parentNode; | ||
59 | + content=div.querySelector(`.card-body`); | ||
60 | + content.style.transform = "translate3d(0px, 0px, 0px)"; | ||
61 | + content.style.transition = "all 0.5s"; | ||
62 | +} |
CVpage/static/js/bootstrap.bundle.min.js
0 → 100644
This diff is collapsed. Click to expand it.
CVpage/static/js/custom.js
0 → 100644
1 | +$(".box").each(function(){ | ||
2 | + var box=$(this) | ||
3 | + var boxImgs=$(this).children('img') | ||
4 | + var myAnimation = new hoverEffect({ | ||
5 | + parent: box[0], | ||
6 | + intensity: 1.0, | ||
7 | + speedIn:1.3, | ||
8 | + speedOut:1.3, | ||
9 | + angle:Math.PI/2, | ||
10 | + image1: boxImgs[0].getAttribute('src'), | ||
11 | + image2: boxImgs[1].getAttribute('src'), | ||
12 | + displacementImage: box[0].getAttribute('displacementImage') | ||
13 | + }); | ||
14 | +}) | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
CVpage/static/js/detail.js
0 → 100644
1 | +const strong=document.querySelector('strong.textblack') | ||
2 | +const card=document.querySelector('svg.bi-card-list') | ||
3 | +const playBtn=document.querySelector('svg.bi-file-play') | ||
4 | + | ||
5 | +strong.classList.remove('textblack') | ||
6 | +strong.classList.add('text-white') | ||
7 | +card.setAttribute('fill','white') | ||
8 | +function playBtnOverHandler(){ | ||
9 | + playBtn.setAttribute('fill','black'); | ||
10 | + playBtn.style.transform= "scale(1.3)"; | ||
11 | + playBtn.style.transition= 'all 0.3s'; | ||
12 | +} | ||
13 | +function playBtnOutHandler(){ | ||
14 | + playBtn.setAttribute('fill','white'); | ||
15 | + playBtn.style.transform= "scale(1.0)"; | ||
16 | + playBtn.style.transition= 'all 0.3s'; | ||
17 | +} | ||
18 | +playBtn.addEventListener("mouseover",playBtnOverHandler) | ||
19 | +playBtn.addEventListener("mouseout",playBtnOutHandler) | ||
20 | +//playBtn.addEventListener("onclick",playBtnHandler)어디서 컨트롤할지 안정함 | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
CVpage/static/js/hover-effect.umd.js
0 → 100644
1 | +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("three"),require("gsap/TweenMax")):"function"==typeof define&&define.amd?define(["three","gsap/TweenMax"],t):e.hoverEffect=t(e.THREE,e.TweenMax)}(this,function(e,t){return t=t&&t.hasOwnProperty("default")?t.default:t,function(n){function i(){for(var e=arguments,t=0;t<arguments.length;t++)if(void 0!==e[t])return e[t]}console.log("%c Hover effect by Robin Delaporte: https://github.com/robin-dela/hover-effect ","color: #bada55; font-size: 0.8rem");var r=n.parent,o=n.displacementImage,a=n.image1,s=n.image2,f=i(n.imagesRatio,1),d=i(n.intensity1,n.intensity,1),l=i(n.intensity2,n.intensity,1),u=i(n.angle,Math.PI/4),v=i(n.angle1,u),m=i(n.angle2,3*-u),c=i(n.speedIn,n.speed,1.6),p=i(n.speedOut,n.speed,1.2),g=i(n.hover,!0),h=i(n.easing,Expo.easeOut),y=i(n.video,!1);if(r)if(a&&s&&o){var x=new e.Scene,F=new e.OrthographicCamera(r.offsetWidth/-2,r.offsetWidth/2,r.offsetHeight/2,r.offsetHeight/-2,1,1e3);F.position.z=1;var w=new e.WebGLRenderer({antialias:!1,alpha:!0});w.setPixelRatio(2),w.setClearColor(16777215,0),w.setSize(r.offsetWidth,r.offsetHeight),r.appendChild(w.domElement);var L=function(){w.render(x,F)},H=new e.TextureLoader;H.crossOrigin="";var E,W,V=H.load(o,L);if(V.magFilter=V.minFilter=e.LinearFilter,y){var M=function(){requestAnimationFrame(M),w.render(x,F)};M(),(y=document.createElement("video")).autoplay=!0,y.loop=!0,y.src=a,y.load();var P=document.createElement("video");P.autoplay=!0,P.loop=!0,P.src=s,P.load();var R=new e.VideoTexture(y),T=new e.VideoTexture(P);R.magFilter=T.magFilter=e.LinearFilter,R.minFilter=T.minFilter=e.LinearFilter,P.addEventListener("loadeddata",function(){P.play(),(T=new e.VideoTexture(P)).magFilter=e.LinearFilter,T.minFilter=e.LinearFilter,C.uniforms.texture2.value=T},!1),y.addEventListener("loadeddata",function(){y.play(),(R=new e.VideoTexture(y)).magFilter=e.LinearFilter,R.minFilter=e.LinearFilter,C.uniforms.texture1.value=R},!1)}else R=H.load(a,L),T=H.load(s,L),R.magFilter=T.magFilter=e.LinearFilter,R.minFilter=T.minFilter=e.LinearFilter;var U=f;r.offsetHeight/r.offsetWidth<U?(E=1,W=r.offsetHeight/r.offsetWidth/U):(E=r.offsetWidth/r.offsetHeight*U,W=1);var C=new e.ShaderMaterial({uniforms:{intensity1:{type:"f",value:d},intensity2:{type:"f",value:l},dispFactor:{type:"f",value:0},angle1:{type:"f",value:v},angle2:{type:"f",value:m},texture1:{type:"t",value:R},texture2:{type:"t",value:T},disp:{type:"t",value:V},res:{type:"vec4",value:new e.Vector4(r.offsetWidth,r.offsetHeight,E,W)},dpr:{type:"f",value:window.devicePixelRatio}},vertexShader:"\nvarying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}\n",fragmentShader:"\nvarying vec2 vUv;\n\nuniform float dispFactor;\nuniform float dpr;\nuniform sampler2D disp;\n\nuniform sampler2D texture1;\nuniform sampler2D texture2;\nuniform float angle1;\nuniform float angle2;\nuniform float intensity1;\nuniform float intensity2;\nuniform vec4 res;\nuniform vec2 parent;\n\nmat2 getRotM(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat2(c, -s, s, c);\n}\n\nvoid main() {\n vec4 disp = texture2D(disp, vUv);\n vec2 dispVec = vec2(disp.r, disp.g);\n\n vec2 uv = 0.5 * gl_FragCoord.xy / (res.xy) ;\n vec2 myUV = (uv - vec2(0.5))*res.zw + vec2(0.5);\n\n\n vec2 distortedPosition1 = myUV + getRotM(angle1) * dispVec * intensity1 * dispFactor;\n vec2 distortedPosition2 = myUV + getRotM(angle2) * dispVec * intensity2 * (1.0 - dispFactor);\n vec4 _texture1 = texture2D(texture1, distortedPosition1);\n vec4 _texture2 = texture2D(texture2, distortedPosition2);\n gl_FragColor = mix(_texture1, _texture2, dispFactor);\n}\n",transparent:!0,opacity:1}),b=new e.PlaneBufferGeometry(r.offsetWidth,r.offsetHeight,1),D=new e.Mesh(b,C);x.add(D),g&&(r.addEventListener("mouseenter",_),r.addEventListener("touchstart",_),r.addEventListener("mouseleave",z),r.addEventListener("touchend",z)),window.addEventListener("resize",function(t){r.offsetHeight/r.offsetWidth<U?(E=1,W=r.offsetHeight/r.offsetWidth/U):(E=r.offsetWidth/r.offsetHeight*U,W=1),D.material.uniforms.res.value=new e.Vector4(r.offsetWidth,r.offsetHeight,E,W),w.setSize(r.offsetWidth,r.offsetHeight),L()}),this.next=_,this.previous=z}else console.warn("One or more images are missing");else console.warn("Parent missing");function _(){t.to(C.uniforms.dispFactor,c,{value:1,ease:h,onUpdate:L,onComplete:L})}function z(){t.to(C.uniforms.dispFactor,p,{value:0,ease:h,onUpdate:L,onComplete:L})}}}); | ||
2 | +//# sourceMappingURL=hover-effect.umd.js.map |
CVpage/static/js/jquery-3.5.1.min.js
0 → 100644
This diff is collapsed. Click to expand it.
CVpage/templates/about/about.html
0 → 100644
1 | +<!doctype html> | ||
2 | +<html lang="en"> | ||
3 | + <head> | ||
4 | + <meta charset="utf-8"> | ||
5 | + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||
6 | + <meta name="description" content=""> | ||
7 | + <title>CVpage</title> | ||
8 | + | ||
9 | + | ||
10 | + <!-- Bootstrap core CSS --> | ||
11 | +<link href="{{url_for('static',filename='css/bootstrap.min.css')}}" rel="stylesheet"> | ||
12 | +<link href="{{url_for('static',filename='css/about.css')}}" rel="stylesheet"> | ||
13 | + <style> | ||
14 | + .bd-placeholder-img { | ||
15 | + font-size: 1.125rem; | ||
16 | + text-anchor: middle; | ||
17 | + -webkit-user-select: none; | ||
18 | + -moz-user-select: none; | ||
19 | + -ms-user-select: none; | ||
20 | + user-select: none; | ||
21 | + } | ||
22 | + | ||
23 | + @media (min-width: 768px) { | ||
24 | + .bd-placeholder-img-lg { | ||
25 | + font-size: 3.5rem; | ||
26 | + } | ||
27 | + } | ||
28 | + </style> | ||
29 | + <!-- Custom styles for this template --> | ||
30 | + </head> | ||
31 | + <body> | ||
32 | + {%include 'navbar.html'%} | ||
33 | +<div class="sub" style="z-index: 9999999;"> | ||
34 | + CopyWrite KHJ<br> | ||
35 | + <br> | ||
36 | + <br> | ||
37 | + <br> | ||
38 | + <br> | ||
39 | + <br> | ||
40 | + <br> | ||
41 | +</div> | ||
42 | +<div class=belowHeader> | ||
43 | +<main role="main"> | ||
44 | + <div class="album py-5"> | ||
45 | + <div class="container"> | ||
46 | + <div class="row"> | ||
47 | +<!-- project card start--> | ||
48 | +{%if g.user%} | ||
49 | +<div class="col-md-4"> | ||
50 | + <a class="card mb-4 nooutline" href="{{url_for('about.add')}}"> | ||
51 | + <img src="{{url_for('static',filename='img/plus.png')}}" onmouseenter=zoomIn(event) onmouseleave=zoomOut(event)> | ||
52 | + </img> | ||
53 | + </a> | ||
54 | + <div class="card-body"> | ||
55 | + <p class="card-text">Project Name</p> | ||
56 | + <div class="d-flex justify-content-between align-items-center"> | ||
57 | + <div class="btn-group"> | ||
58 | + <button type="button" class="btn btn-sm btn-outline-secondary">btn</button> | ||
59 | + </div> | ||
60 | + <small class="text-muted">date</small> | ||
61 | + </div> | ||
62 | + </div> | ||
63 | +</div> | ||
64 | +{%endif%} | ||
65 | +{%if w_list%} | ||
66 | +{%for work in w_list%} | ||
67 | + <div class="col-md-4"> | ||
68 | + <a class="card mb-4 nooutline" href="{{url_for('detail.detail',project_id=work.id)}}"> | ||
69 | + <div class='box' onmouseenter=zoomIn(event) onmouseleave=zoomOut(event) displacementImage="{{url_for('static',filename='img/distortion.jpg')}}"> | ||
70 | + <img class=front src="{{url_for('static',filename='img/'+work.pictureName+'1.jpg')}}" width=100% height=225 alt="" onmouseenter=zoomIn(event) onmouseleave=zoomOut(event)> | ||
71 | + <img class=back src="{{url_for('static',filename='img/'+work.pictureName+'2.jpg')}}" width=100% height=225 alt="" onmouseenter=zoomIn(event) onmouseleave=zoomOut(event)> | ||
72 | + </div> | ||
73 | + </a> | ||
74 | + <div class="card-body"> | ||
75 | + <p class="card-text">{{work.projectName}}</p> | ||
76 | + <div class="d-flex justify-content-between align-items-center"> | ||
77 | + <div class="btn-group"> | ||
78 | + <button type="button" onclick="location.href='{{work.gitAddress}}'" class="btn btn-sm btn-outline-secondary">git</button> | ||
79 | + <a href="{{url_for('detail.video',project_id=work.id)}}"> | ||
80 | + <button type="button" class="btn btn-sm btn-outline-secondary btnvideo">video</button> | ||
81 | + </a> | ||
82 | + {%if g.user%} | ||
83 | + <a href="{{url_for('about.delete',project_id=work.id)}}"> | ||
84 | + <button type="button" class="btn btn-sm btn-outline-secondary btnvideo">delete</button> | ||
85 | + </a> | ||
86 | + <a href="{{url_for('about.modify',project_id=work.id)}}"> | ||
87 | + <button type="button" class="btn btn-sm btn-outline-secondary btnvideo">modify</button> | ||
88 | + </a> | ||
89 | + {%endif%} | ||
90 | + </div> | ||
91 | + <small class="text-muted">{{work.create_date|datetime}}</small> | ||
92 | + </div> | ||
93 | + </div> | ||
94 | + </div> | ||
95 | +{%endfor%} | ||
96 | +{%endif%} | ||
97 | +<!-- project card end--> | ||
98 | + | ||
99 | + | ||
100 | + </div> | ||
101 | + </div> | ||
102 | + </div> | ||
103 | + | ||
104 | +</main> | ||
105 | +<br><br><br><br><br><br><br> | ||
106 | +<footer class="text-muted" style="margin-bottom:30rem"> | ||
107 | + <div class="container"> | ||
108 | + <p class="float-right"> | ||
109 | + <a href="#" class="textblack">Back to top</a> | ||
110 | + </p> | ||
111 | + <p> | ||
112 | + <ul> | ||
113 | + <h2 id=aboutme> | ||
114 | + About Me | ||
115 | + </h2> | ||
116 | + <br> | ||
117 | + <li> | ||
118 | + HyungJin Kweon | ||
119 | + </li> | ||
120 | + <li> | ||
121 | + KyungHee Univ. | ||
122 | + </li> | ||
123 | + <li> | ||
124 | + email : intimate0305@khu.ac.kr | ||
125 | + </li> | ||
126 | + <li> | ||
127 | + I'm junior programmer interested in Computer Vision. | ||
128 | + </li> | ||
129 | + </ul> | ||
130 | + </p> | ||
131 | +</footer> | ||
132 | + | ||
133 | +</div> | ||
134 | +<script src="{{url_for('static',filename='js/jquery-3.5.1.min.js')}}"></script> | ||
135 | +<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r120/three.min.js"></script> | ||
136 | +<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script> | ||
137 | +<script src="{{url_for('static',filename='js/hover-effect.umd.js')}}"></script> | ||
138 | +<script src="{{url_for('static',filename='js/about.js')}}"></script> | ||
139 | +<script src="{{url_for('static',filename='js/custom.js')}}"></script> | ||
140 | +<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> | ||
141 | +<script src="{{url_for('static',filename='js/bootstrap.bundle.min.js')}}"></script> | ||
142 | +</body> | ||
143 | +</html> |
CVpage/templates/article/article.html
0 → 100644
File mode changed
CVpage/templates/base.html
0 → 100644
1 | +<!doctype html> | ||
2 | +<html lang="ko"> | ||
3 | +<head> | ||
4 | + <meta charset="utf-8"> | ||
5 | + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||
6 | + <title>CVpage</title> | ||
7 | + <link href="{{url_for('static',filename='css/bootstrap.min.css')}}" rel="stylesheet"> | ||
8 | + <link href="{{url_for('static',filename='css/about.css')}}" rel="stylesheet"> | ||
9 | + <link href="{{url_for('static',filename='css/detail.css')}}" rel="stylesheet"> | ||
10 | +</head> | ||
11 | +<body> | ||
12 | +{% block content %} | ||
13 | +{% endblock %} | ||
14 | +<script src="{{url_for('static',filename='js/jquery-3.5.1.min.js')}}"></script> | ||
15 | +<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r120/three.min.js"></script> | ||
16 | +<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script> | ||
17 | +<script src="{{url_for('static',filename='js/hover-effect.umd.js')}}"></script> | ||
18 | +<script src="{{url_for('static',filename='js/about.js')}}"></script> | ||
19 | +<script src="{{url_for('static',filename='js/custom.js')}}"></script> | ||
20 | +<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> | ||
21 | +<script src="{{url_for('static',filename='js/bootstrap.bundle.min.js')}}"></script> | ||
22 | +<script src="{{url_for('static',filename='js/detail.js')}}"></script> | ||
23 | +</body> | ||
24 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
CVpage/templates/navbar.html
0 → 100644
1 | +<header class="nav-container"> | ||
2 | + <div class="collapse bg-white" id="navbarHeader" > | ||
3 | + <div class="container"> | ||
4 | + <div class="row"> | ||
5 | + <div class="col-sm-8 col-md-7 py-4"><p> | ||
6 | + <h4 class="text-black">CVpage</p> | ||
7 | + <p class="text-muted"> | ||
8 | + This site is designed for personally read papers and project management.</p></h4> | ||
9 | + </div> | ||
10 | + <div class="col-sm-4 offset-md-1 py-4"> | ||
11 | + <h4 class="text-black">Menu</h4> | ||
12 | + <ul class="list-unstyled"> | ||
13 | + <li><a href="{{url_for('about.about')}}#aboutme" class="textblack">About me</a></li> | ||
14 | + <li><a href="https://wikidocs.net/book/5049" class="textblack">Paper Read</a></li> | ||
15 | + <li><a href="https://github.com/AIcodingmaster" class="textblack">Github</a></li> | ||
16 | + </ul> | ||
17 | + </div> | ||
18 | + </div> | ||
19 | + </div> | ||
20 | + </div> | ||
21 | + <div class="wrap_gnb navbar navbar-black bg-black shadow-sm"> | ||
22 | + <div class="container d-flex justify-content-between"> | ||
23 | + <a href="{{url_for('about.about')}}" class="navbar-brand d-flex align-items-center"> | ||
24 | + <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-card-list" fill="black" xmlns="http://www.w3.org/2000/svg" style="margin:10px;"> | ||
25 | + <path fill-rule="evenodd" d="M14.5 3h-13a.5.5 0 0 0-.5.5v9a.5.5 0 0 0 .5.5h13a.5.5 0 0 0 .5-.5v-9a.5.5 0 0 0-.5-.5zm-13-1A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2h-13z"/> | ||
26 | + <path fill-rule="evenodd" d="M5 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 5 8zm0-2.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm0 5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5z"/> | ||
27 | + <circle cx="3.5" cy="5.5" r=".5"/> | ||
28 | + <circle cx="3.5" cy="8" r=".5"/> | ||
29 | + <circle cx="3.5" cy="10.5" r=".5"/> | ||
30 | + </svg> | ||
31 | + <strong class=textblack>Project</strong> | ||
32 | + </a> | ||
33 | + {%if g.user%} | ||
34 | + <a href="{{url_for('main.logout')}}"> | ||
35 | + <strong class="textblack" style="opacity: 0.5;margin-left:-30rem">({{g.user}})</strong> | ||
36 | + </a> | ||
37 | + {%endif%} | ||
38 | + <button class=navButton style="background-color:white;border:0;outline:0" type="button" data-toggle="collapse" data-target="#navbarHeader" aria-controls="navbarHeader" aria-expanded="false" aria-label="Toggle navigation"> | ||
39 | + <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-caret-down-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | ||
40 | + <path d="M7.247 11.14L2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z"/> | ||
41 | + </svg> | ||
42 | + </button> | ||
43 | + </div> | ||
44 | + </div> | ||
45 | + </header> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
CVpage/templates/project_form.html
0 → 100644
1 | +{%extends 'base.html'%} | ||
2 | +{%block content%} | ||
3 | +<form class="form" method="POST" enctype="multipart/form-data"> | ||
4 | + <div> | ||
5 | + {{ form.csrf_token }} | ||
6 | + {{form.projectName.label}} | ||
7 | + {{form.projectName(class="form-control")}} | ||
8 | + {{form.projectType.label}} | ||
9 | + {{form.projectType(class="form-control")}} | ||
10 | + {{form.pictureName.label}} | ||
11 | + {{form.pictureName(class="form-control")}} | ||
12 | + {{form.content.label}} | ||
13 | + {{form.content(class="form-control")}} | ||
14 | + {{form.gitAddress.label}} | ||
15 | + {{form.gitAddress(class="form-control")}} | ||
16 | + 비디오: <input type="file" name="video" id=""> | ||
17 | + 이미지1:<input type="file" name="pic1" id=""> | ||
18 | + 이미지2:<input type="file" name="pic2" id=""> | ||
19 | + <br> | ||
20 | + <button type="submit" class="btn btn-primary">submit</button> | ||
21 | + </div> | ||
22 | + | ||
23 | +</form> | ||
24 | +{%endblock%} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
CVpage/templates/video.html
0 → 100644
CVpage/templates/work/work_detail.html
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | + <head> | ||
4 | + <meta charset="utf-8"> | ||
5 | + <meta name="viewport" content="width=device-width"> | ||
6 | + <title>CVpage</title> | ||
7 | + <link href="{{url_for('static',filename='css/detail.css')}}" rel="stylesheet" type="text/css" /> | ||
8 | + <link href="{{url_for('static',filename='css/bootstrap.min.css')}}" rel="stylesheet"> | ||
9 | + <link href="{{url_for('static',filename='css/about.css')}}" rel="stylesheet"> | ||
10 | + </head> | ||
11 | + <body> | ||
12 | + {%include 'navbar.html'%} | ||
13 | + <div class="detail-container"> | ||
14 | + <a class="side" href="{{url_for('detail.video',project_id=p.id)}}"> | ||
15 | + <svg width="5em" height="5em" viewBox="0 0 16 16" class="bi bi-file-play" fill="white" xmlns="http://www.w3.org/2000/svg"> | ||
16 | + <path fill-rule="evenodd" d="M4 0h8a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2zm0 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H4z"/> | ||
17 | + <path d="M6 10.117V5.883a.5.5 0 0 1 .757-.429l3.528 2.117a.5.5 0 0 1 0 .858l-3.528 2.117a.5.5 0 0 1-.757-.43z"/> | ||
18 | + </svg> | ||
19 | + </a> | ||
20 | + <div class="main"> | ||
21 | + <div class="id_workType"> | ||
22 | + <h5 class="text-white"> | ||
23 | + # {{p.id}} / {{p.projectType}} | ||
24 | + </h5> | ||
25 | + </div> | ||
26 | + <br> | ||
27 | + <h1 class="text-white"> | ||
28 | + <div class="projectName"> | ||
29 | + <strong> | ||
30 | + {{p.projectName}} | ||
31 | + </strong> | ||
32 | + </div> | ||
33 | + </h1> | ||
34 | + <br> | ||
35 | + <h6 class="text-white"> | ||
36 | + <div class="projectContent"> | ||
37 | + {{p.content}} | ||
38 | + </div> | ||
39 | + </h6> | ||
40 | + <br> | ||
41 | + <span> | ||
42 | + <strong class="text-white" style="margin-right: 0.5em"> | ||
43 | + More : | ||
44 | + </strong> | ||
45 | + </span> | ||
46 | + <span class="gitAddress"> | ||
47 | + <strong> | ||
48 | + <a class="textwhite" href="{{p.gitAddress}}">git</a> | ||
49 | + </strong> | ||
50 | + </span> | ||
51 | + <span class="video"> | ||
52 | + <strong> | ||
53 | + <a class="textwhite" href="{{url_for('detail.video',project_id=p.id)}}">video</a> | ||
54 | + </strong> | ||
55 | + </span> | ||
56 | + </div> | ||
57 | + <div class="footer" > | ||
58 | + <h5> | ||
59 | + <span class="left-footer"> | ||
60 | + {%if bp%} | ||
61 | + <div class="text-white"> | ||
62 | + <strong> | ||
63 | + #{{bp.id}} | ||
64 | + </strong> | ||
65 | + </div> | ||
66 | + <div class=bottomBorderL> | ||
67 | + <a class="textwhitebx" href="{{url_for('detail.detail',project_id=bp.id,last_picture=p.pictureName)}}"> | ||
68 | + <strong> | ||
69 | + {{bp.projectName}} | ||
70 | + </strong> | ||
71 | + </a> | ||
72 | + </div> | ||
73 | + {%endif%} | ||
74 | + </span> | ||
75 | + <span class="right-footer"> | ||
76 | + {%if np%} | ||
77 | + <div class="text-white"> | ||
78 | + <strong> | ||
79 | + #{{np.id}} | ||
80 | + </strong> | ||
81 | + </div> | ||
82 | + <div> | ||
83 | + <strong class=bottomBorderR> | ||
84 | + <a class="textwhitebx" href="{{url_for('detail.detail',project_id=np.id,last_picture=p.pictureName)}}"> | ||
85 | + {{np.projectName}} | ||
86 | + </a> | ||
87 | + </strong> | ||
88 | + </div> | ||
89 | + {%endif%} | ||
90 | + </span> | ||
91 | + </h5> | ||
92 | + </div> | ||
93 | + </div> | ||
94 | + <!-- | ||
95 | + {%if last_picture%} | ||
96 | + | ||
97 | + <div class='box' displacementImage="{{url_for('static',filename='img/distortion.jpg')}}"> | ||
98 | + <img class="front bgImg" src="{{url_for('static',filename='img/'+last_picture+'2.jpg')}}" alt="" > | ||
99 | + <img class="back bgImg" src="{{url_for('static',filename='img/'+p.pictureName+'2.jpg')}}" alt=""> | ||
100 | + </div> | ||
101 | + | ||
102 | + {%else%} | ||
103 | + {%endif%} | ||
104 | +--> | ||
105 | + <img class="bgImage" src="{{url_for('static',filename='img/{}1.jpg'.format(p.pictureName))}}" alt=""> | ||
106 | + <script src="{{url_for('static',filename='js/detail.js')}}"></script> | ||
107 | + <script src="{{url_for('static',filename='js/jquery-3.5.1.min.js')}}"></script> | ||
108 | + <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r120/three.min.js"></script> | ||
109 | + <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script> | ||
110 | + <script src="{{url_for('static',filename='js/hover-effect.umd.js')}}"></script> | ||
111 | + <script src="{{url_for('static',filename='js/about.js')}}"></script> | ||
112 | + <script src="{{url_for('static',filename='js/custom.js')}}"></script> | ||
113 | + <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> | ||
114 | + <script src="{{url_for('static',filename='js/bootstrap.bundle.min.js')}}"></script> | ||
115 | + </body> | ||
116 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
CVpage/templates/work/work_form.html
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
CVpage/views/about_view.py
0 → 100644
1 | +from flask import Blueprint,render_template,url_for,session,g,redirect,request | ||
2 | +from werkzeug.utils import secure_filename | ||
3 | +from CVpage.models import Project,db | ||
4 | +from CVpage.form import ProjectForm | ||
5 | +from datetime import datetime | ||
6 | +import os | ||
7 | +bp = Blueprint('about', __name__, url_prefix='/about/') | ||
8 | + | ||
9 | +@bp.route('/') | ||
10 | +def about(): | ||
11 | + work_list=Project.query.order_by(Project.create_date.desc()) | ||
12 | + return render_template('about/about.html',w_list=work_list) | ||
13 | +@bp.route('/add/',methods=('GET','POST')) | ||
14 | +def add(): | ||
15 | + form=ProjectForm() | ||
16 | + if request.method =="POST" and form.validate_on_submit(): | ||
17 | + p=Project(projectName=form.projectName.data, | ||
18 | + projectType=form.projectType.data, | ||
19 | + pictureName=form.pictureName.data, | ||
20 | + content=form.content.data, | ||
21 | + gitAddress=form.content.data, | ||
22 | + create_date=datetime.now()) | ||
23 | + pic1=request.files['pic1'] | ||
24 | + pic2=request.files['pic2'] | ||
25 | + video=request.files['video'] | ||
26 | + pictureName=form.pictureName.data | ||
27 | + pic1.save('/home/ubuntu/projects/CVpage/CVpage/static/img/'+secure_filename(pictureName+'1.jpg')) | ||
28 | + pic2.save('/home/ubuntu/projects/CVpage/CVpage/static/img/'+secure_filename(pictureName+'2.jpg')) | ||
29 | + video.save('/home/ubuntu/projects/CVpage/CVpage/static/video/'+secure_filename(pictureName+'.mp4')) | ||
30 | + db.session.add(p) | ||
31 | + db.session.commit() | ||
32 | + return redirect(url_for('about.about')) | ||
33 | + else: | ||
34 | + return render_template('project_form.html', form=form) | ||
35 | + | ||
36 | +@bp.route('/delete/<int:project_id>') | ||
37 | +def delete(project_id): | ||
38 | + p=Project.query.get(project_id) | ||
39 | + if g.user is "admin": | ||
40 | + import os | ||
41 | + os.remove(f'./CVpage/static/img/{p.pictureName}1.jpg') | ||
42 | + os.remove(f'./CVpage/static/img/{p.pictureName}2.jpg') | ||
43 | + os.remove(f'./CVpage/static/video/{p.pictureName}.mp4') | ||
44 | + db.session.delete(p) | ||
45 | + db.session.commit() | ||
46 | + return redirect(url_for('about.about')) | ||
47 | + | ||
48 | +@bp.route('/modify/<int:project_id>', methods=('GET','POST')) | ||
49 | +def modify(project_id): | ||
50 | + p=Project.query.get(project_id) | ||
51 | + if request.method =="POST":#작성을 하고 form태그의 post요청으로 들어간 것 | ||
52 | + form = ProjectForm() | ||
53 | + bpicN=p.pictureName | ||
54 | + if g.user is "admin" and form.validate_on_submit(): | ||
55 | + pic1=request.files['pic1'] | ||
56 | + pic2=request.files['pic2'] | ||
57 | + video=request.files['video'] | ||
58 | + form.populate_obj(p) | ||
59 | + if pic1 is None or pic2 is None or video is None: | ||
60 | + return render_template('project_form.html', form=form) | ||
61 | + os.remove('/home/ubuntu/projects/CVpage/CVpage/static/img/'+secure_filename(bpicN+'1.jpg')) | ||
62 | + os.remove('/home/ubuntu/projects/CVpage/CVpage/static/img/'+secure_filename(bpicN+'2.jpg')) | ||
63 | + os.remove('/home/ubuntu/projects/CVpage/CVpage/static/video/'+secure_filename(bpicN+'.mp4')) | ||
64 | + pic1.save('/home/ubuntu/projects/CVpage/CVpage/static/img/'+secure_filename(form.pictureName.data+'1.jpg')) | ||
65 | + pic2.save('/home/ubuntu/projects/CVpage/CVpage/static/img/'+secure_filename(form.pictureName.data+'2.jpg')) | ||
66 | + video.save('/home/ubuntu/projects/CVpage/CVpage/static/video/'+secure_filename(form.pictureName.data+'.mp4')) | ||
67 | + db.session.commit() | ||
68 | + return redirect(url_for('about.about')) | ||
69 | + else:#다른 html에서 접근한 것(GET요청일 경우) | ||
70 | + form = ProjectForm(obj=p)#기존 데이터를 대입시켜서 리턴 | ||
71 | + return render_template('project_form.html', form=form) | ||
72 | + | ||
73 | +@bp.route('/admin/<int:pw>') | ||
74 | +def admin(pw): | ||
75 | + if pw==123: | ||
76 | + session.clear() | ||
77 | + session['pw']=123 | ||
78 | + return redirect(url_for('about.about')) | ||
79 | + else: | ||
80 | + return redirect(url_for('about.about')) |
CVpage/views/main_view.py
0 → 100644
1 | +from flask import Blueprint,redirect,url_for,session,g | ||
2 | +bp = Blueprint('main', __name__, url_prefix='/') | ||
3 | + | ||
4 | +@bp.before_app_request | ||
5 | +def load_logged_in_user(): | ||
6 | + pw= session.get('pw') | ||
7 | + if pw is 123: | ||
8 | + g.user = "admin" | ||
9 | + | ||
10 | +@bp.route('/logout/') | ||
11 | +def logout(): | ||
12 | + session.clear() | ||
13 | + return redirect(url_for('about.about')) | ||
14 | + | ||
15 | +@bp.route('/admin/<int:pw>') | ||
16 | +def admin(pw): | ||
17 | + if pw==123: | ||
18 | + session.clear() | ||
19 | + session['pw']=123 | ||
20 | + return redirect(url_for('about.about')) | ||
21 | + else: | ||
22 | + return redirect(url_for('about.about')) | ||
23 | + | ||
24 | +@bp.route('/') | ||
25 | +def index(): | ||
26 | + return redirect(url_for('about.about')) | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
CVpage/views/workdetail_view.py
0 → 100644
1 | +from flask import Blueprint,render_template,request | ||
2 | +from CVpage.models import Project | ||
3 | +bp = Blueprint('detail', __name__, url_prefix='/detail/') | ||
4 | + | ||
5 | +@bp.route('/<int:project_id>') | ||
6 | +def detail(project_id): | ||
7 | + p=Project.query.get(project_id) | ||
8 | + bp=Project.query.get(project_id+1) | ||
9 | + np=Project.query.get(project_id-1) | ||
10 | + last_picture=request.args.get('last_picture',None)#key값 p를 찾아보고 없으면 None반환 | ||
11 | + if last_picture==None: | ||
12 | + return render_template('work/work_detail.html',p=p,bp=bp,np=np) | ||
13 | + else: | ||
14 | + return render_template('work/work_detail.html',p=p,bp=bp,np=np,last_picture=last_picture) | ||
15 | + | ||
16 | +@bp.route('/video/<int:project_id>') | ||
17 | +def video(project_id): | ||
18 | + p=Project.query.get(project_id) | ||
19 | + return render_template('/video.html',p=p) | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
README.md
0 → 100644
__pycache__/config.cpython-36.pyc
0 → 100644
No preview for this file type
__pycache__/config.cpython-38.pyc
0 → 100644
No preview for this file type
config.py
0 → 100644
migrations/README
0 → 100644
1 | +Generic single-database configuration. | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
migrations/__pycache__/env.cpython-36.pyc
0 → 100644
No preview for this file type
migrations/__pycache__/env.cpython-38.pyc
0 → 100644
No preview for this file type
migrations/alembic.ini
0 → 100644
1 | +# A generic, single database configuration. | ||
2 | + | ||
3 | +[alembic] | ||
4 | +# template used to generate migration files | ||
5 | +# file_template = %%(rev)s_%%(slug)s | ||
6 | + | ||
7 | +# set to 'true' to run the environment during | ||
8 | +# the 'revision' command, regardless of autogenerate | ||
9 | +# revision_environment = false | ||
10 | + | ||
11 | + | ||
12 | +# Logging configuration | ||
13 | +[loggers] | ||
14 | +keys = root,sqlalchemy,alembic | ||
15 | + | ||
16 | +[handlers] | ||
17 | +keys = console | ||
18 | + | ||
19 | +[formatters] | ||
20 | +keys = generic | ||
21 | + | ||
22 | +[logger_root] | ||
23 | +level = WARN | ||
24 | +handlers = console | ||
25 | +qualname = | ||
26 | + | ||
27 | +[logger_sqlalchemy] | ||
28 | +level = WARN | ||
29 | +handlers = | ||
30 | +qualname = sqlalchemy.engine | ||
31 | + | ||
32 | +[logger_alembic] | ||
33 | +level = INFO | ||
34 | +handlers = | ||
35 | +qualname = alembic | ||
36 | + | ||
37 | +[handler_console] | ||
38 | +class = StreamHandler | ||
39 | +args = (sys.stderr,) | ||
40 | +level = NOTSET | ||
41 | +formatter = generic | ||
42 | + | ||
43 | +[formatter_generic] | ||
44 | +format = %(levelname)-5.5s [%(name)s] %(message)s | ||
45 | +datefmt = %H:%M:%S |
migrations/env.py
0 → 100644
1 | +from __future__ import with_statement | ||
2 | + | ||
3 | +import logging | ||
4 | +from logging.config import fileConfig | ||
5 | + | ||
6 | +from sqlalchemy import engine_from_config | ||
7 | +from sqlalchemy import pool | ||
8 | + | ||
9 | +from alembic import context | ||
10 | + | ||
11 | +# this is the Alembic Config object, which provides | ||
12 | +# access to the values within the .ini file in use. | ||
13 | +config = context.config | ||
14 | + | ||
15 | +# Interpret the config file for Python logging. | ||
16 | +# This line sets up loggers basically. | ||
17 | +fileConfig(config.config_file_name) | ||
18 | +logger = logging.getLogger('alembic.env') | ||
19 | + | ||
20 | +# add your model's MetaData object here | ||
21 | +# for 'autogenerate' support | ||
22 | +# from myapp import mymodel | ||
23 | +# target_metadata = mymodel.Base.metadata | ||
24 | +from flask import current_app | ||
25 | +config.set_main_option( | ||
26 | + 'sqlalchemy.url', | ||
27 | + str(current_app.extensions['migrate'].db.engine.url).replace('%', '%%')) | ||
28 | +target_metadata = current_app.extensions['migrate'].db.metadata | ||
29 | + | ||
30 | +# other values from the config, defined by the needs of env.py, | ||
31 | +# can be acquired: | ||
32 | +# my_important_option = config.get_main_option("my_important_option") | ||
33 | +# ... etc. | ||
34 | + | ||
35 | + | ||
36 | +def run_migrations_offline(): | ||
37 | + """Run migrations in 'offline' mode. | ||
38 | + | ||
39 | + This configures the context with just a URL | ||
40 | + and not an Engine, though an Engine is acceptable | ||
41 | + here as well. By skipping the Engine creation | ||
42 | + we don't even need a DBAPI to be available. | ||
43 | + | ||
44 | + Calls to context.execute() here emit the given string to the | ||
45 | + script output. | ||
46 | + | ||
47 | + """ | ||
48 | + url = config.get_main_option("sqlalchemy.url") | ||
49 | + context.configure( | ||
50 | + url=url, target_metadata=target_metadata, literal_binds=True | ||
51 | + ) | ||
52 | + | ||
53 | + with context.begin_transaction(): | ||
54 | + context.run_migrations() | ||
55 | + | ||
56 | + | ||
57 | +def run_migrations_online(): | ||
58 | + """Run migrations in 'online' mode. | ||
59 | + | ||
60 | + In this scenario we need to create an Engine | ||
61 | + and associate a connection with the context. | ||
62 | + | ||
63 | + """ | ||
64 | + | ||
65 | + # this callback is used to prevent an auto-migration from being generated | ||
66 | + # when there are no changes to the schema | ||
67 | + # reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html | ||
68 | + def process_revision_directives(context, revision, directives): | ||
69 | + if getattr(config.cmd_opts, 'autogenerate', False): | ||
70 | + script = directives[0] | ||
71 | + if script.upgrade_ops.is_empty(): | ||
72 | + directives[:] = [] | ||
73 | + logger.info('No changes in schema detected.') | ||
74 | + | ||
75 | + connectable = engine_from_config( | ||
76 | + config.get_section(config.config_ini_section), | ||
77 | + prefix='sqlalchemy.', | ||
78 | + poolclass=pool.NullPool, | ||
79 | + ) | ||
80 | + | ||
81 | + with connectable.connect() as connection: | ||
82 | + context.configure( | ||
83 | + connection=connection, | ||
84 | + target_metadata=target_metadata, | ||
85 | + process_revision_directives=process_revision_directives, | ||
86 | + **current_app.extensions['migrate'].configure_args | ||
87 | + ) | ||
88 | + | ||
89 | + with context.begin_transaction(): | ||
90 | + context.run_migrations() | ||
91 | + | ||
92 | + | ||
93 | +if context.is_offline_mode(): | ||
94 | + run_migrations_offline() | ||
95 | +else: | ||
96 | + run_migrations_online() |
migrations/script.py.mako
0 → 100644
1 | +"""${message} | ||
2 | + | ||
3 | +Revision ID: ${up_revision} | ||
4 | +Revises: ${down_revision | comma,n} | ||
5 | +Create Date: ${create_date} | ||
6 | + | ||
7 | +""" | ||
8 | +from alembic import op | ||
9 | +import sqlalchemy as sa | ||
10 | +${imports if imports else ""} | ||
11 | + | ||
12 | +# revision identifiers, used by Alembic. | ||
13 | +revision = ${repr(up_revision)} | ||
14 | +down_revision = ${repr(down_revision)} | ||
15 | +branch_labels = ${repr(branch_labels)} | ||
16 | +depends_on = ${repr(depends_on)} | ||
17 | + | ||
18 | + | ||
19 | +def upgrade(): | ||
20 | + ${upgrades if upgrades else "pass"} | ||
21 | + | ||
22 | + | ||
23 | +def downgrade(): | ||
24 | + ${downgrades if downgrades else "pass"} |
migrations/versions/415b13ebc457_.py
0 → 100644
1 | +"""empty message | ||
2 | + | ||
3 | +Revision ID: 415b13ebc457 | ||
4 | +Revises: | ||
5 | +Create Date: 2020-08-26 02:18:08.862101 | ||
6 | + | ||
7 | +""" | ||
8 | +from alembic import op | ||
9 | +import sqlalchemy as sa | ||
10 | + | ||
11 | + | ||
12 | +# revision identifiers, used by Alembic. | ||
13 | +revision = '415b13ebc457' | ||
14 | +down_revision = None | ||
15 | +branch_labels = None | ||
16 | +depends_on = None | ||
17 | + | ||
18 | + | ||
19 | +def upgrade(): | ||
20 | + # ### commands auto generated by Alembic - please adjust! ### | ||
21 | + op.create_table('article', | ||
22 | + sa.Column('id', sa.Integer(), nullable=False), | ||
23 | + sa.Column('subject', sa.String(length=200), nullable=False), | ||
24 | + sa.Column('content', sa.Text(), nullable=False), | ||
25 | + sa.Column('create_date', sa.DateTime(), nullable=False), | ||
26 | + sa.PrimaryKeyConstraint('id') | ||
27 | + ) | ||
28 | + op.create_table('project', | ||
29 | + sa.Column('id', sa.Integer(), nullable=False), | ||
30 | + sa.Column('projectName', sa.String(length=200), nullable=False), | ||
31 | + sa.Column('projectType', sa.String(length=200), nullable=False), | ||
32 | + sa.Column('pictureName', sa.String(length=200), nullable=False), | ||
33 | + sa.Column('content', sa.Text(), nullable=False), | ||
34 | + sa.Column('gitAddress', sa.String(length=200), nullable=False), | ||
35 | + sa.Column('create_date', sa.DateTime(), nullable=False), | ||
36 | + sa.PrimaryKeyConstraint('id') | ||
37 | + ) | ||
38 | + op.create_table('user', | ||
39 | + sa.Column('id', sa.Integer(), nullable=False), | ||
40 | + sa.Column('username', sa.String(length=150), nullable=False), | ||
41 | + sa.Column('password', sa.String(length=200), nullable=False), | ||
42 | + sa.Column('email', sa.String(length=120), nullable=False), | ||
43 | + sa.PrimaryKeyConstraint('id'), | ||
44 | + sa.UniqueConstraint('email'), | ||
45 | + sa.UniqueConstraint('username') | ||
46 | + ) | ||
47 | + # ### end Alembic commands ### | ||
48 | + | ||
49 | + | ||
50 | +def downgrade(): | ||
51 | + # ### commands auto generated by Alembic - please adjust! ### | ||
52 | + op.drop_table('user') | ||
53 | + op.drop_table('project') | ||
54 | + op.drop_table('article') | ||
55 | + # ### end Alembic commands ### |
migrations/versions/47168028e699_.py
0 → 100644
1 | +"""empty message | ||
2 | + | ||
3 | +Revision ID: 47168028e699 | ||
4 | +Revises: 8692d2d51066 | ||
5 | +Create Date: 2020-08-31 05:13:48.638348 | ||
6 | + | ||
7 | +""" | ||
8 | +from alembic import op | ||
9 | +import sqlalchemy as sa | ||
10 | + | ||
11 | + | ||
12 | +# revision identifiers, used by Alembic. | ||
13 | +revision = '47168028e699' | ||
14 | +down_revision = '8692d2d51066' | ||
15 | +branch_labels = None | ||
16 | +depends_on = None | ||
17 | + | ||
18 | + | ||
19 | +def upgrade(): | ||
20 | + # ### commands auto generated by Alembic - please adjust! ### | ||
21 | + op.drop_table('article') | ||
22 | + # ### end Alembic commands ### | ||
23 | + | ||
24 | + | ||
25 | +def downgrade(): | ||
26 | + # ### commands auto generated by Alembic - please adjust! ### | ||
27 | + op.create_table('article', | ||
28 | + sa.Column('id', sa.INTEGER(), nullable=False), | ||
29 | + sa.Column('subject', sa.VARCHAR(length=200), nullable=False), | ||
30 | + sa.Column('content', sa.TEXT(), nullable=False), | ||
31 | + sa.Column('create_date', sa.DATETIME(), nullable=False), | ||
32 | + sa.PrimaryKeyConstraint('id') | ||
33 | + ) | ||
34 | + # ### end Alembic commands ### |
migrations/versions/8692d2d51066_.py
0 → 100644
1 | +"""empty message | ||
2 | + | ||
3 | +Revision ID: 8692d2d51066 | ||
4 | +Revises: 415b13ebc457 | ||
5 | +Create Date: 2020-08-31 05:13:14.858317 | ||
6 | + | ||
7 | +""" | ||
8 | +from alembic import op | ||
9 | +import sqlalchemy as sa | ||
10 | + | ||
11 | + | ||
12 | +# revision identifiers, used by Alembic. | ||
13 | +revision = '8692d2d51066' | ||
14 | +down_revision = '415b13ebc457' | ||
15 | +branch_labels = None | ||
16 | +depends_on = None | ||
17 | + | ||
18 | + | ||
19 | +def upgrade(): | ||
20 | + # ### commands auto generated by Alembic - please adjust! ### | ||
21 | + op.drop_table('user') | ||
22 | + # ### end Alembic commands ### | ||
23 | + | ||
24 | + | ||
25 | +def downgrade(): | ||
26 | + # ### commands auto generated by Alembic - please adjust! ### | ||
27 | + op.create_table('user', | ||
28 | + sa.Column('id', sa.INTEGER(), nullable=False), | ||
29 | + sa.Column('username', sa.VARCHAR(length=150), nullable=False), | ||
30 | + sa.Column('password', sa.VARCHAR(length=200), nullable=False), | ||
31 | + sa.Column('email', sa.VARCHAR(length=120), nullable=False), | ||
32 | + sa.PrimaryKeyConstraint('id'), | ||
33 | + sa.UniqueConstraint('email'), | ||
34 | + sa.UniqueConstraint('username') | ||
35 | + ) | ||
36 | + # ### end Alembic commands ### |
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
-
Please register or login to post a comment