detection-dataset-annotator 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- detection_dataset_annotator/__init__.py +1 -0
- detection_dataset_annotator/about.py +13 -0
- detection_dataset_annotator/desktop.py +103 -0
- detection_dataset_annotator/icons/logo.png +0 -0
- detection_dataset_annotator/modules/__init__.py +1 -0
- detection_dataset_annotator/modules/configure.py +59 -0
- detection_dataset_annotator/modules/wabout.py +108 -0
- detection_dataset_annotator/program.py +12 -0
- detection_dataset_annotator/program_annotator.py +614 -0
- detection_dataset_annotator/program_project.py +409 -0
- detection_dataset_annotator-0.1.0.dist-info/METADATA +67 -0
- detection_dataset_annotator-0.1.0.dist-info/RECORD +16 -0
- detection_dataset_annotator-0.1.0.dist-info/WHEEL +5 -0
- detection_dataset_annotator-0.1.0.dist-info/entry_points.txt +3 -0
- detection_dataset_annotator-0.1.0.dist-info/licenses/LICENSE +674 -0
- detection_dataset_annotator-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# about.py
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.0"
|
|
4
|
+
__package__ = "detection_dataset_annotator"
|
|
5
|
+
__program_name__ = "detection-dataset-annotator"
|
|
6
|
+
__program_project__ = "detection-dataset-project"
|
|
7
|
+
__author__ = "Fernando Pujaico Rivera"
|
|
8
|
+
__email__ = "fernando.pujaico.rivera@gmail.com"
|
|
9
|
+
__description__ = "A slight annotator of detection datasets"
|
|
10
|
+
__url_source__ = "https://github.com/trucomanx/DetectionDatasetAnnotator"
|
|
11
|
+
__url_doc__ = "https://github.com/trucomanx/DetectionDatasetAnnotator/tree/main/doc"
|
|
12
|
+
__url_funding__ = "https://trucomanx.github.io/en/funding.html"
|
|
13
|
+
__url_bugs__ = "https://github.com/trucomanx/DetectionDatasetAnnotator/issues"
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import detection_dataset_annotator.about as about
|
|
3
|
+
import subprocess
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def update_desktop_database(desktop_path):
|
|
7
|
+
applications_dir = os.path.expanduser(desktop_path)
|
|
8
|
+
try:
|
|
9
|
+
subprocess.run(
|
|
10
|
+
["update-desktop-database", applications_dir],
|
|
11
|
+
check=True
|
|
12
|
+
)
|
|
13
|
+
print("Shortcut database updated successfully.")
|
|
14
|
+
except subprocess.CalledProcessError as e:
|
|
15
|
+
print(f"Error updating the database: {e}")
|
|
16
|
+
except FileNotFoundError:
|
|
17
|
+
print("The command 'update-desktop-database' was not found. Verify that the package 'desktop-file-utils' is installed.")
|
|
18
|
+
|
|
19
|
+
def create_desktop_file(desktop_path, overwrite=False, program_name=None):
|
|
20
|
+
base_dir_path = os.path.dirname(os.path.abspath(__file__))
|
|
21
|
+
icon_path = os.path.join(base_dir_path, 'icons', 'logo.png')
|
|
22
|
+
|
|
23
|
+
if program_name is None:
|
|
24
|
+
__program_name = about.__program_name__
|
|
25
|
+
else:
|
|
26
|
+
__program_name = program_name
|
|
27
|
+
|
|
28
|
+
script_path = os.path.expanduser(f"~/.local/bin/{__program_name}")
|
|
29
|
+
|
|
30
|
+
desktop_entry = f"""[Desktop Entry]
|
|
31
|
+
Name={__program_name}
|
|
32
|
+
Comment={about.__description__}
|
|
33
|
+
Exec={script_path}
|
|
34
|
+
Terminal=false
|
|
35
|
+
Type=Application
|
|
36
|
+
Icon={icon_path}
|
|
37
|
+
StartupNotify=true
|
|
38
|
+
Categories=Education;ResearchTools;
|
|
39
|
+
Keywords=organizer;python;
|
|
40
|
+
Encoding=UTF-8
|
|
41
|
+
StartupWMClass={about.__package__}
|
|
42
|
+
"""
|
|
43
|
+
path = os.path.expanduser(os.path.join(desktop_path,f"{__program_name}.desktop"))
|
|
44
|
+
|
|
45
|
+
if not os.path.exists(path) or overwrite == True:
|
|
46
|
+
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
47
|
+
with open(path, "w") as f:
|
|
48
|
+
f.write(desktop_entry)
|
|
49
|
+
os.chmod(path, 0o755)
|
|
50
|
+
print(f"File {__program_name}.desktop created in {path}.")
|
|
51
|
+
update_desktop_database(desktop_path)
|
|
52
|
+
|
|
53
|
+
def create_desktop_directory( directory_name = "ResearchTools",
|
|
54
|
+
long_name = "Scientific research",
|
|
55
|
+
comment = "Tools for Writing and Research Support",
|
|
56
|
+
icon = "accessories-text-editor",
|
|
57
|
+
overwrite = False):
|
|
58
|
+
|
|
59
|
+
desktop_entry = f"""[Desktop Entry]
|
|
60
|
+
Version=1.0
|
|
61
|
+
Type=Directory
|
|
62
|
+
Name={long_name}
|
|
63
|
+
Comment={comment}
|
|
64
|
+
Icon={icon}
|
|
65
|
+
"""
|
|
66
|
+
path = os.path.expanduser(f"~/.local/share/desktop-directories/{directory_name}.directory")
|
|
67
|
+
|
|
68
|
+
if not os.path.exists(path) or overwrite == True: # Evita sobrescrever
|
|
69
|
+
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
70
|
+
with open(path, "w") as f:
|
|
71
|
+
f.write(desktop_entry)
|
|
72
|
+
os.chmod(path, 0o755)
|
|
73
|
+
print(f"File {path} created.")
|
|
74
|
+
|
|
75
|
+
def create_desktop_menu(directory_name = "ResearchTools",
|
|
76
|
+
basename = "research-tools",
|
|
77
|
+
overwrite = False):
|
|
78
|
+
|
|
79
|
+
desktop_entry = f"""<!-- ~/.config/menus/applications-merged/{basename}.menu -->
|
|
80
|
+
<Menu>
|
|
81
|
+
<Name>Applications</Name>
|
|
82
|
+
<Menu>
|
|
83
|
+
<Name>{directory_name}</Name>
|
|
84
|
+
<Directory>{directory_name}.directory</Directory>
|
|
85
|
+
<Include>
|
|
86
|
+
<Category>{directory_name}</Category>
|
|
87
|
+
</Include>
|
|
88
|
+
</Menu>
|
|
89
|
+
</Menu>
|
|
90
|
+
"""
|
|
91
|
+
path = os.path.expanduser(f"~/.config/menus/applications-merged/{basename}.menu")
|
|
92
|
+
|
|
93
|
+
if not os.path.exists(path) or overwrite == True: # Evita sobrescrever
|
|
94
|
+
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
95
|
+
with open(path, "w") as f:
|
|
96
|
+
f.write(desktop_entry)
|
|
97
|
+
print(f"File {path} created.")
|
|
98
|
+
|
|
99
|
+
if __name__ == '__main__':
|
|
100
|
+
create_desktop_menu()
|
|
101
|
+
create_desktop_directory()
|
|
102
|
+
create_desktop_file()
|
|
103
|
+
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
def verify_default_config(path,default_content={}):
|
|
5
|
+
"""
|
|
6
|
+
Cria o arquivo JSON no caminho especificado com conteúdo padrão,
|
|
7
|
+
criando diretórios intermediários se necessário.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# Se o arquivo não existir, cria com o conteúdo padrão
|
|
11
|
+
if not os.path.exists(path):
|
|
12
|
+
# Garante que os diretórios existam
|
|
13
|
+
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
14
|
+
with open(path, 'w', encoding='utf-8') as f:
|
|
15
|
+
json.dump(default_content, f, ensure_ascii=False, indent=4)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def merge_defaults(config, defaults):
|
|
19
|
+
"""
|
|
20
|
+
Adiciona valores de defaults que não existam em config.
|
|
21
|
+
Funciona recursivamente para dicionários aninhados.
|
|
22
|
+
"""
|
|
23
|
+
for key, value in defaults.items():
|
|
24
|
+
if key not in config:
|
|
25
|
+
config[key] = value
|
|
26
|
+
elif isinstance(value, dict) and isinstance(config[key], dict):
|
|
27
|
+
merge_defaults(config[key], value)
|
|
28
|
+
return config
|
|
29
|
+
|
|
30
|
+
# Lê o JSON no início do programa
|
|
31
|
+
def load_config(config_path, default_content=None):
|
|
32
|
+
"""
|
|
33
|
+
Carrega o JSON de configuração e preenche com valores padrão se necessário.
|
|
34
|
+
"""
|
|
35
|
+
config = {}
|
|
36
|
+
if os.path.exists(config_path):
|
|
37
|
+
with open(config_path, 'r', encoding='utf-8') as f:
|
|
38
|
+
try:
|
|
39
|
+
config = json.load(f)
|
|
40
|
+
except json.JSONDecodeError:
|
|
41
|
+
print("Erro ao ler config, usando defaults")
|
|
42
|
+
config = {}
|
|
43
|
+
|
|
44
|
+
if default_content:
|
|
45
|
+
config = merge_defaults(config, default_content)
|
|
46
|
+
|
|
47
|
+
return config
|
|
48
|
+
|
|
49
|
+
def save_config(path,content):
|
|
50
|
+
"""
|
|
51
|
+
Cria o arquivo JSON no caminho especificado com conteúdo padrão,
|
|
52
|
+
criando diretórios intermediários se necessário.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
# Garante que os diretórios existam
|
|
56
|
+
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
57
|
+
with open(path, 'w', encoding='utf-8') as f:
|
|
58
|
+
json.dump(content, f, ensure_ascii=False, indent=4)
|
|
59
|
+
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from PyQt5.QtWidgets import QDialog, QLabel, QPushButton, QVBoxLayout
|
|
2
|
+
from PyQt5.QtGui import QPixmap
|
|
3
|
+
from PyQt5.QtCore import Qt
|
|
4
|
+
|
|
5
|
+
class AboutWindow(QDialog):
|
|
6
|
+
"""About dialog window"""
|
|
7
|
+
def __init__(self, data, logo_path, parent=None):
|
|
8
|
+
super().__init__(parent)
|
|
9
|
+
self.setWindowTitle("About")
|
|
10
|
+
self.setMinimumSize(500, 300)
|
|
11
|
+
|
|
12
|
+
# Create layout
|
|
13
|
+
layout = QVBoxLayout(self)
|
|
14
|
+
|
|
15
|
+
# Logo
|
|
16
|
+
logo_label = QLabel()
|
|
17
|
+
pixmap = QPixmap(logo_path)
|
|
18
|
+
pixmap = pixmap.scaled(100, 100, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
|
19
|
+
logo_label.setPixmap(pixmap)
|
|
20
|
+
logo_label.setAlignment(Qt.AlignCenter)
|
|
21
|
+
layout.addWidget(logo_label)
|
|
22
|
+
|
|
23
|
+
# Description
|
|
24
|
+
description_label = QLabel(f"<b>{data['description']}</b>")
|
|
25
|
+
description_label.setWordWrap(True)
|
|
26
|
+
description_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
|
|
27
|
+
layout.addWidget(description_label)
|
|
28
|
+
|
|
29
|
+
# Add separator
|
|
30
|
+
separator = QLabel()
|
|
31
|
+
separator.setFrameShape(QLabel.HLine)
|
|
32
|
+
separator.setFrameShadow(QLabel.Sunken)
|
|
33
|
+
layout.addWidget(separator)
|
|
34
|
+
|
|
35
|
+
# Package info
|
|
36
|
+
package_label = QLabel(f"Package: {data['package']}")
|
|
37
|
+
package_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
|
|
38
|
+
package_label.setAlignment(Qt.AlignLeft)
|
|
39
|
+
layout.addWidget(package_label)
|
|
40
|
+
|
|
41
|
+
# Program info
|
|
42
|
+
program_label = QLabel(f"Program: {data['program_name']}")
|
|
43
|
+
program_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
|
|
44
|
+
program_label.setAlignment(Qt.AlignLeft)
|
|
45
|
+
layout.addWidget(program_label)
|
|
46
|
+
|
|
47
|
+
# Version info
|
|
48
|
+
version_label = QLabel(f"Version: {data['version']}")
|
|
49
|
+
version_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
|
|
50
|
+
version_label.setAlignment(Qt.AlignLeft)
|
|
51
|
+
layout.addWidget(version_label)
|
|
52
|
+
|
|
53
|
+
# Author info
|
|
54
|
+
author_label = QLabel(f"Author: {data['author']}")
|
|
55
|
+
author_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
|
|
56
|
+
author_label.setAlignment(Qt.AlignLeft)
|
|
57
|
+
layout.addWidget(author_label)
|
|
58
|
+
|
|
59
|
+
# Email info
|
|
60
|
+
email_label = QLabel(f"Email: <a href=\"mailto:{data['email']}\">{data['email']}</a>")
|
|
61
|
+
email_label.setTextInteractionFlags(Qt.TextSelectableByMouse| Qt.LinksAccessibleByMouse)
|
|
62
|
+
email_label.setOpenExternalLinks(True)
|
|
63
|
+
email_label.setAlignment(Qt.AlignLeft)
|
|
64
|
+
layout.addWidget(email_label)
|
|
65
|
+
|
|
66
|
+
# Add another separator
|
|
67
|
+
separator2 = QLabel()
|
|
68
|
+
separator2.setFrameShape(QLabel.HLine)
|
|
69
|
+
separator2.setFrameShadow(QLabel.Sunken)
|
|
70
|
+
layout.addWidget(separator2)
|
|
71
|
+
|
|
72
|
+
# Source URL
|
|
73
|
+
source_label = QLabel(f"Source: <a href=\"{data['url_source']}\">{data['url_source']}</a>")
|
|
74
|
+
source_label.setTextInteractionFlags(Qt.TextSelectableByMouse| Qt.LinksAccessibleByMouse)
|
|
75
|
+
source_label.setOpenExternalLinks(True)
|
|
76
|
+
source_label.setAlignment(Qt.AlignLeft)
|
|
77
|
+
layout.addWidget(source_label)
|
|
78
|
+
|
|
79
|
+
# Doc URL
|
|
80
|
+
doc_label = QLabel(f"Documentation: <a href=\"{data['url_doc']}\">{data['url_doc']}</a>")
|
|
81
|
+
doc_label.setTextInteractionFlags(Qt.TextSelectableByMouse| Qt.LinksAccessibleByMouse)
|
|
82
|
+
doc_label.setOpenExternalLinks(True)
|
|
83
|
+
doc_label.setAlignment(Qt.AlignLeft)
|
|
84
|
+
layout.addWidget(doc_label)
|
|
85
|
+
|
|
86
|
+
# Funding URL
|
|
87
|
+
funding_label = QLabel(f"Funding: <a href=\"{data['url_funding']}\">{data['url_funding']}</a>")
|
|
88
|
+
funding_label.setTextInteractionFlags(Qt.TextSelectableByMouse| Qt.LinksAccessibleByMouse)
|
|
89
|
+
funding_label.setOpenExternalLinks(True)
|
|
90
|
+
funding_label.setAlignment(Qt.AlignLeft)
|
|
91
|
+
layout.addWidget(funding_label)
|
|
92
|
+
|
|
93
|
+
# Bugs URL
|
|
94
|
+
bugs_label = QLabel(f"Bugs: <a href=\"{data['url_bugs']}\">{data['url_bugs']}</a>")
|
|
95
|
+
bugs_label.setTextInteractionFlags(Qt.TextSelectableByMouse| Qt.LinksAccessibleByMouse)
|
|
96
|
+
bugs_label.setOpenExternalLinks(True)
|
|
97
|
+
bugs_label.setAlignment(Qt.AlignLeft)
|
|
98
|
+
layout.addWidget(bugs_label)
|
|
99
|
+
|
|
100
|
+
# OK Button
|
|
101
|
+
ok_button = QPushButton("OK")
|
|
102
|
+
ok_button.clicked.connect(self.accept)
|
|
103
|
+
layout.addWidget(ok_button)
|
|
104
|
+
|
|
105
|
+
def show_about_window(data, logo_path):
|
|
106
|
+
dialog = AboutWindow(data, logo_path)
|
|
107
|
+
dialog.exec_()
|
|
108
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import detection_dataset_annotator.about as about
|
|
4
|
+
import detection_dataset_annotator.modules.configure as configure
|
|
5
|
+
|
|
6
|
+
# Caminho para o arquivo de configuração
|
|
7
|
+
CONFIG_PATH = os.path.join(os.path.expanduser("~"),".config",about.__package__,"config.json")
|
|
8
|
+
|
|
9
|
+
configure.verify_default_config(CONFIG_PATH, default_content={"casa":"verde"})
|
|
10
|
+
|
|
11
|
+
CONFIG=configure.load_config(CONFIG_PATH)
|
|
12
|
+
print("Hola!")
|