mirror of
https://github.com/ankitects/anki.git
synced 2025-09-20 23:12:21 -04:00
Merge remote-tracking branch 'upstream/master' into add-tags-on-update
This commit is contained in:
commit
e481cce816
602 changed files with 202264 additions and 148 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -6,8 +6,7 @@
|
|||
.build
|
||||
.coverage
|
||||
.DS_Store
|
||||
build
|
||||
dist
|
||||
pyenv
|
||||
.mypy_cache
|
||||
__pycache__
|
||||
i18n
|
||||
|
|
52
CONTRIBUTORS
Normal file
52
CONTRIBUTORS
Normal file
|
@ -0,0 +1,52 @@
|
|||
If you have made changes to Anki's AGPL code, you are welcome to distribute
|
||||
the changed code under the AGPL license.
|
||||
|
||||
If you would like to contribute your code back to the official release, we ask
|
||||
that you license your contributions under the BSD 3 clause license. Portions
|
||||
of the code are also used in AnkiWeb and AnkiMobile, and accepting
|
||||
contributions under an AGPL license would mean we could no longer use the code
|
||||
we have written in those projects.
|
||||
|
||||
In your first pull request, please add your name below. By adding your name to
|
||||
this file, you assert that any code you contribute to the Anki project is
|
||||
licensed under the BSD 3 clause license. If any pull request you make contains
|
||||
code that you don't own the copyright to, you agree to make that clear when
|
||||
submitting the request.
|
||||
|
||||
For users who previously confirmed the license of their contributions on the
|
||||
support site, it would be great if you could add your name below as well.
|
||||
|
||||
********************
|
||||
|
||||
- Sample Name
|
||||
|
||||
********************
|
||||
|
||||
The text of the 3 clause BSD license follows:
|
||||
|
||||
Contributions copyright the above contributors, 2010-Present.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
49
LICENSE
49
LICENSE
|
@ -1 +1,48 @@
|
|||
Primarily GNU AGPL3+ - please see the LICENSE file in each subfolder.
|
||||
Anki is licensed under the GNU Affero General Public License, version 3 or
|
||||
later, with portions contributed by Anki users licensed under the BSD-3
|
||||
license (see CONTRIBUTORS).
|
||||
|
||||
The following included source code items use a license other than AGPL3:
|
||||
|
||||
In the pylib folder:
|
||||
|
||||
* The anki/template/ folder is based off pystache: MIT.
|
||||
* The SuperMemo importer: GPL3.
|
||||
* The Pauker importer: BSD-3.
|
||||
* statsbg.py: CC BY-SA 3.0.
|
||||
|
||||
In the qt folder:
|
||||
|
||||
* Anki's translations are a mix of BSD and public domain.
|
||||
* mpv.py: MIT.
|
||||
* winpaths.py: MIT.
|
||||
* MathJax: Apache 2.
|
||||
* jQuery and jQuery-UI: MIT.
|
||||
* browsersel.js: CC BY 2.5.
|
||||
* plot.js: MIT.
|
||||
|
||||
The above list only covers the source code that is vendored in this
|
||||
repository. Binary distributions also include copies of Qt translation
|
||||
files (LGPL), and all of the Python, Rust and Javascript libraries
|
||||
that this code references.
|
||||
|
||||
Anki's logo is copyright Alex Fraser, and is licensed under the AGPL3 like the
|
||||
rest of Anki's code.
|
||||
|
||||
The logo is also available under a limited alternative license for inclusion
|
||||
in books, blogs, videos and so on. If the following conditions are met, you
|
||||
may use the logo in your work without the need to license your work under an
|
||||
AGPL3-compatible license:
|
||||
|
||||
* The logo must be used to refer to Anki, AnkiWeb, AnkiMobile or AnkiDroid,
|
||||
and a link to https://apps.ankiweb.net must be provided. When your
|
||||
content is focused specifically on AnkiDroid, a link to
|
||||
https://play.google.com/store/apps/details?id=com.ichi2.anki&hl=en
|
||||
may be provided instead of the first link.
|
||||
* The work must make it clear that the text/video/etc you
|
||||
are publishing is your own content and not something originating
|
||||
from the Anki project.
|
||||
* The logo must be used unmodified - no cropping, changing of colours
|
||||
or adding or deleting content is allowed. You may resize the image
|
||||
provided the horizontal and vertical dimensions are resized
|
||||
equally.
|
||||
|
|
|
@ -100,10 +100,7 @@ requests instead.
|
|||
License
|
||||
-------
|
||||
|
||||
Please add yourself to the contributors file before sending a pull request
|
||||
for other components:
|
||||
|
||||
https://github.com/ankitects/anki-contributors
|
||||
Please add yourself to the contributors file in your first pull request.
|
||||
|
||||
Add-ons
|
||||
========
|
||||
|
|
|
@ -36,14 +36,13 @@ of http://ankisrs.net/docs/manual.html#_contributing
|
|||
Subcomponents
|
||||
--------------
|
||||
|
||||
- pylib contains a Python module (anki) with most of the non-GUI code.
|
||||
- qt contains the Qt GUI implementation (aqt).
|
||||
- rspy contains a Python module (ankirspy) for accessing the Rust code.
|
||||
- rslib contains the parts of the code implemented in Rust. This
|
||||
is only a tiny subsection at the moment.
|
||||
- proto contains the interface used to communicate between the Rust and
|
||||
Python code.
|
||||
- lib-rust contains the parts of the code implemented in Rust. This
|
||||
is only a tiny subsection at the moment.
|
||||
- lib-rspy contains a Python module (ankirspy) for accessing the Rust code.
|
||||
- lib-python contains a Python module (anki) that covers all of the work
|
||||
not related to the user interface.
|
||||
- anki-qt contains the Qt GUI implementation (aqt).
|
||||
|
||||
Helper scripts
|
||||
--------------
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
Anki is licensed under the GNU Affero General Public License, version 3 or
|
||||
later, with portions contributed by Anki users licensed under the BSD-3
|
||||
license: https://github.com/ankitects/anki-contributors
|
||||
|
||||
Please see LICENSE.logo for the copyright and license of Anki's logo.
|
||||
|
||||
The following included source code items use a license other than AGPL3:
|
||||
|
||||
* Anki's translations are a mix of BSD and public domain.
|
||||
* The Qt translations that are copied in as part of the build process
|
||||
are licensed under the LGPL.
|
||||
* mpv.py: MIT.
|
||||
* winpaths.py: MIT.
|
||||
* MathJax: Apache 2.
|
||||
* jQuery and jQuery-UI: MIT.
|
||||
* browsersel.js: CC BY 2.5.
|
||||
* plot.js: MIT.
|
|
@ -1,20 +0,0 @@
|
|||
Anki's logo is copyright Alex Fraser, and is licensed under the AGPL3 like the
|
||||
rest of Anki's code.
|
||||
|
||||
The logo is also available under a limited alternative license for inclusion
|
||||
in books, blogs, videos and so on. If the following conditions are met, you
|
||||
may use the logo in your work without the need to license your work under an
|
||||
AGPL3-compatible license:
|
||||
|
||||
* The logo must be used to refer to Anki, AnkiMobile or AnkiDroid,
|
||||
and a link to https://apps.ankiweb.net must be provided. When your
|
||||
content is focused specifically on AnkiDroid, a link to
|
||||
https://play.google.com/store/apps/details?id=com.ichi2.anki&hl=en
|
||||
may be provided instead of the first link.
|
||||
* The work must make it clear that the text/video/etc you
|
||||
are publishing is your own content and not something originating
|
||||
from the Anki project.
|
||||
* The logo must be used unmodified - no cropping, changing of colours
|
||||
or adding or deleting content is allowed. You may resize the image
|
||||
provided the horizontal and vertical dimensions are resized
|
||||
equally.
|
|
@ -1,23 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Usage:
|
||||
# tools/tests.sh # run all tests
|
||||
# tools/tests.sh decks # test only test_decks.py
|
||||
# coverage=1 tools/tests.sh # run with coverage test
|
||||
|
||||
set -e
|
||||
|
||||
BIN="$(cd "`dirname "$0"`"; pwd)"
|
||||
export PYTHONPATH=${BIN}/..:${PYTHONPATH}
|
||||
|
||||
nose="python -m nose2 --plugin=nose2.plugins.mp -N 16"
|
||||
|
||||
dir=.
|
||||
|
||||
if [ x$1 = x ]; then
|
||||
lim="tests"
|
||||
else
|
||||
lim="tests.test_$1"
|
||||
fi
|
||||
|
||||
(cd $dir && $nose $lim $args)
|
17
build
Executable file
17
build
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
. scripts.inc
|
||||
|
||||
rm -rf dist
|
||||
|
||||
for dir in $DEVEL; do
|
||||
echo $dir
|
||||
(cd $dir && make build BUILDFLAGS="$BUILDFLAGS")
|
||||
done
|
||||
|
||||
# add build hash to outputs
|
||||
ver=$(cat meta/version)
|
||||
hash=$(cat meta/buildhash)
|
||||
(cd dist && rename "s/$ver/${ver}+$hash/" *.whl)
|
10
bundle
10
bundle
|
@ -1,10 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
. scripts.inc
|
||||
|
||||
for dir in $DEVEL; do
|
||||
echo $dir
|
||||
(cd $dir && make build BUILDFLAGS="$BUILDFLAGS")
|
||||
done
|
2
clean
2
clean
|
@ -4,6 +4,8 @@ set -e
|
|||
|
||||
. scripts.inc
|
||||
|
||||
rm -rf dist
|
||||
|
||||
for dir in $DEVEL; do
|
||||
echo $dir
|
||||
(cd $dir && make clean)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Licensed under the GNU AGPL 3 or later.
|
|
@ -1 +0,0 @@
|
|||
Licensed under the GNU AGPL 3 or later.
|
1
meta/.gitignore
vendored
Normal file
1
meta/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
buildhash
|
1
meta/version
Normal file
1
meta/version
Normal file
|
@ -0,0 +1 @@
|
|||
2.1.17
|
0
lib-python/.gitignore → pylib/.gitignore
vendored
0
lib-python/.gitignore → pylib/.gitignore
vendored
|
@ -6,10 +6,10 @@ MAKEFLAGS += --warn-undefined-variables
|
|||
MAKEFLAGS += --no-builtin-rules
|
||||
RUNARGS :=
|
||||
.SUFFIXES:
|
||||
BLACKARGS := -t py36 anki tests --exclude=backend_pb2
|
||||
BLACKARGS := -t py36 anki tests --exclude='backend_pb2|buildinfo'
|
||||
ISORTARGS := anki tests
|
||||
|
||||
$(shell mkdir -p .build ../build)
|
||||
$(shell mkdir -p .build ../dist)
|
||||
|
||||
PHONY: all
|
||||
all: check
|
||||
|
@ -28,7 +28,7 @@ PROTODEPS := $(wildcard ../proto/*.proto)
|
|||
protoc --proto_path=../proto --python_out=anki --mypy_out=anki $(PROTODEPS)
|
||||
@touch $@
|
||||
|
||||
BUILD_STEPS := .build/run-deps .build/dev-deps .build/py-proto
|
||||
BUILD_STEPS := .build/run-deps .build/dev-deps .build/py-proto anki/buildinfo.py
|
||||
|
||||
# Checking
|
||||
######################
|
||||
|
@ -48,14 +48,14 @@ clean:
|
|||
# Checking python
|
||||
######################
|
||||
|
||||
CHECKDEPS := $(shell find anki tests -name '*.py' | grep -v buildhash.py)
|
||||
CHECKDEPS := $(shell find anki tests -name '*.py')
|
||||
|
||||
.build/mypy: $(CHECKDEPS)
|
||||
mypy anki
|
||||
@touch $@
|
||||
|
||||
.build/test: $(CHECKDEPS)
|
||||
python -m nose2 --plugin=nose2.plugins.mp -N 16
|
||||
python -m pytest --durations=1
|
||||
@touch $@
|
||||
|
||||
.build/lint: $(CHECKDEPS)
|
||||
|
@ -78,10 +78,13 @@ CHECKDEPS := $(shell find anki tests -name '*.py' | grep -v buildhash.py)
|
|||
.PHONY: build
|
||||
build: $(BUILD_STEPS) $(CHECKDEPS)
|
||||
rm -rf dist
|
||||
echo "build='$$(git rev-parse --short HEAD)'" > anki/buildhash.py
|
||||
python setup.py bdist_wheel
|
||||
rsync -a dist/*.whl ../build/
|
||||
rsync -a dist/*.whl ../dist/
|
||||
|
||||
# prepare code for running in place
|
||||
.PHONY: develop
|
||||
develop: $(BUILD_STEPS)
|
||||
|
||||
anki/buildinfo.py: ../meta/version ../meta/buildhash
|
||||
echo "buildhash='$$(cat ../meta/buildhash)'" > $@
|
||||
echo "version='$$(cat ../meta/version)'" >> $@
|
1
pylib/anki/.gitignore
vendored
Normal file
1
pylib/anki/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
buildinfo.py
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import sys
|
||||
|
||||
from anki.buildinfo import version
|
||||
from anki.storage import Collection
|
||||
|
||||
if sys.version_info[0] < 3 or sys.version_info[1] < 5:
|
||||
|
@ -11,8 +12,5 @@ if sys.version_info[0] < 3 or sys.version_info[1] < 5:
|
|||
if sys.getfilesystemencoding().lower() in ("ascii", "ansi_x3.4-1968"):
|
||||
raise Exception("Anki requires a UTF-8 locale.")
|
||||
|
||||
# fmt: off
|
||||
version="2.1.17" # build scripts grep this line, so preserve formatting
|
||||
# fmt: on
|
||||
|
||||
__all__ = ["Collection"]
|
|
@ -5,9 +5,12 @@ from typing import Dict, List
|
|||
import ankirspy # pytype: disable=import-error
|
||||
|
||||
import anki.backend_pb2 as pb
|
||||
import anki.buildinfo
|
||||
|
||||
from .types import AllTemplateReqs
|
||||
|
||||
assert ankirspy.buildhash() == anki.buildinfo.buildhash
|
||||
|
||||
SchedTimingToday = pb.SchedTimingTodayOut
|
||||
|
||||
|
|
@ -101,8 +101,6 @@ def addClozeModel(col) -> NoteType:
|
|||
txt = _("Text")
|
||||
fm = mm.newField(txt)
|
||||
mm.addField(m, fm)
|
||||
fm = mm.newField(_("Extra"))
|
||||
mm.addField(m, fm)
|
||||
t = mm.newTemplate(_("Cloze"))
|
||||
fmt = "{{cloze:%s}}" % txt
|
||||
m[
|
||||
|
@ -116,7 +114,7 @@ def addClozeModel(col) -> NoteType:
|
|||
color: lightblue;
|
||||
}"""
|
||||
t["qfmt"] = fmt
|
||||
t["afmt"] = fmt + "<br>\n{{%s}}" % _("Extra")
|
||||
t["afmt"] = fmt
|
||||
mm.addTemplate(m, t)
|
||||
mm.add(m)
|
||||
return m
|
|
@ -494,10 +494,6 @@ class TimedLog:
|
|||
|
||||
|
||||
def versionWithBuild() -> str:
|
||||
from anki import version
|
||||
from anki.buildinfo import version, buildhash
|
||||
|
||||
try:
|
||||
from anki.buildhash import build # type: ignore # pylint: disable=import-error,no-name-in-module
|
||||
except:
|
||||
build = "dev"
|
||||
return "%s (%s)" % (version, build)
|
||||
return "%s (%s)" % (version, buildhash)
|
|
@ -2,7 +2,7 @@ wheel
|
|||
mypy
|
||||
mypy_protobuf
|
||||
black
|
||||
nose2
|
||||
pytest
|
||||
# fixme: when isort 5.0 is released, switch to pypi
|
||||
git+https://github.com/ankitects/isort#egg=isort
|
||||
# fixme: when pylint supports isort 5.0, switch to pypi
|
|
@ -3,6 +3,9 @@ import setuptools, sys
|
|||
with open("README.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
with open("../meta/version") as fh:
|
||||
version = fh.read().strip()
|
||||
|
||||
platform_reqs = []
|
||||
if sys.platform == "win32":
|
||||
platform_reqs.append("psutil")
|
||||
|
@ -11,7 +14,7 @@ if sys.platform != "win32" and sys.platform != "darwin":
|
|||
|
||||
setuptools.setup(
|
||||
name="anki",
|
||||
version="0.1.0",
|
||||
version=version,
|
||||
author="Ankitects Pty Ltd",
|
||||
description="Anki's library code",
|
||||
long_description=long_description,
|
|
@ -3,8 +3,6 @@
|
|||
import os
|
||||
import tempfile
|
||||
|
||||
from nose2.tools.decorators import with_setup
|
||||
|
||||
from anki import Collection as aopen
|
||||
from anki.exporting import *
|
||||
from anki.importing import Anki2Importer
|
||||
|
@ -41,8 +39,8 @@ def setup1():
|
|||
##########################################################################
|
||||
|
||||
|
||||
@with_setup(setup1)
|
||||
def test_export_anki():
|
||||
setup1()
|
||||
# create a new deck with its own conf to test conf copying
|
||||
did = deck.decks.id("test")
|
||||
dobj = deck.decks.get(did)
|
||||
|
@ -83,8 +81,8 @@ def test_export_anki():
|
|||
assert d2.cardCount() == 1
|
||||
|
||||
|
||||
@with_setup(setup1)
|
||||
def test_export_ankipkg():
|
||||
setup1()
|
||||
# add a test file to the media folder
|
||||
with open(os.path.join(deck.media.dir(), "今日.mp3"), "w") as f:
|
||||
f.write("test")
|
||||
|
@ -99,8 +97,8 @@ def test_export_ankipkg():
|
|||
e.exportInto(newname)
|
||||
|
||||
|
||||
@with_setup(setup1)
|
||||
def test_export_anki_due():
|
||||
setup1()
|
||||
deck = getEmptyCol()
|
||||
f = deck.newNote()
|
||||
f["Front"] = "foo"
|
||||
|
@ -132,8 +130,8 @@ def test_export_anki_due():
|
|||
assert c.due - deck2.sched.today == 1
|
||||
|
||||
|
||||
# @with_setup(setup1)
|
||||
# def test_export_textcard():
|
||||
# setup1()
|
||||
# e = TextCardExporter(deck)
|
||||
# f = unicode(tempfile.mkstemp(prefix="ankitest")[1])
|
||||
# os.unlink(f)
|
||||
|
@ -142,8 +140,8 @@ def test_export_anki_due():
|
|||
# e.exportInto(f)
|
||||
|
||||
|
||||
@with_setup(setup1)
|
||||
def test_export_textnote():
|
||||
setup1()
|
||||
e = TextNoteExporter(deck)
|
||||
fd, f = tempfile.mkstemp(prefix="ankitest")
|
||||
f = str(f)
|
|
@ -1,5 +1,5 @@
|
|||
# coding: utf-8
|
||||
from nose2.tools.such import helper
|
||||
import pytest
|
||||
|
||||
from anki.find import Finder
|
||||
from tests.shared import getEmptyCol
|
||||
|
@ -111,7 +111,7 @@ def test_findCards():
|
|||
assert len(deck.findCards("nid:%d" % f.id)) == 2
|
||||
assert len(deck.findCards("nid:%d,%d" % (f1id, f2id))) == 2
|
||||
# templates
|
||||
with helper.assertRaises(Exception):
|
||||
with pytest.raises(Exception):
|
||||
deck.findCards("card:foo")
|
||||
assert len(deck.findCards("'card:card 1'")) == 4
|
||||
assert len(deck.findCards("card:reverse")) == 1
|
||||
|
@ -147,7 +147,7 @@ def test_findCards():
|
|||
assert len(deck.findCards("-deck:foo")) == 5
|
||||
assert len(deck.findCards("deck:def*")) == 5
|
||||
assert len(deck.findCards("deck:*EFAULT")) == 5
|
||||
with helper.assertRaises(Exception):
|
||||
with pytest.raises(Exception):
|
||||
deck.findCards("deck:*cefault")
|
||||
# full search
|
||||
f = deck.newNote()
|
||||
|
@ -164,7 +164,7 @@ def test_findCards():
|
|||
# assert len(deck.findCards("helloworld", full=True)) == 2
|
||||
# assert len(deck.findCards("back:helloworld", full=True)) == 2
|
||||
# searching for an invalid special tag should not error
|
||||
with helper.assertRaises(Exception):
|
||||
with pytest.raises(Exception):
|
||||
len(deck.findCards("is:invalid"))
|
||||
# should be able to limit to parent deck, no children
|
||||
id = deck.db.scalar("select id from cards limit 1")
|
||||
|
@ -238,9 +238,9 @@ def test_findCards():
|
|||
assert len(deck.findCards("added:1")) == deck.cardCount() - 1
|
||||
assert len(deck.findCards("added:2")) == deck.cardCount()
|
||||
# flag
|
||||
with helper.assertRaises(Exception):
|
||||
with pytest.raises(Exception):
|
||||
deck.findCards("flag:01")
|
||||
with helper.assertRaises(Exception):
|
||||
with pytest.raises(Exception):
|
||||
deck.findCards("flag:12")
|
||||
|
||||
|
|
@ -88,6 +88,10 @@ def test_changes():
|
|||
def removed():
|
||||
return d.media.db.execute("select fname from media where csum is null")
|
||||
|
||||
def advanceTime():
|
||||
d.media.db.execute("update media set mtime=mtime-1")
|
||||
d.media.db.execute("update meta set dirMod = dirMod - 1")
|
||||
|
||||
assert not list(added())
|
||||
assert not list(removed())
|
||||
# add a file
|
||||
|
@ -95,27 +99,26 @@ def test_changes():
|
|||
path = os.path.join(dir, "foo.jpg")
|
||||
with open(path, "w") as f:
|
||||
f.write("hello")
|
||||
time.sleep(1)
|
||||
path = d.media.addFile(path)
|
||||
# should have been logged
|
||||
d.media.findChanges()
|
||||
assert list(added())
|
||||
assert not list(removed())
|
||||
# if we modify it, the cache won't notice
|
||||
time.sleep(1)
|
||||
advanceTime()
|
||||
with open(path, "w") as f:
|
||||
f.write("world")
|
||||
assert len(list(added())) == 1
|
||||
assert not list(removed())
|
||||
# but if we add another file, it will
|
||||
time.sleep(1)
|
||||
advanceTime()
|
||||
with open(path + "2", "w") as f:
|
||||
f.write("yo")
|
||||
d.media.findChanges()
|
||||
assert len(list(added())) == 2
|
||||
assert not list(removed())
|
||||
# deletions should get noticed too
|
||||
time.sleep(1)
|
||||
advanceTime()
|
||||
os.unlink(path + "2")
|
||||
d.media.findChanges()
|
||||
assert len(list(added())) == 1
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue