PersonalTagEnhancer (AutoTagging)

Download and get help for different MediaMonkey Addons.

Moderators: Peke, Gurus

RedX
Posts: 366
Joined: Wed Dec 27, 2006 10:32 am
Location: Germany

Post by RedX »

Does not happen here:

Image
bob61
Posts: 157
Joined: Sun Dec 09, 2007 4:52 pm

Post by bob61 »

RedX wrote:Does not happen here:

Image
I see what the difference is, your album field is populated. After looking into this further I noticed that each time my track was blanked out it had a blank album. Given the nature of the script I'd expect it to simply change values not purge others based on impact to another field. Not sure if that is expected or just a by product.
baker
Posts: 30
Joined: Thu Dec 20, 2007 1:20 pm

Post by baker »

This script works on everything I have tried except it won't change "inc" to Inc."

Code: Select all

     Tag = ReplaceBadTagPortion(Tag, "inc,", "Inc.,")
Any suggestions?
RedX
Posts: 366
Joined: Wed Dec 27, 2006 10:32 am
Location: Germany

Post by RedX »

baker wrote:This script works on everything I have tried except it won't change "inc" to Inc."

Code: Select all

     Tag = ReplaceBadTagPortion(Tag, "inc,", "Inc.,")
Any suggestions?
what your code does is change inc, to Inc., you have the comas inside the ""

try

Code: Select all

     Tag = ReplaceBadTagPortion(Tag, "inc", "Inc.")
since i also use this correction i know it works.

Regards,
Red
sommo

Post by sommo »

Thank you for making it MM3 :D
Last edited by sommo on Sun Jan 20, 2008 9:20 am, edited 1 time in total.
RedX
Posts: 366
Joined: Wed Dec 27, 2006 10:32 am
Location: Germany

Post by RedX »

sommo wrote:is there a mmip for MM3 of this add on?
Really would help a newbie like me out (A)
See previous page
Guest

Post by Guest »

Hi,

seems like the server for the installer of the script (page 4 of the thread) is down. Is there another mirror somewhere? Or could someone cut'n'paste the code here?

I just upgraded to MM3 and need this script 8)

Thanks and cheers for upgrading the script to MM3!!

h00la
callmetom
Posts: 90
Joined: Sun Jul 15, 2007 12:18 pm

Post by callmetom »

Anonymous wrote:Hi,

seems like the server for the installer of the script (page 4 of the thread) is down. Is there another mirror somewhere? Or could someone cut'n'paste the code here?

I just upgraded to MM3 and need this script 8)

Thanks and cheers for upgrading the script to MM3!!

h00la
Same for me - pleeeeease :D :D :D
My Specs:
Windows XP / SP2
Always latest MM version
Sorry for my sometimes bad english (-:
nynaevelan
Posts: 5559
Joined: Wed Feb 07, 2007 11:07 pm
Location: New Jersey, USA
Contact:

Post by nynaevelan »

Here's the code:

Code: Select all

Option Explicit

'//////////////////////////////////////////////////////////////
'// PersonalTagEnhancer                 Updated on 03/04/06  //
'//////////////////////////////////////////////////////////////
'// Made by Steegy aka RC (Ruben Castelein)                  //   
'//                                                          //
'// >>> Fixes most important tags using personal preferences //
'//////////////////////////////////////////////////////////////

'>> ForumURL: http://www.mediamonkey.com/forum/viewtopic.php?t=8044
'>> ScriptName: PersonalTagEnhancer
'>> VersionNumber: 1.0
'>> Author: Steegy aka RC (Ruben Castelein)

'>> Version 1.1 for MM3 by Redx
'>> Only updated the sql statements and created installer


'>>>>EndOfProperties



'///////////////////////////////////////////////////
'// FORM CREATION AND CALLING OF ENHANCER METHODS //
'///////////////////////////////////////////////////

Sub PersonalTagEnhancer
   
   Dim trackList
   Set trackList = SDB.SelectedSongList
   If trackList.count=0 Then
      Set trackList = SDB.AllVisibleSongList
   End If

   If trackList.count=0 Then
      SDB.MessageBox "Select tracks to be updated", mtError, Array(mbOk)
      Exit Sub
   End If

  Dim UI
  Set UI = SDB.UI

  Dim DlgWidth
  DlgWidth = 500

  ' Create the window to be shown
  Dim Form
  Set Form = UI.NewForm
  Form.Common.SetRect 50, 50, DlgWidth, 400
  Form.Common.MinWidth = 200
  Form.Common.MinHeight = 150
  Form.FormPosition = mmFormScreenCenter
  Form.Caption = SDB.Localize("Personal Tag Enhancer")
  Form.StayOnTop = True

  ' Create a web browser component
  Dim WB
  Set WB = UI.NewActiveX(Form, "Shell.Explorer")
  WB.Common.Align = mmAlignClient      ' Fill all client rectangle
  WB.Common.ControlName = "WB"
  Dim doc
  Set doc = WB.Interf.Document

  ' Create a panel at the bottom of the window
  Dim Foot
  Set Foot = UI.NewPanel(Form)
  Foot.Common.Align = mmAlignBottom
  Foot.Common.Height = 35

  ' Create a button that saves the report
  Dim Btn2
  Set Btn2 = UI.NewButton(Foot)
  Btn2.Caption = SDB.Localize("&Ok")
  Btn2.Common.SetRect DlgWidth - 205, 6, 85, 25
  Btn2.Common.Anchors = mmAnchorRight + mmAnchorBottom
  Btn2.UseScript = Script.ScriptPath
  Btn2.OnClickFunc = "OnOK"
  Btn2.Default = true

  ' Create a button that closes the window
  Dim Btn
  Set Btn = UI.NewButton(Foot)
  Btn.Caption = SDB.Localize("&Cancel")
  Btn.Common.SetRect DlgWidth - 105, 6, 85, 25
  Btn.Common.Anchors = mmAnchorRight + mmAnchorBottom
  Btn.UseScript = Script.ScriptPath
  Btn.OnClickFunc = "OnCancel"
  Btn.Cancel = True
 
 
  Dim Progress
  Set Progress = SDB.Progress
  Progress.Text = SDB.Localize("Personal Tag Enhancer: Loading preview of track enhancements...")
  Progress.MaxValue = trackList.count


  Form.SavePositionName = "PTEWindow"
  SDB.Objects("PTEForm") = Form  ' Save reference to the form somewhere, otherwise it would simply disappear


  doc.write "<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">" & vbcrlf
  doc.write "<html>" & vbcrlf
  doc.write "  <head>" & vbcrlf
  doc.write "    <title>" & SDB.Localize("Personal Tag Enhancer") & "</title>" & vbcrlf
  doc.write "  </head>" & vbcrlf

  doc.write "<STYLE TYPE=text/css>" & vbcrlf
  doc.write "body{font-family:'Verdana',sans-serif; background-color:#FFFFFF; font-size:9pt; color:#000000;}" & vbcrlf
  doc.write "H1{font-family:'Verdana',sans-serif; font-size:13pt; font-weight:bold; color:#AAAAAA; text-align:left}" & vbcrlf
  doc.write "P{font-family:'Verdana',sans-serif; font-size:8pt; color:#000000;}" & vbcrlf
  doc.write "TH{font-family:'Verdana',sans-serif; font-size:9pt; font-weight:bold; color:#000000; border-color:#000000; border-style: solid; border-left-width:0px; border-right-width:0px; border-top-width:0px; border-bottom-width:3px;}" & vbcrlf
  doc.write "TD{font-family:'Verdana',sans-serif; font-size:8pt; color:#000000; border-color:#000000; border-style: solid; border-left-width:0px; border-right-width:0px; border-top-width:0px; border-bottom-width:1px;}" & vbcrlf
  doc.write "TD.highlight{font-family:'Verdana',sans-serif; font-size:8pt; background-color:#FFFF77; color:#000000; border-color:#000000; border-style: solid; border-left-width:0px; border-right-width:0px; border-top-width:0px; border-bottom-width:1px;}" & vbcrlf
  doc.write "TR.dark{background-color:#EEEEEE}" & vbcrlf
  doc.write "TR.aleft TH{text-align:left}" & vbcrlf
  doc.write "</STYLE>" & vbcrlf

  doc.write "  <body>" & vbcrlf
  doc.write "    <H1>" & SDB.Localize("Changes by personal preferences:") & "</H1>" & vbcrlf
  doc.write "    <table border=""0"" cellspacing=""0"" cellpadding=""4"" width=""100%"">" & vbcrlf
  doc.write "      <tr class=""aleft"">" & vbcrlf
  doc.write "        <th>" & SDB.Localize("Artist") & "</th>" & vbcrlf
  doc.write "        <th>" & SDB.Localize("Title") & "</th>" & vbcrlf
  doc.write "        <th>" & SDB.Localize("Album") & "</th>" & vbcrlf
  doc.write "        <th>" & SDB.Localize("Album Artist") & "</th>" & vbcrlf
  doc.write "        <th>" & SDB.Localize("Genre") & "</th>" & vbcrlf
  doc.write "        <th>" & SDB.Localize("Track#") & "</th>" & vbcrlf
  doc.write "      </tr>" & vbCrLf
 
 
  Dim i, itm
  Dim artist, album, title, albumArtist, genre, trackOrder
  for i=0 to trackList.count-1
 
  If Progress.Terminate Then
    CloseDown
    Exit Sub
  End if
  Progress.Value = i+1
   
    doc.write "      <tr" & Style() & ">" & vbcrlf

    Set itm = trackList.Item(i)
   
   
   
    '///////////////////////////////////////////////////////////////////////
    '//////////////////////////////////////////
    '//////////////


   artist = FixCommonWords(ChangeCharacters(Trim(itm.ArtistName)))
   title = FixCommonWords(FixBrackets(ChangeCharacters(Trim(itm.Title))))
   genre = FixWrongGenre(Trim(itm.Genre))
   album = FixCommonWords(ChangeCharacters(Trim(itm.AlbumName)))
   If album = "" Then
       albumArtist = ""
       trackOrder = 0
    Else
      albumArtist = FixCommonWords(ChangeCharacters(Trim(itm.AlbumArtistName)))
       trackOrder = itm.trackOrder
    End If

    '                                                         //////////////
    '                             //////////////////////////////////////////
    '///////////////////////////////////////////////////////////////////////

   
    Dim trackOrder_disp
    If trackOrder = 0 Then
       trackOrder_disp = ""
    Else
       trackOrder_disp = trackOrder
    End If
   
    Dim trackOrderItm_disp
    If itm.trackOrder = 0 Then
       trackOrderItm_disp = ""
    Else
       trackOrderItm_disp = itm.trackOrder
    End If
   
    doc.write outField(artist, itm.artistName)
    doc.write outField(title, itm.title)
    doc.write outField(album, itm.albumName)
    doc.write outField(albumArtist, itm.albumArtistName)
    doc.write outField(genre, itm.genre)
    doc.write outField(trackOrder_disp, trackOrderItm_disp)
   
   
    If artist <> "" And artist <> itm.artistName Then
      holdArtist.add itm, artist
    End If
    If albumArtist <> "" And albumArtist <> itm.albumArtistName Then
      holdAlbumArtist.add itm, albumArtist
    End If
    If title <> itm.title Then
      holdTitle.add itm, title
    End If
    If album <> "" And album <> itm.albumName Then
      holdAlbum.add itm, album
    End If
    If genre <> itm.genre Then
      holdGenre.add itm, genre
    End If
    If trackOrder <> itm.trackOrder Then
      holdTrackOrder.add itm, trackOrder
    End If
   
    doc.write "      </tr>" & vbcrlf
   
  next 'i
 
  doc.write "    </table>" & vbcrlf
  doc.write "  </body>" & vbcrlf
  doc.write "</html>" & vbcrlf
  doc.close
  SDB.Objects("holdArtist") = holdArtist
  SDB.Objects("holdAlbumArtist") = holdAlbumArtist
  SDB.Objects("holdAlbum") = holdAlbum
  SDB.Objects("holdTitle") = holdTitle
  SDB.Objects("holdGenre") = holdGenre
  SDB.Objects("holdTrackOrder") = holdTrackOrder
 
  Form.Common.Visible = True                ' Only show the form, don't wait for user input
End Sub

'//////////////////////
'// ENHANCER METHODS //
'//////////////////////

Function ChangeCharacters(Tag)
   Tag = Replace(Tag, "_", " ", 1, -1, 1)
   Tag = Replace(Tag, "´", "'", 1, -1, 1)
   Tag = Replace(Tag, "`", "'", 1, -1, 1)
   
   ChangeCharacters = Tag
End Function


Function FixBrackets(Tag)
    Tag = Replace(Tag, "{", "(", 1, -1, 1)
    Tag = Replace(Tag, "}", "(", 1, -1, 1)
    Tag = Replace(Tag, "[", "(", 1, -1, 1)
    Tag = Replace(Tag, "]", ")", 1, -1, 1)
    Tag = Replace(Tag, "( ", "(", 1, -1, 1)
    Tag = Replace(Tag, " )", ")", 1, -1, 1)
   
   FixBrackets = Tag
End Function


Function FixCommonWords(Tag)
     Tag = ReplaceBadTagPortion(Tag, "featuring", "ft.")
     Tag = ReplaceBadTagPortion(Tag, "features", "ft.")
     Tag = ReplaceBadTagPortion(Tag, "feat", "ft.")
     Tag = ReplaceBadTagPortion(Tag, "feat.", "ft.")
     Tag = ReplaceBadTagPortion(Tag, "ft", "ft.")
     Tag = ReplaceBadTagPortion(Tag, "Ft.", "ft.")

     Tag = ReplaceBadTagPortion(Tag, "presenting", "pres.")
     Tag = ReplaceBadTagPortion(Tag, "presents", "pres.")
     Tag = ReplaceBadTagPortion(Tag, "pres", "pres.")
     Tag = ReplaceBadTagPortion(Tag, "Pres.", "pres.")

     Tag = ReplaceBadTagPortion(Tag, "versus", "vs.")
     Tag = ReplaceBadTagPortion(Tag, "vs", "vs.")
     Tag = ReplaceBadTagPortion(Tag, "Vs.", "vs.")
     
     Tag = ReplaceBadTagPortion(Tag, "dj", "DJ")
     
     Tag = ReplaceBadTagPortion(Tag, "Its", "It's")      'Good changes outweigh the bad ones (real "its")
     Tag = ReplaceBadTagPortion(Tag, "RMX", "Remix")
     
     Tag = ReplaceBadTagPortion(Tag, "dont", "don't")
     
     Tag = ReplaceBadTagPortion(Tag, "aint", "ain't")
     Tag = ReplaceBadTagPortion(Tag, "isnt", "isn't")
     Tag = ReplaceBadTagPortion(Tag, "cant", "can't")
     Tag = ReplaceBadTagPortion(Tag, "ill", "i'll")      'Good changes outweigh the bad ones (real "ill")
     Tag = ReplaceBadTagPortion(Tag, "wouldnt", "wouldn't")
     Tag = ReplaceBadTagPortion(Tag, "wouldve", "would've")
     Tag = ReplaceBadTagPortion(Tag, "shouldnt", "shouldn't")
     Tag = ReplaceBadTagPortion(Tag, "shouldve", "should've")
     
     Tag = ReplaceBadTagPortion(Tag, "[*]", "(Bonus)")
     
     FixCommonWords = Tag
End Function


Function FixWrongGenre(Tag)
   FixWrongGenre = Tag

    Tag = LCase(Tag)
   If Tag = "other" Or Tag = "unknown" Or Tag = "default" Or Tag = "genre" Or Tag = "misc" Then
      FixWrongGenre = ""
   End If
End Function




'/////////////////////////
'// HELPER FIX FUNCTION //
'/////////////////////////

Function ReplaceBadTagPortion(Tag, FromValue, ToValue)
  If InStr(1, Tag, FromValue, 1) = 1 Then
    Tag = Replace(Tag, FromValue & " ", ToValue & " ", 1, -1, 1)
    Tag = Replace(Tag, FromValue & ")", ToValue & ")", 1, -1, 1)
  End If
  If InStrRev(Tag, FromValue, -1, 1) = Len(Tag) - Len(FromValue) + 1 Then
    Tag = Replace(Tag, " " & FromValue, " " & ToValue, 1, -1, 1)
    Tag = Replace(Tag, "(" & FromValue, "(" & ToValue, 1, -1, 1)
  End If
  Tag = Replace(Tag, " " & FromValue & " ", " " & ToValue & " ", 1, -1, 1)
  Tag = Replace(Tag, "(" & FromValue & " ", "(" & ToValue & " ", 1, -1, 1)
  Tag = Replace(Tag, " " & FromValue & ")", " " & ToValue & ")", 1, -1, 1)
  Tag = Replace(Tag, "(" & FromValue & ")", "(" & ToValue & ")", 1, -1, 1)

  ReplaceBadTagPortion = Tag
End Function




'//////////////////
'// DECLARATIONS //
'//////////////////

Public holdArtist, holdAlbum, holdTitle, holdAlbumArtist, holdGenre, holdTrackOrder
Set holdArtist = CreateObject("Scripting.Dictionary")
Set holdAlbum = CreateObject("Scripting.Dictionary")
Set holdTitle = CreateObject("Scripting.Dictionary")
Set holdAlbumArtist = CreateObject("Scripting.Dictionary")
Set holdGenre = CreateObject("Scripting.Dictionary")
Set holdTrackOrder = CreateObject("Scripting.Dictionary")

Const mmAnchorRight = 4
Const mmAnchorBottom = 8
Const mmAlignTop = 1
Const mmAlignBottom = 2
Const mmAlignClient = 5
Const mmListDropdown = 2
Const mmFormScreenCenter = 4
Public styleOn




'//////////////////////////
'// FORM ACTION HANDLERS //
'//////////////////////////

Sub CloseDown
  Set holdAlbum = nothing
  Set holdAlbumArtist = nothing
  Set holdArtist = nothing
  Set holdTitle = nothing
  Set holdGenre = nothing
  Set holdTrackOrder = nothing
  SDB.Objects("PTEForm") = Nothing
  SDB.Objects("holdArtist") = Nothing
  SDB.Objects("holdAlbumArtist") = Nothing
  SDB.Objects("holdAlbum") = Nothing
  SDB.Objects("holdTitle") = Nothing
  SDB.Objects("holdGenre") = Nothing
  SDB.Objects("holdTrackOrder") = Nothing
End Sub


Sub OnCancel(Btn)
  CloseDown
End Sub


Sub OnOK(Btn)
 
  Set holdAlbum = SDB.Objects("holdAlbum")
  Set holdAlbumArtist = SDB.Objects("holdAlbumArtist")
  Set holdArtist = SDB.Objects("holdArtist")
  Set holdTitle = SDB.Objects("holdTitle")
  Set holdGenre = SDB.Objects("holdGenre")
  Set holdTrackOrder = SDB.Objects("holdTrackOrder")

 
  Dim itm, str, sql
  Dim items, albumNames, artistNames
  Set items = CreateObject("Scripting.Dictionary")
  Set albumNames = CreateObject("Scripting.Dictionary")
  Set artistNames = CreateObject("Scripting.Dictionary")
 
  For Each itm In holdArtist
 
    str = holdArtist.item(itm)
    If Not items.exists(itm) Then
      items.add itm, itm
    End If
    itm.artistName = str
    If Not artistNames.exists(str) Then
      sql = "UPDATE Artists SET Artist = " & rdQS(str) & " WHERE Artist= " & rdQS(Itm.ArtistName)
      SDB.database.execSQL(sql)
      ' This will affect ALL instances of this artist, including album artist, and on other tracks.
      artistNames.add str, str
    End If
  Next 'itm
 
  For Each itm In holdAlbumArtist

    str = holdAlbumArtist.item(itm)
    If Not items.exists(itm) Then
      items.add itm, itm
    End If
    itm.albumArtistName = str
    If Not artistNames.exists(str) Then
      sql = "UPDATE Artists SET Artist = " & rdQS(str) & " WHERE Artist= " & rdQS(Itm.ArtistName)
      SDB.database.execSQL(sql)
      artistNames.add str, str
    End If
  Next 'itm
 
  For Each itm In holdAlbum

    str = holdAlbum.item(itm)
    If Not items.exists(itm) Then
      items.add itm, itm
    End If
    itm.albumName = str
    If Not albumNames.exists(str) Then
      sql = "UPDATE Albums SET Album = " & rdQS(str) & " WHERE Album= " & rdQS(Itm.AlbumName)
      SDB.database.execSQL(sql)
      ' This will affect ALL instances of this album, including other tracks.
      albumNames.add str, str
    End If
  Next 'itm
 
  For Each itm In holdTitle
   
    str = holdTitle.item(itm)
    If Not items.exists(itm) Then
      items.add itm, itm
    End If
    itm.title = str
  Next 'itm
 
  For Each itm In holdGenre
   
    str = holdGenre.item(itm)
    If Not items.exists(itm) Then
      items.add itm, itm
    End If
    itm.genre = str
  Next 'itm
 
  For Each itm In holdTrackOrder
 
    str = holdTrackOrder.item(itm)
    If Not items.exists(itm) Then
      items.add itm, itm
    End If
    itm.trackOrder = str
  Next 'itm
 
 
 
 
  Dim list
  Set list = SDB.NewSongList
  For Each itm In items
    list.Add(itm)
  Next
 
  list.UpdateAll
 
  Set items = nothing
  CloseDown
End Sub




'////////////////////////////////////
'// BASIC REPORT UTILITY FUNCTIONS //
'////////////////////////////////////

Function MapXML(original)
  Dim hold
  hold = Replace(original, "&", "&")
  hold = Replace(hold, "  ", "&nbsp; ")
  hold = Replace(hold, "<", "<")
  hold = Replace(hold, ">", ">")
  hold = Replace(hold, """", """)
  Dim i
  i=1
  While i<=Len(hold)
    If (AscW(Mid(hold, i, 1))>127) Then
      hold = Mid(hold, 1, i-1)+"&#"+CStr(AscW(Mid(hold, i, 1)))+";"+Mid(hold, i+1)
    End If
    i=i+1
  WEnd
  MapXML = hold
End Function


Function MapField(fld)
  If fld="" Then
    MapField = "&nbsp;"
  Else
    MapField = MapXML(fld)
  End If
End Function


Function outField (fixed, normal)
  If fixed = normal Then
    outField = "<td>" & MapField(normal) & "</td>" & vbcrlf
  Else
    outField = "<td class=""highlight"" title=""" & SDB.Localize("Old Value: ") & Chr(13) & MapXML(normal) & """>" & MapField(fixed) & "</td>" & vbcrlf
  End If
End Function


Function Style()
  styleOn = Not styleOn
  If styleOn Then
    Style = ""
  Else
    Style = " class=""Dark"""
  End If
End Function


Function rdQS(UnquotedString)
  rdQS = """" & Replace(UnquotedString, "'", "''") & """"
End Function
3.2x - Win7 Ultimate (Zen Touch 2 16 GB/Zen 8GB)
Link to Favorite Scripts/Skins

Join Dropbox, the online site to share your files
callmetom
Posts: 90
Joined: Sun Jul 15, 2007 12:18 pm

Post by callmetom »

Thanx nyn ! :P :P :P
My Specs:
Windows XP / SP2
Always latest MM version
Sorry for my sometimes bad english (-:
h00lah00la
Posts: 1
Joined: Sun Feb 24, 2008 9:02 am

Post by h00lah00la »

YESSS!! Thanks for posting it! Small changes, large effect...

Just wondering - has anyone thought about a Wiki or something to better keep track of new scripts or addons than via forum threads?

Anyways - I'm off tagging some files :D

Cheers, h00la
Vyper
Posts: 845
Joined: Tue May 23, 2006 5:53 pm

Post by Vyper »

I knew how to add scripts posted like what nynaevelan did in MM2 but how do I do it in MM3? Same way?
Stop Button Freak
nynaevelan
Posts: 5559
Joined: Wed Feb 07, 2007 11:07 pm
Location: New Jersey, USA
Contact:

Post by nynaevelan »

Vyper wrote:I knew how to add scripts posted like what nynaevelan did in MM2 but how do I do it in MM3? Same way?
Same way :D

Nyn
3.2x - Win7 Ultimate (Zen Touch 2 16 GB/Zen 8GB)
Link to Favorite Scripts/Skins

Join Dropbox, the online site to share your files
martialartsguy
Posts: 297
Joined: Mon Apr 03, 2006 9:11 am
Location: Denver, CO

Error Message

Post by martialartsguy »

When running PTE I get the following error:

Image
MM 5.0.0.2338

MM Gold since 2006
Steegy
Posts: 3452
Joined: Sat Nov 05, 2005 7:17 pm

Post by Steegy »

The latest script code, which works for MM3, is located here. The code on the first page only works for MM2.
Extensions: ExternalTools, ExtractFields, SongPreviewer, LinkedTracks, CleanImport, and some other scripts (Need Help with Addons > List of All Scripts).
Post Reply