Skip to content
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

enable_chunked_transfer_encoding_without_webserver #110

Merged
merged 32 commits into from
Mar 8, 2022
Merged

enable_chunked_transfer_encoding_without_webserver #110

merged 32 commits into from
Mar 8, 2022

Conversation

dobefore
Copy link
Contributor

@dobefore dobefore commented Sep 8, 2021

this update is based on Anki module 2.1.46
and this PR is incompatible with these PRs #104 ,#105,#106 ,because these PRs are based on webserver like nginx.
So,if this PR is merged,then other three will be discarded.

As the title shows,this make it valid HTTP transfer encoding:Chunked

How to implement?
read file stream handle provided by wsgiref from client request into byte-string,
skip each chunk size by add 2 bytes size,strip CRLF per line
finally , split it into a multi-field dictionary,fields like 'data','v'...

Other non-chunk message ,of course,is handled,mostly with regex.

Other changes are made due to missing attributes or redundant arguments caused by Anki module upgrade.
1.removed unused fn removed in sync.py
2.split remove in sync.py into add_grave apply_graves
...
Known Issue
1.importing a colpkg into an existing and already synced account on Ankidroid may cause media loss on server side

Tested in 2.1.44 ,2.1.47 On PC and 2.15.6 on Ankidroid

@dobefore dobefore changed the title enable_chunked_transfer_encoding_without_browser enable_chunked_transfer_encoding_without_webserver Sep 8, 2021
@marzzzello
Copy link
Contributor

Hey, thanks for your work!
I wanted to try your PR to see if it fixes #108 but I get the following error:

[...]
[2021-09-12 21:29:52,817]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/meta HTTP/1.1" 200 137
[2021-09-12 21:29:52,820]:INFO:ankisyncd.CollectionThread[marzzzello]:Running begin(*[], **{'skey': '02381caa'})
[2021-09-12 21:29:52,821]:INFO:ankisyncd.http:172.24.1.17 "GET /msync/begin?k=5decb7e436525a0683055cb2bd4d1ca4&v=anki%2C2.1.46+%2894913ec2%29%2Clin%3Aarch%3Arolling HTTP/1.1" 200 53
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 590, in __call__
    p=req.params
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 496, in params
    r=self.parse_request
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 427, in parse_request
    items=re.split(repeat,bd)
  File "/usr/local/lib/python3.9/re.py", line 231, in split
    return _compile(pattern, flags).split(string, maxsplit)
  File "/usr/local/lib/python3.9/re.py", line 294, in _compile
    return _cache[type(pattern), pattern, flags]
TypeError: unhashable type: 'list'
[2021-09-12 21:30:00,714]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/upload HTTP/1.1" 500 59

Anki 2.1.46 (2.1.44 throws exactly the same error)
Client says that a problem with AnkiWeb occured.

@dobefore
Copy link
Contributor Author

dobefore commented Sep 13, 2021

thanks for your detailed and useful debug info!
this time the server code seems working!
you could try re-apply the PR.
this works well On ankidroid
known issue.
server code seems to parse chunked bytes stream successfully from client(eglWin10),yet upload checking window will block the process
like this
Snipaste_2021-09-13_19-43-50

,so that checking window must be cancelled ,and hit sync once more.

@marzzzello
Copy link
Contributor

Thanks, it is working now and fixes #108. I am using anki sync server behind a reverse proxy (Traefik).
On AnkiDroid I also have the issue you mentioned ("Checking downloaded file..." takes forever)

@marzzzello
Copy link
Contributor

marzzzello commented Sep 13, 2021

I thought it is working but now I get "problem with AnkiWeb" and this log on the server (forcing a full sync works though):
And I don't know if this error is related to this PR or if it is a general issue.

[2021-09-13 16:42:46,357]:INFO:ankisyncd.CollectionThread[marzzzello]:Running begin(*[], **{'skey': 'cd46a106'})
[2021-09-13 16:42:46,362]:INFO:ankisyncd.http:172.24.1.17 "GET /msync/begin?k=424e6d89093126118cbdcc4e4a608495&v=anki%2C2.1.47+%28dc156f34%29%2Clin%3Aarch%3Arolling HTTP/1.1" 200 53
[2021-09-13 16:42:46,371]:INFO:ankisyncd.CollectionThread[marzzzello]:Running meta(*[], **{'v': 10, 'cv': 'anki,2.1.47 (dc156f34),lin:arch:rolling'})
[2021-09-13 16:42:46,374]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/meta HTTP/1.1" 200 150
[2021-09-13 16:42:46,430]:INFO:ankisyncd.CollectionThread[marzzzello]:Running start(*[], **{'minUsn': 72, 'lnewer': True, 'graves': None})
[2021-09-13 16:42:46,432]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/start HTTP/1.1" 200 39
[2021-09-13 16:42:46,509]:INFO:ankisyncd.CollectionThread[marzzzello]:Running applyChanges(*[], **{'changes': {'models': [], 'decks': [[{'id': 1631455687751, 'mod': 1631544158, 'name': 'Wanikani Ultimate 2: Electric Boogaloo', 'usn': 72, 'lrnToday': [87, 0], 'revToday': [87, 0], 'newToday': [87, 0], 'timeToday': [87, 80356], 'collapsed': True, 'browserCollapsed': True, 'desc': "Please see the <a href='https://ankiweb.net/shared/info/1609000301'>shared deck page</a> for more info.", 'dyn': 0, 'conf': 1, 'extendNew': 200, 'extendRev': 0}], []], 'tags': [], 'conf': {'defaultSearchText': '', 'timeLim': 0, 'dueCounts': True, 'cardCountsSeparateInactive': True, 'localOffset': -120, 'nextPos': 8898, 'schedVer': 2, 'addToCur': True, 'firstDayOfWeek': 0, 'hideAudioPlayButtons': False, 'activeDecks': [1631455687751], 'creationOffset': -120, 'curDeck': 1631455687751, 'curModel': 1228471294, 'estTimes': True, 'collapseTime': 1200, 'interruptAudioWhenAnswering': True, 'newBury': True, 'lastUnburied': 87, 'newSpread': 0, 'rollover': 4, 'sortType': 'noteFld', 'futureDueShowBacklog': True, 'pasteStripsFormatting': False, 'pasteImagesAsPng': False, 'sortBackwards': False, 'dayLearnFirst': False}, 'crt': 1623981600}})
[2021-09-13 16:42:46,533]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/applyChanges HTTP/1.1" 200 45
[2021-09-13 16:42:46,572]:INFO:ankisyncd.CollectionThread[marzzzello]:Running chunk(*[], **{})
[2021-09-13 16:42:46,578]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/chunk HTTP/1.1" 200 54
[2021-09-13 16:42:46,654]:INFO:ankisyncd.CollectionThread[marzzzello]:Running applyChunk(*[], **{'chunk': {'done': True, 'revlog': [[1631544158346, 103, 72, 3, 1, -600, 2500, 6722, 0], [1631544151612, 101, 72, 3, 1, -600, 2500, 8118, 0], [1631544143483, 109, 72, 3, 1, -600, 2500, 8621, 0], [1631544134854, 78, 72, 3, 1, -600, 2500, 9483, 0], [1631544125367, 99, 72, 3, 1, -600, 2500, 6566, 0], [1631544118792, 42, 72, 1, -60, -600, 0, 10027, 0], [1631544108758, 48, 72, 1, -60, -600, 0, 17195, 0], [1631544091551, 92, 72, 1, -60, -60, 0, 13621, 0]], 'cards': [[109, 68, 1631455687751, 0, 1631544143, 72, 2, 2, 88, 1, 2500, 2, 0, 1001, 0, 0, 0, ''], [103, 65, 1631455687751, 0, 1631544158, 72, 2, 2, 88, 1, 2500, 2, 0, 1001, 0, 0, 0, ''], [101, 64, 1631455687751, 0, 1631544151, 72, 2, 2, 88, 1, 2500, 2, 0, 1001, 0, 0, 0, ''], [99, 63, 1631455687751, 0, 1631544125, 72, 2, 2, 88, 1, 2500, 2, 0, 1001, 0, 0, 0, ''], [92, 59, 1631455687751, 1, 1631544091, 72, 1, 1, 1631544152, 0, 0, 2, 0, 2002, 0, 0, 0, ''], [78, 52, 1631455687751, 1, 1631544134, 72, 2, 2, 88, 1, 2500, 5, 0, 1001, 0, 0, 0, ''], [48, 37, 1631455687751, 1, 1631544108, 72, 1, 1, 1631544176, 0, 0, 7, 0, 2002, 0, 0, 0, ''], [42, 34, 1631455687751, 1, 1631544118, 72, 1, 1, 1631544185, 0, 0, 8, 0, 2002, 0, 0, 0, '']]}})
[2021-09-13 16:42:46,662]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/applyChunk HTTP/1.1" 200 4
[2021-09-13 16:42:46,742]:INFO:ankisyncd.CollectionThread[marzzzello]:Running sanityCheck2(*[], **{'client': [[20, 12, 82], 38106, 20003, 4063, 0, 16, 12, 1]})
[2021-09-13 16:42:46,763]:ERROR:ankisyncd.CollectionThread[marzzzello]:Unable to sanityCheck2(*[], **{'client': [[20, 12, 82], 38106, 20003, 4063, 0, 16, 12, 1]}): dictionary update sequence element #0 has length 1; 2 is required
Traceback (most recent call last):
  File "/opt/ankisyncd/ankisyncd/thread.py", line 98, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/opt/ankisyncd/ankisyncd/collection.py", line 45, in execute
    ret = func(*args, **kw)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 714, in run_func
    res = handler_method(**keyword_args)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 152, in sanityCheck2
    return dict(status, c=client, s=server)
