Coder Social home page Coder Social logo

anki-sync-server's People

Contributors

agrueneberg avatar antonofthewoods avatar dsnopek avatar gzz2000 avatar jdoe9910 avatar ospalh avatar reivilibre avatar tsudoko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

anki-sync-server's Issues

Easier installation with setuptools (or similar)

Would it be possible to create a setup file (setuptools) to make installing this easier?

I'm looking at the README and the instructions seem to skip a few steps. How can one run $ python -m ankisyncd if those files are still in the local directory? Should I manually copy it into my Python site-packages directory? Where should I put the ankisyncctl.py and ankisyncd.conf files?

Long media sync times

Is anyone noticing a long sync time for media changes, for those of you who have a large collection? It's 15 minutes on my end. Sometimes it fails, so I have to resync and wait another 15 min, etc.

To reproduce the issue, simply have a large media collection (I have 40k files), make some media changes, and then sync.

I'm not sure if the issue is on the side of AnkiDroid or ankisyncd, just my observations.

need a "for dummy" instruction

as a complete novice of Linux, really want build my own anki sync server, but just can't get a clue on building one that really works. I have searched tons of internet instructions, tried thousands of ways, spent days of hard working, still can get it done!
Would anyone bother to write an instruction for absolute dummies like me? Please!
OS: Ubuntu 16.04

windows anki: the password is not correct

ankidroid is no problem when upload or down load from anki-sync-server. but when i want to uplaod or download data from anki-sync-server, then windows anki always pop up the tooltip 'the password is not correct'. I have no idea about this.
it is more instresting that , if the acount is registed on the anki web, there are no problem to sync data. but the data was backup on the anki web, even though you have created the same acount by the command './ankisyncctl.py username'.
however, if the acount is build by command './ankisyncctl.py adduser username' and is not registed on the anki web, when you sync data , it will pop up the tooltip 'the password is not correct'. I am sure the password is correct, if not i can't sync data for ankidroid.
please give me a hand, thank you. @tsudoko .

no such table: auth

I followed the instruction of this bolg, and install all the dependencies, But still come out of this error when I want to create a new user. How can I fix this?

sudo python3 ./ankisyncctl.py adduser test
Enter password for test:    
Traceback (most recent call last):   
  File "./ankisyncctl.py", line 82, in <module>   
    main()   
  File "./ankisyncctl.py", line 74, in main   
    cmds[c](arg)   
  File "./ankisyncctl.py", line 25, in adduser   
    user_manager.add_user(username, password)   
  File "/home/junyu/anki-sync-server/ankisyncd/users.py", line 108, in add_user   
    self._add_user_to_auth_db(username, password)   
  File "/home/junyu/anki-sync-server/ankisyncd/users.py", line 125, in _add_user_to_auth_db   
    (username, pass_hash))   
sqlite3.OperationalError: no such table: auth   

AnkiDroid: Error syncing media data

I am trying to synchronize with anki-sync-server for the first time, the collections have been synchronized with AnkiWeb before.
I get Error syncing media data org.json.JSONException: Value Anki of type java.lang.String cannot be converted to JSONObject.

two problem I encountered during my use

it may be a long passage if I write it down. In order to visualize it, I recorded it to a video, and the test collection file is also attached within the zip package.

the first issue is about the account. If I delete the user in server without deauthorizing the account in the client, the client will still be able to use this deleted account to sync.

the second issue, my friend gave me a large collection pkg, it's a little bit big, which includes about 7000 media files , when I import the pkg, and then sync, even if I checked the database, the sync would probably fail and causing jam in the server, which will block other clients' connection to the anki-sync-server.

https://send.firefox.com/download/6526c14ca6/#vWJu0mvCc-Cp78FbdfLwog
(This link will not funtion after 24 hours)

AnkiDroid Syncing error 404

Anki Desktop 2.1.14
AnkiDroid 2.8.4

I am using anki sync server behind a NGINX reverse proxy.
My setup works with the Anki desktop client with the SyncRedirector Add-on and the following URLs defined:

{
    "msyncUrl": "http://ankisync.my-domain.org/msync/",
    "syncUrl": "http://ankisync.my-domain.org/sync/"
}

It also works via local network with the IP configured directly:

{
    "msyncUrl": "http://192.168.0.x:27701/msync/",
    "syncUrl": "http://192.168.0.x/sync/"
}

However, I tried both variants with and without a trailing slash at the end of the URL and get the following error with all configurations:

Syncing error, type: 404, message: Not Found

Accessing http://ankisync.my-domain.org/ via mobile web browser displays Anki Sync Server correctly.

I'd be grateful for hints on how to debug this issue further.

ankiserver.pid NOT Found but can ankiserverctl.py in debug mode.

C:\Python34\Scripts>python ankiserverctl.py start
Traceback (most recent call last):
File "ankiserverctl.py", line 165, in
main()
File "ankiserverctl.py", line 145, in main
startsrv(sys.argv[2], False)
File "ankiserverctl.py", line 50, in startsrv
with open(PIDPATH, "w") as pidfile:
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/ankiserver.pid'

Reorganise code to better support extensibility

I'm back again :-). Thanks again for your amazing work on keeping things compatible with the clients! The nasty hacks I talked about in #7 for exposing some user data in a rest-y way turned out to not even scale to one person - I need to totally hammer the API for periods - performance was slow, and the wsgiref started resetting connections after I put it in a container with even moderate load for one user.

That got me thinking - I don't really want to have the hassle of thinking about API performance when all I really want is access to the data. So I decided to implement support for Postgres, meaning the endpoints where performance is critical I can just access the data directly, and all the rest can stay the same.

You mentioned you would be happy to look at some reorganisation PRs to make that easier. What would you say to moving out the SessionManagers (like the UserManagers) into separate modules, adding a PersistenceManager (for managing sqlite3 upload/download) and the creating factory methods for each that will mirror the same behaviour as now but also also potentially dynamically load child classes specified in the config file?

That would mean I could just plop an extra module or two in, add a few lines to the config file and it will Just Work.

If you're interested in Postgres support we could also discuss that, but I'm only half way through and there are already some pretty nasty hacks I need to do to override anki stuff so don't expect anything particularly beautiful :-).

Thanks again for your awesome work on this!

Anki 2.1 ignores mysyncserver.py

With the latest beta (beta 26), Anki will ignore mysyncserver.py if you leave it in the addons21 folder.

https://apps.ankiweb.net/docs/addons21.html

I followed the instructions and got it working:

  1. Create a folder in addons21, name it anything you want
  2. Within that folder create a file called __init__.py
  3. Inside __init__.py, enter the following lines:
import anki.sync
anki.sync.SYNC_BASE = 'http://127.0.0.1:27701/'
anki.sync.SYNC_MEDIA_BASE = 'http://127.0.0.1:27701/msync/'

After doing this, I'm able to sync.

There are still some issues though. Anki wants to keep doing full syncs and oftentimes says that the database is in an inconsistent state.

Installation guide for Anki 2.1 (desktop) unclear

The readme.md sounds like one only needs to place the displayed __init__.py in one folder. The code apparently has a bug anki.sync.SYNC_BASE = "%s" + addr %s will be the string %s and not formatted.
But then why does the "anki-sync-server/addon/" folder exist? Are there supposed to be two folders? Why are they not integrated in one addon?

SQLite code does not use context manager

Instead of

conn = self._conn()
cursor = conn.cursor()
cursor.execute(<some sql>)
conn.commit()

we can do:

conn = self._conn()
with conn:
    conn.execute(<some sql>)

which also handles rollbacks. Would you accept a PR to this effect?

Anki like webpage possible?

Hello! I am a beginner, but I would like to setup Anki Server. Is it possible to set up an Anki like website? And will the addons be still available from the main source at the Anki webpage? thank you! andreas

Some missing things?

I have no idea how many things I've done right and how many wrong. I'm definitely an amatour.
What is not working here?

