Skip to content

Commit d50258a

Browse files
committed
First commit
0 parents  commit d50258a

14 files changed

+601
-0
lines changed

__pycache__/config.cpython-34.pyc

695 Bytes
Binary file not shown.

api/__init__.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from flask import Flask, Blueprint
2+
from flask_restful import Api
3+
4+
from config import config
5+
from api.controllers import auth
6+
7+
8+
def create_app(env):
9+
app = Flask(__name__)
10+
app.config.from_object(config[env])
11+
12+
api_bp = Blueprint('api', __name__)
13+
api = Api(api_bp)
14+
15+
# Code for adding Flask RESTful resources goes here
16+
api.add_resource(auth.AuthLogin, '/auth/login')
17+
api.add_resource(auth.AuthRegister, '/auth/register')
18+
19+
app.register_blueprint(api_bp, url_prefix="/api/v1")
20+
21+
return app
726 Bytes
Binary file not shown.

api/__pycache__/models.cpython-34.pyc

2.41 KB
Binary file not shown.
Binary file not shown.

api/controllers/auth.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from flask_restful import Resource, reqparse, abort
2+
3+
from api.models import User
4+
from api.utils.errors import ValidationError
5+
6+
7+
class AuthLogin(Resource):
8+
"""docstring for AuthLogin"""
9+
10+
def post(self):
11+
parser = reqparse.RequestParser()
12+
parser.add_argument('email', type=str, help="You need to enter your email address", required=True)
13+
parser.add_argument('password', type=str, help="You need to enter your password", required=True)
14+
15+
args = parser.parse_args()
16+
17+
email = args.get('email')
18+
password = args.get('password')
19+
20+
try:
21+
token = User.validate(email, password)
22+
return {'token': token}
23+
except ValidationError as e:
24+
abort(400, message='There was an error while trying to log you in -> {}'.format(e.message))
25+
26+
27+
class AuthRegister(Resource):
28+
"""docstring for AuthRegister"""
29+
30+
def post(self):
31+
parser = reqparse.RequestParser()
32+
parser.add_argument('fullname', type=str, help="You need to enter your full name", required=True)
33+
parser.add_argument('email', type=str, help="You need to enter your email address", required=True)
34+
parser.add_argument('password', type=str, help="You need to enter your password", required=True)
35+
parser.add_argument('password_conf', type=str, help="You need to enter password again for confirmation", required=True)
36+
37+
args = parser.parse_args()
38+
39+
email = args.get('email')
40+
password = args.get('password')
41+
password_conf = args.get('password_conf')
42+
fullname = args.get('fullname')
43+
44+
try:
45+
User.create(
46+
email=email,
47+
password=password,
48+
password_conf=password_conf,
49+
fullname=fullname
50+
)
51+
return {'message': 'Successfully created your account.'}
52+
except ValidationError as e:
53+
abort(400, message='There was an error while trying to create your account -> {}'.format(e.message))

api/controllers/files.py

