diff --git a/kontor-api/src/db/models/media.py b/kontor-api/src/db/models/media.py index 975fef9..ae360b3 100644 --- a/kontor-api/src/db/models/media.py +++ b/kontor-api/src/db/models/media.py @@ -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})' - - diff --git a/kontor-api/src/templates/media/actor_detail.html b/kontor-api/src/templates/media/actor_detail.html index 603c1ff..483f2db 100644 --- a/kontor-api/src/templates/media/actor_detail.html +++ b/kontor-api/src/templates/media/actor_detail.html @@ -20,6 +20,10 @@ Actor Name {{actor.name}} + + URL + {{actor.url}} + Works diff --git a/kontor-scripts/db/models/media.py b/kontor-scripts/db/models/media.py index f8d9dc8..2f43767 100644 --- a/kontor-scripts/db/models/media.py +++ b/kontor-scripts/db/models/media.py @@ -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 diff --git a/kontor-scripts/find_links.py b/kontor-scripts/find_links.py new file mode 100644 index 0000000..70d667a --- /dev/null +++ b/kontor-scripts/find_links.py @@ -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') + diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActor.java index cfc6270..0d2e328 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActor.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/media/data/MediaActor.java @@ -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 mediaActorFiles = new LinkedList<>(); diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorForm.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorForm.java index e011fb7..b9a7dbd 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorForm.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorForm.java @@ -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 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()); } diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorView.java index 23ca35e..f864dee 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorView.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/media/views/MediaActorView.java @@ -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 grid = new Grid<>(MediaActor.class); + Grid grid = new Grid<>(MediaActor.class, false); + Grid.Column idColumn = grid.addColumn(MediaActor::getId) + .setHeader("ID").setResizable(true).setSortable(true); + Grid.Column createdColumn = grid.addColumn(MediaActor::getCreatedDate) + .setHeader("Erstellt").setResizable(true).setSortable(true); + Grid.Column modifiedColumn = grid.addColumn(MediaActor::getLastModifiedDate) + .setHeader("GeƤndert").setResizable(true).setSortable(true); + Grid.Column nameColumn = grid.addColumn(MediaActor::getName) + .setHeader("Name").setResizable(true).setSortable(true); + Grid.Column 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 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; }