-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathtrack.py
More file actions
176 lines (145 loc) · 5.73 KB
/
track.py
File metadata and controls
176 lines (145 loc) · 5.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# --------------------------------------------------------------------------------------------------
# OpenSeaMap API - Web API for OpenSeaMap services.
#
# Written in 2012 by Dominik Fässler [email protected]
#
# To the extent possible under law, the author(s) have dedicated all copyright
# and related and neighboring rights to this software to the public domain
# worldwide. This software is distributed without any warranty.
#
# You should have received a copy of the CC0 Public Domain Dedication along
# with this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
# --------------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------
# Imports external
# --------------------------------------------------------------------------------------------------
import cherrypy
import logging
import os
# --------------------------------------------------------------------------------------------------
# Imports internal
# --------------------------------------------------------------------------------------------------
from error import *
# --------------------------------------------------------------------------------------------------
class Track():
'''
This class allows to handle user tracks. Each track becomes an unique
track id which is referenced to an user. The track file will be
stored in the file system, while information about the user and state
will be stored in the database (table user_tracks).
Each track has an upload state:
0 : New track, nothing uploaded yet.
1 : Upload done, track id can not be used for further uploads.
To have at maximum 100 files in a directory, subdirectories will be
created automatically. Files from '1.dat' to '99.dat' will reside in
the subdirectory '000', Files from '100.dat' to '199.dat' will reside
in '100', ...
'''
# ----------------------------------------------------------------------------------------------
def __init__(self, db):
self._db = db
try:
self._dir = cherrypy.config.get('track.dir', None)
except ConfigParser.NoOptionError as e:
raise Exception('Track directory not defined.')
if self._dir == None:
raise Exception('Track directory not defined.')
# ----------------------------------------------------------------------------------------------
def getNewId(self, username):
cursor = self._db.getCursor()
cursor.execute(
'''
SELECT nextval('user_tracks_track_id_seq')
'''
)
record = cursor.fetchone()
if record == None:
self._db.commit()
cursor.close()
raise Error(201, 'Unable to fetch new track id.', 'TRACK')
trackId = record[0]
cursor.execute(
'''
INSERT INTO user_tracks (track_id, user_name)
VALUES (%s, %s)
''',
(trackId, username)
)
self._db.commit()
cursor.close()
return trackId
# ----------------------------------------------------------------------------------------------
def uploadDone(self, trackId, username, fileHandle, fileName):
assert isinstance(trackId, int)
assert isinstance(fileHandle, file)
cursor = self._db.getCursor()
cursor.execute(
'''
SELECT upload_state
FROM user_tracks
WHERE track_id = %s
AND user_name = %s
''',
(trackId, username)
)
record = cursor.fetchone()
if record == None:
self._db.commit()
cursor.close()
raise Error(202, 'Invalid track id.', 'TRACK')
if record[0] > 0:
self._db.commit()
cursor.close()
raise Error(203, 'Upload already done.', 'TRACK')
size = self._storeFile(trackId, fileHandle)
cursor.execute(
'''
UPDATE user_tracks
SET file_ref = %s, upload_state = 1
WHERE track_id = %s
''',
(fileName, trackId)
)
self._db.commit()
cursor.close()
return size
# ----------------------------------------------------------------------------------------------
def _storeFile(self, trackId, fileHandle):
size = 0
fh = open(self._generateFileName(trackId), 'w')
while True:
data = fileHandle.read(8192)
if not data:
break
fh.write(data)
size += len(data)
fh.close()
return size
# ----------------------------------------------------------------------------------------------
def _generateFileName(self, trackId):
trackDir = str(int(round(trackId / 100)) * 100)
trackFile = str(trackId) + '.dat'
path = os.path.abspath(self._dir)
path = os.path.join(path, trackDir.rjust(3, '0'))
if os.path.exists(path) == False:
os.makedirs(path)
filename = os.path.join(path, trackFile)
return filename;
# ----------------------------------------------------------------------------------------------
def getByUsername(self, username):
cursor = self._db.getCursor()
cursor.execute(
'''
SELECT track_id, file_ref, upload_state
FROM user_tracks
WHERE user_name = %s
ORDER BY track_id ASC
''',
(username,)
)
records = cursor.fetchall()
self._db.commit()
cursor.close()
return records