Digikam : sqlite3 lecture des tables afin de supprimer les images similaires

J’ai fait une petite lecture des tables de Dikikam afin de faire un export des images similaires avec un taux à 1.0 :

$ sqlite3 
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .open similarity.db
sqlite> .tables
ImageHaarMatrix     ImageSimilarity     SimilaritySettings
sqlite> .schema ImageSimilarity
CREATE TABLE ImageSimilarity
                    (imageid1 INTEGER NOT NULL,
                    imageid2 INTEGER NOT NULL,
                    algorithm INTEGER,
                    value DOUBLE,
                    CONSTRAINT Similar UNIQUE(imageid1, imageid2, algorithm));
sqlite> .schema ImageHaarMatrix
CREATE TABLE ImageHaarMatrix
                    (imageid INTEGER PRIMARY KEY,
                    modificationDate DATETIME,
                    uniqueHash TEXT,
                    matrix BLOB);
CREATE TRIGGER delete_similarities DELETE ON ImageHaarMatrix
                    BEGIN
                        DELETE FROM ImageSimilarity
                            WHERE ( ImageSimilarity.imageid1=OLD.imageid OR ImageSimilarity.imageid2=OLD.imageid )
                              AND ( ImageSimilarity.algorithm=1 );
                    END;
sqlite> .schema SimilaritySettings
CREATE TABLE SimilaritySettings
                    (keyword TEXT NOT NULL UNIQUE,
                    value TEXT);
sqlite> .open digikam4.db
sqlite> .tables
AlbumRoots          ImageHistory        ImageRelations      Settings          
Albums              ImageInformation    ImageTagProperties  TagProperties     
DownloadHistory     ImageMetadata       ImageTags           Tags              
ImageComments       ImagePositions      Images              TagsTree          
ImageCopyright      ImageProperties     Searches            VideoMetadata     
sqlite> .schema Images
CREATE TABLE Images
                    (id INTEGER PRIMARY KEY,
                    album INTEGER,
                    name TEXT NOT NULL,
                    status INTEGER NOT NULL,
                    category INTEGER NOT NULL,
                    modificationDate DATETIME,
                    fileSize INTEGER,
                    uniqueHash TEXT,
                    manualOrder INTEGER,
                    UNIQUE (album, name));
CREATE INDEX dir_index  ON Images (album);
CREATE INDEX hash_index ON Images (uniqueHash);
CREATE INDEX image_name_index ON Images (name);
CREATE TRIGGER delete_image DELETE ON Images
                    BEGIN
                        DELETE FROM ImageTags          WHERE imageid=OLD.id;
                        DELETE From ImageInformation   WHERE imageid=OLD.id;
                        DELETE From ImageMetadata      WHERE imageid=OLD.id;
                        DELETE From VideoMetadata      WHERE imageid=OLD.id;
                        DELETE From ImagePositions     WHERE imageid=OLD.id;
                        DELETE From ImageComments      WHERE imageid=OLD.id;
                        DELETE From ImageCopyright     WHERE imageid=OLD.id;
                        DELETE From ImageProperties    WHERE imageid=OLD.id;
                        DELETE From ImageHistory       WHERE imageid=OLD.id;
                        DELETE FROM ImageRelations     WHERE subject=OLD.id OR object=OLD.id;
                        DELETE FROM ImageTagProperties WHERE imageid=OLD.id;
                        UPDATE Albums SET icon=null    WHERE icon=OLD.id;
                        UPDATE Tags SET icon=null      WHERE icon=OLD.id;
                    END;
sqlite>  .schema ImageInformation
CREATE TABLE ImageInformation
                    (imageid INTEGER PRIMARY KEY,
                    rating INTEGER,
                    creationDate DATETIME,
                    digitizationDate DATETIME,
                    orientation INTEGER,
                    width INTEGER,
                    height INTEGER,
                    format TEXT,
                    colorDepth INTEGER,
                    colorModel INTEGER);
CREATE INDEX creationdate_index ON ImageInformation (creationDate);
sqlite> .schema Albums
CREATE TABLE Albums
                    (id INTEGER PRIMARY KEY,
                    albumRoot INTEGER NOT NULL,
                    relativePath TEXT NOT NULL,
                    date DATE,
                    caption TEXT,
                    collection TEXT,
                    icon INTEGER,
                    UNIQUE(albumRoot, relativePath));
CREATE TRIGGER delete_album DELETE ON Albums
                BEGIN
                    DELETE FROM Images
                    WHERE Images.album = OLD.id;
                END;
sqlite> attach 'digikam4.db' as db1;
sqlite> attach 'similarity.db' as db2;
sqlite> select count(*) from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid2 = A.id and B.algorithm = 1.0 and A.album = C.id;
36796
sqlite> select relativePath || '/' || name from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid2 = A.id and B.algorithm = 1.0 and A.album = C.id group by relativePath;
...
sqlite> .output file_duplicate.txt
sqlite> select '.' || relativePath || '/' || name from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid2 = A.id and B.algorithm = 1.0 and A.album = C.id group by relativePath;

sqlite> select count(*) from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid2 = A.id and A.album = C.id and relativePath = '/2019/11/28';
654
sqlite> select count(*) from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid1 = A.id and A.album = C.id and relativePath = '/2019/11/28';
2545
sqlite> .output file_duplicate_2.txt
sqlite> select '.' || relativePath || '/' || name from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid2 = A.id and B.algorithm > 0.96 and A.album = C.id;
sqlite> .output file_duplicate_3.txt
sqlite> select '.' || relativePath || '/' || name from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid1 = A.id and B.algorithm > 0.96 and A.album = C.id;
sqlite> .quit

Ensuite pour la suppression j’ai fait :

$ cat file_duplicate_3.txt |  sed 's/ /\\ /g' > file_duplicate_3_2.txt
...
$ xargs rm -r  <file_duplicate_3_2.txt
...
$ wc -l file_duplicate_3_2.txt
37060 file_duplicate_3_2.txt

Ensuite je fini par :

$ time exiftool -v -r "-filemodifydate<datetimeoriginal" "-filecreateddate<datetimeoriginal" . 
$ sortphotos -r . . --sort %Y/%m/%d 

Et je relance Digikam pour lui refaire faire une analyse complète.

Quelle usine, mais cela fonctionne.

TAPForm : export de Bento vers TAPForm (images incluses)

Le lien de TAPForm sur l’Apple Store : https://itunes.apple.com/fr/app/tap-forms-base-de-donnees/id494995266?mt=12. J’estime que c’est la meilleure alternative à Bento.

Solution ( n°1 ) pour utilisateur de Bento avec une version >= 4.0 :

Attention : les utilisateurs de la dernière version de Bento peuvent utiliser cette méthode qui est beaucoup plus simple :

Pour voir si vous avez la dernière version il faut faire : Bento -> Fichier -> Exporter -> Modèle (et il faut avoir une case à cocher indiquant d’inclure les données).

Solution ( n°2 ) pour utilisateur de Bento avec une version <= 4.0 & souhaitant ne plus utiliser Bento mais TAP Form:

Pour télécharger la dernière version de Bento 4 ( Bento_4.1.2.29717.dmg ) : http://help.filemaker.com/app/answers/detail/a_id/11182 .

Une solution consiste aussi a faire la mise à jours de Bento et à utiliser la mise à jours en version d’essai.

En faisant la mise à jours vous allez donc perdre l’ancienne version de Bento et il ne sera plus possible de faire machine arrière …

Les étapes de la mise à jours :

Après le téléchargement du dmg on l’installe dans Applications et il nous propose d’écraser l’ancien Bento :

Capture d’écran 2015-02-03 à 20.41.23

On passe sur la sécurité, faisant « Ouvrir » :

Capture d’écran 2015-02-03 à 20.43.45

On a cette fenêtre d’avertissement :

Capture d’écran 2015-02-03 à 20.44.15

On continue en cliquant sur « Continuer », on tombe alors dans la longue phase de mise à jours :

Capture d’écran 2015-02-03 à 20.45.39

Pendant ce temps vous pouvez vérifier que vous êtes en version d’essai :

Capture d’écran 2015-02-03 à 20.46.28

 

Problème n°2 : Yosemite

Solution n°2.1 : Accepter ATOS ….(ne marche pas)

Attention si vous utilisez Yosemite vous allez avoir le message suivant :

atos

en anglais cela donne : « atos needs to take control of another process for debugging to continue.  Type your password to allow this. » (« atos doit prendre le contrôle d’un autre processus pour poursuivre le déboggage. Saisissez votre mot de passe pour donner l’autorisation » )

SOLUTION N°2.2 : ANNULER ATOS ….(NE MARCHE PAS)

La solution est donc d’arrêter atos ?! en faisant annuler on obtient une seconde fenêtre :

atos2

Le message « Developper Tools Access doit prendre le contrôle d’un processus pour poursuivre le déboggage. Saisissez votre mot de passe pour donner l’autorisation »

SOLUTION N°2.3 : DEVTOOLSSECURITY….(NE MARCHE PAS)

Pour l’instant je suis à la recherche de solution du type : « devToolsSecurity -enable » cette solution permet de ne pas voir les fenêtres mais la migration ne marche pas …

SOLUTION N°2.4 : MODIFICATION DES PREFERENCES….(NE MARCHE PAS)

Sur un forum Allemand j’ai vu qu’il suffisait de modifier les Préférences de Bento et de faire un redémarrage :

Bento -> Préférence :  Bento-Pref-3-2   Avant :

Bento-Pref-1

Après :

Bento-Pref-2

 

SOLUTION N°2.5 : LA TOUCHE ALT ENFONCEE PENDANT LE LANCEMENT DE BENTO ….(NE MARCHE PAS)

On obtient alors cette fenêtre, et on peut choisir une base vide :

Alt

Si je regarde la console d’erreur j’ai ceci :

Bento has caught the following exception:
NSInvalidArgumentException -- -[GNMPersistentAttribute setName:]: unrecognized selector sent to instance 0x13c0aa80
Stack trace:
__raiseError (in CoreFoundation) + 506
objc_exception_throw (in libobjc.A.dylib) + 276
-[NSObject(NSObject) doesNotRecognizeSelector:] (in CoreFoundation) + 277
___forwarding___ (in CoreFoundation) + 1032
_CF_forwarding_prep_0 (in CoreFoundation) + 14
-[GNMPersistentTable createAttributeWithName:type:] (in GNDataManager) + 103
-[GNMPersistentTable generateTableStorage] (in GNDataManager) + 765
-[GNDomainController initializePersistentStorageWithDomainName:] (in GNDataManager) + 211
-[GNDomainControllerExternal initializePersistentStorageWithDomainName:] (in GNDataManager) + 57
-[GNDataManagerContext(GNSchemaManager_Private) _createDomainFromSpec:forSourceItem:creationPass:importData:] (in GNDataManager) + 485
-[GNDataManagerContext(GNSchemaManager_Private) _createLibraryFromSpec:creationPass:importData:] (in GNDataManager) + 1528
-[GNDataManagerContext(GNSchemaManager) createLibraryFromSpec:] (in GNDataManager) + 56
-[GNDataSourceInstanceCoordinator _loadXMLSchemaFromBundle:forDataSource:] (in GNDataManager) + 472
-[GNDataSourceInstanceCoordinator attachDataSource:fromBundle:] (in GNDataManager) + 381
-[GNDataSourceManager didLoadPlugin:fromBundle:] (in GNDataManager) + 50
-[GNPlugInManager loadPluginWithIdentifier:] (in GNUtility) + 595
-[GNPlugInManager loadAllPlugins] (in GNUtility) + 283
-[GNDataManager _openDatabase] (in GNDataManager) + 2826
-[NSThread main] (in Foundation) + 45
__NSThread__main__ (in Foundation) + 1538
_pthread_body (in libsystem_pthread.dylib) + 138
_pthread_body (in libsystem_pthread.dylib) + 0
thread_start (in libsystem_pthread.dylib) + 34

Mais cela ne fonctionne pas.

SOLUTION N°2.5 : METTRE LA VERSION BENTO 4.0.7 ….(NE MARCHE PAS)

http://help.filemaker.com/app/answers/detail/a_id/10913 :

Par contre il faut faire ceci dans « Sécurité et Confidentialité ».

Securité

On a l’erreur :

SecurityAgent[571]: Error returned from iconservicesagent: Error Domain=NSCocoaErrorDomain Code=4097 "Impossible de communiquer avec un utilitaire." (connection to service named com.apple.iconservices) UserInfo=0x7feba1583490 {NSDebugDescription=connection to service named com.apple.iconservices}

Et ensuite on retombe sur la même erreur :

Bento[560]: Bento has caught the following exception:
NSInvalidArgumentException -- -[GNMPersistentAttribute name]: unrecognized selector sent to instance 0x13983910
Stack trace:
__raiseError (in CoreFoundation) + 506
objc_exception_throw (in libobjc.A.dylib) + 276
-[NSObject(NSObject) doesNotRecognizeSelector:] (in CoreFoundation) + 277
___forwarding___ (in CoreFoundation) + 1032
_CF_forwarding_prep_0 (in CoreFoundation) + 14
-[GNMPersistentAttribute _generateKeyHandler] (in GNDataManager) + 258
-[GNMPersistentProperty keyHandler] (in GNDataManager) + 46
-[GNMPersistentTable _setupTable] (in GNDataManager) + 334
-[GNMPersistentTable awakeFromFetch] (in GNDataManager) + 71
-[GNManagedObject(GNManagedObject_FetchingSPI) initWithEntity:registerWithManagedObjectContext:withRecordData:] (in GNDataManager) + 426
-[GNManagedObjectContext(GNManagedObjectContext_SPI) createManagedObjectWithEntity:fromRecord:] (in GNDataManager) + 144
-[GNManagedObject(GNManagedObject_FetchingSPI) toOneValueForRelationship:] (in GNDataManager) + 209
-[GNMDomain persistentTable] (in GNDataManager) + 74
-[GNMDomain(GNFields) _createSchemaForField:] (in GNDataManager) + 391
-[GNMDomain(GNFields) createFieldWithSpec:withGuid:] (in GNDataManager) + 1575
-[GNMDomain(GNFields) createFieldWithSpec:] (in GNDataManager) + 49
-[GNXFormMigrationController _migrateRelationshipsFromForm:toPresentation:inDisplayContext:] (in GNPresentation) + 858
-[GNXFormMigrationController migrateForm:] (in GNPresentation) + 218
-[NSObject performSelector:withObject:] (in libobjc.A.dylib) + 70
-[GNUpgradeDataModelVersion300To400 doUpgrade] (in GNDataManager) + 777
+[GNUpgradeManager _doUpgradeOnBundleInPlace:usingUpgrader:] (in GNDataManager) + 500
+[GNUpgradeManager upgradeBundle:] (in GNDataManager) + 1435
-[GNDataManager _upgradeDatabaseForBundle:wantsUpgradingDialog:] (in GNDataManager) + 185
-[GNDataManager _openDatabase] (in GNDataManager) + 720
-[NSThread main] (in Foundation) + 45
__NSThread__main__ (in Foundation) + 1538
_pthread_body (in libsystem_pthread.dylib) + 138
_pthread_body (in libsystem_pthread.dylib) + 0
thread_start (in libsystem_pthread.dylib) + 34

