Skip to content

Commit 795c302

Browse files
authored
Merge pull request #1 from ramonaoptics/first_push
First push
2 parents d745ac4 + 7350cc7 commit 795c302

14 files changed

Lines changed: 2961 additions & 0 deletions

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
multiuserfilelock/_version.py export-subst

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.egg-info
2+
.pymon
3+
.tox
4+
dist
5+
build

.travis.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
language: python
2+
python:
3+
- 3.9
4+
- 3.8
5+
- 3.7
6+
install:
7+
- pip install -U tox-travis
8+
script: tox
9+
deploy:
10+
provider: pypi
11+
user: __token__
12+
distributions: sdist bdist_wheel
13+
on:
14+
tags: true
15+
python: 3.7
16+
all_branches: true
17+
password:
18+
secure: YOZIZf+k4u6OuWTDrgl/GOPhK7jEaQiS2iSXCnGUFCcuFL0eKVqxqJQFnI4LUYVUZKyEPLPyESKsvjlj33O3MnetDdh6Jr249kvAK9y/VVBIIIk0XqC2sDqxSj6h7dP33dXfwfmCAMbrR3xMVUUoL0uaTMbQHebhDGG/8yLMxAdnYKXpdTkVeP0vg4Ar2BCXnsR1lbAPW1Co+lSMPiLltIIf3HpFqsEH0C1Nnsbl4nhg5xwsz8Rv1lNXQkfCmlvzJ9RVssF0vQOf5D+VOg0ABKGzWM69Yh3cZjLTpge2Oy8FHJzCmlepa5tH7BlbHYImgSREiOPplUTBiQZdju6X8+QZJathJBFRKClPEJjPfXxGZkcmv+vHWYfEq1bpJxezw3zOprpzdf2S809MolIP3veW4WVaXABhItebKAISZLY1o8OL9Q6UywGnhzg7HJ04bZuVTe0b7WGZJabvmksv4MrEH1SRHKkoVQXJV1DkTBf5dOp7uvE3EAMwZ1msJ9K+4qKavArYc8Hwj6WjytQCB6uY5Z1kDlxU1sHLDhzlj+oPcDzqxt5RBRiJ1cusHCBq/n03o1UdvhvLifE+A0OGS1EHRlYRaloQsJkIlZSPWGR2M7ruEgcrltdgrNbaKbR6lNYjzVGknCp8QC7DifVAFwOZ6hwBcmzwCm58cyrT9Vk=

MANIFEST.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include versioneer.py
2+
include multiuserfilelock/_version.py
3+
include LICENSE

multiuserfilelock/__init__.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
from . import _version
2+
__version__ = _version.get_versions()['version']
3+
4+
from filelock import FileLock, Timeout
5+
import os
6+
import shutil
7+
import tempfile
8+
from pathlib import Path
9+
10+
# Creating the locks directly in the /tmp dir on linux causes
11+
# many problems since the `/tmp` dir has the sticky bit enabled.
12+
# The sticky bit stops an other user from deleting your file.
13+
# It seems that this stops some other user from opening a file for
14+
#
15+
# We tried to use `SoftFileLock` and while it worked,
16+
# SoftFileLocks did not automatically get deleted upon the crash
17+
# or force quit of a python console.
18+
# This made them really problematic when closing python quickly.
19+
#
20+
# Therefore, we store all our locks in a subdirectory
21+
# On linux we set the group of this MultiUserFileLock to
22+
# the desired group so that multiple people
23+
if os.name == 'nt':
24+
# Windows has a pretty bad per use /tmp directory
25+
# We therefore use the public directory, and create a tempdir in there
26+
tmpdir = Path(os.environ.get('public', r'C:\Users\Public')) / 'tmp'
27+
else:
28+
tmpdir = tempfile.gettempdir()
29+
30+
31+
class MultiUserFileLock(FileLock):
32+
def __init__(self, *args, user=None, group=None, chmod=0o666, **kwargs):
33+
if os.name == 'nt':
34+
self._user = None
35+
self._group = None
36+
else:
37+
self._user = user
38+
self._group = group
39+
self._chmod = chmod
40+
# Will create a ._lock_file object
41+
# but will not create the files on the file system
42+
super().__init__(*args, **kwargs)
43+
self._lock_file_path = Path(self._lock_file)
44+
parent = self._lock_file_path.parent
45+
# Even though the "other write" permissions are enabled
46+
# it seems that the operating systems disables that for the /tmp dir
47+
parent.mkdir(mode=0o777, parents=True, exist_ok=True)
48+
49+
if self._group is not None and parent.group() != self._group:
50+
shutil.chown(parent, group=self._group)
51+
52+
# Changing the owner in the tmp directory is hard..
53+
if self._user is not None and parent.owner() != self._user:
54+
shutil.chown(parent, user=self._user)
55+
56+
def acquire(self, *args, **kwargs):
57+
super().acquire(*args, **kwargs)
58+
# once the lock has been acquired, we are more guaranteed that the
59+
# _lock_file exists
60+
if self._chmod:
61+
desired_permissions = self._chmod
62+
current_permissions = self._lock_file_path.stat().st_mode
63+
64+
missing_permissions = (
65+
current_permissions & desired_permissions
66+
) ^ desired_permissions
67+
68+
# changing permissions can be tricky, so only change them
69+
# if we need to
70+
if missing_permissions != 0:
71+
# Make sure the parent directory can be written to by others
72+
self._lock_file_path.chmod(desired_permissions)
73+
if self._group is not None:
74+
if self._lock_file_path.group() != self._group:
75+
shutil.chown(self._lock_file_path, group=self._group)
76+
if self._user is not None:
77+
if self._lock_file_path.owner() != self._user:
78+
shutil.chown(self._lock_file_path, user=self._user)
79+
80+
81+
__all__ = [
82+
'MultiUserFileLock',
83+
'Timeout',
84+
]

0 commit comments

Comments
 (0)