diff --git a/nofussbm/__init__.py b/nofussbm/__init__.py
index b3cceb4..d281531 100644
--- a/nofussbm/__init__.py
+++ b/nofussbm/__init__.py
@@ -15,10 +15,10 @@
# You should have received a copy of the GNU General Public License along with
# "No Fuss Bookmarks". If not, see .
-from logging import StreamHandler, Formatter, getLogger, DEBUG
+from logging import StreamHandler, Formatter, DEBUG
from os import environ
-from flask import Flask, make_response, request, g, redirect, url_for, abort, render_template
+from flask import Flask, make_response, request, redirect, url_for, abort, render_template
from flask.ext.pymongo import PyMongo
from pymongo.errors import OperationFailure
@@ -41,6 +41,9 @@ class Config( object ):
from .api import api
from .helpers import query_from_dict
from .tags import tags
+from .json import NofussbmJSONEncoder, NofussbmJSONDecoder
+app.json_encoder = NofussbmJSONEncoder
+app.json_decoder = NofussbmJSONDecoder
# Register APIs blueprint and setup {before,teardown}_request
@@ -58,7 +61,7 @@ class Config( object ):
stderr_handler = StreamHandler()
stderr_handler.setLevel( DEBUG )
-stderr_handler.setFormatter( Formatter( '%(asctime)s [%(process)s] [%(levelname)s] [Flask: %(name)s] %(message)s','%Y-%m-%d %H:%M:%S' ) )
+stderr_handler.setFormatter( Formatter( '%(asctime)s [%(process)s] [%(levelname)s] [Flask: %(name)s] %(message)s', '%Y-%m-%d %H:%M:%S' ) )
app.logger.addHandler( stderr_handler )
app.logger.setLevel( DEBUG )
@@ -136,7 +139,6 @@ def list( ident ):
if list_appearance == 'html':
for bm in list_query( email, bookmarks_per_page ):
date = bm[ 'date-modified' ]
- print bm
result.append( ( date.strftime( '%Y-%m-%d' ), bm[ 'url' ], bm[ 'title' ], bm[ 'tags' ], bm[ '_id' ] ) )
if content_only:
return render_template( 'list-content.html', bookmarks = result )
diff --git a/nofussbm/api.py b/nofussbm/api.py
index 50ad097..779a7fa 100644
--- a/nofussbm/api.py
+++ b/nofussbm/api.py
@@ -15,12 +15,13 @@
# You should have received a copy of the GNU General Public License along with
# "No Fuss Bookmarks". If not, see .
+import hmac
+import re
+
from base64 import b64encode, b64decode
from datetime import datetime
from functools import wraps
from hashlib import sha1
-import hmac
-import re
from urlparse import parse_qs
from flask import Blueprint, make_response, request, g, json, abort
@@ -35,11 +36,6 @@
RANGE_RE = re.compile( r'bookmarks=(\d+)(-(\d+))?' )
-# Hacks (somehow horrible) to personalize decoding in Flask request.json
-
-from .helpers import setup_json
-setup_json( json )
-
def myjsonify( data = None, code = 200, headers = None ):
data = [] if not data else data
response = make_response( json.dumps( data, indent = 4, sort_keys = True, ensure_ascii = False ) + '\n', code )
diff --git a/nofussbm/helpers.py b/nofussbm/helpers.py
index 6439ac1..16db03d 100644
--- a/nofussbm/helpers.py
+++ b/nofussbm/helpers.py
@@ -15,18 +15,13 @@
# You should have received a copy of the GNU General Public License along with
# "No Fuss Bookmarks". If not, see .
-from datetime import datetime
from email.mime.text import MIMEText
-from json import JSONEncoder, JSONDecoder
from smtplib import SMTP
from bson.objectid import ObjectId, InvalidId
from . import Config
-DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S.%f'
-
-ALLOWED_KEYS = set(( 'title', 'url', 'id', 'tags', 'date-added', 'date-modified' ))
def to_id( id_as_str ):
res = None
@@ -48,43 +43,6 @@ def query_from_dict( email, dct ):
query[ 'title' ] = { '$regex': dct[ 'title' ], '$options': 'i' }
return query
-def setup_json( json ):
-
- def object_hook( dct ):
- res = {}
- for key, value in dct.items():
- if key not in ALLOWED_KEYS: continue
- if key == 'id': res[ 'id' ] = to_id( value )
- elif key == 'tags': res[ 'tags' ] = map( lambda _: _.strip(), value.split( ',' ) )
- elif key.startswith( 'date-' ):
- try:
- res[ key ] = datetime.strptime( value, DATETIME_FORMAT )
- except:
- pass
- else:
- res[ key ] = value
- return res
-
- class Encoder( JSONEncoder ):
- def default(self, obj):
- if isinstance( obj, datetime ):
- return datetime.strftime( obj, DATETIME_FORMAT )
- if isinstance( obj, ObjectId ):
- return str( obj )
- return JSONEncoder.default( self, obj )
-
- prev_dumps = json.dumps
- prev_loads = json.loads
-
- def _dumps( *args, **kwargs ):
- kwargs.update( { 'cls': Encoder } )
- return prev_dumps( *args, **kwargs )
- def _loads( *args, **kwargs ):
- return prev_loads( *args, object_hook = object_hook, **kwargs )
-
- json.dumps = _dumps
- json.loads = _loads
-
# Utility functions
diff --git a/nofussbm/json.py b/nofussbm/json.py
new file mode 100644
index 0000000..73106c9
--- /dev/null
+++ b/nofussbm/json.py
@@ -0,0 +1,59 @@
+# Copyright 2011, Massimo Santini
+#
+# This file is part of "No Fuss Bookmarks".
+#
+# "No Fuss Bookmarks" is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# "No Fuss Bookmarks" is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# "No Fuss Bookmarks". If not, see .
+
+from flask.json import JSONEncoder, JSONDecoder
+from datetime import datetime
+from bson.objectid import ObjectId
+from .helpers import to_id
+
+DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S.%f'
+
+
+class NofussbmJSONEncoder(JSONEncoder):
+
+ def default(self, obj):
+ if isinstance(obj, datetime):
+ return datetime.strftime(obj, DATETIME_FORMAT)
+ if isinstance(obj, ObjectId):
+ return str(obj)
+ return JSONEncoder.default(self, obj)
+
+
+class NofussbmJSONDecoder(JSONDecoder):
+
+ def __init__(self, *args, **kwargs):
+ self.ALLOWED_KEYS = set(['title', 'url', 'id', 'tags', 'date-added', 'date-modified'])
+ self.orig_object_hook = kwargs.pop("object_hook", None)
+ super(NofussbmJSONDecoder, self).__init__(*args, object_hook=self.custom_object_hook, **kwargs)
+
+ def custom_object_hook(self, dct):
+ res = dict()
+ for key, value in dct.items():
+ if key not in self.ALLOWED_KEYS:
+ continue
+ if key == 'id':
+ res['id'] = to_id(value)
+ elif key == 'tags':
+ res['tags'] = [_.strip() for _ in value.split(',')]
+ elif key.startswith('date-'):
+ try:
+ res[key] = datetime.strptime(value, DATETIME_FORMAT)
+ except:
+ pass
+ else:
+ res[key] = value
+ return res