Last active
December 17, 2015 11:19
-
-
Save maestrith/5601781 to your computer and use it in GitHub Desktop.
Nearly complete.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#SingleInstance,Force | |
CoordMode,ToolTip,Screen | |
type:=new xml("types"),OnMessage(0x03,"move") | |
wmp:=ComObjCreate("WMPLayer.OCX") | |
ComObjError(0) | |
global type,wmp,varlist:=[],templist | |
if type.ssn("//version").text!=2 | |
type.add("version","",2),Compile() | |
Gui,2:Add,Edit,w800 h400 hwnddebug -Wrap | |
Gui,2:Show,x0 y0,Debug | |
aplay() | |
return | |
debug(x){ | |
global debug | |
ControlSetText,,%x%,ahk_id%debug% | |
} | |
4GuiEscape: | |
ExitApp | |
return | |
class xml{ | |
__New(param*){ | |
ref:=param.1,root:=param.2,file:=param.3 | |
file:=file?file:ref ".xml",root:=!root?ref:root | |
temp:=ComObjCreate("MSXML2.DOMDocument"),temp.setProperty("SelectionLanguage","XPath") | |
if param.4 | |
temp.loadxml(param.4),this.xml:=temp | |
else | |
{ | |
ifexist %file% | |
temp.load(file),this.xml:=temp | |
else | |
this.xml:=xml.CreateElement(temp,root) | |
this.file:=file | |
} | |
xml.xk({ref:ref,obj:this}) | |
} | |
xk(xml=""){ | |
static list:=[] | |
if IsObject(xml) | |
return list[xml.ref]:=xml.obj | |
if !xml | |
return list | |
if list[xml] | |
return list[xml] | |
} | |
__Get(x=""){ | |
return this.xml.xml | |
} | |
CreateElement(doc,root){ | |
x:=doc.CreateElement(root),doc.AppendChild(x) | |
return doc | |
} | |
add(path="",att="",text="",dup="",find="",under=""){ | |
main:=this.xml.SelectSingleNode("*") | |
for a,b in find | |
if found:=main.SelectSingleNode("//" path "[@" a "='" b "']"){ | |
for a,b in att | |
found.setattribute(a,b) | |
found.text:=text | |
return found | |
} | |
if under | |
{ | |
p:=under | |
new:=this.xml.CreateElement(path),p.AppendChild(new) | |
for a,b in att | |
new.SetAttribute(a,b) | |
if !(text="") | |
new.text:=text | |
return new | |
} | |
if p:=this.xml.SelectSingleNode(path) | |
for a,b in att | |
p.SetAttribute(a,b) | |
else | |
{ | |
p:=main | |
Loop,Parse,path,/ | |
{ | |
total.=A_LoopField "/" | |
if dup | |
new:=this.xml.CreateElement(A_LoopField),p.AppendChild(new) | |
else if !new:=p.SelectSingleNode("//" Trim(total,"/")) | |
new:=this.xml.CreateElement(A_LoopField),p.AppendChild(new) | |
p:=new | |
} | |
for a,b in att | |
p.SetAttribute(a,b) | |
if Text!="" | |
p.text:=text | |
} | |
return p | |
} | |
remove(){ | |
this.xml:="" | |
} | |
save(){ | |
this.xml.transformNodeToObject(xml.style(),this.xml) | |
this.xml.save(this.file) | |
} | |
transform(){ | |
this.xml.transformNodeToObject(xml.style(),this.xml) | |
} | |
ssn(node){ | |
return this.xml.SelectSingleNode(node) | |
} | |
sn(node){ | |
return this.xml.SelectNodes(node) | |
} | |
style(){ | |
static | |
if !IsObject(xsl){ | |
xsl:=ComObjCreate("MSXML2.DOMDocument") | |
style= | |
( | |
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> | |
<xsl:output method="xml" indent="yes" encoding="UTF-8"/> | |
<xsl:template match="@*|node()"> | |
<xsl:copy> | |
<xsl:apply-templates select="@*|node()"/> | |
<xsl:for-each select="@*"> | |
<xsl:text></xsl:text> | |
</xsl:for-each> | |
</xsl:copy> | |
</xsl:template> | |
</xsl:stylesheet> | |
) | |
xsl.loadXML(style),Style:=null | |
} | |
return xsl | |
} | |
easyatt(node,notext=""){ | |
list:=[],nodes:=sn(node,"@*") | |
while,n:=nodes.item[A_Index-1] | |
list[n.nodename]:=n.text | |
if !notext | |
list[1]:=node.text | |
return list | |
} | |
} | |
ssn(node,path){ | |
return node.SelectSingleNode(path) | |
} | |
sn(node,path){ | |
return node.SelectNodes(path) | |
} | |
t(x*){ | |
for a,b in x | |
list.=b "`n" | |
ToolTip,%list% | |
} | |
m(x*){ | |
for a,b in x | |
list.=b "`n" | |
MsgBox,% list | |
} | |
compile(){ | |
types:=[] | |
types["Audio"]:={id:"{4202947A-A563-4B05-A754-A1B4B5989849}",name:"Music in my library"} | |
types["Video"]:={id:"{B2D9BDDC-8E49-444B-9BA4-193ABF9C7870}",name:"Video in my library"} | |
types["Photo"]:={id:"{CC823400-A8E4-4081-B073-D3B6D952FE69}",name:"Pictures in my library"} | |
types["TV"]:={id:"{E5415A66-7763-4BDE-B97F-5557CA73C303}",name:"TV shows in my library"} | |
audio:=[{name:"Artist"},{name:"Album Artist",att:"WM/AlbumArtist"},{name:"Album Title",att:"WM/AlbumTitle"},{name:"Auto Rating",ap:"Effective Rating"},{name:"Bitrate"},{name:"Composer",att:"WM/Composer"},{name:"Conductor",att:"WM/Conductor"},{name:"Content Distributor",att:"WM/ContentDistributor"},{name:"Provider Genre"},{name:"Date Added",ap:"Acquisition Date"},{name:"Encoding Date"},{name:"Recording Date"},{name:"File name",ap:"SourceURL"},{name:"File size"},{name:"File Type"},{name:"Genre"},{name:"Language"},{name:"Playback Duration"},{name:"Mood"},{name:"User Rating"},{name:"Parental Rating",att:"WM/ParentalRating"},{name:"Period"},{name:"Playcount: Afternoon play totals"},{name:"Playcount: Evening play totals"},{name:"Playcount: Morning play totals"},{name:"Playcount: Night play totals"},{name:"Playcount: Total"},{name:"Playcount: Weekday play totals"},{name:"Playcount: Weekend play totals"},{name:"Playcount: Afternoon play totals"},{name:"Playcount: Evening play totals"},{name:"Playcount: Night play totals"},{name:"Provider"},{name:"Publisher",att:"WM/Publisher"},{name:"Release Date"},{name:"Subgenre"},{name:"Subtitle"},{name:"Title"},{name:"Writer"}] | |
video:=[{name:"Actor"},{name:"Auto Rating",ap:"Effective Rating"},{name:"Auto Rating",ap:"Effective Rating"},{name:"Bitrate"},{name:"Broadcast time",ap:"MediaOriginalBroadcastTime"},{name:"Channel",ap:"MediaOriginalChannel",att:"WM/MediaOriginalChannel"},{name:"Content Distributor",att:"WM/ContentDistributor"},{name:"Content Provider Genre",ap:"Provider Genre"},{name:"Date Added",ap:"Acquisition Date"},{name:"Encoding Date"},{name:"Recording Date"},{name:"Director"},{name:"File name",ap:"SourceURL"},{name:"File size"},{name:"File Type",ap:"FileType"},{name:"Genre"},{name:"Language"},{name:"Playback Duration"},{name:"User Rating"},{name:"Parental Rating",ap:"WM/ParentalRating"},{name:"Playcount: Afternoon play totals"},{name:"Playcount: Evening play totals"},{name:"Playcount: Morning play totals"},{name:"Playcount: Night play totals"},{name:"Playcount: Total"},{name:"Playcount: Weekday play totals"},{name:"Playcount: Weekend play totals"},{name:"Producer",att:"WM/Producer"},{name:"Provider",att:"WM/Provider"},{name:"Publisher",att:"WM/Publisher"},{name:"Release Date"},{name:"Station name",att:"WM/MediaStationName"},{name:"Subtitle"},{name:"Title"},{name:"Writer"}] | |
photo:=[{name:"Author"},{name:"Caption"},{name:"Date Added",ap:"Acquisition Date"},{name:"Date taken",ap:"DateTimeTaken"},{name:"File name",ap:"SourceURL"},{name:"Image height",ap:"ImageHeight",att:"WM/VideoHeight"},{name:"Image width",ap:"ImageWidth",att:"WM/VideoWidth"},{name:"Month Taken"},{name:"User Rating"},{name:"Year Taken",ap:"DateTimeTakenYear",att:"RecordingTimeYear"},{name:"File Type",ap:"FileType",att:"FileType"}] | |
;radio:=[{name:"Date att:"AcquisitionTimeDay"},{att:"AcquisitionTimeMonth"},{att:"AcquisitionTimeYear"},{att:"AcquisitionTimeYearMonth"},{att:"AcquisitionTimeYearMonthDay"},{att:"Author"},{att:"Bitrate"},{att:"CanonicalFileType"},{att:"FileType"},{att:"MediaType"},{att:"SourceURL"},{att:"Title"},{att:"WM/Language"},{att:"WM/Provider"}] | |
for a,name in ["Audio","Video","Photo"]{ | |
current:=type.add(name),main:="" | |
for a,b in types[name] | |
current.SetAttribute(a,b) | |
for a,name in %name% | |
type.add("name",name,"",1,"",current),main.="|" name.name | |
type.add("list","",main,"","",current) | |
} | |
/* | |
for x,name in ["Audio","Video","Photo","TV"]{ | |
} | |
*/ | |
main:=[] | |
for a,b in ["Artist","Actor","Album Artist","Album Title","Author","Caption","Channel","Composer","Conductor","Content Distributor","Content Provider Genre","Director","Episode","File Type","Genre","Language","Mood","Parental Rating","Period","Producer","Provider","Publisher","Series","Station name","Subgenre","Subtitle","Title","Writer"] | |
main[b]:=[["list1"],["Equals|Does Not Equal|Is|Is Not|Contains|Does Not Contain"],["|Any string value"]] | |
main["Bitrate"]:=[["list2"],["Is At Least","Is No More Than","Is"],[48,64,96,128,160,192,256,300,500,750,1000,1500,3000,4500,6000,7500]] | |
for a,b in ["File size","Image height","Image width"] | |
main[b]:=[["list3"],["Is Less Than","Is Greater Than","Is","Is Not"],["Any number"]] | |
for a,b in ["Broadcast time","Encoding Date","Recording Date","Date taken","Release Date"] | |
main[b]:=[["list4"],["Is Before","Is Later Than","Is","Is Not"],["Yesterday","Last week","Last month","6 months","1 year","2 years","5 years","2000s","1990s","1980s","1970s","1960s","1950s","1940s"]] | |
main["Date Added"]:=[["list5"],["Is Before","Is After","Is","Is Not"],["Yesterday","Last week","Last month","6 months","1 year","2 years","5 years"]] | |
main["Month Taken"]:=[["list6"],["Is Before","Is More Recent Than","Is","Is Not"],[1,2,3,4,5,6,7,8,9,10,11,12,13]] | |
main["Year Taken"]:=[["list7"],["Is Before","Is More Recent Than","Is","Is Not"],["Any year"]] | |
for a,b in ["Auto Rating","User Rating"] | |
main[b]:=[["list8"],["Is At Least","Is No More Than","Is","Is Not"],["Unrated","1 Star","2 Stars","3 Stars","4 Stars","5 Stars"]] | |
main["File name"]:=[["list9"],["Contains","Does Not Contain"],["Any string"]] | |
main["Playback Duration"]:=[["list10"],["Is Less Than","Is Greater Than","Is","Is Not"],[30,60,120,180,240,300,360]] | |
for a,b in ["Playcount: Afternoon play totals","Playcount: Evening play totals","Playcount: Morning play totals","Playcount: Night play totals","Playcount: Total","Playcount: Weekday play totals","Playcount: Weekend play totals"] | |
main[b]:=[["list11"],["Is Less Than","Is Greater Than","Is","Is Not"],["Any number"]] | |
condition:=type.add("condition") | |
for a,b in Main{ | |
list:=type.sn("//*[@name='" a "']"),list1:=list2:="" | |
while,l:=list.item(A_Index-1) | |
l.SetAttribute("list",b.1.1) | |
if !type.ssn("//condition/" b.1.1){ | |
for a,con in b.2 | |
list1.="|" con | |
for a,val in b.3 | |
list2.="|" val | |
type.add(b.1.1,{condition:list1,value:list2},"","","",condition) | |
} | |
} | |
Loop,2 | |
type.Transform() | |
type.save() | |
} | |
aplay(){ | |
global templist,tv,aphwnd | |
Gui,4:+hwndaphwnd +ToolWindow | |
Hotkey,IfWinActive,ahk_id%aphwnd% | |
Hotkey,Delete,remove,On | |
Hotkey,BackSpace,remove,On | |
Gui,4:Font,s10 | |
Gui,4:Add,Treeview,xm w680 h400 hwndtv gtv AltSubmit -0x4 | |
Gui,4:Default | |
TV_Add("Click here to add Media Types") | |
varlist.tv:=tv | |
Gui,4:Add,ListView,w680 h300 NoSortHdr,Media | |
Gui,4:Show | |
x=<?wpl version="1.0"?><smil><head><title>Temporary List</title></head><body><seq><smartPlaylist title="Temporary List"></smartPlaylist></seq></body></smil> | |
templist:=new xml("temp","","",x) | |
templist.xml.save("temp.wpl") | |
} | |
remove: | |
Gui,4:Default | |
main:=templist.ssn("//*[@tv='" TV_GetSelection() "']") | |
TV_Delete(TV_GetSelection()) | |
if main.nodename="sourceFilter" | |
main:=main.parentnode | |
main.parentnode.removechild(main) | |
templist.Transform(),debug(templist[]) | |
return | |
4GuiContextMenu: | |
CoordMode,mouse,Screen | |
MouseGetPos,x,y,,Control | |
if control=SysListView321 | |
{ | |
Gui,5:Destroy | |
media:=playlist.item(LV_GetNext()-1) | |
Gui,5:Add,ListView,w800 r40 AltSubmit -ReadOnly geditatt,Media Attribute|Attribute Name | |
Gui,5:Default | |
loop,% media.attributecount(){ | |
name:=media.getattributename(A_Index-1) | |
if Media.isReadOnlyItem(name)!=-1 | |
LV_Add("",media.getiteminfo(name),name) | |
} | |
Loop,2 | |
LV_ModifyCol(A_Index,"AutoHDR") | |
Gui,5:Show | |
;m(playlist.item(LV_GetNext()-1).name) | |
return | |
} | |
return | |
editatt: | |
if A_GuiEvent=Normal | |
{ | |
send,{f2} | |
return | |
} | |
Gui,4:Default | |
in:=LV_GetNext()-1 | |
Gui,5:Default | |
if RegExMatch(A_GuiEvent,"e"){ | |
LV_GetText(val,LV_GetNext()),LV_GetText(att,LV_GetNext(),2) | |
playlist.item(in).setiteminfo(att,val) | |
if (att="title"){ | |
displaylist() | |
} | |
} | |
return | |
addtype: | |
Gui,5:Submit | |
Gui,4:Default | |
tt:=TV_GetSelection() | |
in:=xml.easyatt(type.ssn("//" addtype)) | |
root:=TV_Add(in.name) | |
main:=templist.ssn("//smartPlaylist"),top:=templist.add("querySet","","","","",main) | |
templist.add("sourceFilter",{id:in.id,name:in.name,tv:root,type:addtype},"",0,0,top) | |
TV_Delete(tt),TV_Add("Click here to add Media Types") | |
templist.Transform(),debug(templist[]) | |
displaylist() | |
return | |
tv: | |
tv() | |
return | |
tv(){ | |
global | |
if !(A_GuiEvent="Normal"&&TV_GetSelection()) | |
return | |
if WinExist("ahk_id" sett){ | |
Gui,5:Destroy | |
return | |
} | |
tv:=varlist.tv | |
main:=templist.ssn("//*[@tv='" tt:=TV_GetSelection() "']"),t:=ssn(main,"@type").text | |
WinGetPos,wx,wy,,,ahk_id%tv% | |
VarSetCapacity(rc,16),NumPut(TV_GetSelection(),rc) | |
SendMessage,0x1104,1,&rc,,ahk_id%tv% | |
SendMessage,0x111c,0,0,,ahk_id%tv% | |
height:=errorlevel,nx:=NumGet(rc,0)+wx,ny:=NumGet(rc,4)+wy | |
if !main | |
{ | |
Gui,5:Destroy | |
Gui,5:-Caption | |
Gui,5:Margin,0,0 | |
Gui,5:Add,DDL,Choose1 vaddtype x0 y0,Audio|Video|Photo | |
Gui,5:Add,Button,gaddtype x+1 Default,Add Type | |
Gui,5:show,x%nx% y%ny%,Add a new type | |
return | |
} | |
if (main.nodename="sourceFilter") | |
dis:="",ny+=height,psel:="" | |
if (main.nodename="fragment") | |
psel:=ssn(main,"@name").Text,dis:="Disabled" | |
Gui,5:Destroy | |
Gui,5:Default | |
Gui,-Caption +hwndapl +Owner4 +hwndsett | |
Gui,Margin,0,0 | |
Gui,Add,ComboBox,x0 y0 vfragment %dis% gfirst w220 | |
Gui,Add,ComboBox,x+0 w140 vcon | |
Gui,Add,ComboBox,x+0 w200 vval | |
varlist.sett:=sett | |
if !psel | |
Gui,Add,Button,x+0 gaddst Default,Add | |
else | |
Gui,Add,Button,x+0 gchange Default,Update | |
popcb([psel]) | |
Gui,Show,% "x" nx "y" ny | |
} | |
change: | |
Gui,5:Submit | |
Gui,4:Default | |
main:=templist.ssn("//*[@tv='" TV_GetSelection() "']") | |
if (ssn(main,"@name").text="bitrate"&&val>1000) | |
val/=1000 | |
for a,b in [con,val] | |
main.childnodes.item(A_Index-1).text:=b | |
TV_Modify(TV_GetSelection(),"",fragment " : " con " : " val) | |
templist.Transform(),debug(templist[]) | |
displaylist() | |
return | |
addst: | |
;Create a function to test the values for this and the edit portion as well | |
Gui,5:Submit,Nohide | |
Gui,4:Default | |
anycon:={"any string":"value","any number":"numerical value","any year":"year value (eg: 2001)"} | |
ComObjError(0) | |
if !type.ssn("//*[@name='" fragment "']"){ | |
m("Please choose from the list of available options") | |
ControlFocus,ComboBox1 | |
return | |
} | |
ComObjError(1) | |
for a,b in {ComboBox2:con,ComboBox3:val}{ | |
if (anycon[b]){ | |
m("Please give the item a " anycon[b]) | |
ControlFocus,%a% | |
return | |
} | |
} | |
if (fragment="bitrate"&&val>1000) | |
val:=Floor(val/1000) | |
list:=type.ssn("//*[@name='" fragment "']/@list").text | |
ea:=xml.easyatt(type.ssn("//" list)) | |
main:=templist.ssn("//*[@tv='" TV_GetSelection() "']") | |
t:=ssn(main,"@type").text | |
tt:=TV_Add(fragment " : " con " : " val,ex:=ssn(main,"@tv").text) | |
TV_Modify(ex,"Expand") | |
ff:=type.ssn("//*[@name='" fragment "']/@ap").text | |
fragment:=ff?ff:fragment | |
frag:=templist.add("fragment",{name:fragment,tv:tt,type:t},"","","",main) | |
for a,b in {condition:con,value:val} | |
templist.add("argument",{name:a},b,"","",frag) | |
templist.Transform(),debug(templist[]) | |
Gui,5:Destroy | |
displaylist() | |
return | |
displaylist(){ | |
global templist,playlist | |
Gui,4:Default | |
templist.xml.save("temp.wpl") | |
f:=wmp.MediaCollection.add(A_ScriptDir "\temp.wpl") | |
LV_Delete(),playlist:=wmp.PlaylistCollection.getByName("Temporary List") | |
if playlist.count>1 | |
Loop,% playlist.Count{ | |
pl:=playlist.item(A_Index-1) | |
wmp.playlistcollection.remove(pl) | |
} | |
playlist:=wmp.PlaylistCollection.getByName("Temporary List").item(0) | |
loop,% playlist.count | |
LV_Add("",playlist.item(A_Index-1).getiteminfo("Title")) | |
} | |
first: | |
popcb(1) | |
return | |
popcb(x=""){ | |
global fragment,t,templist | |
if IsObject(x){ | |
name:=type.ssn("//*[@ap='" x.1 "']/@name").text | |
x.1:=name?name:x.1 | |
GuiControl,5:,ComboBox1,% type.ssn("//" t "/list").text | |
if !x.1 | |
GuiControl,5:Choose,ComboBox1,1 | |
else | |
GuiControl,5:ChooseString,ComboBox1,% x.1 | |
} | |
Gui,5:Submit,Nohide | |
list:=type.ssn("//" t "/*[@name='" fragment "']/@list") | |
rep:=type.ssn("//*[@name='" fragment "']/@att").text | |
rep:=rep?rep:fragment | |
ComObjError(0) | |
count:=wmp.mediacollection.getAttributeStringCollection(rep,t) | |
Loop,% count.count | |
if item:=count.item(A_Index-1) | |
ll.="|" item | |
ComObjError(1) | |
for a,b in {condition:2,value:3}{ | |
ov:=ssn(list,"//" list.text "/@" a).text | |
nv:=A_Index=1?ov | |
nv:=(A_Index=2&&ll)?ll:ov | |
GuiControl,5:,ComboBox%b%,%nv% | |
GuiControl,5:Choose,ComboBox%b%,1 | |
} | |
if x.1{ | |
Gui,4:Default | |
main:=templist.ssn("//*[@tv='" TV_GetSelection() "']") | |
Gui,5:Default | |
while,val:=main.childnodes.item(A_Index-1){ | |
GuiControl,5:ChooseString,% "ComboBox" A_Index+1,% val.text | |
if ErrorLevel | |
{ | |
GuiControl,5:,ComboBox3,% "|" val.text | |
GuiControl,5:Choose,ComboBox3,1 | |
} | |
} | |
} | |
templist.Transform() | |
debug(templist[]) | |
} | |
5GuiEscape: | |
5GuiClose: | |
Gui,5:Destroy | |
return | |
move(a,b,c,d){ | |
global sett | |
if WinExist("ahk_id" sett) | |
Gui,5:Destroy | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment