diff --git a/python/README.rst b/python/README.rst index d7f69305..8c4985aa 100644 --- a/python/README.rst +++ b/python/README.rst @@ -16,8 +16,9 @@ Install First you need to execute all the build steps to install the delta-core C-library, see https://github.com/deltachat/deltachat-core/blob/master/README.md#build -Next, you need to perform:: +Presuming you have the delta-core library installed, you can then from the root of the repo:: + cd python pip install -e . Afterwards you should be able to successfully import the bindings:: diff --git a/python/doc/Makefile b/python/doc/Makefile new file mode 100644 index 00000000..f309f543 --- /dev/null +++ b/python/doc/Makefile @@ -0,0 +1,241 @@ +# Makefile for Sphinx documentation +# + +VERSION = $(shell python -c "import conf ; print(conf.version)") +DOCZIP = devpi-$(VERSION).doc.zip +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +export HOME=/tmp/home +export TESTHOME=$(HOME) + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +# This variable is not auto generated as the order is important. +USER_MAN_CHAPTERS = commands\ + user\ + indices\ + packages\ +# userman/index.rst\ +# userman/devpi_misc.rst\ +# userman/devpi_concepts.rst\ + + +#export DEVPI_CLIENTDIR=$(CURDIR)/.tmp_devpi_user_man/client +#export DEVPI_SERVERDIR=$(CURDIR)/.tmp_devpi_user_man/server + +chapter = commands + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp \ + epub latex latexpdf text man changes linkcheck doctest gettext install \ + quickstart-releaseprocess quickstart-pypimirror quickstart-server regen \ + prepare-quickstart\ + regen.server-fresh regen.server-restart regen.server-clean\ + regen.uman-all regen.uman + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo + @echo "User Manual Regen Targets" + @echo " regen.uman regenerates page. of the user manual chapeter e.g. regen.uman chapter=..." + @echo " regen.uman-all regenerates the user manual" + @echo " regen.uman-clean stop temp server and clean up directory" + @echo " Chapter List: $(USER_MAN_CHAPTERS)" + +clean: + -rm -rf $(BUILDDIR)/* + +version: + @echo "version $(VERSION)" + +doczip: html + python doczip.py $(DOCZIP) _build/html + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/devpi.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/devpi.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/devpi" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/devpi" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + + +regen: quickstart-pypimirror quickstart-releaseprocess quickstart-server + rm -rf TARGETDIR + +quickstart-pypimirror: + USER=testuser sh regen.sh --update quickstart-pypimirror.rst + +quickstart-releaseprocess: + USER=testuser sh regen.sh --update quickstart-releaseprocess.rst + +quickstart-server: + USER=testuser sh regen.sh --update quickstart-server.rst + + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# USER MANUAL TARGETS + + +$(USER_MAN_CHAPTERS): + @echo Regenerating $@ + USER=testuser python regendoc.py --update userman/devpi_$@.rst + +regen.sample_undo: + -hg revert --all ./userman/pysober + +regen.server-fresh: regen.server-clean + devpi-server --start --serverdir=$(TESTHOME)/.devpi/server --init + +regen.server-restart: + -devpi-server --stop --serverdir=$(TESTHOME)/.devpi/server + devpi-server --start --serverdir=$(TESTHOME)/.devpi/server + +regen.server-clean: regen.sample_undo + @echo stopping server + -devpi-server --stop --serverdir=$(TESTHOME)/.devpi/server + @echo deleting $(TESTHOME)/.devpi state + -rm -rf $(TESTHOME)/.devpi + @echo deleting pysober/dist + -rm -rf userman/pysober/dist + hg revert --all userman/pysober + + + +regen.uman-all : regen.server-fresh $(USER_MAN_CHAPTERS) + hg revert --all userman/pysober + rm -rf userman/pysober/dist + +regen.uman: regen.server-restart $(chapter) + + diff --git a/python/doc/install.rst b/python/doc/install.rst index d7f69305..44dc63e4 100644 --- a/python/doc/install.rst +++ b/python/doc/install.rst @@ -1,6 +1,6 @@ -deltachat python bindings -========================= +Building and Installing deltachat +====================================== This package provides bindings to the delta-core_ C-library which provides imap/smtp/crypto handling as well as chat/group/messages @@ -16,8 +16,9 @@ Install First you need to execute all the build steps to install the delta-core C-library, see https://github.com/deltachat/deltachat-core/blob/master/README.md#build -Next, you need to perform:: +Presuming you have the delta-core library installed, you can then from the root of the repo:: + cd python pip install -e . Afterwards you should be able to successfully import the bindings:: diff --git a/python/src/deltachat/account.py b/python/src/deltachat/account.py index b5f68374..9270b183 100644 --- a/python/src/deltachat/account.py +++ b/python/src/deltachat/account.py @@ -95,13 +95,8 @@ class Contact(object): return capi.lib.dc_get_contact(self.dc_context, self.id) def __del__(self): - try: - dc_contact_unref = capi.lib.dc_contact_unref - self._property_cache - except: # noqa - pass - else: - dc_contact_unref(self.dc_contact_t) + if lib is not None and hasattr(self, "_property_cache"): + lib.dc_contact_unref(self.dc_contact_t) @property_with_doc def addr(self): @@ -156,7 +151,7 @@ class Chat(object): def get_messages(self): """ return list of messages in this chat. - :returns: list of Message objects for this chat. + :returns: list of :class:`Message` objects for this chat. """ dc_array_t = lib.dc_get_chat_msgs(self.dc_context, self.id, 0, 0) return list(iter_array_and_unref(dc_array_t, lambda x: Message(self.dc_context, x))) @@ -275,7 +270,9 @@ class Account(object): return Contact(self.dc_context, capi.lib.DC_CONTACT_ID_SELF) def create_contact(self, email, name=ffi.NULL): - """ Return a :class:`Contact` object. + """ create a (new) Contact. If there already is a Contact + with that e-mail address, it is unblocked and its name is + updated. :param email: email-address (text type) :param name: display name for this contact (optional) @@ -287,12 +284,13 @@ class Account(object): return Contact(self.dc_context, contact_id) def get_contacts(self, query=ffi.NULL, with_self=False, only_verified=False): - """ return list of :class:`Contact` objects. + """ get a (filtered) list of contacts. :param query: if a string is specified, only return contacts whose name or e-mail matches query. :param only_verified: if true only return verified contacts. :param with_self: if true the self-contact is also returned. + :returns: list of :class:`Message` objects. """ flags = 0 query = convert_to_bytes_utf8(query) @@ -304,9 +302,10 @@ class Account(object): return list(iter_array_and_unref(dc_array_t, lambda x: Contact(self.dc_context, x))) def create_chat_by_contact(self, contact): - """ return a Chat object with the specified contact. + """ create or get an existing 1:1 chat object for the specified contact. :param contact: chat_id (int) or contact object. + :returns: a :class:`Chat` object. """ contact_id = getattr(contact, "id", contact) assert isinstance(contact_id, int) @@ -315,9 +314,11 @@ class Account(object): return Chat(self.dc_context, chat_id) def create_chat_by_message(self, message): - """ return a Chat object for the given message. + """ create or get an existing 1:1 chat object for the specified sender + of the specified message. :param message: messsage id or message instance. + :returns: a :class:`Chat` object. """ msg_id = getattr(message, "id", message) assert isinstance(msg_id, int) @@ -325,10 +326,7 @@ class Account(object): return Chat(self.dc_context, chat_id) def get_message_by_id(self, msg_id): - """ return a message object. - - :returns: :class:`Message` instance. - """ + """ return Message instance. """ return Message(self.dc_context, msg_id) def mark_seen_messages(self, messages):