Страница 1 из 1

Помогите оживить кнопку со скриптом на Питоне

Добавлено: Пн янв 22, 2024 23:55
dumi
Попросил ИИ написать скрипт для кнопки для Тотала и он мне его написал (честно говоря, изумил! ...). Он предложил Питон, а я не возражал, так как равно ни языков подходящих, ни глубин устройства Тотала не знаю, и разбираться особо не хочу - я не программист. Но заказанная функция, между тем, меня действительно очень и очень интересует.
Сценарий вкратце: 1) В текущей директории найти и запомнить выделенные файлы со значениями их атрибутов дат (съемки, создания и модернизации); 2) Открыть штатную форму "Свойства"; 3) После закрытия формы "Свойства" (по нажатию пользователем ОК), по списку в памяти восстановить значения дат в файлах.
Сыр-бор из-за того, что после сохранения редактирования тегов в форме "Свойства", значение даты модернизации меняется на текущую, что категорически неприемлемо (теги можно менять оптом сразу в большом количестве файлов).
Я не программист, но для себя бывало кое-что кое-в-чем программировал. Поэтому скрипт по смыслу показался мне в общем понятным, и с точки зрения бизнес-логики правильным. Но ... не работает :( ; При нажатии кнопки в Тотале, что-то черное мигает (вероятно, это окно самого Питона), и больше ничего не происходит. Не мог бы кто-н глянуть? Может даже не сильно много нужно подправить, чтобы заработало? чем черт (ИИ) не шутит ...
Версия Тотала - 9.21а (вряд ли важно, но ...)

[cut="Код который написал ИИ:"]

Код: Выделить всё

# Импортируем модули
import os
import datetime
import subprocess
from PIL import Image
from PIL.ExifTags import TAGS

# Создаем таблицу соответствия
table = {}

# Получаем список выделенных файлов фотографий в текущей директории
files = os.listdir(".")
selected_files = [f for f in files if f.endswith(".jpg") or f.endswith(".png")]

# Перебираем все выделенные файлы
for file in selected_files:
# Открываем файл как изображение
image = Image.open(file)
# Получаем словарь с метаданными EXIF
exif = image.getexif()
# Извлекаем дату съемки, если есть
date_taken = exif.get(36867, None)

#------------ эти строчки я уже сам вставил, думал может хоть застрянет на этом, но ни фига ...
# print("Дата съемки - ", date_taken) 
#-----------------------------

# Получаем дату создания и редактирования файла
date_created = datetime.datetime.fromtimestamp(os.path.getctime(file))
date_modified = datetime.datetime.fromtimestamp(os.path.getmtime(file))
# Сохраняем имена и даты в таблице
table[file] = (date_taken, date_created, date_modified)

# Открываем форму "Свойства" Total Commander
# Для этого используем команду wcmicons.exe с параметром 100
# Эта команда должна быть в папке с Total Commander
# Если нет, то нужно указать полный путь к ней
subprocess.run(["wcmicons.exe", "100"])

# После закрытия формы, перебираем все записанные в таблице файлы
for file in table:
# Получаем даты из таблицы
date_taken, date_created, date_modified = table[file]
# Если дата съемки есть, то устанавливаем ее в метаданные EXIF
if date_taken:
image = Image.open(file)
exif = image.getexif()
exif[36867] = date_taken
image.save(file, exif=exif)
# Устанавливаем дату создания и редактирования файла
os.utime(file, (date_created.timestamp(), date_modified.timestamp()))
[/cut]
Добавлено спустя 24 минуты:
dumi писал(а):# Открываем форму "Свойства" Total Commander
# Для этого используем команду wcmicons.exe с параметром 100
# Эта команда должна быть в папке с Total Commander
# Если нет, то нужно указать полный путь к ней
subprocess.run(["wcmicons.exe", "100"])
Блин, только отправил пост, осенило проверить наличие этого файла. Так его нет :( Есть только "wcmicons.dll" ... Попробовал заменить в коде на "dll", но как и следовало ожидать, не работает. И что же делать? Как открыть форму "Свойства"?
Добавлено спустя 1 час 19 минут:
Объяснил ИИ ситуацию и попросил переписать этот фрагмент кода под мою версию ТС. И он переписал:

Код: Выделить всё

# Открываем форму "Свойства" Total Commander
# Для этого используем команду rundll32.exe с параметрами wcmicons.dll и 100
# Эта команда должна быть в папке с Total Commander
# Если нет, то нужно указать полный путь к ней
subprocess.run(["rundll32.exe", "wcmicons.dll,100"])
Но все равно, не работает, визуально ничего не изменилось :(

Добавлено: Ср янв 24, 2024 06:06
CaptainFlint
dumi
Главная проблема тут в том, что ИИ не существует. То, что из каждого утюга обзывают искусственным интеллектом, на самом деле является системой генерации грамматически адекватных текстов на естественных языках. Эта система просто поштучно выбрасывает одно слово за другим, выбирая те, которые, как ей кажется, лучше всего состыкуются с предшествующим текстом. В итоге фразы получаются грамматически корректными, но использовать их как базу знаний чревато. И уж тем более это не инструмент создания программ. Иногда он может сгенерировать что-то рабочее или полурабочее, так как в обучающую подборку, видимо, попали в том числе и программистские сайты. Но предполагать, что этот генератор автоматически "додумает" за автора техническое задание и сгенерирует код для такой узкоспециальной ситуации — по меньшей мере наивно. Я уж не говорю о том, что если есть желание воспользоватся скриптом, то хорошо бы для начала разобраться, как его положено запускать и как смотреть консольный вывод, куда попадают в числе прочего добавленный автором print() и сообщения об ошибках. (Обычно для этого открывают отдельную консоль и работают в ней.)

Что касается этого скрипта, можно даже не пытаться с ним что-то делать. Он совершенно безнадёжен.
Во-первых, он банально синтаксически некорректен: все блоки в питоне обязаны иметь отступы, а здесь их нет.
Во-вторых, "выделенными файлами" господин бредогенератор обозвал вообще все имеющиеся в текущем каталоге JPG- и PNG-файлы (что особенно мило, учитывая, что EXIF-данных в PNG не бывает). И вообще, во всём коде нет ни единой инструкции, которая хоть как-то взаимодействовала бы с Тоталом. Скрипт даже не подозревает о существовании такой программы, если не считать случайное упоминание wcmicons, да и то в вопиюще неадекватном контексте.
В-третьих, то, что называется открытием диалога "Свойства" — это просто полный бред. Эта команда (что первый вариант, что второй) не может работать ни при каких условиях. Диалог открывается совершенно иначе, и более того, даже невозможно сказать, как это делать правильно, потому что в постановке задачи не уточняется, надо его открывать поочерёдно для каждого файла или один для всех выделенных файлов.
В-четвёртых, в задании речь шла о восстановлении даты-времени файла, а скрипт пытается восстановить EXIF-данные (впрочем, не могу сказать, успешно ли; я с модулем exif не работал, а проверять не вижу смысла).

Короче говоря, чем пытаться править это нагенерённое убожище, проще и быстрее делать скрипт с нуля. Только для этого всё-таки надо внятно и чётко расписать, что и как должно работать, и тогда есть шанс, что кто-нибудь из участников напишет подходящий скрипт.

Добавлено: Чт янв 25, 2024 15:31
dumi
CaptainFlint писал(а):dumi
Главная проблема тут в том, что ИИ не существует.
Тут это не главная проблема. Не говоря о том, что под "ИИ" многие подразумевают разные вещи и поэтому можно увязнуть в трактовании того, что имел ввиду CaptainFlint (кстати, догадываюсь, что в несколько иной формулировке, я бы с ним согласился). В моем посте "ИИ" это лишь специфика, и мне казалась довольно любопытная, моего подхода к решению вполне ординарной для данного ресурса задачи, но прежде совершенно не доступной мне для решения никакими традиционными способами. Да, кроме того, как минимум, я рассматриваю это как некий эксперимент.
Возвращаясь к теме старттопика. Форма "Свойства" открывается один раз и при закрытии сохраняет одни и те же значения отредактированного поля (например, тегов) во все выделенные файлы (у которых имеется такое свойство). Другими словами - речь о групповом "тегировании" файлов. Так эта форма сейчас работает сама по себе - ничего тут, кроме её открытия, программировать не надо.
Но при этом происходит одно отрицательное побочное "явление" - изменяется дата последнего редактирования файлов. Весь сыр-бор ради исправления этого нестерпимого изъяна.

Добавлено: Сб янв 27, 2024 20:56
dumi
Полнофункциональная работающая первая часть скрипта:
[cut="Скрипт:"]

Код: Выделить всё

# Импортируем модуль os для работы с файлами и директориями
import os
import sys
import stat
import datetime
import subprocess
# Импортируем модуль tkinter для работы с GUI
import tkinter as tk
# Импортируем модуль PIL для работы с изображениями
from PIL import Image
from PIL.ExifTags import TAGS
# Импортируем модуль pywinauto для работы с окнами
from pywinauto import application

# ------------------------------------------------------
# Создаем таблицу соответствия
table = {}

# Получаем список выделенных файлов из аргументов командной строки
# (согласно стандартным шаблонам ТС, установленным в свойствах кнопки (%S)
# Первый аргумент (sys.argv[0]) - это имя скрипта, поэтому мы его пропускаем
selected_files = sys.argv[1:]

# Цикл по файлам в списке
for file in selected_files:
   if file.endswith ((".jpg", "JPG")):   # or file.endswith ((".png", "PNG")):   
      if os.path.isfile (file) and os.access (file, os.R_OK):
         # Проверяем, что файл доступен
         file_info = os.stat (file)
         file_attributes = file_info.st_mode
         if file_attributes:   # & stat.FILE_ATTRIBUTE_ARCHIVE:
            # Открываем файл как изображение
            image = Image.open (file)
            # Получаем словарь с метаданными EXIF
            exif = image._getexif()  	
            # Извлекаем дату съемки, если есть
            date_taken = exif.get(36867, None)
            # Получаем дату создания и редактирования файла
            date_created = datetime.datetime.fromtimestamp(os.path.getctime(file))
            date_modified = datetime.datetime.fromtimestamp(os.path.getmtime(file))
            # Сохраняем имена и даты в таблице
            table[file] = (date_taken, date_created, date_modified)
[/cut]Некоторые форумчане поспешили высказаться (по другим каналам) весьма скептически о достоинствах представленного в старттопике кода ("говнокода"), вышедшего из под "пера" ИИ, и о бессмысленности затеи воспользоваться ИИ для компенсации собственного невежества (полного и бесспорного) для решения обозначенной выше (разумется бездарно) задачи. Вместо того, чтобы сначала в надлежащем порядке трепетно поизучать "матчасть". Предлагаю оппонентам сравнить исходный и конечный тексты скрипта, и убедиться, что не так уж сильно они различаются. Т.е., не такую уж чушь несёт ИИ (чем бы оно ни было). Кроме того, предлагаю сопоставить варианты разработки для неофита: 1) "необходима отладка" или 2) "начать с самого начала" (не представляя в какой стороне и на каком отдалении оно находится)...– Особенно в контексте, вероятно, разовой потребности.

Добавлено: Чт фев 01, 2024 20:49
dumi
Задача решена. Скрипт разделил на две части / две кнопки: 1) Сохранить даты (в файл ".json"); 2) Восстановить даты. Тем самым избавился от вопроса открытия формы "Свойства" из скрипта и ожидания скриптом закрытия формы пользователем.
Недостаток решения - Питон, который пришлось специально устанавливать в систему. Несколько расточительно ради одного маленького прибамбаса. Но когда начал делать, было еще любопытно, что за зверь такой - Рython, про который нынче из каждого утюга ... Слышал название уж лет 20 назад. Но раньше он был на периферии ..., а сейчас - какая-то Питономания ... :mrgreen:

Тему можно закрыть, но я не знаю как ...