-
Notifications
You must be signed in to change notification settings - Fork 18
Mongo filetypes #966
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Mongo filetypes #966
Changes from 15 commits
0e68c71
f2af51a
5cdd129
466ca1b
0e1ffa0
206d69e
b043b86
ad9a703
dd7e4ca
0cdbf5d
6cf6e2c
c5c6b42
82684f2
d79658a
3af4e58
0cc3c28
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,7 @@ | |
| import elasticsearch | ||
|
|
||
| from . import util | ||
| from .dao.dbutil import try_replace_one | ||
| from .dao.dbutil import try_replace_one, try_update_one | ||
|
|
||
| logging.basicConfig( | ||
| format='%(asctime)s %(name)16.16s %(filename)24.24s %(lineno)5d:%(levelname)4.4s %(message)s', | ||
|
|
@@ -161,6 +161,7 @@ def apply_env_variables(config): | |
| 'container.json', | ||
| 'device.json', | ||
| 'file.json', | ||
| 'filetype.json', | ||
| 'file-update.json', | ||
| 'group-new.json', | ||
| 'group-update.json', | ||
|
|
@@ -226,6 +227,7 @@ def create_or_recreate_ttl_index(coll_name, index_name, ttl): | |
|
|
||
| def initialize_db(): | ||
| log.info('Initializing database, creating indexes') | ||
|
|
||
| # TODO review all indexes | ||
| db.users.create_index('api_key.key') | ||
| db.projects.create_index([('gid', 1), ('name', 1)]) | ||
|
|
@@ -251,7 +253,12 @@ def initialize_db(): | |
| create_or_recreate_ttl_index('downloads', 'timestamp', 60) | ||
|
|
||
| now = datetime.datetime.utcnow() | ||
| db.groups.update_one({'_id': 'unknown'}, {'$setOnInsert': { 'created': now, 'modified': now, 'label': 'Unknown', 'permissions': []}}, upsert=True) | ||
| try_update_one(db, | ||
| 'groups', {'_id': 'unknown'}, | ||
| {'$setOnInsert': {'created': now, 'modified': now, 'label': 'Unknown', 'permissions': []}}, | ||
| upsert=True) | ||
|
|
||
| log.info('Initializing database, creating indexes ....DONE') | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's make this two log statements, one before the |
||
|
|
||
| def get_config(): | ||
| global __last_update, __config, __config_persisted #pylint: disable=global-statement | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| from pymongo.errors import DuplicateKeyError | ||
| from ..web.errors import APIStorageException | ||
|
|
||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this whitespace is in error
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just followed pep8. It says: Surround top-level function and class definitions with two blank lines. |
||
| def try_replace_one(db, coll_name, query, update, upsert=False): | ||
| """ | ||
| Mongo does not see replace w/ upsert as an atomic action: | ||
|
|
@@ -39,3 +40,18 @@ def fault_tolerant_replace_one(db, coll_name, query, update, upsert=False): | |
| time.sleep(random.uniform(0.01,0.05)) | ||
|
|
||
| raise APIStorageException('Unable to replace object.') | ||
|
|
||
|
|
||
| def try_update_one(db, coll_name, query, update, upsert=False): | ||
| """ | ||
| Mongo does not see replace w/ upsert as an atomic action: | ||
| https://jira.mongodb.org/browse/SERVER-14322 | ||
|
|
||
| This function will try a replace_one operation, returning the result and if the operation succeeded. | ||
| """ | ||
| try: | ||
| result = db[coll_name].update_one(query, update, upsert=upsert) | ||
| except DuplicateKeyError: | ||
| return result, False | ||
| else: | ||
| return result, True | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| import re | ||
|
|
||
| from .. import config | ||
| from ..auth import require_admin, require_login | ||
| from ..validators import validate_data, InputValidationException | ||
| from ..web import base | ||
|
|
||
|
|
||
| class FileType(base.RequestHandler): | ||
|
|
||
| @require_login | ||
| def get(self): | ||
| """Get file types""" | ||
| return config.db.filetypes.find() | ||
|
|
||
| @require_admin | ||
| def post(self): | ||
| """ | ||
| Insert or replace a file type. Required fields: '_id' and 'regex' where the '_id' is the unique name of | ||
| the file type and 'regex' is a regular expression which is used to figure out the file type from the file name. | ||
| """ | ||
| payload = self.request.json_body | ||
| validate_data(payload, 'filetype.json', 'input', 'POST') | ||
| try: | ||
| re.compile(payload['regex']) | ||
| except re.error: | ||
| raise InputValidationException('Invalid regular expression') | ||
| result = config.db.filetypes.replace_one({'_id': payload['_id']}, payload, upsert=True) | ||
| if result.acknowledged: | ||
| _id = result.upserted_id if result.upserted_id else payload['_id'] | ||
| return {'_id': _id} | ||
| else: | ||
| self.abort(404, 'File type {} not updated'.format(payload['_id'])) | ||
|
|
||
| @require_admin | ||
| def delete(self, _id): | ||
| """Delete a file type""" | ||
| result = config.db.filetypes.delete_one({'_id': _id}) | ||
| if result.deleted_count: | ||
| return {'deleted': result.deleted_count} | ||
| else: | ||
| self.abort(404, 'File type {} not removed'.format(_id)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the same regex as
fnameabove, does it need to be separate?