PS C:\Users\xxx\Desktop\Anki_sync\anki-sync-server> python -m ankisyncd
Traceback (most recent call last):
File "C:\Users\xxx\AppData\Local\Programs\Python\Python38\lib\runpy.py", line 193, in _run_module_as_main return _run_code(code, main_globals, None,
File "C:\Users\xxx\AppData\Local\Programs\Python\Python38\lib\runpy.py", line 86, in _run_code exec(code, run_globals)
File "C:\Users\xxx\Desktop\Anki_sync\anki-sync-server\ankisyncd\__main__.py", line 8, in <module> import ankisyncd.sync_app
File "C:\Users\xxx\Desktop\Anki_sync\anki-sync-server\ankisyncd\sync_app.py", line 37, in <module> import anki.db ModuleNotFoundError: No module named 'anki.db'

Also feel free to change the title as I'm not sure what I should've put there.

6500kb limited, a strange phenomenon

I upload my data normally until it reachs 6500kb. Whether it is anki2.0 or anki2.1.8, it always fails to upload when the data has already uploaded 6500kb.
server: centos 7 python3.6

Local server data is not cleared

After deleting the PC version of Anki data, sync the private server again, it shows that the synchronization is correct, but the private server data is not cleared

Environmental description:
os: Windows7
PC anki version: 2.1.20
Python version :3.6

Invalid syntax when running sync_app

Hi!

I'm trying to get this working with python3 (adduser function won't work with python2) but I got stuck on last step while running python3 ankisyncd/sync_app.py ankisyncd.conf (i'm using master branch):

File "ankisyncd/sync_app.py", line 116
    print(f"applyGraves chunk: {chunk}")
                                      ^
SyntaxError: invalid syntax

With python2 I get the same error.
I tried to comment out that line or removing that f after print( (I don't know about python at all, so I did it just to try) and I got this:

Traceback (most recent call last):
  File "ankisyncd/sync_app.py", line 36, in <module>
    import anki.db
ImportError: No module named 'anki'

Thanks a lot!

Adding Docker support

I have created a Docker image based on your work sometime before and I am curious if it could be merged or linked to your repository to centralise our efforts as one of your contributors suggested:
kuklinistvan/docker-anki-sync-server#2

Also, I'd like to say thank you to you for maintaining ankisyncd as well as to all the contributors!

Could we know how to stop the anki-server?

Sometimes anki-server may encounter some accidental bug causing no connection, and I need to restart it, but there is no command to stop the server. So I can only kill it or reboot the Linux. Is there a python command can stop or restart the server?

AssertionError in _adopt_media_changes_from_zip

I am operating on 3b8fe9e

I encountered an AssertionError while attempting to push some media changes from Anki (2.1.15 and 2.1.19) on Ubuntu. As part of that process, ankisyncd is being requested to delete some media files which do not currently exist in the collection.media directory. This triggers the AssertionError on assert self.col.media.lastUsn() == oldUsn + processed_count

To help debug, I added some print statements to the immediately-preceding code:

# We count all files we are to remove, even if we don't have them in
# our media directory and our db doesn't know about them.
processed_count = len(media_to_remove) + len(media_to_add)

assert len(meta) == processed_count  # sanity check

print(f'==== POINT A :: usn={usn}, oldUsn={oldUsn}, len(meta)==processed_count=={processed_count}', file=sys.stderr)
if media_to_remove:
    print(f'==== Removing media: {repr(media_to_remove)}', file=sys.stderr)
    self._remove_media_files(media_to_remove)

if media_to_add:
    print(f'==== Adding media: {repr(media_to_add)}', file=sys.stderr)
    self.col.media.db.executemany(
        "INSERT OR REPLACE INTO media VALUES (?,?,?)", media_to_add)
    self.col.media.db.commit()

print(f'==== POINT B :: lastUsn()={self.col.media.lastUsn()}, oldUsn={oldUsn}, processed_count={processed_count}', file=sys.stderr)
assert self.col.media.lastUsn() == oldUsn + processed_count  # TODO: move to some unit test
return processed_count

The output is as follows:

[2020-01-22 16:48:18,298]:INFO:ankisyncd.CollectionThread[yq-class-Z1]:Starting...
[2020-01-22 16:48:18,299]:INFO:ankisyncd.CollectionThread[yq-class-Z1]:Running meta(*[], **{'v': 9, 'cv': 'ankidesktop,2.1.15 (442df9d6),lin:ubuntu:18.04'})
[2020-01-22 16:48:18,312]:INFO:ankisyncd.http:127.0.0.1 "POST /sync/meta HTTP/1.0" 200 112
[2020-01-22 16:48:20,560]:INFO:ankisyncd.CollectionThread[yq-class-Z1]:Running operation_upload(*[b'SQLite format 3\x00\x10\x00\x01\x01\x00@  \x00\x00\x00\xc4\x00\x00\x00\x81\x00\x00\x00\x0f\x00\x00\x00\x01\x00\x00\x00\x18\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00...', <__main__.SyncUserSession object at 0x7ff9be98deb8>], **{})
[2020-01-22 16:48:20,573]:INFO:ankisyncd.http:127.0.0.1 "POST /sync/upload HTTP/1.0" 200 2
[2020-01-22 16:48:20,630]:INFO:ankisyncd.CollectionThread[yq-class-Z1]:Running begin(*[], **{'skey': '7ca4d999'})
[2020-01-22 16:48:20,631]:INFO:ankisyncd.http:127.0.0.1 "POST /msync/begin HTTP/1.0" 200 52
[2020-01-22 16:48:20,682]:INFO:ankisyncd.CollectionThread[yq-class-Z1]:Running mediaChanges(*[], **{'lastUsn': 1347})
[2020-01-22 16:48:20,683]:INFO:ankisyncd.http:127.0.0.1 "POST /msync/mediaChanges HTTP/1.0" 200 23
[2020-01-22 16:48:20,742]:INFO:ankisyncd.CollectionThread[yq-class-Z1]:Running uploadChanges(*[], **{'data': b'PK\x03\x04\x14\x00\x00\x00\x08\x00\n\x866P\xec[G\xf9\r\x01\x00\x00R\x03\x00\x00\x05\x00\x00\x00_metauR\xcbj\xc3@\x0c\xfc\x95\xe0s\x08\x92f\xa4]}K\x08:\x06\n\x85\xfc\xff\xa9\xb2K\xa1\xe0\xf5Y\xc3<\xf5|n&:T\xc5U\x14\x82R...'})
==== POINT A :: usn=1347, oldUsn=1347, len(meta)==processed_count==25
==== Removing media: ['20171105101303_14010.jpg', '20180302112534_42967.mp3', '20180301160604_88997.mp3', '20180302133019_27990.mp3', '20180416092356_40344.jpg', '20171030214910_26553.jpg', '20180302092239_46576.mp3', '20180227113121_59562.mp3', '20180302101241_19948.mp3', '20180227115011_64478.mp3', '20171110165954_33939.jpg', '20180604115213_14556.mp3', '20180227141910_86300.mp3', '20180302112109_54634.mp3', '20171104220557_42406.jpg', '20180227165103_57636.mp3', '20180301150503_63690.mp3', '20180301155325_64802.mp3', '20180227094943_28410.mp3', '20171121221705_63044.jpg', '20180227113240_97547.mp3', '20180227145848_50959.mp3', '20180227133215_10335.mp3', '20171105113357_96684.jpg', '20180301142836_52352.mp3']
==== POINT B :: lastUsn()=1347, oldUsn=1347, processed_count=25
[2020-01-22 16:48:20,746]:ERROR:ankisyncd.CollectionThread[yq-class-Z1]:Unable to uploadChanges(*[], **{'data': b"PK\x03\x04\x14\x00\x00\x00\x08\x00\n\x866P\xec[G\xf9\r\x01\x00\x00R\x03\x00\x00\x05\x00\x00\x00_metauR\xcbj\xc3@\x0c\xfc\x95\xe0s\x08\x92f\xa4]}K\x08:\x06\n\x85\xfc\xff\xa9\xb2K\xa1\xe0\xf5Y\xc3<\xf5|n&:T\xc5U\x14\x82R\x8a\xca\xe3\xeb\xf3\xde\xee\xb7m{\xddo\x07b\n\xc4T\xcd\xc1\xa2e\x8c\xc7\xf7\x07'\x84jH\x08k\xce\xcc5\xc2\x14\r\xcb\xb2\x91)\x0b\x04\x9b!\r\x1eE\x01y\xf21\xf4 a\xaa\x94\x85;\xd6N\x9b\xc3\x90\xc5\xf0\x11\x0b\x15\xb3N\x0c5-O\x0f\xbbp*j\xd4\xd2L\xce+\x0e\xef\xc8\x15\xe48#\xfa\xda\x0c\xd1\x02, \x91\x0b\xa7\xddUst'\xdd\xba\xfb\x95S\xea\x9ev\x06d\xd5\xd8\xef.*Y\xce\x00W>\x84f\xe2>z9J,|\xec*\xd1\x0f\x80\xea\xbe\xb0\xf2\xb1o\xeb\xe2\x8d\xe8\xfbr\xb9\x03\xe10\xef>\x9aq\x9dE\x92I\x94M\xea\x99c\xec9\xcctHs@\x16\xeb\xff-\xd71*\x87s\xf5cGc>9\xcb%=/\x10\x80\xa9W'\x86/\x1b\xf3VA7\x96\x11s\xe5cOK\x9b\x88\xf2\xfe\xd6\x7fi_?PK\x01\x02\x14\x03\x14\x00\x00\x00\x08\x00\n\x866P\xec[G\xf9\r\x01\x00\x00R\x03\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x00\x00_metaPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x003\x00\x00\x000\x01\x00\x00\x00\x00"}): 
Traceback (most recent call last):
  File "/home/anki/src/anki-sync-server/ankisyncd/thread.py", line 98, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/home/anki/src/anki-sync-server/ankisyncd/collection.py", line 46, in execute
    ret = func(*args, **kw)
  File "ankisyncd/sync_app.py", line 622, in run_func
    res = handler_method(**keyword_args)
  File "ankisyncd/sync_app.py", line 197, in uploadChanges
    processed_count = self._adopt_media_changes_from_zip(z)
  File "ankisyncd/sync_app.py", line 272, in _adopt_media_changes_from_zip
    assert self.col.media.lastUsn() == oldUsn + processed_count  # TODO: move to some unit test
AssertionError
Traceback (most recent call last):
  File "/usr/lib/python3.6/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "/home/anki/.local/lib/python3.6/site-packages/webob/dec.py", line 129, in __call__
    resp = self.call_func(req, *args, **kw)
  File "/home/anki/.local/lib/python3.6/site-packages/webob/dec.py", line 193, in call_func
    return self.func(req, *args, **kwargs)
  File "ankisyncd/sync_app.py", line 599, in __call__
    result = self._execute_handler_method_in_thread(url, data, session)
  File "ankisyncd/sync_app.py", line 631, in _execute_handler_method_in_thread
    result = thread.execute(run_func, kw=keyword_args)
  File "/home/anki/src/anki-sync-server/ankisyncd/thread.py", line 79, in execute
    raise ret
  File "/home/anki/src/anki-sync-server/ankisyncd/thread.py", line 98, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/home/anki/src/anki-sync-server/ankisyncd/collection.py", line 46, in execute
    ret = func(*args, **kw)
  File "ankisyncd/sync_app.py", line 622, in run_func
    res = handler_method(**keyword_args)
  File "ankisyncd/sync_app.py", line 197, in uploadChanges
    processed_count = self._adopt_media_changes_from_zip(z)
  File "ankisyncd/sync_app.py", line 272, in _adopt_media_changes_from_zip
    assert self.col.media.lastUsn() == oldUsn + processed_count  # TODO: move to some unit test
AssertionError
[2020-01-22 16:48:20,752]:INFO:ankisyncd.http:127.0.0.1 "POST /msync/uploadChanges HTTP/1.0" 500 59

The actual collection.media directory contains exactly the 1347 files which it would be expected to contain after a successful sync. The media_to_remove (such as 20180301160604_88997.mp3) do exist under other users but not this user (yq-class-Z1).

Note that I've reproduced this every time that I try to sync, but the first time it failed there were not yet any debug print statements, so I don't have debug output from the first time it occurred.

Interestingly, I also see the same error when attempting to pull (force a download sync) from the server.

I am happy to help debug this if there's anything I can do to assist. anki-sync-server is a core piece of our infrastructure and I really appreciate your work on it.

Checking database while having freshly added cards in a deck causes inconsistency

Hey tsudoku,

I am not sure if I should this report to you or directly to the developers of Anki Desktop, but I have encountered an interesting behavior that can break syncing, while I was about to update the image to support the latest version of Anki.

Anki Desktop version: 2.1.14
ankisyncd version: 7ef3d4f on master

Reproduction:

  1. Set up ankisyncd and point an Anki Desktop instance to it

  2. Create a deck and some cards, maybe manipulate them

  3. Synchronize making sure it works at this point

  4. Ensure that you have at least one completely fresh, unreviewed card
    It should look as follows in the browser:
    due1000000

  5. Synchronize again - it should still work

  6. BREAK IT: Hit Check datatabase...

A message similar to this one should appear:
Found 1 new cards with a due number >= 1,000,000 - consider repositioning them in the Browse screen.
Database rebuilt and optimized.

  1. Sync again - now it is broken
    inconsistent

The server output does not seem to contain too much useful information at the very moment this message appears on the client side:

[2019-07-08 12:31:20,928]:INFO:ankisyncd.CollectionThread[sajat_anki]:Running meta(*[], **{'v': 9, 'cv': 'ankidesktop,2.1.14 (7b93e985),lin:arch:rolling'})
[2019-07-08 12:31:20,930]:INFO:ankisyncd.http:172.17.0.1 "POST /sync/meta HTTP/1.1" 200 112

What do you think, is it related to ankisyncd or should I forward this bug to the developers of Anki Desktop?

Best regards,
István

cannot run in uwsgi

Hi, i installed syn server and i was success to run it from console and sync with linux's and android's anki. But i want to serve it behind uWSGI (and latter via nginx due TLS), and deploy it in public net (to have more robust solution as python's simple server), but i encounter a problem, which i am not able to solve.

I prepared simple file for uWSGI (with some "debug" prints):

import os
from pathlib import Path
import sys

import uwsgi
import ankisyncd.config
from ankisyncd.sync_app import SyncApp
from ankisyncd.thread import shutdown

print(sys.path)

# Replace with your app's method of configuration
cfgfile  = os.environ.get('ANKI_CONFIG', Path(__file__).parent.resolve() / "ankisyncd.conf")

print("Loading config from %s" % cfgfile)
config = ankisyncd.config.load(cfgfile)

print(config)

# uWSGI will look for this variable
print("Initialize application...")
application = SyncApp(config)

def do_shutdown():
    print("Doing shutdown...")
    shutdown()

# will be invoked after uWSGI reload or shutdown
uwsgi.atexit = do_shutdown

Then i run uWSGI simple instance from anksi-sync-server's directory:

uwsgi --plugin python3,http --http :27701 --master --enable-threads --wsgi-file uwsgi.py

It basically loads application object from uwsgi.py file, which is SyncApp() object and serves it via HTTP. Apps starts nicely:

*** Starting uWSGI 2.0.18-debian (64bit) on [Sun May 12 09:57:31 2019] ***
compiled with version: 8.2.0 on 10 February 2019 02:42:46
os: Linux-4.19.0-4-amd64 #1 SMP Debian 4.19.28-2 (2019-03-15)
nodename: debmail
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 1
current working directory: /home/slavko/anki-sync-server
detected binary path: /usr/bin/uwsgi-core
your processes number limit is 1818
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on :27701 fd 4
uwsgi socket 0 bound to TCP address 127.0.0.1:40809 (port auto-assigned) fd 3
Python version: 3.7.3rc1 (default, Mar 13 2019, 11:01:15)  [GCC 8.3.0]
Python main interpreter initialized at 0x55f67b1314d0
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 145840 bytes (142 KB) for 1 cores
*** Operational MODE: single process ***
['./anki-bundled', '/usr/share/anki', '.', '', '/usr/lib/python37.zip', '/usr/lib/python3.7', '/usr/lib/python3.7/lib-dynload', '/usr/local/lib/python3.7/dist-packages', '/usr/lib/python3/dist-packages']
Loading config from /home/slavko/anki-sync-server/ankisyncd.conf
<Section: sync_app>
Initialize application...
WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x55f67b1314d0 pid: 2748 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 2748)
spawned uWSGI worker 1 (pid: 2751, cores: 1)
spawned uWSGI http 1 (pid: 2752)

Here you can see print's output (after "Operational MODE: single process" line), that paths are added into sys.path, config is loaded, and app initialized. I am able to connect to it, then it basically works:

wget -qO- --server-response http://debmail.skk:27701/
  HTTP/1.1 200 OK
  Content-Type: text/html; charset=UTF-8
  Content-Length: 16
Anki Sync Server

But when i try to sync with it, i got error about missing module anki.sched:

--- Logging error ---
Traceback (most recent call last):
  File "./ankisyncd/thread.py", line 98, in _run
  File "./ankisyncd/collection.py", line 42, in execute
  File "./ankisyncd/collection.py", line 72, in open
  File "./ankisyncd/collection.py", line 66, in _get_collection
  File "./anki-bundled/anki/storage.py", line 40, in Collection
  File "./anki-bundled/anki/collection.py", line 75, in __init__
  File "./anki-bundled/anki/collection.py", line 100, in _loadScheduler
ModuleNotFoundError: No module named 'anki.sched'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.7/logging/__init__.py", line 1034, in emit
    msg = self.format(record)
  File "/usr/lib/python3.7/logging/__init__.py", line 880, in format
    return fmt.format(record)
  File "/usr/lib/python3.7/logging/__init__.py", line 619, in format
    record.message = record.getMessage()
  File "/usr/lib/python3.7/logging/__init__.py", line 380, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
  File "/usr/lib/python3.7/threading.py", line 885, in _bootstrap
    self._bootstrap_inner()
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "./ankisyncd/thread.py", line 101, in _run
Message: 'Unable to %s(*%s, **%s): %s'
Arguments: ('/home/slavko/anki-sync-server/collections/slavko/collection.anki2', 'meta', '[]', "{'v': 9, 'cv': 'ankidesktop,2.1.8,lin:debian:buster/sid'}", ModuleNotFoundError("No module named 'anki.sched'"))
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/webob/dec.py", line 129, in __call__
    resp = self.call_func(req, *args, **kw)
  File "/usr/lib/python3/dist-packages/webob/dec.py", line 193, in call_func
    return self.func(req, *args, **kwargs)
  File "./ankisyncd/sync_app.py", line 557, in __call__
  File "./ankisyncd/sync_app.py", line 634, in _execute_handler_method_in_thread
  File "./ankisyncd/thread.py", line 79, in execute
  File "./ankisyncd/thread.py", line 98, in _run
  File "./ankisyncd/collection.py", line 42, in execute
  File "./ankisyncd/collection.py", line 72, in open
  File "./ankisyncd/collection.py", line 66, in _get_collection
  File "./anki-bundled/anki/storage.py", line 40, in Collection
  File "./anki-bundled/anki/collection.py", line 75, in __init__
  File "./anki-bundled/anki/collection.py", line 100, in _loadScheduler
ModuleNotFoundError: No module named 'anki.sched'
[pid: 2751|app: 0|req: 2/2] 192.168.10.1 () {36 vars in 465 bytes} [Sun May 12 10:00:04 2019] POST /sync/meta => generated 0 bytes in 221 msecs (HTTP/1.1 500) 0 headers in 0 bytes (0 switches on core 0)

When i run the same instance directly, all works:

python3 -m ankisyncd
[2019-05-12 10:13:55,609]:INFO:ankisyncd:Loaded config from /home/slavko/anki-sync-server/ankisyncd.conf
[2019-05-12 10:13:55,610]:INFO:ankisyncd.users:Found auth_db_path in config, using SqliteUserManager for auth
[2019-05-12 10:13:55,611]:INFO:ankisyncd.sessions:Found session_db_path in config, using SqliteSessionManager for auth
[2019-05-12 10:13:55,612]:INFO:ankisyncd:Serving HTTP on 0.0.0.0 port 27701...
[2019-05-12 10:14:01,516]:INFO:ankisyncd.CollectionThread[slavko]:Starting...
[2019-05-12 10:14:01,517]:INFO:ankisyncd.CollectionThread[slavko]:Running meta(*[], **{'v': 9, 'cv': 'ankidesktop,2.1.8,lin:debian:buster/sid'})
[2019-05-12 10:14:01,524]:INFO:ankisyncd.http:192.168.10.1 "POST /sync/meta HTTP/1.1" 200 108
[2019-05-12 10:14:41,099]:INFO:ankisyncd.CollectionThread[slavko]:Running meta(*[], **{'v': 9, 'cv': 'ankidesktop,2.1.8,lin:debian:buster/sid'})
[2019-05-12 10:14:41,100]:INFO:ankisyncd.http:192.168.10.1 "POST /sync/meta HTTP/1.1" 200 108

I really don't know, what is missing, can you please give me some tips, where to go?

sync upload error by ankidroid

when I upload data by ankidroid, then windows server throw the bellow error:

Traceback (most recent call last):
  File "C:\Python37\lib\wsgiref\handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "C:\Python37\lib\site-packages\webob\dec.py", line 129, in __call__
    resp = self.call_func(req, *args, **kw)
  File "C:\Python37\lib\site-packages\webob\dec.py", line 193, in call_func
    return self.func(req, *args, **kwargs)
  File "C:\Users\hqzxj\Documents\work\anki-sync-server\ankisyncd\sync_app.py", line 572, in __call__
    result = thread.execute(self.operation_upload, [data['data'], session])
  File "C:\Users\hqzxj\Documents\work\anki-sync-server\ankisyncd\thread.py", line 79, in execute
    raise ret
  File "C:\Users\hqzxj\Documents\work\anki-sync-server\ankisyncd\thread.py", line 98, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "C:\Users\hqzxj\Documents\work\anki-sync-server\ankisyncd\collection.py", line 44, in execute
    ret = func(*args, **kw)
  File "C:\Users\hqzxj\Documents\work\anki-sync-server\ankisyncd\sync_app.py", line 488, in operation_upload
    return self.full_sync_manager.upload(col, data, session)
  File "C:\Users\hqzxj\Documents\work\anki-sync-server\ankisyncd\full_sync.py", line 28, in upload
    os.rename(temp_db_path, session.get_collection_path())
FileExistsError: [WinError 183] Cannot create a file when that file already exists: 'C:\\Users\\hqzxj\\Documents\\work\\anki-sync-server\\srv\\anki\\ankisyncd\\hqzxjczx\\collection.anki2.tmp' -> 'C:\\Users\\hqzxj\\Documents\\work\\anki-sync-server\\srv\\anki\\ankisyncd\\hqzxjczx\\collection.anki2'

ankidroid version is 2.8.4
anki-sync-server is the master version
windows anki is 2.1.11
@tsudoko

Anki Windows 2.1.18 Failed to sync. I'm suggesting a patch

Version 2.1.18 (fb9d59fe)
Python 3.8.0 Qt 5.14.0 PyQt 5.13.2

Snipaste_2020-01-16_21-15-35

I got this error and cannot sync the changes made on my android device to my windows computer. After struggling for a while I realized that the server responded a 500. By examining the output (btw I use the docker version and a docker attach):

ERROR:root:CollectionThread[/app/data/collections/gzz/collection.anki2]: Unable to start(*[], **{}): start() got an unexpected keyword argument 'offset'
Traceback (most recent call last):
  File "/app/anki-sync-server/ankisyncd/thread.py", line 71, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/app/anki-sync-server/ankisyncd/collection.py", line 39, in execute
    ret = func(*args, **kw)
  File "/app/anki-sync-server/ankisyncd/sync_app.py", line 673, in run_func
    res = handler_method(**keyword_args)
TypeError: start() got an unexpected keyword argument 'offset'
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/wsgiref/handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "/usr/local/lib/python3.7/site-packages/webob/dec.py", line 129, in __call__
    resp = self.call_func(req, *args, **kw)
  File "/usr/local/lib/python3.7/site-packages/webob/dec.py", line 193, in call_func
    return self.func(req, *args, **kwargs)
  File "/app/anki-sync-server/ankisyncd/sync_app.py", line 605, in __call__
    result = self._execute_handler_method_in_thread(url, data, session)
  File "/app/anki-sync-server/ankisyncd/sync_app.py", line 682, in _execute_handler_method_in_thread
    result = thread.execute(run_func)
  File "/app/anki-sync-server/ankisyncd/thread.py", line 52, in execute
    raise ret
  File "/app/anki-sync-server/ankisyncd/thread.py", line 71, in _run
    ret = self.wrapper.execute(func, args, kw, return_queue)
  File "/app/anki-sync-server/ankisyncd/collection.py", line 39, in execute
    ret = func(*args, **kw)
  File "/app/anki-sync-server/ankisyncd/sync_app.py", line 673, in run_func
    res = handler_method(**keyword_args)
TypeError: start() got an unexpected keyword argument 'offset'

It seems that it is a new offset argument passed to SyncCollectionHandler.start causes the trouble. I found that it's always a None in my case so I just added it and ignored it, it just works.

    def start(self, minUsn, lnewer, graves={"cards": [], "notes": [], "decks": []}, offset=None):

Please check if you also have this problem with Anki 2.1.18. If it's the right thing to do I can make a pull request on this one-line patch.

INFO:ankisyncd.http:xxx.xxx.xxx.xxx "POST /msync//begin HTTP/1.1" 404 52

The OS was Debian 10 Buster
The python version was python3
The anki-sync-server server can be installed as the instruction as this git document description.

Android Phone: AnkiDroid version 2.9.2
Linux Laptop: Anki Version 2.1.15 (442df9d6) Qt 5.12.1 PyQt 5.11.3

'''''''''''''''''''''
result:
The anki-sync-server running as normal. And the media attachment can not be used.
The AnkiDroid v2.92 can sync with anki-sync-server as normal. except that "Sync error: Syncing error, type: 404, message: Not Found"

The linux version Anki2.1.15 can sync with anki-sync-server as normal.

'''''''''''''''''''''''''''
anki-sync-server system log:
...
INFO:ankisyncd.http:xxx.xxx.xxx.xxx "POST /sync/finish HTTP/1.1" 200 13
...
INFO:ankisyncd.http:xxx.xxx.xxx.xxx "POST /msync//begin HTTP/1.1" 404 52

'''''''''
What's your opinion on this topic?
Could you please give any idea?

Thanks!

Question: status of anki_2_1 branch

I actually do want the REST api and it looks (from the name!) like you have a branch that has been updated to 2.1 (upstream doesn't appear to be, and isn't merging useful patches...), and still contains the REST api. @tsudoko can you comment on this branch? It appears to have been updated until late last year. Is it worth starting from that to get 2.1 compatibility and the REST api? Thanks!

Public Instance

Is anyone running a public intance of this?

If not, would it not be a good idea to have one, for those who do not want to spend the time setting everything up? It could be for paid accounts only, something like 1eur/month or something.

I want to sync my anki from desktop<->android but I am not comfortable using closed source software (ankiweb) nor can I setup this server..

Lock session during sync

Only one client per session at a time should be able to sync. Starting a sync from multiple clients at the same time is generally a bad idea, it's not clear what state both clients will end up in after syncing.

Reimplementing the RESTapi

Hi everyone.
Iam trying to reimplement the RESTapi which was included in the original Anki-sync-server by dsnopek.
My programming is quite noobish, so i will proably fail. Therefore if any of you guys wants to help out please say so. Would be great to get that API up and running again.
I hope there is a supercoder out there with a little time of his/hers hands. :) :D
Cheers!!

sqlite3.OperationalError: unable to open database file

Hello,

I'm trying to get things set up using the master branch. I followed the instructions, but I'm getting stuck on step 3:

image

Here's what I've got in my ankysyncd.conf file:

image

Any thoughts on where to proceed from here?

Thanks

Ankidroid can't connect to anki-sync-server

I've setup anki-sync-server, opened the port 27701 on my router, manage to sync my laptop Anki to the server using the internet ip.
I can also access the server from my android's browser and see the message "Anki Sync Server"
But when I try syncing from the phone, it failed with the following error:

Screenshot_20200303-200008

From the readme:

AnkiDroid
Advanced → Custom sync server

Unless you have set up a reverse proxy to handle encrypted connections, use http as the protocol. The port will be either the default, 27701, or whatever you have specified in ankisyncd.conf (or, if using a reverse proxy, whatever port you configured to accept the front-end connection).

Do not use trailing slashes.

It looks like http isn't supported by default on android
https://better-coding.com/solved-android-cannot-send-data-to-the-server-cleartext-communication-to-not-permitted-by-network-security-policy/

TypeError: start() got an unexpected keyword argument 'offset'

I was testing ankisyncd against version 2.1.0 to actually use the version mentioned in README.md. Meanwhile it works fine on Android (2.9.1), on AnkiDesktop (2.1.19) I get this message on the second sync (after I have confirmed the "Download form AnkiWeb" message):
"Syncing failed:
AnkiWeb encountered an error. Please try again in a few minutes, and if the problem persists, please file a bug report."

Between the two synchronizations I reviewed exactly one card on the desktop side.

anki-sync-server_1  | [2020-02-04 17:38:52,250]:INFO:ankisyncd.http:172.20.0.1 "POST /sync/start HTTP/1.1" 500 59
anki-sync-server_1  | [2020-02-04 17:39:35,575]:INFO:ankisyncd.CollectionThread[en]:Running meta(*[], **{'v': 9, 'cv': 'ankidesktop,2.1.19 (3c8690ae),lin:arch:rolling'})
anki-sync-server_1  | [2020-02-04 17:39:35,576]:INFO:ankisyncd.http:172.20.0.1 "POST /sync/meta HTTP/1.1" 200 110
anki-sync-server_1  | [2020-02-04 17:39:35,584]:INFO:ankisyncd.CollectionThread[en]:Running start(*[], **{'minUsn': 100, 'lnewer': True, 'offset': None})
anki-sync-server_1  | [2020-02-04 17:39:35,585]:ERROR:ankisyncd.CollectionThread[en]:Unable to start(*[], **{'minUsn': 100, 'lnewer': True, 'offset': None}): start() got an unexpected keyword argument 'offset'
anki-sync-server_1  | Traceback (most recent call last):
anki-sync-server_1  |   File "/app/anki-sync-server/ankisyncd/thread.py", line 98, in _run
anki-sync-server_1  |     ret = self.wrapper.execute(func, args, kw, return_queue)
anki-sync-server_1  |   File "/app/anki-sync-server/ankisyncd/collection.py", line 44, in execute
anki-sync-server_1  |     ret = func(*args, **kw)
anki-sync-server_1  |   File "/app/anki-sync-server/ankisyncd/sync_app.py", line 626, in run_func
anki-sync-server_1  |     res = handler_method(**keyword_args)
anki-sync-server_1  | TypeError: start() got an unexpected keyword argument 'offset'
anki-sync-server_1  | Traceback (most recent call last):
anki-sync-server_1  |   File "/usr/local/lib/python3.7/wsgiref/handlers.py", line 137, in run
anki-sync-server_1  |     self.result = application(self.environ, self.start_response)
anki-sync-server_1  |   File "/usr/local/lib/python3.7/site-packages/webob/dec.py", line 129, in __call__
anki-sync-server_1  |     resp = self.call_func(req, *args, **kw)
anki-sync-server_1  |   File "/usr/local/lib/python3.7/site-packages/webob/dec.py", line 193, in call_func
anki-sync-server_1  |     return self.func(req, *args, **kwargs)
anki-sync-server_1  |   File "/app/anki-sync-server/ankisyncd/sync_app.py", line 558, in __call__
anki-sync-server_1  |     result = self._execute_handler_method_in_thread(url, data, session)
anki-sync-server_1  |   File "/app/anki-sync-server/ankisyncd/sync_app.py", line 635, in _execute_handler_method_in_thread
anki-sync-server_1  |     result = thread.execute(run_func, kw=keyword_args)
anki-sync-server_1  |   File "/app/anki-sync-server/ankisyncd/thread.py", line 79, in execute
anki-sync-server_1  |     raise ret
anki-sync-server_1  |   File "/app/anki-sync-server/ankisyncd/thread.py", line 98, in _run
anki-sync-server_1  |     ret = self.wrapper.execute(func, args, kw, return_queue)
anki-sync-server_1  |   File "/app/anki-sync-server/ankisyncd/collection.py", line 44, in execute
anki-sync-server_1  |     ret = func(*args, **kw)
anki-sync-server_1  |   File "/app/anki-sync-server/ankisyncd/sync_app.py", line 626, in run_func
anki-sync-server_1  |     res = handler_method(**keyword_args)
anki-sync-server_1  | TypeError: start() got an unexpected keyword argument 'offset'
anki-sync-server_1  | [2020-02-04 17:39:35,586]:INFO:ankisyncd.http:172.20.0.1 "POST /sync/start HTTP/1.1" 500 59

code 400, message Bad request version ('À')

I use AnkiDroid 2.8.5beta1
and get code 400, message Bad request version ('À')
on the sync server console output log. So I configured my client correctly (it reaches the server).

Invalidate sessions when deleting account

Split from #27:

the first issue is about the account. If I delete the user in server without deauthorizing the account in the client, the client will still be able to use this deleted account to sync.

Desktop v2.1.5 sync fail "json.decoder.JSONDecodeError

Thanks for you work,I configured server work fine.
But when I sync from anki desktop to server,It dumps

Traceback (most recent call last):
File "aqt\sync.py", line 382, in _sync
File "aqt\sync.py", line 362, in abortingSync
File "anki\sync.py", line 41, in sync
File "anki\sync.py", line 593, in meta
File "json_init
.py", line 354, in loads
File "json\decoder.py", line 339, in decode
File "json\decoder.py", line 357, in raw_decode
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

============
anki desktop:
version 2.1.5
platform windows 10

anki-sync-server jam problem when encountered a big mount of meida files

I just installed the latest anki-sync-server, but the jam problem still exixts.
When the user have a big amount of media files, the sync will not succeed, and the other user will not be able to use the sync server any more, unless I restart the server manually.
The demonstration video file is attached below (within the zip file, there is a 7z file, the video is in the 7z file. sorry the video is 30MB, so I have to double zip it, so it can be uploaded):

jam promlem demon.zip

you can also download the mp4 file directly here

Sync media 404

client version: Anki Version 2.1.12 (on Ubuntu 18.04), AnkiDroid (on the android phone)

Issue: error 404 while sync media files.

I find the HTTP request URL is a mistake for the media files sync. Such as POST /msync//begin HTTP/1.1, there is an excrescent slash in the URL.

In ./ankisyncd/sync_app.py , I changed the media sync URL

  • from: url = req.path[len(self.base_media_url):]
  • to: url = req.path[len(self.base_media_url):].replace('/','')

Then it worked. Should I pull request for this?

  • Debug message is below:
192.168.31.190 - - [16/May/2019 12:19:12] "POST /sync/sanityCheck2 HTTP/1.1" 200 16
INFO:root:CollectionThread[/app/data/collections/kunlocal/collection.anki2]: Running finish(*[], **{})
192.168.31.190 - - [16/May/2019 12:19:12] "POST /sync/finish HTTP/1.1" 200 13
192.168.31.190 - - [16/May/2019 12:19:31] "POST /msync//begin HTTP/1.1" 404 52
INFO:root:Monitor is closing collection on inactive CollectionThread[/app/data/collections/kunlocal/collection.anki2]
INFO:root:CollectionThread[/app/data/collections/kunlocal/collection.anki2]: Running _close(*[], **{})
INFO:root:CollectionThread[/app/data/collections/kunlocal/collection.anki2]: Running meta(*[], **{})
192.168.31.190 - - [16/May/2019 12:46:20] "POST /sync/meta HTTP/1.1" 200 110
192.168.31.190 - - [16/May/2019 12:46:20] "POST /msync//begin HTTP/1.1" 404 52
INFO:root:CollectionThread[/app/data/collections/kunlocal/collection.anki2]: Running meta(*[], **{})
192.168.31.190 - - [16/May/2019 12:46:22] "POST /sync/meta HTTP/1.1" 200 110
192.168.31.190 - - [16/May/2019 12:46:22] "POST /msync//begin HTTP/1.1" 404 52
INFO:root:CollectionThread[/app/data/collections/kunlocal/collection.anki2]: Running meta(*[], **{})
192.168.31.190 - - [16/May/2019 12:46:43] "POST /sync/meta HTTP/1.1" 200 110
192.168.31.190 - - [16/May/2019 12:46:43] "POST /msync//begin HTTP/1.1" 404 52
INFO:root:Monitor is closing collection on inactive CollectionThread[/app/data/collections/kunlocal/collection.anki2]
INFO:root:CollectionThread[/app/data/collections/kunlocal/collection.anki2]: Running _close(*[], **{})

how can I rest the password, when I don't remember the username of anki-sync-server

I've been use anki-sync-server for couple of years for sync between pc and mobile.

after upgrade anki to 2.1, I noticed I have to login server again, but unfortunately I didn't remember the username and password of it. I should note them in my password log, but I didn't.

how can I reset them?
I am a novice of linux stuff, would very appreciate if you can let me know more step by step way. thanks.

New release?

It's been 3 years since the last release, and I would prefer to use release versions when packaging ankisyncd. Any chance you could bump the release version to incorporate the changes in the past few years sometime soon?

Thanks!

fatal error: Python.h: No such file or directory

when I run this commandpip3 install -r requirements.txt, it shows the following error:

Ignoring psutil: markers 'sys_platform == "win32"' don't match your environment
Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.6/site-packages (from -r requirements.txt (line 1)) (4.7.1)
Requirement already satisfied: send2trash in /usr/local/lib64/python3.6/site-packages (from -r requirements.txt (line 2)) (1.5.0)
Collecting pyaudio (from -r requirements.txt (line 3))
  Using cached https://files.pythonhosted.org/packages/ab/42/b4f04721c5c5bfc196ce156b3c768998ef8c0ae3654ed29ea5020c749a6b/PyAudio-0.2.11.tar.gz
Collecting requests (from -r requirements.txt (line 4))
  Using cached https://files.pythonhosted.org/packages/7d/e3/20f3d364d6c8e5d2353c72a67778eb189176f08e873c9900e10c0287b84b/requests-2.21.0-py2.py3-none-any.whl
Collecting decorator (from -r requirements.txt (line 5))
  Using cached https://files.pythonhosted.org/packages/f1/cd/7c8240007e9716b14679bc217a1baefa4432aa30394f7e2ec40a52b1a708/decorator-4.3.2-py2.py3-none-any.whl
Collecting markdown (from -r requirements.txt (line 6))
  Using cached https://files.pythonhosted.org/packages/7a/6b/5600647404ba15545ec37d2f7f58844d690baf2f81f3a60b862e48f29287/Markdown-3.0.1-py2.py3-none-any.whl
Collecting distro (from -r requirements.txt (line 8))
  Using cached https://files.pythonhosted.org/packages/ea/35/82f79b92fa4d937146c660a6482cee4f3dfa1f97ff3d2a6f3ecba33e712e/distro-1.4.0-py2.py3-none-any.whl
Requirement already satisfied: soupsieve>=1.2 in /usr/local/lib/python3.6/site-packages (from beautifulsoup4->-r requirements.txt (line 1)) (1.8)
Collecting chardet<3.1.0,>=3.0.2 (from requests->-r requirements.txt (line 4))
  Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests->-r requirements.txt (line 4))
  Using cached https://files.pythonhosted.org/packages/60/75/f692a584e85b7eaba0e03827b3d51f45f571c2e793dd731e598828d380aa/certifi-2019.3.9-py2.py3-none-any.whl
Collecting urllib3<1.25,>=1.21.1 (from requests->-r requirements.txt (line 4))
  Using cached https://files.pythonhosted.org/packages/62/00/ee1d7de624db8ba7090d1226aebefab96a2c71cd5cfa7629d6ad3f61b79e/urllib3-1.24.1-py2.py3-none-any.whl
Collecting idna<2.9,>=2.5 (from requests->-r requirements.txt (line 4))
  Using cached https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl
Building wheels for collected packages: pyaudio
  Building wheel for pyaudio (setup.py) ... error
  Complete output from command /bin/python36 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-fwzy1qst/pyaudio/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/pip-wheel-k1o3i0sh --python-tag cp36:
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.linux-x86_64-3.6
  copying src/pyaudio.py -> build/lib.linux-x86_64-3.6
  running build_ext
  building '_portaudio' extension
  creating build/temp.linux-x86_64-3.6
  creating build/temp.linux-x86_64-3.6/src
  gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/usr/include/python3.6m -c src/_portaudiomodule.c -o build/temp.linux-x86_64-3.6/src/_portaudiomodule.o
  src/_portaudiomodule.c:28:20: fatal error: Python.h: No such file or directory
   #include "Python.h"
                      ^
  compilation terminated.
  error: command 'gcc' failed with exit status 1

  ----------------------------------------
  Failed building wheel for pyaudio
  Running setup.py clean for pyaudio
Failed to build pyaudio
Installing collected packages: pyaudio, chardet, certifi, urllib3, idna, requests, decorator, markdown, distro
  Running setup.py install for pyaudio ... error
    Complete output from command /bin/python36 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-fwzy1qst/pyaudio/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-tt74n3z_/install-record.txt --single-version-externally-managed --compile:
    running install
    running build
    running build_py
    creating build
    creating build/lib.linux-x86_64-3.6
    copying src/pyaudio.py -> build/lib.linux-x86_64-3.6
    running build_ext
    building '_portaudio' extension
    creating build/temp.linux-x86_64-3.6
    creating build/temp.linux-x86_64-3.6/src
    gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/usr/include/python3.6m -c src/_portaudiomodule.c -o build/temp.linux-x86_64-3.6/src/_portaudiomodule.o
    src/_portaudiomodule.c:28:20: fatal error: Python.h: No such file or directory
     #include "Python.h"
                        ^
    compilation terminated.
    error: command 'gcc' failed with exit status 1

    ----------------------------------------
Command "/bin/python36 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-fwzy1qst/pyaudio/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-tt74n3z_/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-install-fwzy1qst/pyaudio/

image

my installation step:

git clone https://github.com/tsudoko/anki-sync-server.git /usr/local/anki-sync-server

cd /usr/local/anki-sync-server

git submodule update --init

cd anki-bundled

yum install portaudio-devel

pip3 install -r requirements.txt

Error on full sync upload

Hello,

I've been testing this out with Anki 2.1.0 beta 4. Whenever I make a change to my deck that requires a full sync upload, like changing a note type, I get the following error:

Syncing failed:
Traceback (most recent call last):
  File "aqt/sync.py", line 340, in run
  File "aqt/sync.py", line 396, in _sync
  File "aqt/sync.py", line 425, in _fullSync
  File "anki/sync.py", line 680, in upload
  File "anki/sync.py", line 565, in req
  File "anki/sync.py", line 510, in assertOk
Exception: Unknown response code: 400

Full sync downloads work okay for me.

Thanks

Add the addon to https://ankiweb.net/shared/addons/2.1?

It would be great for the addon to be able to be installed directly from within Anki, without having to go into hidden directories, copy, unzip. As it now does everything from config, is there a reason why it hasn't been uploaded? I had a quick look and from what I can tell there is already one existing custom sync addon there, though it is a little sneaky in that the description is not in English.

I didn't see anything in the terms that suggests setting an alternative sync server is against the T&C, and it would be very handy for me to have this.

I can take on the responsibility for keeping it up to date and supporting it, if you prefer not to take that on.

Plan to support v2 scheduler?

I've encountered an error like #47
the solution introduced in #48 just explicitly points out no support of v2 scheduler

Is there any plan to add support for v2 scheduler?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.