Apr 142009
 

Introduction

For some time, I have casually noticed that Gnome’s Evolution was not spell-checking my email messages.  Most other email clients, text editors, and even modern web-browsers, at least check your spelling as you type, underlining misspelled words with red wavy lines.  Evolution has this capability, but it was not enabled on my system.  Here is how I enabled spell-check on my Gentoo system for Evolution.

Solution

Gnome’s Evolution is dependent upon external spell checkers to perform this function.  Popular open-source checkers include ispell, aspell, and hunspell.  Aspell is newer than ispell, and was designed to replace it, at least according to aspell’s web-siteHunspell is an up and coming spell-checker, based on MySpell and backwards compatible with its dictionaries.  Apparently, Hunspell is used in many popular projects, such as:  OpenOffice, Mozilla Firefox, Mozilla Thunderbird, Opera, and Google Chrome.

All of these above spell-checkers are developed to be language independent; therefore, you also must also install a language specific “library” or “dictionary” to complete the installation.

Evolution appears to use aspell.  However, I installed all 3 spell-checkers and English dictionaries for each checker, plus a few other utilities, like so:

# emerge -pvt app-text/aspell app-text/gnome-spell app-text/ispell \
app-text/spellutils app-vim/vim-spell-en dev-perl/Text-Aspell dev-perl/gtk2-spell \
dev-python/gtkspell-python app-dicts/aspell-en app-dicts/myspell-en

Check to make sure you satisfied with the proposed installations, and then commit:

# emerge app-text/aspell app-text/gnome-spell app-text/ispell \
app-text/spellutils app-vim/vim-spell-en dev-perl/Text-Aspell dev-perl/gtk2-spell \
dev-python/gtkspell-python app-dicts/aspell-en app-dicts/myspell-en

After emerging the above packages and restarting Evolution, I was able to select dictionaries and enable the “Check as you type” feature by navigating here:

Evolution -> Edit -> Preferences -> Composer Preferences -> Spell Checking

Now I had nice red wavy lines everywhere! 🙂

BTW, I did encounter a problem where some of my dictionaries or checkers became corrupted, so I had to re-install (re-emerge) all of the above packages to fix the problem, even though I had previously installed these packages.

Share
Jan 232009
 

Problem Introduction

I use an open-source solution for hosting my family’s photos, called Gallery. Recently, my gallery2 install crashed, and I lost my online database. “No big deal”, I thought. “I have all the pictures saved on my local computer.” WRONG-O!!! I hit two major snags: One, gallery can stumble very easily while doing a bulk upload from a local server. Two, all of the album dates were stamped with the time of my recent upload, which destroyed by chronological sorting of the albums.

I started manually “editing” each album through Gallery2’s web interface, but that gets old real fast, so I decided to try a little MySQL wizardry.

Solution

Gallery2 stores most of its data, except for the photos and movies, in a MySQL database on the web-server. Of course, you can use other back-ends, but MySQL is very popular. The database can be manipulated using your favorite MySQL monitor, whether that occurs through a command shell or a web-interface, like phpMyAdmin.

My solution was to use MySQL to search through each album, find the oldest picture, and update the album’s origination date to match the oldest picture.

Using my favorite MySQL interface, I crafted the following SQL statement to examine the problem:

SELECT g_id AS albumId, g_title, g_originationTimestamp, (
SELECT MIN(g_originationTimestamp)
FROM g2_Item
INNER JOIN g2_ItemAttributesMap
 
ON g2_Item.g_id = g2_ItemAttributesMap.g_itemId
WHERE g_parentSequence LIKE CONCAT( '%/', albumId, '/' )
) AS oldestPicture
FROM g2_Item
INNER JOIN g2_ItemAttributesMap ON g2_Item.g_id = g2_ItemAttributesMap.g_itemId
WHERE g_canContainChildren > 0

This produced results like:

albumId albumTitle currentTime oldestPicture
7 Gallery 1232042846 NULL
58896 Caleb’s Turn 1232650930 1175871585
59400 Originals 1232650977 1175871585
59416 Landscapes and Nature 1232651065 1232651128
59417 Blossoms and Sunsets 1232651128 1081207812
59600 icebergs 1232651167 1232651167
59633 More Sunsets and Bathtime 1232651168 1174399484
59634 Originals 1232651168 1174399529
59943 Trees and Geese 1232651264 1081295988
60013 Family Photos 1232653712 978487347

As you can see, many of the albums had pictures much older than the timestamp on the folder. The theory appears sound. Let’s experiment!

Attempt #1

Since we are experimenting on your gallery database, obviously you want to back it up first. If I have to tell you that, you are in over your head. 😉

Using a modified version of the above query, I tried to update the origination timestamp to the value of the oldest picture, like so:

UPDATE g2_Item AS albumId SET g_originationTimestamp =
(
SELECT MIN(g_originationTimestamp)
FROM g2_Item INNER JOIN g2_ItemAttributesMap
ON g2_Item.g_id=g2_ItemAttributesMap.g_itemId
WHERE g_parentSequence LIKE CONCAT('%/', albumId.g_id, '/')
) WHERE g_canContainChildren > 0

Unfortunately, this produces the following error:

ERROR #1093 - You can't specify target table 'albumId' for update in FROM clause

Apparently, UPDATE will not allow you to modify a table that is part of the query. That seems reasonable. However, that is exactly what I needed to do. This forced me to create a temporary table to hold the intermediate results, and then use those results to update the desired table.

