Skip to content

Commit

Permalink
Switch to ruff and reformat code.
Browse files Browse the repository at this point in the history
  • Loading branch information
tasn committed Sep 2, 2024
1 parent 8ccee52 commit e0e4375
Show file tree
Hide file tree
Showing 25 changed files with 464 additions and 416 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ jobs:
- name: Update pip and install deps
run: |
python -m pip install --upgrade pip
python -m pip install check-manifest flake8
python -m pip install check-manifest
python -m pip install -r requirements-dev.txt
- name: Check MANIFEST.in in a source package
run: check-manifest -v

- name: Static code analysis and code style check
run: flake8 ./
run: |
ruff check .
ruff format --check .
14 changes: 7 additions & 7 deletions etesync_dav/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
"""

__copyright__ = 'Copyright (C) 2017-2021 Tom Hacohen'
__version__ = '0.32.1'
__license__ = 'GPL-3.0-only'
__author__ = 'Tom Hacohen'
__author_email__ = '[email protected]'
__url__ = 'https://github.com/etesync/etesync-dav'
__description__ = 'A CalDAV and CardDAV frontend for EteSync'
__copyright__ = "Copyright (C) 2017-2021 Tom Hacohen"
__version__ = "0.32.1"
__license__ = "GPL-3.0-only"
__author__ = "Tom Hacohen"
__author_email__ = "[email protected]"
__url__ = "https://github.com/etesync/etesync-dav"
__description__ = "A CalDAV and CardDAV frontend for EteSync"
31 changes: 16 additions & 15 deletions etesync_dav/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,26 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from appdirs import user_config_dir, user_data_dir
import os

LISTEN_ADDRESS = os.environ.get('ETESYNC_LISTEN_ADDRESS', 'localhost')
LISTEN_PORT = os.environ.get('ETESYNC_LISTEN_PORT', '37358')
from appdirs import user_config_dir, user_data_dir

LISTEN_ADDRESS = os.environ.get("ETESYNC_LISTEN_ADDRESS", "localhost")
LISTEN_PORT = os.environ.get("ETESYNC_LISTEN_PORT", "37358")

DEFAULT_HOSTS = '{}:{}'.format(LISTEN_ADDRESS, LISTEN_PORT)
DEFAULT_HOSTS = "{}:{}".format(LISTEN_ADDRESS, LISTEN_PORT)

SERVER_HOSTS = os.environ.get('ETESYNC_SERVER_HOSTS', DEFAULT_HOSTS)
LEGACY_CONFIG_DIR = os.environ.get('ETESYNC_CONFIG_DIR', user_config_dir("etesync-dav", "etesync"))
DATA_DIR = os.environ.get('ETESYNC_DATA_DIR', user_data_dir("etesync-dav", "etesync"))
SERVER_HOSTS = os.environ.get("ETESYNC_SERVER_HOSTS", DEFAULT_HOSTS)
LEGACY_CONFIG_DIR = os.environ.get("ETESYNC_CONFIG_DIR", user_config_dir("etesync-dav", "etesync"))
DATA_DIR = os.environ.get("ETESYNC_DATA_DIR", user_data_dir("etesync-dav", "etesync"))

ETESYNC_URL = os.environ.get('ETESYNC_URL', 'https://api.etebase.com/partner/etesync/')
LEGACY_ETESYNC_URL = os.environ.get('ETESYNC_URL', 'https://api.etesync.com/')
DATABASE_FILE = os.environ.get('ETESYNC_DATABASE_FILE', os.path.join(DATA_DIR, 'etesync_data.db'))
ETEBASE_DATABASE_FILE = os.environ.get('ETEBASE_DATABASE_FILE', os.path.join(DATA_DIR, 'etebase_data.db'))
ETESYNC_URL = os.environ.get("ETESYNC_URL", "https://api.etebase.com/partner/etesync/")
LEGACY_ETESYNC_URL = os.environ.get("ETESYNC_URL", "https://api.etesync.com/")
DATABASE_FILE = os.environ.get("ETESYNC_DATABASE_FILE", os.path.join(DATA_DIR, "etesync_data.db"))
ETEBASE_DATABASE_FILE = os.environ.get("ETEBASE_DATABASE_FILE", os.path.join(DATA_DIR, "etebase_data.db"))

HTPASSWD_FILE = os.path.join(DATA_DIR, 'htpaswd')
CREDS_FILE = os.path.join(DATA_DIR, 'etesync_creds')
HTPASSWD_FILE = os.path.join(DATA_DIR, "htpaswd")
CREDS_FILE = os.path.join(DATA_DIR, "etesync_creds")

SSL_KEY_FILE = os.path.join(DATA_DIR, 'etesync.key')
SSL_CERT_FILE = os.path.join(DATA_DIR, 'etesync.crt')
SSL_KEY_FILE = os.path.join(DATA_DIR, "etesync.key")
SSL_CERT_FILE = os.path.join(DATA_DIR, "etesync.crt")
44 changes: 26 additions & 18 deletions etesync_dav/local_cache/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import os

import msgpack
from etebase import Account, Client, CollectionAccessLevel, FetchOptions

from etebase import Account, Client, FetchOptions, CollectionAccessLevel
from etesync_dav import config

from . import db, models


COL_TYPES = ["etebase.vcard", "etebase.vevent", "etebase.vtodo"]


Expand All @@ -30,11 +29,12 @@ def msgpack_decode(content):
def batch(iterable, n=1):
length = len(iterable)
for ndx in range(0, length, n):
yield iterable[ndx:min(ndx + n, length)]
yield iterable[ndx : min(ndx + n, length)]


def get_millis():
import time

return int(round(time.time() * 1000))


Expand Down Expand Up @@ -65,26 +65,30 @@ def _init_db(self, db_path):
from playhouse.sqlite_ext import SqliteExtDatabase

directory = os.path.dirname(db_path)
if directory != '' and not os.path.exists(directory):
if directory != "" and not os.path.exists(directory):
os.makedirs(directory)

database = SqliteExtDatabase(db_path, pragmas={
'journal_mode': 'wal',
'foreign_keys': 1,
})
database = SqliteExtDatabase(
db_path,
pragmas={
"journal_mode": "wal",
"foreign_keys": 1,
},
)

self._set_db(database)

def _init_db_tables(self, database, additional_tables=None):
CURRENT_DB_VERSION = 1

database.create_tables([models.Config, models.User, models.CollectionEntity,
models.ItemEntity, models.HrefMapper], safe=True)
database.create_tables(
[models.Config, models.User, models.CollectionEntity, models.ItemEntity, models.HrefMapper], safe=True
)
if additional_tables:
database.create_tables(additional_tables, safe=True)

default_db_version = CURRENT_DB_VERSION
config, created = models.Config.get_or_create(defaults={'db_version': default_db_version})
config, created = models.Config.get_or_create(defaults={"db_version": default_db_version})

def sync(self):
self.sync_collection_list()
Expand Down Expand Up @@ -235,8 +239,12 @@ def get(self, uid):
with db.database_proxy:
col_mgr = self.etebase.get_collection_manager()
try:
return Collection(col_mgr, self.user.collections.where(
(models.CollectionEntity.uid == uid) & ~models.CollectionEntity.deleted).get())
return Collection(
col_mgr,
self.user.collections.where(
(models.CollectionEntity.uid == uid) & ~models.CollectionEntity.deleted
).get(),
)
except models.CollectionEntity.DoesNotExist as e:
raise DoesNotExist(e)

Expand Down Expand Up @@ -301,10 +309,10 @@ def get(self, uid):
with db.database_proxy:
item_mgr = self.col_mgr.get_item_manager(self.col)
try:
return Item(item_mgr,
self.cache_col.items.where(
(models.ItemEntity.uid == uid) & ~models.ItemEntity.deleted
).get())
return Item(
item_mgr,
self.cache_col.items.where((models.ItemEntity.uid == uid) & ~models.ItemEntity.deleted).get(),
)
except models.ItemEntity.DoesNotExist:
return None

Expand All @@ -323,7 +331,7 @@ def __init__(self, item_mgr, cache_item):

@property
def uid(self):
return self.meta['name']
return self.meta["name"]

# FIXME: cache
@property
Expand Down
14 changes: 5 additions & 9 deletions etesync_dav/local_cache/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class User(db.BaseModel):


class CollectionEntity(db.BaseModel):
local_user = pw.ForeignKeyField(User, backref='collections', on_delete='CASCADE')
local_user = pw.ForeignKeyField(User, backref="collections", on_delete="CASCADE")
# The uid of the collection (same as Etebase)
uid = pw.CharField(null=False, index=True)
eb_col = pw.BlobField()
Expand All @@ -24,13 +24,11 @@ class CollectionEntity(db.BaseModel):
local_stoken = pw.CharField(null=True, default=None)

class Meta:
indexes = (
(('local_user', 'uid'), True),
)
indexes = ((("local_user", "uid"), True),)


class ItemEntity(db.BaseModel):
collection = pw.ForeignKeyField(CollectionEntity, backref='items', on_delete='CASCADE')
collection = pw.ForeignKeyField(CollectionEntity, backref="items", on_delete="CASCADE")
# The uid of the content (vobject uid)
uid = pw.CharField(null=False, index=True)
eb_item = pw.BlobField()
Expand All @@ -39,11 +37,9 @@ class ItemEntity(db.BaseModel):
deleted = pw.BooleanField(null=False, default=False)

class Meta:
indexes = (
(('collection', 'uid'), True),
)
indexes = ((("collection", "uid"), True),)


class HrefMapper(db.BaseModel):
content = pw.ForeignKeyField(ItemEntity, primary_key=True, backref='href', on_delete='CASCADE')
content = pw.ForeignKeyField(ItemEntity, primary_key=True, backref="href", on_delete="CASCADE")
href = pw.CharField(null=False, index=True)
53 changes: 25 additions & 28 deletions etesync_dav/mac_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,19 @@
from subprocess import check_call

from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID

from etesync_dav.config import SSL_KEY_FILE, SSL_CERT_FILE
from etesync_dav.config import SSL_CERT_FILE, SSL_KEY_FILE

KEY_CIPHER = 'rsa'
KEY_CIPHER = "rsa"
KEY_SIZE = 4096
KEY_DAYS = 3650 # That's 10 years.

ON_MAC = sys.platform == 'darwin'
ON_WINDOWS = sys.platform in ['win32', 'cygwin']
ON_MAC = sys.platform == "darwin"
ON_WINDOWS = sys.platform in ["win32", "cygwin"]


class Error(Exception):
Expand All @@ -43,27 +42,25 @@ def has_ssl():


def needs_ssl():
return (ON_MAC or ON_WINDOWS) and \
not has_ssl()
return (ON_MAC or ON_WINDOWS) and not has_ssl()


def generate_cert(cert_path: str = SSL_CERT_FILE, key_path: str = SSL_KEY_FILE,
key_size: int = KEY_SIZE, key_days: int = KEY_DAYS):
def generate_cert(
cert_path: str = SSL_CERT_FILE, key_path: str = SSL_KEY_FILE, key_size: int = KEY_SIZE, key_days: int = KEY_DAYS
):
if os.path.exists(key_path):
print('Skipping key generation as already exists.')
print("Skipping key generation as already exists.")
return

hostname = 'localhost'
hostname = "localhost"

key = rsa.generate_private_key(
public_exponent=65537,
key_size=key_size,
backend=default_backend(),
)

name = x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, hostname)
])
name = x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, hostname)])

# best practice seem to be to include the hostname in the SAN, which *SHOULD* mean COMMON_NAME is ignored.
alt_names = [x509.DNSName(hostname)]
Expand Down Expand Up @@ -92,31 +89,31 @@ def generate_cert(cert_path: str = SSL_CERT_FILE, key_path: str = SSL_KEY_FILE,
encryption_algorithm=serialization.NoEncryption(),
)

with open(key_path, 'wb') as f:
with open(key_path, "wb") as f:
f.write(key_pem)
with open(cert_path, 'wb') as f:
with open(cert_path, "wb") as f:
f.write(cert_pem)


def macos_trust_cert(cert_path: str = SSL_CERT_FILE):
if not ON_MAC:
raise Error('this is not macOS.')
check_call(['security', 'import', cert_path])
check_call(['security', 'add-trusted-cert', '-p', 'ssl', cert_path])
raise Error("this is not macOS.")
check_call(["security", "import", cert_path])
check_call(["security", "add-trusted-cert", "-p", "ssl", cert_path])


def windows_trust_cert(cert_path: str = SSL_CERT_FILE):
"""Import given certificate into a certificate store."""
if not ON_WINDOWS:
raise Error('this is not Windows.')
raise Error("this is not Windows.")
check_call(
[
'powershell.exe',
'Import-Certificate',
'-FilePath',
"powershell.exe",
"Import-Certificate",
"-FilePath",
'"{}"'.format(cert_path),
'-CertStoreLocation',
r'Cert:\CurrentUser\Root',
"-CertStoreLocation",
r"Cert:\CurrentUser\Root",
]
)

Expand All @@ -127,4 +124,4 @@ def trust_cert(cert_path: str = SSL_CERT_FILE):
elif ON_MAC:
macos_trust_cert(cert_path)
else:
raise Error('Only supported on windows/macOS')
raise Error("Only supported on windows/macOS")
Loading

0 comments on commit e0e4375

Please sign in to comment.