add column to MediaActor to store weblink

This commit is contained in:
Thomas Peetz
2025-08-03 17:37:57 +02:00
parent aed2413b88
commit 450bfdb394
7 changed files with 103 additions and 6 deletions
+1 -2
View File
@@ -71,6 +71,7 @@ class MediaFile(Base, BaseMixin, BaseVideoMixin):
class MediaActor(Base, BaseMixin):
__tablename__ = 'media_actor'
name = Column(String)
url = Column(String, unique=True)
media_actor_files = relationship("MediaActorFile")
@@ -107,5 +108,3 @@ class MediaVideo(Base, BaseMixin):
return f'{self.url}({self.id})'
else:
return f'{self.title}({self.id})'
@@ -20,6 +20,10 @@
<th scope="row">Actor Name</th>
<td colspan="2">{{actor.name}}</td>
</tr>
<tr>
<th scope="row">URL</th>
<td colspan="2">{{actor.url}}</td>
</tr>
<tr>
<th scope="row">Works</th>
<td colspan="2">
+3
View File
@@ -98,6 +98,7 @@ class MediaFile(Base, BaseMixin, BaseVideoMixin):
class MediaActor(Base, BaseMixin):
__tablename__ = 'media_actor'
name = Column(String)
url = Column(String, unique=True)
media_actor_files = relationship("MediaActorFile")
def import_dict(self, import_data: Dict[AnyStr, Any]):
@@ -106,6 +107,7 @@ class MediaActor(Base, BaseMixin):
self.last_modified_date = import_data['last_modified_date']
self.version = import_data['version']
self.name = import_data['name']
self.url = import_data['url']
def export_dict(self) -> Dict[AnyStr, Any]:
item: Dict[AnyStr, Any] = {}
@@ -114,6 +116,7 @@ class MediaActor(Base, BaseMixin):
item['last_modified_date'] = str(self.last_modified_date)
item['version'] = self.version
item['name'] = self.name
item['url'] = self.url
return item
+66
View File
@@ -0,0 +1,66 @@
"""
download files with URLs from DB
"""
import logging.config
import requests
import yaml
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
from pathlib import Path
from bs4 import BeautifulSoup
from platformdirs import PlatformDirs
parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument('--verbose', '-v', action='count', default=0)
parser.add_argument('--config', '-c', default='kontor-docker')
args = parser.parse_args()
def get_logger(level: int, config: str):
dirs = PlatformDirs(config)
logging_config = Path(dirs.user_config_dir, 'logging-config.yaml')
with open(logging_config, 'rt') as f:
configDict = yaml.safe_load(f.read())
logging.config.dictConfig(configDict)
logger = logging.getLogger('development')
if level is not None:
match level:
case 0:
logger.setLevel(logging.INFO)
case 1:
logger.setLevel(logging.DEBUG)
case _:
logger.setLevel(logging.CRITICAL)
return logger
if __name__ == '__main__':
log = get_logger(args.verbose, args.config)
log.info('kontor.update_titles started')
response = requests.get("http://127.0.0.1:8800/api/media/files?review=true")
log.info(f"Status: {response.status_code}")
data = response.json()
log.info(f"data: {len(data)}")
for item in data:
link = item['url']
log.info(f"{item['id']} - {str(link)}")
try:
r = requests.get(link)
soup = BeautifulSoup(r.content, "html.parser")
title = soup.title.string
anchors = soup.find_all('a')
for anchor in anchors:
if anchor.has_attr('href'):
link_url = anchor['href']
if link_url and link_url.__contains__('pornstars/'):
log.info(link_url)
item['title'] = title
item['review'] = False
except Exception as error:
log.info(f"something went wrong: {error} {anchor}")
item['title'] = None
item['review'] = True
#update = requests.put(f"http://127.0.0.1:8800/api/media/files/{item['id']}", json=item)
#log.info(f"update status: {update.status_code}")
#log.info(f"update result: {update.json()}")
log.info('kontor.update_titles finished')
@@ -23,6 +23,9 @@ public class MediaActor extends AbstractEntity {
@Column(unique = true)
private String name;
@Nullable
private String url;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "media_actor", cascade = CascadeType.REFRESH, orphanRemoval = true)
@Nullable
List<MediaActorFile> mediaActorFiles = new LinkedList<>();
@@ -7,7 +7,6 @@ import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.listbox.MultiSelectListBox;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.BeanValidationBinder;
@@ -22,6 +21,7 @@ import java.util.List;
public class MediaActorForm extends FormLayout {
TextField name = new TextField("Name");
TextField url = new TextField("URL");
Grid<MediaActorFile> mediaActorFiles = new Grid<>(MediaActorFile.class);
Button save = new Button("Save");
@@ -37,6 +37,7 @@ public class MediaActorForm extends FormLayout {
mediaActorFiles.setColumns("media_file.title");
mediaActorFiles.getColumnByKey("media_file.title").setHeader("File Title");
add(name, 2);
add(url, 2);
add(mediaActorFiles, 2);
add(createButtonsLayout());
}
@@ -2,6 +2,7 @@ package de.thpeetz.kontor.media.views;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
@@ -10,9 +11,12 @@ import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.annotation.SpringComponent;
import de.thpeetz.kontor.common.views.ColumnToggleContextMenu;
import de.thpeetz.kontor.common.views.MainLayout;
import de.thpeetz.kontor.media.MediaConstants;
import de.thpeetz.kontor.media.data.MediaActor;
import de.thpeetz.kontor.media.data.MediaFile;
import de.thpeetz.kontor.media.services.MediaFileService;
import jakarta.annotation.security.PermitAll;
import lombok.Getter;
@@ -26,7 +30,17 @@ import org.springframework.context.annotation.Scope;
public class MediaActorView extends VerticalLayout {
@Getter
Grid<MediaActor> grid = new Grid<>(MediaActor.class);
Grid<MediaActor> grid = new Grid<>(MediaActor.class, false);
Grid.Column<MediaActor> idColumn = grid.addColumn(MediaActor::getId)
.setHeader("ID").setResizable(true).setSortable(true);
Grid.Column<MediaActor> createdColumn = grid.addColumn(MediaActor::getCreatedDate)
.setHeader("Erstellt").setResizable(true).setSortable(true);
Grid.Column<MediaActor> modifiedColumn = grid.addColumn(MediaActor::getLastModifiedDate)
.setHeader("Geändert").setResizable(true).setSortable(true);
Grid.Column<MediaActor> nameColumn = grid.addColumn(MediaActor::getName)
.setHeader("Name").setResizable(true).setSortable(true);
Grid.Column<MediaActor> urlColumn = grid.addColumn(MediaActor::getUrl)
.setHeader("URL").setResizable(true).setSortable(true);
TextField filterText = new TextField();
@Getter
MediaActorForm form;
@@ -46,7 +60,6 @@ public class MediaActorView extends VerticalLayout {
private void configureGrid() {
grid.addClassName("media-actor-grid");
grid.setSizeFull();
grid.setColumns("name");
grid.getColumns().forEach(col -> col.setAutoWidth(true));
grid.asSingleSelect().addValueChangeListener(event -> editMediaActor(event.getValue()));
}
@@ -90,7 +103,15 @@ public class MediaActorView extends VerticalLayout {
Button addMediaActorButton = new Button("Add actor");
addMediaActorButton.addClickListener(click -> addMediaActor());
HorizontalLayout toolbar = new HorizontalLayout(filterText, addMediaActorButton);
Button menuButton = new Button("Show/Hide Columns");
menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
ColumnToggleContextMenu<MediaActor> columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton);
columnToggleContextMenu.addColumnToggleItem(idColumn);
columnToggleContextMenu.addColumnToggleItem(createdColumn);
columnToggleContextMenu.addColumnToggleItem(modifiedColumn);
columnToggleContextMenu.addColumnToggleItem(nameColumn);
columnToggleContextMenu.addColumnToggleItem(urlColumn);
HorizontalLayout toolbar = new HorizontalLayout(filterText, addMediaActorButton, menuButton);
toolbar.addClassName("toolbar");
return toolbar;
}