Skip to content

Commit ecd2345

Browse files
Add initial working application
1 parent f27f049 commit ecd2345

File tree

6 files changed

+611
-0
lines changed

6 files changed

+611
-0
lines changed

app.py

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
from flask import Flask
2+
from flask import jsonify
3+
from flask import request
4+
from flask import render_template
5+
from flask import redirect, url_for
6+
from flask import send_from_directory
7+
8+
from flask_login import UserMixin, LoginManager, login_required, login_user, logout_user, current_user
9+
10+
from flask_mongoengine import MongoEngine, DoesNotExist
11+
from mongoengine.errors import NotUniqueError
12+
13+
from passlib.hash import pbkdf2_sha512 as sha512
14+
15+
from uuid import uuid4
16+
17+
import os
18+
19+
app = Flask(__name__)
20+
21+
# app.config['DEBUG'] = True
22+
app.config['MONGODB_DB'] = 'FLASK_VUE_APP'
23+
app.config['MONGODB_HOST'] = 'localhost'
24+
app.config['MONGODB_PORT'] = 27017
25+
app.config['SECRET_KEY'] = "get the hell outta here!"
26+
27+
db = MongoEngine(app)
28+
29+
30+
login_manager = LoginManager()
31+
login_manager.init_app(app)
32+
33+
34+
@login_manager.user_loader
35+
def load_user(user):
36+
return User.objects.get(id=user)
37+
38+
39+
@login_manager.unauthorized_handler
40+
def unauthorized():
41+
# do stuff
42+
return redirect('/')
43+
44+
45+
class User(UserMixin,db.Document):
46+
username = db.StringField(max_length=255, unique=True)
47+
password = db.StringField(max_length=255)
48+
active = db.BooleanField(default=True)
49+
confirmed_at = db.DateTimeField()
50+
51+
def __unicode__(self):
52+
return self.id
53+
54+
def is_authenticated(self):
55+
return True
56+
57+
def get_id(self):
58+
return unicode(self.id)
59+
60+
def is_active(self):
61+
return True
62+
63+
def is_anonymous(self):
64+
return False
65+
66+
def verify(self,password):
67+
return sha512.verify(password, self.password)
68+
69+
class Photo(db.Document):
70+
name = db.StringField(max_length=50)
71+
url = db.URLField(verify_exists=True)
72+
user = db.ReferenceField(User)
73+
74+
# to server protected static files, they are in instance folder instead of static folder
75+
@app.route('/protected/<path:filename>')
76+
@login_required
77+
def protected(filename):
78+
return send_from_directory(
79+
os.path.join(app.instance_path, 'protected'),
80+
filename
81+
)
82+
83+
@app.route('/')
84+
def index():
85+
try:
86+
if current_user.username:
87+
return redirect(url_for("dashboard"))
88+
except AttributeError:
89+
# User not logged in
90+
return render_template('index.html')
91+
92+
@app.route('/login', methods=['POST'])
93+
def login():
94+
data=request.get_json('data',None)
95+
print "login", data
96+
try:
97+
if data:
98+
data=data['data']
99+
user = User.objects.get(username=data['username'])
100+
if user.verify(data['password']):
101+
user = User.objects.get(id = user.id)
102+
login_user(user)
103+
print current_user.username
104+
return jsonify(status=True)
105+
else:
106+
return jsonify(code=200, message="Invalid credentials!")
107+
108+
except DoesNotExist as e:
109+
return jsonify(code=200, status=False, message="No user found!")
110+
except Exception as e:
111+
raise e
112+
113+
@app.route('/signup', methods=['POST'])
114+
def signup():
115+
data = request.get_json('data',None)
116+
117+
if data:
118+
data = data['data']
119+
print "signup", data
120+
try:
121+
new_user=User(username = data['username'], password = sha512.hash(data['password'])).save()
122+
return redirect(url_for('dashboard'))
123+
except NotUniqueError as nu:
124+
return jsonify(code=200, status=False, message='Username already taken, we are sorry! Please try another.')
125+
else:
126+
res = jsonify(status = 400, message='Invalid data supplied')
127+
res.status_code = 400
128+
return res
129+
130+
@app.route('/logout', methods=['GET'])
131+
def logout():
132+
logout_user()
133+
return redirect(url_for('index'))
134+
135+
136+
@app.route('/dashboard')
137+
@login_required
138+
def dashboard():
139+
print current_user.username
140+
return render_template("dashboard.html")
141+
142+
@app.route('/dashboard/getData', methods=['GET'])
143+
@login_required
144+
def get_data():
145+
return jsonify(status=True,message=uuid4())
146+
147+
@app.route('/dashboard/addPhoto', methods=['POST'])
148+
@login_required
149+
def add_photo():
150+
data = request.get_json('data', None)
151+
try:
152+
if data:
153+
data = data['data']
154+
new_photo = Photo(name = data['name'], url = data['url'], user=current_user.id)
155+
new_photo.save()
156+
return jsonify(status=True)
157+
else:
158+
return jsonify(status=False, message="Data not matching")
159+
except Exception as e:
160+
raise e
161+
162+
@app.route('/dashboard/getPhotos', methods=['GET'])
163+
@login_required
164+
def get_photos():
165+
try:
166+
photos = Photo.objects(user=current_user.id)
167+
photos_ = [{'name':photo.name, 'url':photo.url} for photo in photos]
168+
print photos_
169+
return jsonify(status=True, photos=photos_)
170+
except Exception as e:
171+
raise e
172+
173+
# @app.errorhandler(404)
174+
# def handle_404(e):
175+
# return render_template('404.html')
176+
177+
if __name__ == '__main__':
178+
app.run(debug=True, port=8000)

