Skip to content

Commit e2d3d56

Browse files
committed
adopt management command filer_to_finder to changed interface
1 parent c5aa02c commit e2d3d56

File tree

3 files changed

+81
-23
lines changed

3 files changed

+81
-23
lines changed

README-Finder.md

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,16 @@ while preserving the possibility to perform queries across all tables. This allo
5050
models inheriting from the `AbstractFileModel` without the need of **django-polymorphic**, and thus
5151
a join between two or more tables for each query.
5252

53-
The Admin interface has also been completely rewritten and allows multi-tenant usage out of the box.
54-
For instance, there is no more list view for the `FolderModel` and the `FileModel` (or any
55-
specialized implementation). Instead, there are only details views for each of those models. This is
56-
much nearer to what a user would expect from a file system. Therefore, if a user wants to access the
57-
list view of a folder, he is redirected immediately to the detail view of the root folder of the
58-
given tenant. From there, he can traverse the folder tree in the same manner he's used to from his
59-
operating system.
53+
Each root folder is associated with a *realm*. A realm is a named area inside the file system, which
54+
can be used to separate files and folders of different tenants. Each realm has its own root folder.
55+
By using realms, it is possible to use **django-filer** in a multi-tenant environment.
56+
57+
The Admin interface has also been completely rewritten. For instance, there is no more list view for
58+
the `FolderModel` and the `FileModel` (or any specialized implementation). Instead, there are only
59+
details views for each of those models. This is much nearer to what a user would expect from a file
60+
system. Therefore, if a user wants to access the list view of a folder, he is redirected immediately
61+
to the detail view of the root folder of the given tenant. From there, he can traverse the folder
62+
tree in the same manner he's used to from his operating system.
6063

6164

6265
## New User Interface
@@ -95,8 +98,8 @@ ancestors. This allows to easily move files between those folders.
9598
### Multiple Favrourite Folders
9699

97100
Each user can have multiple favourite folders. This allows him to quickly access those folders from
98-
the navigation bar. It also it pssoble to drag a file from the current view into one of the tabs for
99-
of the favorite folders.
101+
the navigation bar. It is also possible to drag a file from the current view into one of the tabs
102+
for of the favorite folders.
100103

101104

102105
### Implementation Details
@@ -142,7 +145,56 @@ If you use:
142145
* `finder.contrib.audio` or `finder.contrib.video`, assure that `ffmpeg-python` is installed.
143146
* `finder.contrib.image.pil`, assure that `Pillow` is installed.
144147
* `finder.contrib.image.svg`, assure that `reportlab` and `svglib` are installed.
145-
* Postgres as database, install `psycopg2` or `psycopg2-binary` if available for your platform.
148+
* Postgres as a database, install `psycopg2` or `psycopg2-binary` if available for your platform.
149+
150+
Each realm requires two storage backends. One for the public files and one for their thumbnails
151+
and/or samples. Add these storage backends to the `STORAGES` setting in your `settings.py`:
152+
153+
```python
154+
STORAGES = {
155+
'default': {
156+
'BACKEND': 'django.core.files.storage.FileSystemStorage',
157+
},
158+
'staticfiles': {
159+
'BACKEND': 'django.contrib.staticfiles.storage.StaticFilesStorage',
160+
},
161+
'finder_public': {
162+
'BACKEND': 'finder.storage.FinderSystemStorage',
163+
'OPTIONS': {
164+
'location': '/path/to/your/media/filer_public',
165+
'base_url': '/media/filer_public/',
166+
'allow_overwrite': True,
167+
},
168+
},
169+
'finder_public_samples': {
170+
'BACKEND': 'finder.storage.FinderSystemStorage',
171+
'OPTIONS': {
172+
'location': '/path/to/your/media/filer_public_thumbnails',
173+
'base_url': '/media/filer_public_thumbnails/',
174+
'allow_overwrite': True,
175+
},
176+
},
177+
}
178+
```
179+
180+
If instead of using the local file system you want to use another storage backend, such as Amazon S3
181+
or Google Cloud Storage, configure the corresponding storage backend in the `STORAGES` setting as:
182+
183+
```python
184+
STORAGES = {
185+
...
186+
'finder_public': {
187+
'BACKEND': 'storages.backends.s3.S3Storage',
188+
'OPTIONS': {...},
189+
},
190+
'finder_public_samples': {
191+
'BACKEND': 'storages.backends.s3.S3Storage',
192+
'OPTIONS': {...},
193+
},
194+
}
195+
```
196+
197+
Note that multiple realms can share the same storage location or bucket.
146198

147199
Run the migrations for app `finder`:
148200

finder/management/commands/filer_to_finder.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def handle(self, verbosity, *args, **options):
2424

2525
def forward(self):
2626
site = Site.objects.get(id=settings.SITE_ID)
27-
owner = FilerFolder.objects.filter(parent__isnull=True, owner__isnull=False).first().owner
27+
owner = FilerFolder.objects.filter(parent__isnull=True).first().owner
2828
try:
2929
realm = FinderRealmModel.objects.get(site=site, slug=admin_site.name)
3030
except FinderRealmModel.DoesNotExist:
@@ -35,16 +35,17 @@ def forward(self):
3535
self.migrate_folder(filer_folder, realm.root_folder)
3636

3737
def migrate_folder(self, filer_folder, finder_parent):
38-
finder_folder = finder_parent.listdir(name=filer_folder.name, is_folder=True).first()
39-
if finder_folder is None:
38+
if finder_folder := finder_parent.listdir(name=filer_folder.name, is_folder=True).first():
39+
finder_folder = FinderFolder.objects.get(id=finder_folder['id'])
40+
else:
4041
finder_folder = FinderFolder.objects.create(
4142
name=filer_folder.name,
4243
parent=finder_parent,
4344
created_at=filer_folder.created_at,
4445
last_modified_at=filer_folder.modified_at,
4546
owner_id=filer_folder.owner_id,
4647
)
47-
self.stdout.write(f"Create folder {finder_folder} in {finder_parent}")
48+
self.stdout.write(f"Create folder {finder_folder} in {finder_parent}”.")
4849

4950
allowed_image_types = ['image/gif', 'image/jpeg', 'image/png', 'image/webp', 'image/svg+xml']
5051
for filer_file in filer_folder.files.all():
@@ -60,8 +61,11 @@ def migrate_file(self, filer_file, finder_parent):
6061
path = Path(filer_file.file.name)
6162
inode_id = path.parent.stem
6263
try:
63-
finder_file = FinderFile.objects.get_inode(id=inode_id)
64+
finder_file = FinderFile.objects.get(id=inode_id)
6465
except FinderFile.DoesNotExist:
66+
if not filer_file._file_size:
67+
self.stderr.write(f"File {filer_file} has no file size.")
68+
return
6569
FinderFile.objects.create(
6670
id=inode_id,
6771
name=filer_file.name if filer_file.name else filer_file.original_filename,
@@ -91,15 +95,19 @@ def migrate_image(self, filer_image, finder_parent):
9195
meta_data = {'alt_text': getattr(filer_image, 'default_alt_text', '')}
9296
try:
9397
center_x, center_y = map(float, filer_image.subject_location.split(','))
94-
# since Filer does not store the area of interest, we assume it is 10px
95-
meta_data['crop_x'] = center_x - 5
96-
meta_data['crop_y'] = center_y - 5
97-
meta_data['crop_size'] = 10
98+
# since Filer does not store the area of interest, we assume it's 20% of its width or height
99+
crop_size = int(round(max(filer_image.width, filer_image.height) * 0.2))
100+
meta_data['crop_x'] = center_x - crop_size / 2
101+
meta_data['crop_y'] = center_y - crop_size / 2
102+
meta_data['crop_size'] = crop_size
98103
except ValueError:
99104
pass
100105
try:
101-
finder_image = FinderImage.objects.get_inode(id=inode_id)
102-
except FinderFile.DoesNotExist:
106+
finder_image = FinderImage.objects.get(id=inode_id)
107+
except FinderImage.DoesNotExist:
108+
if not filer_image._file_size:
109+
self.stderr.write(f"Image {filer_image} has no file size.")
110+
return
103111
FinderImage.objects.create(
104112
id=inode_id,
105113
name=filer_image.name if filer_image.name else filer_image.original_filename,

finder/management/commands/finder.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ def handle(self, verbosity, subcommand, *args, **options):
2020
self.reorganize()
2121
elif subcmd == 'reorder':
2222
self.reorder()
23-
elif subcmd == 'migrate-filer':
24-
call_command('filer_to_finder', verbosity=verbosity)
2523
else:
2624
self.stderr.write(f"Unknown subcommand ‘{subcmd}’")
2725

0 commit comments

Comments
 (0)