J’ai tenté de faire ceci dans une console :

mkdir ${TMPDIR}/com.apple.IconServices

Mais j’ai cette erreur ensuite :

Bento[858]: (
 0 CoreFoundation 0x94267373 __raiseError + 195
 1 libobjc.A.dylib 0x9ade1a2a objc_exception_throw + 276
 2 CoreFoundation 0x9426bed5 -[NSObject(NSObject) doesNotRecognizeSelector:] + 277
 3 CoreFoundation 0x941a3378 ___forwarding___ + 1032
 4 CoreFoundation 0x941a2f4e _CF_forwarding_prep_0 + 14
 5 GNDataManager 0x00716c92 -[GNMPersistentAttribute _generateKeyHandler] + 258
 6 GNDataManager 0x0071710f -[GNMPersistentProperty keyHandler] + 46
 7 GNDataManager 0x0071b6df -[GNMPersistentTable _setupTable] + 334
 8 GNDataManager 0x0071b9e6 -[GNMPersistentTable awakeFromFetch] + 71
 9 GNDataManager 0x0054f7c4 -[GNManagedObject(GNManagedObject_FetchingSPI) initWithEntity:registerWithManagedObjectContext:withRecordData:] + 426
 10 GNDataManager 0x0055b24d -[GNManagedObjectContext(GNManagedObjectContext_SPI) createManagedObjectWithEntity:fromRecord:] + 144
 11 GNDataManager 0x0054f037 -[GNManagedObject(GNManagedObject_FetchingSPI) toOneValueForRelationship:] + 209
 12 GNDataManager 0x005e1888 -[GNMDomain persistentTable] + 74
 13 GNDataManager 0x005e2ee8 -[GNMDomain(GNFields) _createSchemaForField:] + 391
 14 GNDataManager 0x005e4bd6 -[GNMDomain(GNFields) createFieldWithSpec:withGuid:] + 1575
 15 GNDataManager 0x005e2657 -[GNMDomain(GNFields) createFieldWithSpec:] + 49
 16 GNPresentation 0x003a3a64 -[GNXFormMigrationController _migrateRelationshipsFromForm:toPresentation:inDisplayContext:] + 858
 17 GNPresentation 0x003a3692 -[GNXFormMigrationController migrateForm:] + 218
 18 libobjc.A.dylib 0x9addf853 -[NSObject performSelector:withObject:] + 70
 19 GNDataManager 0x006d5fa1 -[GNUpgradeDataModelVersion300To400 doUpgrade] + 777
 20 GNDataManager 0x006306a4 +[GNUpgradeManager _doUpgradeOnBundleInPlace:usingUpgrader:] + 500
 21 GNDataManager 0x00630dff +[GNUpgradeManager upgradeBundle:] + 1435
 22 GNDataManager 0x0056fd3a -[GNDataManager _upgradeDatabaseForBundle:wantsUpgradingDialog:] + 185
 23 GNDataManager 0x005726de -[GNDataManager _openDatabase] + 720
 24 Foundation 0x9108bb3f -[NSThread main] + 45
 25 Foundation 0x9108ba91 __NSThread__main__ + 1538
 26 libsystem_pthread.dylib 0x92365e13 _pthread_body + 138
 27 libsystem_pthread.dylib 0x92365d89 _pthread_body + 0
 28 libsystem_pthread.dylib 0x92363e52 thread_start + 34
)

 

SOLUTION N°2.6 : METTRE LA VERSION BENTO 3 et SUPPRIMER ICAL, POUR ENSUITE REMETTRE LA VERSION BENTO 4 ….(NE MARCHE PAS)

La suppression d’iCal permet un démarrage plus rapide mais ensuite on tombe dans le même problème.