instance/protected/main.js

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Template strings goes here -----------------------------------------------
2+
var photo_page = `<div>
3+
<h2 v-cloak>[[ msg_add_photo ]]</h2>
4+
<hr>
5+
<form v-on:submit.prevent="submitPhoto()">
6+
<fieldset>
7+
<legend>Add Photo</legend>
8+
<div class="form-group">
9+
<label class="control-label col-md-2" for="photo_name">Photo Name</label>
10+
<div class="col-md-10">
11+
<input type="text"
12+
class="form-control"
13+
name="photo_name"
14+
id="photo_name"
15+
v-model="photo_form.name"
16+
placeholder="Enter the name for photo" required/>
17+
</div>
18+
</div>
19+
<div class="form-group">
20+
<label class="control-label col-md-2" for="photo_url">Photo Url</label>
21+
<div class="col-md-10">
22+
<input type="text"
23+
class="form-control"
24+
name="photo_url"
25+
id="photo_url"
26+
v-model="photo_form.url"
27+
placeholder="Enter the url for photo" required/>
28+
</div>
29+
</div>
30+
<div class="form-group">
31+
<div class="col-md-10 col-md-offset-2">
32+
<button type="reset" class="btn btn-default">Clear</button>
33+
<button class="btn btn-success" v-on:submit.prevent="submitPhoto()">Add</button>
34+
</div>
35+
</div>
36+
</fieldset>
37+
</form>
38+
</div>`
39+
40+
41+
var album_page = `<div>
42+
<h2 v-cloak>[[ msg_album ]]</h2>
43+
<strong>Your current uuid: <code v-cloak>[[ server_data ]]</code></strong>
44+
<br>
45+
<a target="_blank" class="btn btn-info" v-on:click="loadAlbum()">Load Abum</a>
46+
<hr>
47+
<div id="photo_album" class="container">
48+
<div class="row placeholders">
49+
<div class="col-sm-12 col-md-8 col-lg-12 placeholder" >
50+
<div class="col-lg-3 col-md-4 col-sm-8" v-for="photo in photos">
51+
<img class="img-responsive" :src="photo.url"/>
52+
<label>[[ photo.name ]]</label>
53+
</div>
54+
</div>
55+
</div>
56+
</div>
57+
</div>`
58+
59+
// End of template strings ---------------------------------------------------
60+
const Photo = {
61+
template: photo_page ,
62+
delimiters:['[[',']]'],
63+
data(){
64+
data = {
65+
msg_add_photo:"Loaded the page where you can add your awesome photo urls!",
66+
photo_form:{}
67+
}
68+
69+
return data
70+
},
71+
methods:{
72+
submitPhoto: function(){
73+
this.$http.post('/dashboard/addPhoto', {data:this.photo_form})
74+
.then(res => {
75+
if (res.data.status = true) {
76+
// reload route forcibily since its same route (refer : https://github.com/vuejs/vue-router/issues/296)
77+
this.$router.go({path:'/add', force:true})
78+
}
79+
})
80+
console.log(this.photo_form)
81+
}
82+
}
83+
}
84+
85+
86+
const Album = {
87+
template: album_page ,
88+
delimiters:['[[',']]'],
89+
data(){
90+
data = {
91+
msg_album:"Loaded Album page",
92+
// load data from server while routing
93+
server_data:'',
94+
photos:{}
95+
}
96+
return data
97+
},
98+
created:function(){
99+
this.$http.get('/dashboard/getData')
100+
.then(res => {
101+
if (res.data.status == true) {
102+
this.server_data = res.data.message
103+
console.log(this.server_data)
104+
}
105+
})
106+
},
107+
methods:{
108+
loadAlbum: function(){
109+
this.$http.get('/dashboard/getPhotos')
110+
.then(res => {
111+
if (res.data.status == true) {
112+
this.photos = res.data.photos
113+
console.log(this.photos)
114+
}
115+
})
116+
}
117+
}
118+
119+
}
120+
121+
const routes = [
122+
{
123+
path: '/add',
124+
component: Photo
125+
},
126+
{ path: '/album', component: Album }
127+
]
128+
129+
const router = new VueRouter({
130+
routes // short for `routes: routes`
131+
})
132+
133+
134+
var app = new Vue({
135+
router
136+
}).$mount('#app')
137+