+205
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
import os
2+
3+
from flask import request, g
4+
from flask_restful import reqparse, abort, Resource, marshal_with, fields
5+
from werkzeug import secure_filename
6+
from utils.decorators import login_required, validate_user
7+
8+
from api.models import File
9+
10+
BASE_DIR = os.path.abspath(
11+
os.path.dirname(os.path.dirname(__file__))
12+
)
13+
14+
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
15+
16+
file_array_serializer = {
17+
'id': fields.String,
18+
'name': fields.String,
19+
'size': fields.Integer,
20+
'uri': fields.String,
21+
'is_folder': fields.Boolean,
22+
'parent_id': fields.String,
23+
'creator': fields.String,
24+
'date_created': fields.DateTime(dt_format='rfc822'),
25+
'date_modified': fields.DateTime(dt_format='rfc822'),
26+
}
27+
28+
file_serializer = {
29+
'id': fields.String,
30+
'name': fields.String,
31+
'size': fields.Integer,
32+
'uri': fields.String,
33+
'is_folder': fields.Boolean,
34+
'objects': fields.Nested(file_array_serializer, default=[]),
35+
'parent_id': fields.String,
36+
'creator': fields.String,
37+
'date_created': fields.DateTime(dt_format='rfc822'),
38+
'date_modified': fields.DateTime(dt_format='rfc822'),
39+
}
40+
41+
def is_allowed(filename):
42+
return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
43+
44+
class CreateList(Resource):
45+
"""docstring for CreateList"""
46+
@login_required
47+
@validate_user
48+
@marshal_with(file_array_serializer)
49+
50+
def get(self, user_id):
51+
try:
52+
return File.filter({'creator': user_id, 'parent_id': 0})
53+
except Exception as e:
54+
abort(500, message="There was an error while trying to get your files --> {}".format(e.message))
55+
56+
@login_required
57+
@validate_user
58+
@marshal_with(file_serializer)
59+
def post(self, user_id):
60+
try:
61+
parser = reqparse.RequestParser()
62+
parser.add_argument('name', type=str, help="This should be the folder name if creating a folder")
63+
parser.add_argument('parent_id', type=str, help="This should be the parent folder id")
64+
parser.add_argument('is_folder', type=str, help="This indicates whether you are trying to create a folder or not")
65+
66+
args = parser.parse_args()
67+
68+
name = args.get('name', None)
69+
parent_id = args.get('parent_id', None)
70+
is_folder = args.get('is_folder', False)
71+
72+
parent = None
73+
74+
# Are we adding this to a oarent folder?
75+
if parent_id is not None:
76+
parent = File.find(parent_id)
77+
if parent is None:
78+
raise Exception("This folder does not exist")
79+
if not parent['is_folder']:
80+
raise Exception("Select a valid folder to upload to")
81+
82+
# Are we creating a folder?
83+
if is_folder:
84+
if name is None:
85+
raise Exception("You need to specify a name for this folder")
86+
87+
return Folder.create(
88+
name=name,
89+
parent=parent,
90+
is_folder=is_folder,
91+
creator=user_id
92+
)
93+
else:
94+
files = request.files['file']
95+
96+
if files and is_allowed(files.filename):
97+
_dir = os.path.join(BASE_DIR, 'upload/{}/'.format(user_id))
98+
99+
if not os.path.isdir(_dir):
100+
os.mkdir(_dir)
101+
102+
filename = secure_filename(files.filename)
103+
to_path = os.path.join(_dir, filename)
104+
files.save(to_path)
105+
fileuri = os.path.join('upload/{}/'.format(user_id), filename)
106+
filesize = os.path.getsize(to_path)
107+
108+
return File.create(
109+
name=filename,
110+
uri=fileuri,
111+
size=filesize,
112+
parent=parent,
113+
creator=user_id
114+
)
115+
raise Exception("You did not supply a valid file in your request")
116+
except Exception as e:
117+
abort(500, message="There was an error while processing your request --> {}".format(e.message))
118+
119+
120+
class ViewEditDelete(Resource):
121+
"""docstring for ViewEditDelete"""
122+
@login_required
123+
@validate_user
124+
@belongs_to_user
125+
@marshal_with(file_serializer)
126+
def get(self, user_id, file_id):
127+
try:
128+
should_download = request.args.get('download', False)
129+
if should_download == 'true':
130+
parts = os.path.split(g.file['uri'])
131+
return send_from_directory(directory=parts[0], filename=parts[1])
132+
return g.file
133+
except Exception as e:
134+
abort(500, message="There was an error while processing your request --> {}".format(e.message))
135+
136+
@login_required
137+
@validate_user
138+
@belongs_to_user
139+
@marshal_with(file_serializer)
140+
def put(self, user_id, file_id):
141+
try:
142+
update_fields = {}
143+
parser = reqparse.RequestParser()
144+
145+
parser.add_argument('name', type=str, help="New name for the file/folder")
146+
parser.add_argument('parent_id', type=str, help="New parent folder for the file/folder")
147+
148+
args = parser.parse_args()
149+
150+
name = args.get('name', None)
151+
parent_id = args.get('parent_id', None)
152+
153+
if name is not None:
154+
update_fields['name'] = name
155+
156+
if parent_id is not None and g.file['parent_id'] != parent_id:
157+
if parent_id != '0':
158+
folder_access = Folder.filter({'id': parent_id, 'creator': user_id})
159+
if not folder_access:
160+
abort(404, message="You don't have access to the folder you're tyring to move this object to")
161+
162+
if g.file['is_folder']:
163+
update_fields['tag'] = g.file['id'] if parent_id == '0' else '{}#{}'.format(folder_access['tag'], folder['last_index'])
164+
Folder.move(g.file, folder_access)
165+
else:
166+
File.move(g.file, folder_access)
167+
168+
update_fields['parent_id'] = parent_id
169+
170+
if g.file['is_folder']:
171+
Folder.update(file_id, update_fields)
172+
else:
173+
File.update(file_id, update_fields)
174+
175+
return File.find(file_id)
176+
except Exception as e:
177+
abort(500, message="There was an error while processing your request --> {}".format(e.message))
178+
179+
@login_required
180+
@validate_user
181+
@belongs_to_user
182+
@marshal_with(file_serializer)
183+
def delete(self, user_id, file_id):
184+
try:
185+
hard_delete = request.args.get('hard_delete', False)
186+
if not g.file['is_folder']:
187+
if hard_delete == 'true':
188+
os.remove(g.file['uri'])
189+
File.delete(file_id)
190+
else:
191+
File.update(file_id, {'status': False})
192+
else:
193+
if hard_delete == 'true':
194+
folders = Folder.filter(lambda folder: folder['tag'].startswith(g.file['tag']))
195+
for folder in folders:
196+
files = File.filter({'parent_id': folder['id'], 'is_folder': False})
197+
File.delete_where({'parent_id': folder['id'], 'is_folder': False})
198+
for f in files:
199+
os.remove(f['uri'])
200+
else:
201+
File.update(file_id, {'status': False})
202+
File.update_where({'parent_id': file_id}, {'status': False})
203+
return "File has been deleted successfully", 204
204+
except Exception as e:
205+
abort(500, message="There was an error while processing your request --> {}".format(e.message))

0 commit comments

Comments
 (0)