# Copyright (c) 2004-5 Marek Hnilica. All rights reserved. # Module providing gui for freedb search # Distributed under GPL version 2, or (at your option) later import wx from wx.grid import * import PyCDDB,string,types,utils import cPickle def TranslateToStr(List): TempList=[] for element in List: TempList.append(str(element)) return TempList def Message(parent,text,label): Mes=wx.MessageDialog(parent,text,label,wx.ICON_WARNING) Mes.ShowModal() Mes.Destroy() class LookUp(wx.Dialog): def __init__(self,parent,FreedbAutoAppendDiscid,AlbumLengths): wx.Dialog.__init__(self,parent,-1,'Searching in FreeDB database...',style=wx.RESIZE_BORDER|wx.CLOSE_BOX) # datas to be sent to freedb server [self.AlbumId,self.Offsets,self.TotalTime]=PyCDDB.GetAlbumId(AlbumLengths) self.Argument=[string.zfill(hex(self.AlbumId)[2:],8),str(len(self.Offsets))]+TranslateToStr(self.Offsets)+[str(self.TotalTime)] MainSizer=wx.BoxSizer(wx.VERTICAL) GridPanel=wx.Panel(self,-1) GridSizer=wx.BoxSizer(wx.VERTICAL) CloseButton=wx.Button(self,wx.ID_CANCEL) wx.EVT_BUTTON(CloseButton,CloseButton.GetId(),self.ClickedClose) self.AppendDiscid=wx.ToggleButton(self,wx.NewId(),'Append freedb discid & genre to files') self.AppendDiscid.SetValue(FreedbAutoAppendDiscid) ButSizer=wx.BoxSizer(wx.HORIZONTAL) ButSizer.AddMany([ (CloseButton,1,wx.EXPAND), (200,0), (self.AppendDiscid,1,wx.EXPAND), ]) MainSizer.AddMany([ (GridPanel,1,wx.EXPAND), (ButSizer,0,wx.EXPAND), (wx.Panel(self,-1,size=(-1,5)),0,wx.EXPAND), (wx.StaticText(self,-1,'Double-click on label of column to use values in cells'),0,wx.EXPAND), ]) self.CenterOnParent() self.Tags='' # return value checked in main mbox file; if not self.Tags=='' than tags are to be written, otherwise is search ignored self.dbSession=PyCDDB.PyCDDB() try: self.Items=self.dbSession.query(string.join(self.Argument)) except: utils.GeneralError(self,label='Unable to establish Internet connection',text='Connection to FreeDB server failed.\nEither your Internet connection is not working or freedb.org is down.') return if len(self.Items)==0: msg=wx.MessageDialog(None,'Requested album is not in database yet.','Unknown album',wx.ICON_INFORMATION) msg.ShowModal() msg.Destroy() return FullList={} # fetching might take long time: let user know if len(self.Items)==1: ProgDiag=wx.ProgressDialog("Please wait...","1 result found, fetching data from server...",len(self.Items),self) else: ProgDiag=wx.ProgressDialog("Please wait...","%s results found, fetching data from server..."%str(len(self.Items)),len(self.Items),self,wx.PD_REMAINING_TIME|wx.PD_CAN_ABORT) fetched=0 for i in range(len(self.Items)): # adds fetched data to FullList dict, which than contains all fetched data DataForItem=self.dbSession.read(self.Items[i]) try: [Artist,Album]=string.split(DataForItem['DTITLE'],'/',1) except ValueError: [Artist,Album]=(DataForItem['DTITLE'],'') FullList[i]=[Artist,Album,DataForItem['TTITLE'],DataForItem['DGENRE'],DataForItem['DYEAR']] fetched+=1 # if clicked cancel, show fetched, don't quit if ProgDiag.Update(i)==0: break ProgDiag.Destroy() # create list of columns to be created i=1 ListOfCols=['Artist','Album','Genre','Year'] TempList={} dps=cPickle.dumps lps=cPickle.loads sorted={} for i in range(len(FullList)): if not dps(FullList[i]) in TempList: TempList[dps(FullList[i])]=1 else: TempList[dps(FullList[i])]=TempList[dps(FullList[i])]+1 values=TempList.values() for i in values: sorted[i]=[] for key in TempList: oldlist=sorted[TempList[key]] oldlist.append(key) sorted[TempList[key]]=oldlist # create cols for i in range(len(lps(TempList.keys()[0])[2])): ListOfCols.append('Title '+string.zfill(str(i),2)) # create the grid self.Grid=Grid(GridPanel, -1) self.Grid.CreateGrid(len(ListOfCols),len(TempList)) for i in range(len(ListOfCols)): self.Grid.SetRowLabelValue(i,ListOfCols[i]) GridSizer.Add(self.Grid,1,wx.EXPAND) GridSizer.Fit(GridPanel) GridPanel.SetSizer(GridSizer) GridPanel.SetAutoLayout(1) EVT_GRID_LABEL_LEFT_DCLICK(self.Grid,self.FinishedSelecting) values=sorted.keys() values.reverse() RecordPos=0 for num in values: actual=sorted[num] # adds text to grid for packed in actual: record=lps(packed) # we strip because results are sometimes space-padded self.Grid.SetCellValue(0,RecordPos,string.strip(record[0])) self.Grid.SetCellValue(1,RecordPos,string.strip(record[1])) self.Grid.SetCellValue(2,RecordPos,string.strip(record[3])) self.Grid.SetCellValue(3,RecordPos,string.strip(record[4])) for TitlePos in range(len(record[2])): self.Grid.SetCellValue(4+TitlePos,RecordPos,string.strip(record[2][TitlePos])) if num==1: text='One match contain:' else: text='%s matches contains:'%str(num) self.Grid.SetColLabelValue(RecordPos,text) RecordPos+=1 RowAttr=GridCellAttr() RowAttr.SetBackgroundColour(wx.Colour(255,255,230)) self.Grid.AutoSize() for i in range(4): self.Grid.SetRowAttr(i,RowAttr) if len(FullList)==1: self.SetLabel('Finished fetching data: 1 result') else: self.SetLabel('Finished fetching data: %s results'%str(len(FullList))) MainSizer.Fit(self) self.SetSizer(MainSizer) self.SetAutoLayout(1) self.SetSize(parent.GetSize()) self.CenterOnParent() self.ShowModal() def FinishedSelecting(self,evt): ''' makes self.Tags variable to contain reliable data''' Col=evt.GetCol() if Col>=0: FreedbString=string.join((self.Items[Col]['category'],self.Items[Col]['disc_id']),'/') Artist=self.Grid.GetCellValue(0,Col) Album=self.Grid.GetCellValue(1,Col) Genre=self.Grid.GetCellValue(2,Col) Year=self.Grid.GetCellValue(3,Col) Titles=[] for i in range(4,self.Grid.GetNumberRows()): Titles.append(self.Grid.GetCellValue(i,Col)) if self.AppendDiscid.GetValue(): self.Tags=[Artist,Album,Genre,Year,Titles,FreedbString] else: self.Tags=[Artist,Album,Genre,Year,Titles] self.Close() def ClickedClose(self,evt): self.Close()