ValueError: dictionary update sequence element #0 has length 1; 2 is required
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 653, in __call__
    result = self._execute_handler_method_in_thread(url, data, session)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 723, in _execute_handler_method_in_thread
    result = thread.execute(run_func, kw=keyword_args)
  File "/opt/ankisyncd/ankisyncd/thread.py", line 79, in execute
    raise ret
  File "/opt/ankisyncd/ankisyncd/thread.py", line 98, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/opt/ankisyncd/ankisyncd/collection.py", line 45, in execute
    ret = func(*args, **kw)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 714, in run_func
    res = handler_method(**keyword_args)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 152, in sanityCheck2
    return dict(status, c=client, s=server)
ValueError: dictionary update sequence element #0 has length 1; 2 is required
[2021-09-13 16:42:46,772]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/sanityCheck2 HTTP/1.1" 500 59
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 626, in __call__
    raise HTTPNotFound()
webob.exc.HTTPNotFound: The resource could not be found.
[2021-09-13 16:42:46,815]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/abort HTTP/1.1" 500 59
[2021-09-13 16:42:57,815]:INFO:ankisyncd.http:127.0.0.1 "GET / HTTP/1.1" 200 16
[2021-09-13 16:43:27,991]:INFO:ankisyncd.http:127.0.0.1 "GET / HTTP/1.1" 200 16

@marzzzello
Copy link
Contributor

I also get this error:

[2021-09-13 18:46:26,074]:INFO:ankisyncd.CollectionThread[marzzzello]:Running meta(*[], **{'v': 10, 'cv': 'ankidroid,2.15.6,android:11:GM1917'})
[2021-09-13 18:46:26,082]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/meta HTTP/1.1" 200 150
[2021-09-13 18:46:26,303]:INFO:ankisyncd.CollectionThread[marzzzello]:Running start(*[], **{'minUsn': 72, 'lnewer': False, 'graves': {'cards': [], 'notes': [], 'decks': []}})
[2021-09-13 18:46:26,306]:ERROR:ankisyncd.CollectionThread[marzzzello]:Unable to start(*[], **{'minUsn': 72, 'lnewer': False, 'graves': {'cards': [], 'notes': [], 'decks': []}}): 'DeckManager' object has no attribute 'remove'
Traceback (most recent call last):
  File "/opt/ankisyncd/ankisyncd/thread.py", line 98, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/opt/ankisyncd/ankisyncd/collection.py", line 45, in execute
    ret = func(*args, **kw)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 714, in run_func
    res = handler_method(**keyword_args)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 130, in start
    self.apply_graves(graves,self.maxUsn)
  File "/opt/ankisyncd/ankisyncd/sync.py", line 233, in apply_graves
    self.col.decks.remove(graves['decks'])
AttributeError: 'DeckManager' object has no attribute 'remove'
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 653, in __call__
    result = self._execute_handler_method_in_thread(url, data, session)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 723, in _execute_handler_method_in_thread
    result = thread.execute(run_func, kw=keyword_args)
  File "/opt/ankisyncd/ankisyncd/thread.py", line 79, in execute
    raise ret
  File "/opt/ankisyncd/ankisyncd/thread.py", line 98, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/opt/ankisyncd/ankisyncd/collection.py", line 45, in execute
    ret = func(*args, **kw)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 714, in run_func
    res = handler_method(**keyword_args)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 130, in start
    self.apply_graves(graves,self.maxUsn)
  File "/opt/ankisyncd/ankisyncd/sync.py", line 233, in apply_graves
    self.col.decks.remove(graves['decks'])