static/js/app.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Vue.config.delimiters = ['[[',']]']
2+
3+
Vue.http.options.root = '/';
4+
var hello = new Vue({
5+
el:'#vueApp',
6+
delimiters:['[[',']]'],
7+
data:{
8+
message:'Welcome to Vue App!'
9+
}
10+
})
11+
12+
13+
var login = new Vue({
14+
delimiters:['[[',']]'],
15+
el:'#loginForm',
16+
data:{
17+
form:{
18+
username:'',
19+
password:''
20+
}
21+
},
22+
23+
methods:{
24+
loginUser: function(){
25+
console.log(this.form)
26+
this.$http.post('/login', {data:this.form})
27+
.then(response => {
28+
if (response.data.status == true ){
29+
window.location.href = '/dashboard'
30+
}
31+
}, response => {
32+
console.log("error >>> ",response.data.message)
33+
})
34+
}
35+
}
36+
})
37+
38+
39+
var signup = new Vue({
40+
delimiters:['[[',']]'],
41+
el:'#signupForm',
42+
data:{
43+
form:{
44+
username:'',
45+
password:'',
46+
error_msg:'',
47+
has_error:''
48+
}
49+
},
50+
51+
methods:{
52+
signupUser: function(){
53+
this.$http.post('/signup', {data:this.form})
54+
.then(response => {
55+
if (response.data.code == 200 && response.data.status == true){
56+
window.location.href = '/'
57+
}
58+
else{
59+
this.form.error_msg = response.data.message;
60+
this.form.has_error = "has-error";
61+
}
62+
}, response => {
63+
console.log("error >>> ",response.data.message)
64+
})
65+
}
66+
}
67+
})

0 commit comments

Comments
 (0)