Attempt #2

Here was my final solution, which required 4 separate statements:

DROP TABLE IF EXISTS newAlbumTimes;

This first statement is only necessary, if you iterate and experiment with this approach. It deletes the temporary table, if it exists, which may happen after you tweak something and try again, depending on your connection method.

CREATE TEMPORARY TABLE newAlbumTimes (albumId INT(11), albumTitle VARCHAR(128), albumTimeStamp INT(11), oldestPicture INT(11))
SELECT g_id AS albumId, g_title AS albumTitle, g_originationTimestamp AS albumTimeStamp, (
SELECT MIN(g_originationTimestamp )
FROM g2_Item
INNER JOIN g2_ItemAttributesMap
 
ON g2_Item.g_id = g2_ItemAttributesMap.g_itemId
WHERE g_parentSequence LIKE CONCAT( '%/', albumId, '/' )
) AS oldestPicture
FROM g2_Item
INNER JOIN g2_ItemAttributesMap ON g2_Item.g_id = g2_ItemAttributesMap.g_itemId
WHERE g_canContainChildren >0
ORDER BY oldestPicture;

Now that is the “brains” of the operation. First, notice the select statement, very similar to the original query. However, these results are being fed into a “CREATE TEMPORARY TABLE” statement, which catches the results. Notice, we had to tell MySQL the structure of this temporary table, which should generally match the structure of the output columns. This temporary table will be destroyed when the connection closes. However, we will use this table in the meantime, to update the timestamps based on the oldest picture’s timestamp.

UPDATE g2_Item INNER JOIN newAlbumTimes
ON g2_Item.g_id = newAlbumTimes.albumId
SET g_originationTimestamp=oldestPicture
WHERE oldestPicture AND oldestPicture < albumTimeStamp;

Using the temporary table, the origination time is updated for all albums in the item table, but only if the oldest picture column is non-NULL and if the picture is stamped older than the album. Otherwise, we assume the time stamp for the album is better than what we have calculated, so we leave it alone.

UPDATE g2_Entity INNER JOIN newAlbumTimes
ON g2_Entity.g_id = newAlbumTimes.albumId
SET g_creationTimestamp=oldestPicture, g_modificationTimestamp=oldestPicture
WHERE oldestPicture AND oldestPicture < g_creationTimeStamp;

We also have to update the creation time stamps, which is the date actually displayed and permitted to be edited for the album. This is the statement that does what we want!

Conclusion

Running the above 4 statements in order produces the desired affect.  Preferably, these should be executed as a single entry to avoid the temporary table disappearing. However, this procedure only “bubbles up” the oldest time stamp by one level.  Most albums will be updated correctly after this.  However, if you have nested albums (albums inside albums), you will have to run this procedure at least once for each level of album (or folder) hierarchy.  This will cause your top level album to show a creation date equal to or older than the oldest picture anywhere in its hierarchy.

Notes

If you are running an older version (Gallery1) or newer version (Gallery3, currently in early development), you will obviously have to modify the above statements to match the your database structure. Also, these statements were executed using MySQL 5.0.70. If you use an older version, like MySQL 4.0, you may find the nested queries do not work. This will require you to create an additional temporary table to cache those intermediate results – much more complicated.  It may be better to upgrade, if you can.

You can include additional constraints on the WHERE clause of the final two statements to only modify certain albums.  This can be useful if you are only want to fix a certain subset of albums in your gallery.

Share
Nov 202008
 

Introduction

In TikiWiki’s setup, an admin account is created.  The default password is “admin”.  And, you are forced to change that password as soon as you login.  Unfortunately, you are not required to provide an email address for the “admin” account during setup.

This sets the stage for two moments of sheer panic:

  1. You log out of admin, forget the password, and try to reset the password:  Resetting passwords typically require an email address; therefore, you cannot reset the password.  Yikes!  8-|
  2. While in admin you enable, “Challenge-Response Authorization”.  Later, you log out of admin and try to log back in.  Unfortunately, “Challenge-Response Authorization”, although more secure and therefore desirable, depends on the user additionally entering his email address.  But, the admin account has no email address, and so you cannot log back in as admin, even if you know the password.  Double Yikes!!! 8-|

If you get bitten, here are a couple of anti-venom therapies.

Solution

If you have database access (MySQL, in this case), either via a shell, MySQL client, or phpMyAdmin, you can directly update the database.  Instructions here are for shell access:

To simply reset the admin password to “admin”:

$ mysql -u my_db_user_id i -p my_db_name
Enter password:

mysql> UPDATE `users_users` SET `password`='admin', `hash`= md5('adminadmin') WHERE
    -> `login`='admin';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> quit;
Bye

Once you log in, you should obviously change the password to a strong, non-default password.

If you are unable to login, and you cannot reset the password, because you forgot to assign an email address to the “admin” account, do the following:

$ mysql -u my_db_user_id i -p my_db_name
Enter password:

mysql> UPDATE `users_users` SET `email`='myemail@server.com' WHERE `login`='admin';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> quit;
Bye

By setting the email address for the admin account, you can now reset the password, assuming you did not disable that feature too, before you logged out. >8-|

If you are still stuck, be sure to check out phpMyAdmin, which provides you a graphical tool to explore and edit the underlying MySQL database without knowing the command-line syntax.

References

http://doc.tikiwiki.org/tiki-index.php?page=lost+admin+password&bl=y

http://doc.tikiwiki.org/tiki-view_faq.php?faqId=7

Share