AttributeError: 'DeckManager' object has no attribute 'remove'
[2021-09-13 18:46:26,340]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/start HTTP/1.1" 500 59
[2021-09-13 18:46:35,434]:INFO:ankisyncd.CollectionThread[marzzzello]:Running meta(*[], **{'v': 10, 'cv': 'ankidroid,2.15.6,android:11:GM1917'})

@dobefore
Copy link
Contributor Author

dobefore commented Sep 14, 2021

thanks for pointing out these constructive matters.

after more debuging,server code sync normally.Tested in version 2.1.44,46,47 On Windows and 2.15.6 on Ankidroid,especially full-upload and full-download

in order to enjoy this, some advice hope to be taken:
1.make sure anki dependency/module is set to 2.1.46
2.a reverse proxy is of no use,so kill it

if there are also issues about the server,feel free to post!

@dobefore
Copy link
Contributor Author

there is still some problems about sync with a bulk of media , the progress is not yet finished

@dobefore
Copy link
Contributor Author

after revising parse request code,this time server support multi-deck,importing .colpkg,.apkg file syncing

@marzzzello
Copy link
Contributor

marzzzello commented Sep 16, 2021

It mostly works good now.
The only problem I have is that AnkiDroid only works with full sync. The desktop version works fine also fails sometimes.

The server logs this error for AnkiDroid:

[2021-09-16 23:03:56,834]:INFO:ankisyncd.CollectionThread[marzzzello]:Running meta(*[], **{'v': 10, 'cv': 'ankidroid,2.15.6,android:11:GM1917'})
[2021-09-16 23:03:56,844]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/meta HTTP/1.1" 200 150
[2021-09-16 23:03:57,142]:INFO:ankisyncd.CollectionThread[marzzzello]:Running start(*[], **{'minUsn': 76, 'lnewer': True, 'graves': {'cards': [], 'notes': [], 'decks': []}})
[2021-09-16 23:03:57,144]:ERROR:ankisyncd.CollectionThread[marzzzello]:Unable to start(*[], **{'minUsn': 76, 'lnewer': True, 'graves': {'cards': [], 'notes': [], 'decks': []}}): 'DeckManager' object has no attribute 'remove'
Traceback (most recent call last):
  File "/opt/ankisyncd/ankisyncd/thread.py", line 98, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/opt/ankisyncd/ankisyncd/collection.py", line 45, in execute
    ret = func(*args, **kw)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 720, in run_func
    res = handler_method(**keyword_args)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 125, in start
    self.apply_graves(graves,self.maxUsn)
  File "/opt/ankisyncd/ankisyncd/sync.py", line 233, in apply_graves
    self.col.decks.remove(graves['decks'])
AttributeError: 'DeckManager' object has no attribute 'remove'
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 659, in __call__
    result = self._execute_handler_method_in_thread(url, data, session)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 729, in _execute_handler_method_in_thread
    result = thread.execute(run_func, kw=keyword_args)
  File "/opt/ankisyncd/ankisyncd/thread.py", line 79, in execute
    raise ret
  File "/opt/ankisyncd/ankisyncd/thread.py", line 98, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/opt/ankisyncd/ankisyncd/collection.py", line 45, in execute
    ret = func(*args, **kw)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 720, in run_func
    res = handler_method(**keyword_args)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 125, in start
    self.apply_graves(graves,self.maxUsn)
  File "/opt/ankisyncd/ankisyncd/sync.py", line 233, in apply_graves
    self.col.decks.remove(graves['decks'])

For Anki desktop this error appears:

[2021-09-16 23:04:38,468]:INFO:ankisyncd.CollectionThread[marzzzello]:Running begin(*[], **{'skey': 'cd46a106'})
[2021-09-16 23:04:38,482]:INFO:ankisyncd.http:172.24.1.17 "GET /msync/begin?k=424e6d89093126118cbdcc4e4a608495&v=anki%2C2.1.47+%28dc156f34%29%2Clin%3Aarch%3Arolling HTTP/1.1" 200 53
[2021-09-16 23:04:38,489]:INFO:ankisyncd.CollectionThread[marzzzello]:Running meta(*[], **{'v': 10, 'cv': 'anki,2.1.47 (dc156f34),lin:arch:rolling'})
[2021-09-16 23:04:38,492]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/meta HTTP/1.1" 200 150
[2021-09-16 23:04:38,527]:INFO:ankisyncd.CollectionThread[marzzzello]:Running start(*[], **{'minUsn': 76, 'lnewer': False, 'graves': None})
[2021-09-16 23:04:38,528]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/start HTTP/1.1" 200 39
[2021-09-16 23:04:38,556]:INFO:ankisyncd.CollectionThread[marzzzello]:Running applyChanges(*[], **{'changes': {'models': [], 'decks': [[], []], 'tags': []}})
[2021-09-16 23:04:38,568]:ERROR:ankisyncd.CollectionThread[marzzzello]:Unable to applyChanges(*[], **{'changes': {'models': [], 'decks': [[], []], 'tags': []}}): 'Collection' object has no attribute 'all_config'
Traceback (most recent call last):
  File "/opt/ankisyncd/ankisyncd/thread.py", line 98, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/opt/ankisyncd/ankisyncd/collection.py", line 45, in execute
    ret = func(*args, **kw)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 720, in run_func
    res = handler_method(**keyword_args)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 133, in applyChanges
    lchg = self.changes()
  File "/opt/ankisyncd/ankisyncd/sync.py", line 76, in changes
    d['conf'] = json.loads(self.col.all_config())
AttributeError: 'Collection' object has no attribute 'all_config'
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 659, in __call__
    result = self._execute_handler_method_in_thread(url, data, session)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 729, in _execute_handler_method_in_thread
    result = thread.execute(run_func, kw=keyword_args)
  File "/opt/ankisyncd/ankisyncd/thread.py", line 79, in execute
    raise ret
  File "/opt/ankisyncd/ankisyncd/thread.py", line 98, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/opt/ankisyncd/ankisyncd/collection.py", line 45, in execute
    ret = func(*args, **kw)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 720, in run_func
    res = handler_method(**keyword_args)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 133, in applyChanges
    lchg = self.changes()
  File "/opt/ankisyncd/ankisyncd/sync.py", line 76, in changes
    d['conf'] = json.loads(self.col.all_config())
AttributeError: 'Collection' object has no attribute 'all_config'
[2021-09-16 23:04:38,570]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/applyChanges HTTP/1.1" 500 59
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 632, in __call__
    raise HTTPNotFound()
webob.exc.HTTPNotFound: The resource could not be found.
[2021-09-16 23:04:38,601]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/abort HTTP/1.1" 500 59

@dobefore
Copy link
Contributor Author

dobefore commented Sep 17, 2021

thanks for your testing!

AttributeError: 'DeckManager' object has no attribute 'remove'
AttributeError: 'Collection' object has no attribute 'all_config'

issues like those are caused by anki module upgrade.

would you mind updating anki module by using pip?
pip install anki==2.1.46
and restarting server

@marzzzello
Copy link
Contributor

Ok, I was on anki 2.1.40 on the server because that's defined here https://github.com/ankicommunity/anki-sync-server/blob/develop/src/requirements.txt#L4

After upgrading the other errors are gone. But now I have this error (it also came up for AnkiDroid):

