# Advanced event hooks

**URL:** <https://discourse.beets.io/t/advanced-event-hooks/1205>\
**Category:** Help\
**Created:** [April 8, 2020, 11:20pm UTC](https://discourse.beets.io/t/advanced-event-hooks/1205 "2020-04-08T23:20:45Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![phirestalker](https://avatars.discourse-cdn.com/v4/letter/p/d6d6ee/32.png) [@phirestalker](https://discourse.beets.io/u/phirestalker)\
**Post date:** [April 8, 2020, 11:20pm UTC](https://discourse.beets.io/t/advanced-event-hooks/1205/1 "2020-04-08T23:20:45Z")

</div>

Where can I find out how to configure beets to do specific tasks on import, and more importantly, on write?  
I would like to create a par2 set for each music track after verifying it with the badfiles plugin. Also, every time a file is changed (i.e., tags are written), it should trigger a delete and recreation said par2 file.

---

<div class="post-metadata">

**Author:** ![adrian](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.beets.io/adrian/32/4_2.png) [@adrian](https://discourse.beets.io/u/adrian)\
**Post date:** [April 9, 2020, 1:42am UTC](https://discourse.beets.io/t/advanced-event-hooks/1205/2 "2020-04-09T01:42:21Z")

</div>

Hi! Have you seen the hook plugin?  
[https://beets.readthedocs.io/en/stable/plugins/hook.html](https://beets.readthedocs.io/en/stable/plugins/hook.html)

---

<div class="post-metadata">

**Author:** ![phirestalker](https://avatars.discourse-cdn.com/v4/letter/p/d6d6ee/32.png) [@phirestalker](https://discourse.beets.io/u/phirestalker)\
**Post date:** [April 9, 2020, 2:20pm UTC](https://discourse.beets.io/t/advanced-event-hooks/1205/3 "2020-04-09T14:20:50Z")

</div>

That looks great. I was looking at the events and I have a question. Is the after\_write event fired after each imported file is written? The description makes it sound like it is only fired when updated tags are written.  
Also, the documentation shows methods of the Item class, but it does not show the names of the fields. I know one of them is Item.path. It looks like that is the full path, however, I need just the filename. Is there a listing of the available fields in the Item class?

---

<div class="post-metadata">

**Author:** ![adrian](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.beets.io/adrian/32/4_2.png) [@adrian](https://discourse.beets.io/u/adrian)\
**Post date:** [April 9, 2020, 4:01pm UTC](https://discourse.beets.io/t/advanced-event-hooks/1205/4 "2020-04-09T16:01:03Z")

</div>

Hmm, can you maybe clarify your question? “After each imported file is written” and “updated tags are written” sound like the same thing to me…

Some place to look for the fields available are the `beet fields` command and the source code for the `Item` class. For the filename, though, I think you probably just want the Python standard library:  
[https://docs.python.org/3.8/library/os.path.html#os.path.basename](https://docs.python.org/3.8/library/os.path.html#os.path.basename)

---

<div class="post-metadata">

**Author:** ![phirestalker](https://avatars.discourse-cdn.com/v4/letter/p/d6d6ee/32.png) [@phirestalker](https://discourse.beets.io/u/phirestalker)\
**Post date:** [April 9, 2020, 4:55pm UTC](https://discourse.beets.io/t/advanced-event-hooks/1205/5 "2020-04-09T16:55:26Z")

</div>

Will the after\_write event be fired after a file is imported even if import is set to not Auto tag?

---

<div class="post-metadata">

**Author:** ![adrian](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.beets.io/adrian/32/4_2.png) [@adrian](https://discourse.beets.io/u/adrian)\
**Post date:** [April 9, 2020, 6:53pm UTC](https://discourse.beets.io/t/advanced-event-hooks/1205/6 "2020-04-09T18:53:23Z")

</div>

Aha, no—maybe you want `item_imported` instead?

---

<div class="post-metadata">

**Author:** ![phirestalker](https://avatars.discourse-cdn.com/v4/letter/p/d6d6ee/32.png) [@phirestalker](https://discourse.beets.io/u/phirestalker)\
**Post date:** [April 9, 2020, 6:57pm UTC](https://discourse.beets.io/t/advanced-event-hooks/1205/7 "2020-04-09T18:57:24Z")

</div>

That says it is only called for singletons, but I will be importing my music directory first which is organized by album, and then I will import an album at a time as I rip new cds.  
Do I need to hook into item\_imported and album\_imported?  
Having to hook into album\_imported will make my script programming much more difficult.

Oh, and I need the event that I hook into to be fired after all operations on the file are done and the file handle is closed.

---

<div class="post-metadata">

**Author:** ![adrian](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.beets.io/adrian/32/4_2.png) [@adrian](https://discourse.beets.io/u/adrian)\
**Post date:** [April 9, 2020, 8:14pm UTC](https://discourse.beets.io/t/advanced-event-hooks/1205/8 "2020-04-09T20:14:59Z")

</div>

Yeah, you might want to handle both, and just use a shell for loop over the items for the album case. Give it a shot and see how it goes!

---

<div class="post-metadata">

**Author:** ![phirestalker](https://avatars.discourse-cdn.com/v4/letter/p/d6d6ee/32.png) [@phirestalker](https://discourse.beets.io/u/phirestalker)\
**Post date:** [April 9, 2020, 9:33pm UTC](https://discourse.beets.io/t/advanced-event-hooks/1205/9 "2020-04-09T21:33:40Z")

</div>

EDIT: figured it out

I can’t figure this hook config out. I formed it like in the documentation but it is giving me an error.

> ```
> configuration error: file /Users/phire/.config/beets/config.yaml could not be read: mapping values are not allowed here
> in "/Users/phire/.config/beets/config.yaml", line 45, column 20
> 
> ```

and my config file is

> directory: /Volumes/data/My Documents/Music  
> library: /Volumes/data/My Documents/Music/musiclibrary.db
> 
> import:  
> copy: yes  
> autotag: yes  
> bell: yes
> 
> match:  
> ignored\_media: [‘Data CD’, ‘DVD’, ‘DVD-Video’, ‘Blu-ray’, ‘HD-DVD’, ‘VCD’, ‘SVCD’, ‘UMD’, ‘VHS’]
> 
> threaded: yes
> 
> ui:  
> color: yes
> 
> plugins: badfiles lastimport lastgenre replaygain fetchart embedart lyrics hook playlist smartplaylist
> 
> lyrics:  
> sources: google lyricwiki musixmatch genius
> 
> embedart:  
> remove\_art\_file: yes
> 
> replaygain:  
> backend: gstreamer
> 
> lastgenre:  
> canonical: yes  
> source: track
> 
> lastfm:  
> user: me
> 
> playlist:  
> playlist\_dir: /Volumes/data/My Documents/Music/playlists  
> auto: yes
> 
> paths:  
> default: $albumartist/$album%aunique{}/$track $title
> 
> hook:  
> hooks:  
> - event: after\_write  
> command: ~/bin/createpar “{item.path}”