Bento-1234

SOLUTION N°2.7 : CHANGER lA RESOLUTION D’ECRAN…(NE MARCHE PAS)

Je voulais essayer tous les conseils des forums … on sait jamais.

TailleEcran

Conclusion : Rien ne marche, le problème vient de la migration et donc des données. Quand je lance Bento 4 en temps que « Guest » (Invité) , il fonctionne correctement. J’ai aussi pu voir sur les forums que beaucoup de personnes avaient du envoyer leurs fichiers à FileMaker afin que la migration puisse fonctionner.

Solution (n°3a) : pour utilisateur de Bento avec une version <= 4.0 & souhaitant utiliser Bento & TAP Form  :

Solution (n°3b) : pour utilisateur de Bento avec une version <= 4.0 & qui a eu un échec dans la migration vers Bento 4.0  :

Sinon pour les autres, j’ai traduit les deux tutoriels suivants dans la langue de Molière et ajouté les captures d’écrans:

Les logiciels :

Voici donc les versions des logiciels :

  • La version de Bento 3 ( version 3.0.6 : 17853 ) : « Bento is a trademark of FileMaker, Inc »

Bento-1

Pour information :

  • 8 Janvier 2008          => Bento v1
  • 14 Octobre 2008      => Bento v2
  • 29 septembre 2009  => Bento v3
  • 16 Mars 2011           => Bento v4
  • 31 juillet 2013           => Arrêt de Bento.

 

  • La version de TAPForm : 3.0.3 (611)

Bento-export

  • La version de mon Mac: OS X Yosemite : 10.10.2 .

Bento-export

  • La version de FireFox : 33.1.1 :

Bento-export

  • La version de PHP : 5.5.14 : il faut installer MAMP.

MAMP

php -v

PHP 5.5.14 (cli) (built: Sep  9 2014 19:09:25)

Copyright (c) 1997-2014 The PHP Group

Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies

Début de la traduction :

Tutoriel – Comment exporter des images Bento et les importer dans Tap Forms ?

Une des limites de Bento est de ne pouvoir exporter les images intégrées dans les « médias ». Même FileMaker ne peut pas importer des champs « média » Bento. Ce tutoriel vous montre comment le faire, et comment importer tous vos dossiers – y compris les images – dans Tap Forms.

Si vous avez une douzaine de dossiers, arrêtez de lire et faites le manuellement: cela sera plus rapide. Mais si vous avez des centaines de dossiers et chaque dossier a une ou plusieurs images, alors la suite de cette demi-heure tutoriel va vous faire économiser des jours de travail fastidieux.

La seule application commerciale dont vous avez besoin c’est Bento pour Mac. Donc, nous allons commencer!

Avant de commencer

Ce tutoriel suppose que la totalité ou la plupart de vos images soient dans le même format (par exemple jpeg ou png). Si vous avez pris des photos avec votre iPhone ou iPad, cela devraient être JPEG. Si vous avez importé des photos sur la version Mac, vous devez savoir ce que vous avez importé.

Étape 1: sauvegarde de votre base de données Bento

Ouvrez Bento pour Mac, et si vous utilisez Bento pour iPhone ou iPad, synchroniser vos données de sorte que vous avez les données les plus récentes sur votre Mac. Dans le menu Fichier choisissez « Sauvegarder les données de Bento …. » et enregistrez-le où vous voulez si vous travaillez sur une copie de la base de données sans risque de vissage la db.

Soit au démarrage :

Bento-export

Soit via le menu : « Sauvegarder les données de Bento …. »

Bento-export

Étape 2: exporter un fichier .csv avec des informations d’image

Vous pouvez exporter dans un fichier .csv dans Bento, mais les données d’image (l’image elle-même et une référence à son nom de fichier) seront absentes, donc nous devons le faire manuellement.

–> Fichier –> Exporter .

Bento-export

Puis :

Bento-export2

Télécharger la dernière version de Mozilla Firefox, puis dans le menu Outils, sélectionnez « Téléchargement ».

Bento-export3

Chercher « SQLite Manager » et l’installer; vous devez redémarrer Firefox pour l’utiliser.

Bento-export4 Bento-export5Maintenant le menu Outils a un nouvel élément, « SQLite Manager »: sélectionnez-le pour lancer l’extension Firefox.

Capture d’écran 2015-02-02 à 16.45.35

Dans le menu de base de données dans la fenêtre FireFox sélectionnez « Se connecter base de données » – ou cliquez sur l’icône correspondante sur la barre d’outils. Sélectionnez « Tous les fichiers » dans le menu déroulant Format, puis naviguer vers le fichier de sauvegarde Bento vous avez enregistré il y a quelques minutes.

Vous verrez que le fichier est un paquet, un dossier qui contient d’autres dossiers; accédez à
Bento sauvegarde [date].bentodb> Contenu> Ressources et choisir le fichier évidemment nommé « Database ».

Bento-export

Il y a beaucoup de tables dans la base de données, vous devez maintenant trouver la table que vous voulez exporter. Une table représente une bibliothèque Bento. Si le premier nom que vous avez donné à votre bibliothèque Bento a été « Mes films », puis la table sera principalement nommé « gn_lib_my_movies ». Cliquez dessus.

Note : Dans mon cas c’était « gn_lib_files_1« . 

Maintenant, nous devons nous débarrasser d’un grand nombre de données Bento dont nous n’avons pas besoin ou que nous ne pouvons pas utiliser. Par exemple, Bento enregistre combien vous avez de photos et les coordonnées de l’image dans le domaine des médias.
Faites un clic droit sur tous les champs suivants et sélectionnez « Drop colonne »

Bento-export

(vous devez confirmer deux fois, ignorer l’avertissement parce que vous travaillez sur une copie de la base de données):

gn_gnRecordOrder
gn_gnDateCreated (optionel) : je pense qu’il faut laisser cette colonne.
gn_idGnField
gnent
gnpk
gnopt
gn_table
gn_DateModified (optional) : je pense qu’il faut laisser cette colonne.
gnguid
gn_[name of the image field]GnFieldpanOffset
gn_[name of the image field]GnFieldzoomFactor

Il reste toutes vos données personnelles, y compris une référence au fichier image.

Maintenant cliquez sur le bouton « Exporter »: vous arriverez à la section «Assistant d’exportation ». cochez la case « Première ligne contient les noms de colonne » case et laisser le reste inchangé. Cliquez sur OK et enregistrez le fichier csv.

Bento-export

Si vous voulez jeter un coup d’oeil à vos données, cliquez sur le « Browse & Recherche » onglet. Vous verrez que le contenu de vos champs d’image est quelque chose comme « bento://asset/22C0C417-6ED5-4E56-A60E-0A5623CA1FED ». C’est une référence à un dossier dans le dossier « actifs » du paquet Bento. Ce dossier une (et une seule) image qui peut avoir des noms différents contient.

Étape 3: modifier le fichier csv

Cette étape est rapide. Télécharger TextWrangler depuis le Mac App Store ou à partir du lien ci-dessus.

Bento-export2

Ouvrez le fichier csv avec TextWrangler, et dans le menu de recherche sélectionner « Rechercher » (« Search »). Une fenêtre se affichera. Cochez la case « Grep » sur la partie inférieure et de copier et coller cette chaîne dans la boîte « Rechercher » de texte (y compris les guillemets):

« bento://asset/([A-F0-9-]*) »

puis copiez et collez cette chaîne dans la case « Remplacer » de texte (y compris les guillemets):

« \1\ .jpg » (si la plupart des images sont au format JPEG)

ou

« \1\ .png » (si la plupart des images sont au format PNG)

Maintenant, cliquez sur « Remplacer tout ».

Après cela, notre exemple

« bento://asset/22C0C417-6ED5-4E56-A60E-0A5623CA1FED »

aurait transformé en

« 22C0C417-6ED5-4E56-A60E-0A5623CA1FED.jpg »

Note : Dans ma version de bento (Bento version 3 et non Bento version 4) c’est beaucoup plus simple. Il faut supprimer : « bentomedia:// »

Bento-Export-2 Bento-Export-3

Enregistrez le fichier csv.

Étape 4: lancer le script (uniquement pour les utilisateurs de BENTO 4, les UTILISATEURS DE BENTO 3 n’ont pas A FAIRE CELA)

Accédez au Finder et à votre fichier de sauvegarde .bentodb. Faites un clic droit dessus et choisissez Afficher le contenu du paquet (« Show Package Contents »). Accédez à « Contents> Ressources ».

Bento-export

Télécharger ce script:

http://www.tapforms.com/code/bntfolderstofiles.zip

Décompressez-le, puis copiez-le dans le dossier Ressources.

Si vous voulez vérifier que ce ne efface pas votre disque dur ou envoie du spam à tous vos contacts, ouvrir avec TextWrangler.

Note : Voici le contenu du script, c’est du PHP, j’aurais préféré du bash ou du python:

#!/usr/bin/php
<?php
/*
bntfolderstofiles
A tool to rename the images in the Assets folder of the Japanese Food Box db
Copyright (c) 2013, Giacomo M. Vernoni
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
 list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this
 list of conditions and the following disclaimer in the documentation and/or
 other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
// Define the folder name, change for tests
define(ASSETS_FOLDER, "Assets/");
// if the folder doesn't exist, exit with an error and some instructions
if (!file_exists(ASSETS_FOLDER))
{
 echo "Error: folder '".ASSETS_FOLDER."' not found.
Quick instructions:
1) make a backup of your database.
2) right click on the backup database
and select 'Show package contents'
3) copy this script into the Contents/Resources/ folder
4) open Applications/Utilities/Terminal and
- type 'cd' without the quotes
- add a space
- drag the Resources folder to the Terminal window
- hit [return]
- type ./bntfolderstofiles [return]
";
 exit();
}
// Scan the contents of the Assets folder
$folders = scandir(ASSETS_FOLDER);
// Process every image folder
foreach ($folders as $folderName)
{
 // Proceed only if the item does not begin with "." and it's a directory
 if (substr($folderName, 0, 1) <> "." and is_dir(ASSETS_FOLDER.$folderName))
 {
 // Scan the content of the image folder
 $files = scandir(ASSETS_FOLDER.$folderName);
 
 //Every folder contains a single image
 foreach ($files as $fileName)
 {
 // Proceed only if the item does not begin with "." and it's an image
 $ext = substr($fileName, -3);
 if (substr($fileName, 0, 1) <> "." and ($ext == "jpg" | $ext == "png"))
 {
 // Rename the file as the folder, moving one level up
 if (rename(ASSETS_FOLDER."$folderName/$fileName" , ASSETS_FOLDER."$folderName.$ext"))
 {
 // Delete the folder
 rmdir(ASSETS_FOLDER.$folderName);
 }
 }
 }
 // Print out the old name and the new name
 echo $fileName." -> $folderName.$ext\n";
 }
}

?>

Note : Pour ma version de Bento (Bento 3) j’ai du modifier le script (avec MacVim & non TextWrangler … Grrr). J’ai changé ceci :

define(ASSETS_FOLDER, « Media/« );

Mais le script n’est pas utile sous Bento 3 car tous les fichiers sont déjà sous Media, il n’y a pas de sous répertoire.

Suite de la traduction:

Jetez un oeil au dossier Assets: les images de toutes vos bibliothèques Bento y sont stockées, une par dossier.

Ouvrez Applications> Utilitaires > Terminal, puis tapez sans les guillemets, ajouter un espace, puis faites glisser le dossier Resources dans la fenêtre de terminal. Vous devriez voir quelque chose comme:

cd  /Users/John/Documents/Bento\ backup\-\ 2013-08-05.bentodb/Contents/Resources

Tapez « Entrer » (« Retour »).

maintenant, tapez

./bntfolderstofiles

et le tapez « Entrer ».

Vous devriez voir une liste courante sur l’écran; le nom sur la gauche est le nom original, l’une sur la droite est le nouveau nom qui correspond à celle dans le fichier csv.

Etape 5 (Facultatif): JPEG et PNG

Si la plupart de vos images sont au format JPEG, allez dans le Finder et de regarder le nouveaux dossier « Asset ». Maintenant toutes les images sont là. Rechercher « .png » dans le champ de recherche, pour vérifier se il y a des images PNG.

Copiez le nom, et TextWrangler recherche pour elle (décochez « grep »). Modifier manuellement l’extension de « jpg » à « png ».

Faites l’inverse, si la plupart de vos images sont PNG et vous trouver quelques JPEG.

Si vous ne trouvez pas un match, probablement l’image appartient à une autre bibliothèque Bento. Plus de détails sur ce dans l’étape suivante.

Étape 6: importer le template dans Tap Forms

Revenons à notre fichier csv dans TextWrangler. La première ligne doit contenir les noms des champs, séparés par des virgules.

Vous devez renommer toutes les colonnes avec un meilleur nom, par exemple, de «gn_titleGnField » à titre de film, puis ajouter le tag de terrain après le nom: <text>, <number>, <note>, <photo>, <check_mark>, <rating> sont les plus communs.

  • <text> : texte
  • <number> : nombre
  • <note> : note
  • <photo> : images, pdf, média ?
  • <check_mark> : case à cocher.
  • <rating> : évaluation.
  • <date> : date au format texte.
  • <date_time> :
  • <time> :

Par exemple, votre première ligne devrait ressembler à:

Titre du film <text>, Année <number>, Ma note <rating>, Affiche <photo>, DVD <check_mark>, Blu-Ray <check_mark>.

Enregistrez le fichier csv, et l’utiliser pour importer votre bibliothèque Bento dans Tap Forms.

Bento-export-2

Maintenant, vous devez importer les images: la procédure est différente pour l’iPhone / iPad et la version Mac.

Pour importer vos images dans la version mobile, TAP Form lancé, démarrer le serveur FTP, et copier toutes vos images dans le dossier Photos. Je recommande d’utiliser Cyberduck, que vous pouvez télécharger à partir http://cyberduck.ch. Utiliser une connexion anonyme et assurez-vous que vous entrez 8080 dans le champ de numéro de port et juste l’adresse IP dans l’adresse du serveur. Appuyez sur les formes seront afficher l’adresse IP et le numéro de port pour vous sur l’écran Fichiers fois que vous avez démarré le serveur FTP intégré.

Note : Cette procédure n’est pas la plus propre mais la plus courte . il est possible de faire dans Bento et faire (« Exporter le modèle »):

Bento-export

Et faire ensuite des manipulations sur le fichier XML … 

Suite de la traduction:

Pour importer vos images dans TAP Forms Mac:

Copier toutes vos images dans ce dossier si vous ne utilisez pas de synchronisation iCloud:

~ /Library/conteneurs/com.tapforms.mac/Data/Documents/Photos

ou copier toutes vos images dans ce dossier si vous avez activé dans iCloud Sync Tap formes:

~/Library/Mobile Documents/FXLPHZS84D~com~clickspace~tapforms/Documents/Photos/ 

Rappelez-vous que le symbole « ~ » est un raccourci pour votre dossier de départ (par exemple / Utilisateurs / john).

Si vous ne voyez pas le dossier Bibliothèque de votre accueil de l’utilisateur, allez dans le Finder et sélectionnez le menu « Aller> Aller au dossier … » et collez le chemin ci-dessus.

Notes : Dans Finder vous allez sur « Aller » et vous maintenez la commande « alt », et vous avez la possibilité d’aller sous le dossier Bibliothèque.

Notes : Pour ma part j’ai 450 Mo de fichiers (PDF, PNG, JPG, JPEG, GIF).

Il faut donc modifier le programme en conséquence : 

if (substr($fileName, 0, 1) <> "." and ($ext == "jpg" | $ext == "png" | $ext == "pdf" | $ext == "gif")))

S’il vous plaît noter que les fichiers que vous copiez dans le dossier Tap Forms sont les images de toutes vos bibliothèques, et pas seulement la Bibliothèque (ou une table: le fichier csv) vous venez d’importer.

Cela implique que si vous importez une autre bibliothèque Bento, vous pouvez sauter l’étape 4.

Notes 1 (les chiffres à virgules): Si vous avez tout fait alors vous avez pu voir une erreur dans les chiffres à virgule, il faut reprendre le fichier et remplacer tous les points par des virgules. Mais le problème c’est que l’on perd toutes les images.

Le mieux est donc de refaire l’exportation avec le bon format (c.a.d. Point-virgule et Les guillemets doubles, toujours):

Bento-export-3

Ensuite il faut faire un petit programme pour modifier seulement les virgules des chiffres à virgule.

Sinon il existe une autre solution avec TextWrangler :

(« )([0-9]+)\.([0-9]+)(« )

Bento-export

 

Notes 2 (les dates … un vrai problème):

Par exemple cette date le 1 janvier 2001 est stockée en REAL : 39600. Et le 1 avril 2009 est stocké comme REAL : 260272800.

Normalement le format est celui-ci d’après ce tutoriel : http://www.tutorialspoint.com/sqlite/sqlite_data_types.htm :

« The number of days since noon in Greenwich on November 24, 4714 B.C. »

 

Mais en fait pour avoir la date il faut faire ceci :

Unix Timestamp (date + 978307200).

Cela commence au 1 janvier 2001 (l’epoch Cocoa). Il reste maintenant à avoir un tag spécifique pour faire l’import.

Notes 3 : SQLite : 

Vous avez aussi cet outil qui est gratuit : Valentina Studio.

Bento4

 

Vous pouvez alors ouvrir la base de TAP Form par exemple : Macintosh HD ▸ Utilisateurs ▸ Votre utilisateur ▸ Bibliothèque ▸ Containers ▸ com.tapforms.mac ▸ Data ▸ Documents ▸ TapForms_db.sqlite

TAPForm-export

 

Ou encore celle de Bento …

L’ancien problème de TAPForm :

Le seul problème de TAPForm, qui m’avait fait ne pas choisir ce logiciel, était le copier/coller des chiffres à virgules. En Europe, on utilise la virgule et, aux Etats-Unis le point.

Par exemple je suis sous « Numbers » et j’ai ceci :

Numberje fais un copier/coller vers TAPForm et j’ai 1.00.

Maintenant ce problème est fixé !

Evolutions :

En terme d’évolution cela serait bien s’il existait une version Android de TAPForm. Mais cela ne semble pas être d’actualité.

 

Voici mes précédents articles :

https://www.cyber-neurones.org/2014/01/alternative-a-bento/

Je ne suis pas le seul à penser que TAP Form est une bonne alternative à Bento , la solution proposée par FileMaker est hors de prix:

… je ne suis pas le seul a avoir eu le problème.

I have spent a few days to research and try some, and even purchased Tap Forms, another simple personal database app on Mac, which works sooooo slow and makes me frustrated.

… il n’est pas convaincu lui.

« BENTO is Dead – Long Live TAP FORMS »