[2021-09-17 12:53:22,490]:INFO:ankisyncd.CollectionThread[marzzzello]:Running meta(*[], **{'v': 10, 'cv': 'anki,2.1.46 (94913ec2),lin:arch:rolling'})
[2021-09-17 12:53:22,492]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/meta HTTP/1.1" 200 150
[2021-09-17 12:53:22,521]:INFO:ankisyncd.CollectionThread[marzzzello]:Running start(*[], **{'minUsn': 76, 'lnewer': False, 'graves': None})
[2021-09-17 12:53:22,523]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/start HTTP/1.1" 200 39
[2021-09-17 12:53:22,545]:INFO:ankisyncd.CollectionThread[marzzzello]:Running applyChanges(*[], **{'changes': {'models': [], 'decks': [[], []], 'tags': []}})
[2021-09-17 12:53:22,668]:ERROR:ankisyncd.CollectionThread[marzzzello]:Unable to applyChanges(*[], **{'changes': {'models': [], 'decks': [[], []], 'tags': []}}): the JSON object must be str, bytes or bytearray, not dict
Traceback (most recent call last):
  File "/opt/ankisyncd/ankisyncd/thread.py", line 98, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/opt/ankisyncd/ankisyncd/collection.py", line 45, in execute
    ret = func(*args, **kw)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 720, in run_func
    res = handler_method(**keyword_args)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 133, in applyChanges
    lchg = self.changes()
  File "/opt/ankisyncd/ankisyncd/sync.py", line 76, in changes
    d['conf'] = json.loads(self.col.all_config())
  File "/usr/local/lib/python3.9/json/__init__.py", line 339, in loads
    raise TypeError(f'the JSON object must be str, bytes or bytearray, '
TypeError: the JSON object must be str, bytes or bytearray, not dict
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 659, in __call__
    result = self._execute_handler_method_in_thread(url, data, session)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 729, in _execute_handler_method_in_thread
    result = thread.execute(run_func, kw=keyword_args)
  File "/opt/ankisyncd/ankisyncd/thread.py", line 79, in execute
    raise ret
  File "/opt/ankisyncd/ankisyncd/thread.py", line 98, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/opt/ankisyncd/ankisyncd/collection.py", line 45, in execute
    ret = func(*args, **kw)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 720, in run_func
    res = handler_method(**keyword_args)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 133, in applyChanges
    lchg = self.changes()
  File "/opt/ankisyncd/ankisyncd/sync.py", line 76, in changes
    d['conf'] = json.loads(self.col.all_config())
  File "/usr/local/lib/python3.9/json/__init__.py", line 339, in loads
    raise TypeError(f'the JSON object must be str, bytes or bytearray, '
TypeError: the JSON object must be str, bytes or bytearray, not dict
[2021-09-17 12:53:22,716]:INFO:ankisyncd.http:172.24.1.17 "POST /sync/applyChanges HTTP/1.1" 500 59
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "/opt/ankisyncd/ankisyncd/sync_app.py", line 632, in __call__
    raise HTTPNotFound()
webob.exc.HTTPNotFound: The resource could not be found.

@dobefore
Copy link
Contributor Author

thanks for rasing it. problem solved

@marzzzello
Copy link
Contributor

What needs to be done to get this merged?

@dobefore
Copy link
Contributor Author

dobefore commented Dec 11, 2021

thanks for your concern.The reasons may be as follows:

  1. less battletested
  2. may bring breaking changes
  3. need more programming skills to make it more modulized
    and etc. I hope this can be kept as a draft and provide users an alternative to begin their vovage.

@bitsf
Copy link

bitsf commented Dec 12, 2021

I tested it with latest version

  1. patch with this PR
  2. upgrade Anki module to 2.1.49 in requirements.txt
  3. use anki desktop 2.1.49
  4. use anki droid 2.15.6 (need setup https proxy for anki server)

@marzzzello
Copy link
Contributor

I tested it with latest version

1. patch with this PR
2. upgrade Anki module to 2.1.49 in requirements.txt
3. use anki desktop 2.1.49
4. use anki droid 2.15.6 (need setup https proxy for anki server)

I set it up the same way and it worked fine too.
But now I replaced the python sync server with the new sync server written in rust:
https://github.com/ankicommunity/anki-sync-server-rs

@VikashKothary VikashKothary marked this pull request as draft December 13, 2021 19:04
@VikashKothary
Copy link
Member

VikashKothary commented Dec 13, 2021

I'm going to mark this as draft: since it seems like it's not ready to be merged? Feel free to change it back when ready @dobefore.

That being said, it's okay if it's not 100% battle tested, that's what the develop branch is for. I can also cut a release before merging this PR if instability is a major concern.

@dobefore
Copy link
Contributor Author

dobefore commented Feb 2, 2022

change log:
make as small changes to SyncApp.call layout as possible: imitate decorator wsgiref and change to decorator chunked

@VikashKothary ,ready to be merged

@dobefore dobefore marked this pull request as ready for review February 2, 2022 10:43
Copy link
Member

@VikashKothary VikashKothary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job with this. It's a really big win because it makes the web server optional.

I've just left some comments to improve the clarity and maintainability of the code. But once that's done, it should be good to go. I can also see you've already got users testing it which is great.

@dobefore
Copy link
Contributor Author

dobefore commented Feb 4, 2022

@VikashKothary ,there are still some cases which we need to use reverse proxies to forward requests,for example,we want to make secure connection and set certicate.Could you have a look at readme and make a revision?

@VikashKothary VikashKothary self-requested a review February 6, 2022 14:18
@VikashKothary VikashKothary merged commit 16fbf6e into ankicommunity:develop Mar 8, 2022
@VikashKothary
Copy link
Member

Thank you so much for your hard work @dobefore. It's good to see this feature merged.

Thank you to @marzzzello and @bitsf for testing out this new feature. It's always appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants