diff --git a/AnkiServer/apps/rest_app.py b/AnkiServer/apps/rest_app.py index fa10422..ab0ad3e 100644 --- a/AnkiServer/apps/rest_app.py +++ b/AnkiServer/apps/rest_app.py @@ -53,9 +53,7 @@ class RestApp(object): """A WSGI app that implements RESTful operations on Collections, Decks and Cards.""" # Defines not only the valid handler types, but their position in the URL string - # TODO: this broken - it allows a model to contain cards, for example.. We need to - # give a pattern for each handler type. - handler_types = ['collection', ['model', 'note', 'deck'], 'card'] + handler_types = ['collection', ['model', 'note', 'deck', 'card']] def __init__(self, data_root, allowed_hosts='*', setup_new_collection=None, use_default_handlers=True, collection_manager=None): from AnkiServer.threading import getCollectionManager @@ -345,7 +343,7 @@ class CollectionHandler(RestHandlerBase): ids = col.findCards(query) if req.data.get('preload', False): - cards = [CardHandler._serialize(col.getCard(id)) for id in req.ids] + cards = [CardHandler._serialize(col.getCard(id), req.data) for id in req.ids] else: cards = [{'id': id} for id in req.ids] @@ -396,7 +394,7 @@ class CollectionHandler(RestHandlerBase): card.startTimer() - result = CardHandler._serialize(card) + result = CardHandler._serialize(card, req.data) result['answer_buttons'] = self._get_answer_buttons(col, card) return result @@ -489,10 +487,11 @@ class NoteHandler(RestHandlerBase): def _serialize(note): d = { 'id': note.id, - 'model': note.model()['name'], + 'model': note.model(), 'tags': ' '.join(note.tags), } # TODO: do more stuff! + return d def index(self, col, req): @@ -527,7 +526,7 @@ class CardHandler(RestHandlerBase): """Default handler group for 'card' type.""" @staticmethod - def _serialize(card): + def _serialize(card, opts): d = { 'id': card.id, 'isEmpty': card.isEmpty(), @@ -550,8 +549,19 @@ class CardHandler(RestHandlerBase): 'usn': card.usn, 'timerStarted': card.timerStarted, } + + if opts.get('load_note', False): + d['note'] = NoteHandler._serialize(card.col.getNote(card.nid)) + + if opts.get('load_deck', False): + d['deck'] = card.col.decks.get(card.did) + return d + def index(self, col, req): + card = col.getCard(req.ids[1]) + return self._serialize(card, req.data) + # Our entry point def make_app(global_conf, **local_conf): # TODO: we should setup the default language from conf! diff --git a/tests/test_rest_app.py b/tests/test_rest_app.py index 14bd6f0..849fdd6 100644 --- a/tests/test_rest_app.py +++ b/tests/test_rest_app.py @@ -42,8 +42,10 @@ class RestAppTest(unittest.TestCase): ('collection/user/note/123/handler', ('note', 'handler', ['user', '123'])), ('collection/user/deck/name', ('deck', 'index', ['user', 'name'])), ('collection/user/deck/name/handler', ('deck', 'handler', ['user', 'name'])), - ('collection/user/deck/name/card/123', ('card', 'index', ['user', 'name', '123'])), - ('collection/user/deck/name/card/123/handler', ('card', 'handler', ['user', 'name', '123'])), + #('collection/user/deck/name/card/123', ('card', 'index', ['user', 'name', '123'])), + #('collection/user/deck/name/card/123/handler', ('card', 'handler', ['user', 'name', '123'])), + ('collection/user/card/123', ('card', 'index', ['user', '123'])), + ('collection/user/card/123/handler', ('card', 'handler', ['user', '123'])), # the leading slash should make no difference! ('/collection/user', ('collection', 'index', ['user'])), ] @@ -222,7 +224,7 @@ class CollectionHandlerTest(CollectionTestBase): ret = self.execute('find_notes', {'preload': True}) self.assertEqual(len(ret), 1) self.assertEqual(ret[0]['id'], note_id) - self.assertEqual(ret[0]['model'], 'Basic') + self.assertEqual(ret[0]['model']['name'], 'Basic') def test_add_note(self): # make sure there are no notes (yet) @@ -422,6 +424,44 @@ class DeckHandlerTest(CollectionTestBase): self.assertEqual(ret, None) self.mock_app.execute_handler.assert_called_with('collection', 'next_card', self.collection, RestHandlerRequest(self.mock_app, {'deck': '1'}, ['collection_name'], {})) +class CardHandlerTest(CollectionTestBase): + def setUp(self): + super(CardHandlerTest, self).setUp() + self.handler = CardHandler() + + def execute(self, name, data, card_id): + ids = ['collection_name', card_id] + func = getattr(self.handler, name) + req = RestHandlerRequest(self.mock_app, data, ids, {}) + return func(self.collection, req) + + def test_index_simple(self): + self.add_default_note() + + note_id = self.collection.findNotes('')[0] + card_id = self.collection.findCards('')[0] + + ret = self.execute('index', {}, card_id) + self.assertEqual(ret['id'], card_id) + self.assertEqual(ret['nid'], note_id) + self.assertEqual(ret['did'], 1) + self.assertFalse(ret.has_key('note')) + self.assertFalse(ret.has_key('deck')) + + def test_index_load(self): + self.add_default_note() + + note_id = self.collection.findNotes('')[0] + card_id = self.collection.findCards('')[0] + + ret = self.execute('index', {'load_note': 1, 'load_deck': 1}, card_id) + self.assertEqual(ret['id'], card_id) + self.assertEqual(ret['nid'], note_id) + self.assertEqual(ret['did'], 1) + self.assertEqual(ret['note']['id'], note_id) + self.assertEqual(ret['note']['model']['name'], 'Basic') + self.assertEqual(ret['deck']['name'], 'Default') + if __name__ == '__main__': unittest.main()