Compare commits

...

10 commits

Author SHA1 Message Date
Unrud
a239b3dccc Bump version to 3.0.1 2020-05-22 16:33:06 +02:00
Unrud
4d08cab382 Shorter web interface title 2020-05-22 16:33:05 +02:00
Unrud
55cfceaba3 Use generic version in docker example 2020-05-22 16:33:05 +02:00
Unrud
80bf7340f5 Fix XML error messages
Fixes #825
2020-05-22 16:33:04 +02:00
Unrud
ada9fa1cce Remove useless constant 2020-05-19 17:06:26 +02:00
Unrud
6158fb961b Trim all (ASCII) whitespace characters 2020-05-19 07:03:58 +02:00
Unrud
1f8cb8ed89 Remove unnecessary string trimming 2020-05-19 06:52:01 +02:00
Unrud
159ae0067d
Specify branch for test badge 2020-05-19 04:39:56 +02:00
Unrud
c3e33d83e3
Upload coverage for all branches 2020-05-19 04:32:52 +02:00
Unrud
b3e14f2844 Bump version to 3.0.0 2020-05-19 04:19:12 +02:00
12 changed files with 26 additions and 22 deletions

View file

@ -19,7 +19,7 @@ jobs:
- name: Run tests - name: Run tests
run: python setup.py test run: python setup.py test
- name: Upload coverage to Coveralls - name: Upload coverage to Coveralls
if: github.event_name == 'push' && github.ref == 'refs/heads/master' if: github.event_name == 'push'
env: env:
COVERALLS_PARALLEL: true COVERALLS_PARALLEL: true
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
@ -29,7 +29,7 @@ jobs:
coveralls-finish: coveralls-finish:
needs: test needs: test
if: github.event_name == 'push' && github.ref == 'refs/heads/master' if: github.event_name == 'push'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Set up Python - name: Set up Python

View file

@ -33,7 +33,7 @@ Want more? Check the [tutorials](#tutorials) and the
### What's New? ### What's New?
Read the Read the
[changelog on GitHub.](https://github.com/Kozea/Radicale/blob/master/NEWS.md) [changelog on GitHub.](https://github.com/Kozea/Radicale/blob/3.0.x/NEWS.md)
# Tutorials # Tutorials
## Simple 5-minute setup ## Simple 5-minute setup
@ -1331,7 +1331,7 @@ add new features, fix bugs or update the documentation.
### Documentation ### Documentation
To change or complement the documentation create a pull request to To change or complement the documentation create a pull request to
[DOCUMENTATION.md](https://github.com/Kozea/Radicale/blob/master/DOCUMENTATION.md). [DOCUMENTATION.md](https://github.com/Kozea/Radicale/blob/3.0.x/DOCUMENTATION.md).
# Download # Download

View file

@ -1,6 +1,6 @@
FROM alpine:latest FROM alpine:latest
# Version of Radicale (e.g. 3.0.0) # Version of Radicale (e.g. 3.0.x)
ARG VERSION=master ARG VERSION=master
# Install dependencies # Install dependencies

View file

@ -1,6 +1,10 @@
# News # News
## master ## 3.0.1
* Fix XML error messages
## 3.0.0
This release is incompatible with previous releases. This release is incompatible with previous releases.
See the upgrade checklist below. See the upgrade checklist below.

View file

@ -1,9 +1,9 @@
# Read Me # Read Me
![Test](https://github.com/Kozea/Radicale/workflows/Test/badge.svg) ![Test](https://github.com/Kozea/Radicale/workflows/Test/badge.svg?branch=3.0.x)
[![Coverage Status](https://coveralls.io/repos/github/Kozea/Radicale/badge.svg?branch=master)](https://coveralls.io/github/Kozea/Radicale?branch=master) [![Coverage Status](https://coveralls.io/repos/github/Kozea/Radicale/badge.svg?branch=3.0.x)](https://coveralls.io/github/Kozea/Radicale?branch=3.0.x)
Radicale is a free and open-source CalDAV and CardDAV server. Radicale is a free and open-source CalDAV and CardDAV server.
For the complete documentation, please visit For the complete documentation, please visit
[Radicale "master" documentation](https://radicale.org/master.html). [Radicale "3.0" Documentation](https://radicale.org/3.0.html).

View file

@ -349,8 +349,7 @@ class Application(
xml_declaration=True) xml_declaration=True)
return f.getvalue() return f.getvalue()
def _webdav_error_response(self, human_tag, def _webdav_error_response(self, human_tag, status=client.CONFLICT):
status=httputils.WEBDAV_PRECONDITION_FAILED[0]):
"""Generate XML error response.""" """Generate XML error response."""
headers = {"Content-Type": "text/xml; charset=%s" % self._encoding} headers = {"Content-Type": "text/xml; charset=%s" % self._encoding}
content = self._write_xml_content(xmlutils.webdav_error(human_tag)) content = self._write_xml_content(xmlutils.webdav_error(human_tag))

View file

@ -28,6 +28,7 @@ Use ``load()`` to obtain an instance of ``Configuration`` for use with
import contextlib import contextlib
import math import math
import os import os
import string
from collections import OrderedDict from collections import OrderedDict
from configparser import RawConfigParser from configparser import RawConfigParser
@ -74,11 +75,11 @@ def filepath(value):
def list_of_ip_address(value): def list_of_ip_address(value):
def ip_address(value): def ip_address(value):
try: try:
address, port = value.strip().rsplit(":", 1) address, port = value.rsplit(":", 1)
return address.strip("[] "), int(port) return address.strip(string.whitespace + "[]"), int(port)
except ValueError: except ValueError:
raise ValueError("malformed IP address: %r" % value) raise ValueError("malformed IP address: %r" % value)
return [ip_address(s.strip()) for s in value.split(",")] return [ip_address(s) for s in value.split(",")]
def str_or_callable(value): def str_or_callable(value):

View file

@ -38,9 +38,6 @@ NOT_FOUND = (
CONFLICT = ( CONFLICT = (
client.CONFLICT, (("Content-Type", "text/plain"),), client.CONFLICT, (("Content-Type", "text/plain"),),
"Conflict in the request.") "Conflict in the request.")
WEBDAV_PRECONDITION_FAILED = (
client.CONFLICT, (("Content-Type", "text/plain"),),
"WebDAV precondition failed.")
METHOD_NOT_ALLOWED = ( METHOD_NOT_ALLOWED = (
client.METHOD_NOT_ALLOWED, (("Content-Type", "text/plain"),), client.METHOD_NOT_ALLOWED, (("Content-Type", "text/plain"),),
"The method is not allowed on the requested resource.") "The method is not allowed on the requested resource.")

View file

@ -1059,10 +1059,13 @@ class BaseRequestsMixIn:
</prop> </prop>
%s %s
</sync-collection>""" % sync_token_xml) </sync-collection>""" % sync_token_xml)
if sync_token and status == 409: xml = DefusedET.fromstring(answer)
if status in (403, 409):
assert xml.tag == xmlutils.make_clark("D:error")
assert sync_token and xml.find(
xmlutils.make_clark("D:valid-sync-token")) is not None
return None, None return None, None
assert status == 207 assert status == 207
xml = DefusedET.fromstring(answer)
assert xml.tag == xmlutils.make_clark("D:multistatus") assert xml.tag == xmlutils.make_clark("D:multistatus")
sync_token = xml.find(xmlutils.make_clark("D:sync-token")).text.strip() sync_token = xml.find(xmlutils.make_clark("D:sync-token")).text.strip()
assert sync_token assert sync_token

View file

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<script src="fn.js"></script> <script src="fn.js"></script>
<title>Web interface for Radicale</title> <title>Radicale Web Interface</title>
<link href="css/main.css" media="screen" rel="stylesheet"> <link href="css/main.css" media="screen" rel="stylesheet">
<link href="css/icon.png" type="image/png" rel="shortcut icon"> <link href="css/icon.png" type="image/png" rel="shortcut icon">
<style> <style>

View file

@ -131,7 +131,7 @@ def make_href(base_prefix, href):
def webdav_error(human_tag): def webdav_error(human_tag):
"""Generate XML error message.""" """Generate XML error message."""
root = ET.Element(make_clark("D:error")) root = ET.Element(make_clark("D:error"))
root.append(ET.Element(human_tag)) root.append(ET.Element(make_clark(human_tag)))
return root return root

View file

@ -42,7 +42,7 @@ from setuptools import find_packages, setup
# When the version is updated, a new section in the NEWS.md file must be # When the version is updated, a new section in the NEWS.md file must be
# added too. # added too.
VERSION = "master" VERSION = "3.0.1"
WEB_FILES = ["web/internal_data/css/icon.png", WEB_FILES = ["web/internal_data/css/icon.png",
"web/internal_data/css/main.css", "web/internal_data/css/main.css",
"web/internal_data/fn.js", "web/internal_data/fn.js",