Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add or remove a bookmark tag in Firefox via the command line?

I have been looking at the places database and at the Web Extension Bookmarks API but I'm not sure how to do it or if it is possible.

like image 251
Andrew Avatar asked Sep 03 '25 09:09

Andrew


1 Answers

I believe that is not possible via the Web Extension Bookmarks API. That is reserved and can be used only within an add-on.

To quote:

JavaScript APIs for WebExtensions can be used inside the extension's background scripts and in any other documents bundled with the extension, including browser action or page action popups, sidebars, options pages, or new tab pages. A few of these APIs can also be accessed by an extension's content scripts (see the list in the content script guide).

To use the more powerful APIs you need to request permission in your extension's manifest.json

I don't know if you are on windows or *nix. The general idea would be to manipulate the SQLite database.

For bookmarks you need a file called places.sqlite which you can find on windows at - C:\Users\login\AppData\Roaming\Mozilla\Firefox\Profiles

On *nix you can do:

find . -name 'places.sqlite' and usually you will get it somewhere in your home:

e.g. /home/tukanos/.mozilla/firefox/tf8oiuhk.default/places.sqlite

I'll cover only windows & powershell now (you can do that also for *nix):

I think it is also good idea to follow a best practices guide for the places.sqlfile. Be sure to read it before you start changing the file.

NOTE: make backup of your places.sqlite before playing with it!

In powershell you would

Import-Module pssqlite 

(Download the module here if you are using PS version < 5.0)

Then get your path for places.sqlite

$db = 'C:\Users\login\AppData\Roaming\Mozilla\Firefox\Profiles\tf8oiuhk.default\places.sqlite'

To query the sql database:

$sqlFirefoxQuery = "SELECT places.id, 
                           places.URL,
                           places.GUID,
                           bookmarks.title,
                           bookmarks.id,
                           bookmarks.parent
                      FROM moz_places as places
                      JOIN moz_bookmarks as bookmarks 
                        ON places.id = bookmarks.fk"


Invoke-SqliteQuery -DataSource $db -QueryTimeout 20 -Query $sqlFirefoxQuery | Out-file -Encoding UTF8 Bookmarks_firefox.txt

The logic is the same for inserting, updating, deleting data.

Below you can find example of insert and delete as that was your question.

To insert data use sql INSERT INTO For example:

insert into moz_bookmarks (attributes) VALUES (your_values), (next_values)

e.g.

INSERT INTO moz_bookmarks (type, parent, title, dateAdded)  
     VALUES (1,5,'MyBookmark',CURRENT_TIMESTAMP)

To remove values you should use sql's delete:

DELETE FROM from moz_places
     WHERE id=1112

(don't forget to close your Firefox)

Use your database link - to find the attributes: https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Places/Database

Edit - How to get a tag from sqlite DB?

To simply list all tabs in the bookmarks directory:

select * from moz_bookmarks where parent=4

explanation: This will get you all the bookmarks stored in your places.sqlite file. The tags are stored in the column title the TAGs folder has id=4

You can check the ID from in table moz_bookmarks_roots:

╔═══╦═════════════════╦═══════════════╗
║   ║ root_name       ║ folder_id     ║
╠═══╬═════════════════╬═══════════════╣
║ 1 ║ places          ║   1           ║
║ 2 ║ menu            ║   2           ║
║ 3 ║ toolbar         ║   3           ║
║ 4 ║ tags            ║   4           ║
║ 5 ║ unfiled         ║   5           ║
╚═══╩═════════════════╩═══════════════╝

Now how to find a tag with certain bookmarks?

  1. First find your bookmark which you want to work with e.g. title from this question "%How can I add or remove a bookmark tag%"

    SELECT * FROM moz_places where title LIKE '%How can I add or remove a bookmark tag%'
    

The result:

id              : 20079
url             : https://stackoverflow.com/questions/51124179/how-can-i-add-or-remove-a-bookmark-tag-in-firefox-via-the-command-line/51264053?noredirect=1#
                  comment89523757_51264053
title           : How can I add or remove a bookmark tag in Firefox via the command line? - Stack Overflow
rev_host        : moc.wolfrevokcats.
visit_count     : 1
hidden          : 0
typed           : 0
favicon_id      : 238
frecency        : 125
last_visit_date : 1531301813682000
guid            : w6vYlxdKQU6V
foreign_count   : 2
url_hash        : 47357855952022
  1. Then you go to moz_bookmarks table where you can find the actual records (id from moz_places is fk from moz_bookmarks).

    select * from moz_bookmarks where fk=20079
    

This result:

    id           : 76
    type         : 1
    fk           : 20079
    parent       : 75
    position     : 0
    title        : How can I add or remove a bookmark tag in Firefox via the command line? - Stack Overflow
    keyword_id   :
    folder_type  :
    dateAdded    : 1531298577890000
    lastModified : 1531298577894000
    guid         : R0961JLfZYKj

    id           : 78
    type         : 1
    fk           : 20079
    parent       : 77
    position     : 0
    title        :
    keyword_id   :
    folder_type  :
    dateAdded    : 1531298593884000
    lastModified : 1531298593884000
    guid         : BW__oMQbHerd

As you see you get two records. One has parent=75 which is the bookmark folder. Second one is a mapping of fk=20079 (id) to parent=77 which are the actual tag(s):

    SELECT * FROM moz_bookmarks where id = 77

Where you get the tags in the title attribute:

    id           : 77
    type         : 2
    fk           :
    parent       : 4
    position     : 0
    title        : stack_overflow test
    keyword_id   :
    folder_type  :
    dateAdded    : 1531298593878000
    lastModified : 1531298593884000
    guid         : AVcyFpGkrfzV

So the tags in my case were: stack_overflow test

The E-R schema for places.sqlite you can find here.

Edit 2 Forgot to answer the question directly.

When changing the sqlite database close Firefox instance.

To add a tag - you have to understand the logic (I have to pick a new bookmark which has no tags yet):

First to create I have to have a new bookmark

$sqlFirefoxQuery = "SELECT * FROM moz_places where title LIKE '%Cnn%'"

PS C:\> Invoke-SqliteQuery -DataSource $db -QueryTimeout 20 -Query $sqlFirefoxQuery


id              : 20223
url             : https://edition.cnn.com/
title           : CNN International - Breaking News, US News, World News and Video
rev_host        : moc.nnc.noitide.
visit_count     : 1
hidden          : 0
typed           : 0
favicon_id      : 2015
frecency        : 75
last_visit_date : 1531392673997000
guid            : qqCRafq4FIcn
foreign_count   : 1
url_hash        : 47358730651511

Then I select from moz_bookmarks table:

$sqlFirefoxQuery = "select * from moz_bookmarks where fk=20223"
PS C:\> Invoke-SqliteQuery -DataSource $db -QueryTimeout 20 -Query $sqlFirefoxQuery

id           : 79
type         : 1
fk           : 20223
parent       : 75
position     : 1
title        : CNN International - Breaking News, US News, World News and Video
keyword_id   :
folder_type  :
dateAdded    : 1531392718191000
lastModified : 1531392718197000
guid         : 2ywnKBmbDWJI

As you see there is only one record instead of two (check above the section where I select the moz_bookmarks and find two records)

You then have to find out a free id(s) at table moz_bookmarks. In my case it is id=80 and id=81 (can be different in your case):

Now comes the tricky part where you have to get GUID. You can get one via GUI - SQLite Manager and its SELECT GENERATE_GUID(). However, we need one without gui so we have to create it.

If you check the gecko's python makeGuid() function you will see that they are using md5, hex. I will do it with similar functions hex() and randomblob().

First to generate the tag record: Then the record itself (type=2, parent=4):

id           : 80
type         : 2
fk           :
parent       : 4
position     : 0
title        : news insert_firefox_tag_example
keyword_id   :
folder_type  :
dateAdded    : 1531298593878000
lastModified : 1531298593884000
guid         : <generated_GUID>

The actual insert:

$sqlFirefoxQuery = "INSERT INTO moz_bookmarks (id, type, parent, position, title, dateAdded, lastModified, guid)
     VALUES (80,
             2,
             4,
             0,
             'news insert_firefox_tag_example',
             strftime('%s',CURRENT_TIMESTAMP)*1000000,
             strftime('%s',CURRENT_TIMESTAMP)*1000000,
             hex(randomblob(2)) || hex(randomblob(2)) || hex(randomblob(2)))"

Then you have to create the record that links it:

    id          : 81
    type       : 1
    fk          : 20223
    parent       : 80
    position     : 0
    title        :
    keyword_id   :
    folder_type  :
    dateAdded    : 1531298593884000
    lastModified : 1531298593884000
    guid         : <generated_GUID>

The actual insert:

$sqlFirefoxQuery = "INSERT INTO moz_bookmarks (id, type, fk, parent, position, dateAdded, lastModified, guid)
     VALUES (81,
             1,
             20223,
             80,
             0,
             strftime('%s',CURRENT_TIMESTAMP)*1000000,
             strftime('%s',CURRENT_TIMESTAMP)*1000000,
             hex(randomblob(2)) || hex(randomblob(2)) || hex(randomblob(2)))"

Now you can check your record where you have added two new tags news insert_firefox_tag_example.

To update a tag with new_tag (you have to add the current tags too!):

$sqlFirefoxQuery = "UPDATE moz_bookmarks
                       SET title = 'stack_overflow test new_tag' 
                     WHERE id = 77"

Then execute it:

Invoke-SqliteQuery -DataSource $db -QueryTimeout 20 -Query $sqlFirefoxQuery

You will get updated tags:

PS C:\> $sqlFirefoxQuery = "SELECT * FROM moz_bookmarks where id = 77"
PS C:\> Invoke-SqliteQuery -DataSource $db -QueryTimeout 20 -Query $sqlFirefoxQuery


id           : 77
type         : 2
fk           :
parent       : 4
position     : 0
title        : stack_overflow test new_tag
keyword_id   :
folder_type  :
dateAdded    : 1531298593878000
lastModified : 1531298593884000
guid         : AVcyFpGkrfzV

To remove the tags you can do simply put an empty string (don't forget that the changes will be probably seen after Firefox restart):

$sqlFirefoxQuery = "UPDATE moz_bookmarks
                       SET title = '' 
                     WHERE id = 77"

The result:

PS C:\> $sqlFirefoxQuery = "SELECT * FROM moz_bookmarks where id = 77"
PS C:\> Invoke-SqliteQuery -DataSource $db -QueryTimeout 20 -Query $sqlFirefoxQuery


id           : 77
type         : 2
fk           :
parent       : 4
position     : 0
title        :
keyword_id   :
folder_type  :
dateAdded    : 1531298593878000
lastModified : 1531298593884000
guid         : AVcyFpGkrfzV

So that is it.

like image 121
tukan Avatar answered Sep 04 '25 23:09

tukan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!