#!/usr/bin/env python # -*- coding:Utf-8 -*- #--------------------------------------------------------------------------- #Copyright (C) 2006 bouleetbil #This program is free software; you can redistribute it and/or #modify it under the terms of the GNU General Public License #as published by the Free Software Foundation; either version 2 #of the License, or (at your option) any later version. #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. #You should have received a copy of the GNU General Public License #along with this program; if not, write to the Free Software #Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #--------------------------------------------------------------------------- # \ ^__^ # \ (oo)\_______ # (__)\ )\/\ # ||----w | # || || #--------------------------------------------------------------------------- #depend of feedparser and wxpython from wxPython.wx import * from wxPython.grid import * import sys,os import feedparser import platform import re import cPickle sys.path.insert(0, "./modules") from urllib2 import Request, urlopen #Section Configuration #"http://packages.gentoo.org/archs/x86/stable/gentoo_simple.rss", #"http://packages.gentoo.org/archs/x86/testing/gentoo_simple.rss", feeds=[ "http://packages.gentoo.org/feed/arch/x86/stable", "http://packages.gentoo.org/feed/arch/x86/testing", "http://packages.gentoo.org/feed/arch/x86/masked", "http://www.gentoo.org/rdf/en/glsa-index.rdf" ] # The indice of feeds security En_NumSecurite = 4 # view thee feed security 1=>true 0=>false bo_AfficheAlerteSecurity = 1 #view only our install paquets 0=>false 1=>true bo_AffichePaquetInstall = 0 #nb of title nb_Limit=50 ch_RepFeed="/tmp/feeds/" ch_RepFeed2="/tmp/feeds_gp2x/" #End configuration if not os.path.isdir('/tmp') : os.mkdir('/tmp') ch_DbPortage="/var/db/pkg/" #--------------------------------------------------------------------------- def get_url(url): req = Request(url) try: handle = urlopen(req) except IOError, e: if hasattr(e, 'reason'): print 'ERROR!!' print '\tReason: ', e.reason raise "error" elif hasattr(e, 'code'): print 'ERROR!!' print '\tError code: ', e.code raise "error" return handle.read() def fixname(url): invalid_chars=re.compile('\.|\&|\?|\=') filename='' lname=url.split('/')[2:] for n in lname: if n != "": filename=filename+'_'+n filename=invalid_chars.sub('_',filename).lstrip('_')+".xml" return filename class CustomDataTable(wxPyGridTableBase): def __init__(self,data): self.data= data wxPyGridTableBase.__init__(self) self.colLabels = [ 'Canal', 'Paquets','URL' ] self.dataTypes = [wxGRID_VALUE_STRING, wxGRID_VALUE_STRING, wxGRID_VALUE_STRING] def GetNumberRows(self): return len(self.data) + 2 def GetNumberCols(self): return len(self.data[0]) def IsEmptyCell(self, row, col): try: return not self.data[row][col] except IndexError: return true def GetValue(self, row, col): try: return self.data[row][col] except IndexError: return '' def SetValue(self, row, col, value): try: self.data[row][col] = value except IndexError: self.data.append([''] * self.GetNumberCols()) self.SetValue(row, col, value) msg = wxGridTableMessage(self, # The table wxGRIDTABLE_NOTIFY_ROWS_APPENDED, # what we did to it 1) # how many self.GetView().ProcessTableMessage(msg) self.GetView().MoveCursorDown(false) def GetColLabelValue(self, col): return self.colLabels[col] def GetTypeName(self, row, col): return self.dataTypes[col] def CanGetValueAs(self, row, col, typeName): colType = self.dataTypes[col].split(':')[0] if typeName == colType: return true else: return False def CanSetValueAs(self, row, col, typeName): return self.CanGetValueAs(row, col, typeName) #--------------------------------------------------------------------------- class CustTableGrid(wxGrid): def __init__(self, parent, data): wxGrid.__init__(self, parent, -1) self.table = CustomDataTable(data) self.SetTable(self.table, true) self.SetRowLabelSize(0) self.SetMargins(0,0) self.AutoSizeColumns(False) EVT_GRID_CELL_LEFT_DCLICK(self, self.OnLeftDClick) def OnLeftDClick(self, evt): if self.CanEnableCellControl(): self.EnableCellEditControl() #--------------------------------------------------------------------------- class FrameEnCours(wxFrame): def __init__(self, parent): wxFrame.__init__(self, parent, -1, "Packets Gentoo", size=(550,300)) self.data=[] #self.data = [ # ["canal", "texte paquets"], # ["canal", "texte paquets"], # ["canal", "texte paquets"] # ] ################### #Feed if not os.path.isdir(ch_RepFeed) : os.mkdir(ch_RepFeed) if not os.path.isdir(ch_RepFeed2) : os.mkdir(ch_RepFeed2) p=platform.platform().lower() if 'windows' in p: opsys='windows' elif 'linux' in p: opsys='linux' import posix elif 'macintosh': opsys='macos' else: opsys='unknown' print """ Unknown platform!! Please send a report including this error message and your OS/platform to bouleetbil@frogdev.info. """ if not platform.platform().lower().startswith('windows'): import posix dic_tit_arch={} en_Feed=0 for url in feeds: en_Feed=en_Feed+1 if bo_AfficheAlerteSecurity == 0 : if en_Feed == En_NumSecurite : break print "Url detected:%s"%url print "\tDownloading...", sys.stdout.flush() filename=fixname(url) try: fh=open(ch_RepFeed+filename,'w') except IOError: print "ERROR!!" print "Please create a 'feeds' directory" sys.exit(0) try: fh.write(get_url(url)) except: print "ERROR!!" print "Couldn't write feed" continue fh.close() print "Done" print "\tParsing...", sys.stdout.flush() ruta_o=os.path.join(ch_RepFeed, filename) o = feedparser.parse(ruta_o) try: t_o=o.feed.title print "\t" print "**Canal : "+t_o+"**" ch_Titre = t_o if en_Feed == 1 : ch_Titre = ch_Titre+" Stable" if en_Feed == 2 : ch_Titre = ch_Titre+" Testing" if en_Feed == 3 : ch_Titre = ch_Titre+" Hard mask" self.data.append([ch_Titre, "",""]) nb_Canal = 0 #affichage du canal #parcours des feeds print str(len(o['entries']))+" paquets" nb=0 nb_Canal=nb_Canal+1 for i in o['entries']: #print "\t"+o['entries'][nb]['title'] ch_Inst="" ch_Paquet = o['entries'][nb]['title'] print "Recoit: "+ch_Paquet Tab_Paquet=ch_Paquet.split(" ") Tab_RepPaquet=ch_Paquet.split("/") ch_Paquet=ch_Paquet.replace(' ','-',1) #print Tab_Paquet[0] files = os.listdir(ch_DbPortage) bo_Append=0 if bo_AffichePaquetInstall == 0 : bo_Append=1 if bo_AfficheAlerteSecurity == 1 : if en_Feed == En_NumSecurite : bo_Append=1 for fn in files: #if paquet name in xml is app-xxx/name if fn == Tab_RepPaquet[0] : print "=>Recherche dans "+fn #The name is app-xxx/name version Tab_NomPaquet=Tab_RepPaquet[1].split(" ") filesbis = os.listdir(ch_DbPortage+fn) for fnbis in filesbis: #obsolete #print "==>Compare "+fnbis[0:len(Tab_NomPaquet[0])]+" avec "+Tab_NomPaquet[0] #if fnbis[0:len(Tab_NomPaquet[0])] == Tab_NomPaquet[0] : # if fnbis[len(Tab_NomPaquet[0]):len(Tab_NomPaquet[0])+1] == "-" : # #The version as prefix "-" # #the paquet is equal # #print "Installe : "+fnbis+" New Version : "+ch_Paquet # ch_Inst=fnbis+" is installed" # bo_Append=1 #fin obsolete Tab_PaqRecu=fnbis[0:len(Tab_NomPaquet[0])].split("-") Tab_PaqInstall=Tab_NomPaquet[0].split("-") en_PaqRecu=len(Tab_PaqRecu) en_PaqInstall=len(Tab_PaqInstall) #Maintenant on peux deduire le nom du paquet ch_paquetRecu="" ch_paquetInst="" en_cptdel=0 while en_cptdel <> en_PaqRecu-1 : #il faut sortir des que numerique c'est une version qui demarre if Tab_PaqRecu[en_cptdel][0] == "0" or Tab_PaqRecu[en_cptdel][0] == "1" or Tab_PaqRecu[en_cptdel][0] == "2" or Tab_PaqRecu[en_cptdel][0] == "3" or Tab_PaqRecu[en_cptdel][0] == "4" or Tab_PaqRecu[en_cptdel][0] == "5" or Tab_PaqRecu[en_cptdel][0] == "6" or Tab_PaqRecu[en_cptdel][0] == "7" or Tab_PaqRecu[en_cptdel][0] == "8" or Tab_PaqRecu[en_cptdel][0] == "9" : break ch_paquetRecu=ch_paquetRecu+"-"+Tab_PaqRecu[en_cptdel] en_cptdel=en_cptdel+1 en_cptdel=0 while en_cptdel <> en_PaqInstall-1 : #il faut sortir des que numerique c'est une version qui demarre if Tab_PaqInstall[en_cptdel][0] == "0" or Tab_PaqInstall[en_cptdel][0] == "1" or Tab_PaqInstall[en_cptdel][0] == "2" or Tab_PaqInstall[en_cptdel][0] == "3" or Tab_PaqInstall[en_cptdel][0] == "4" or Tab_PaqInstall[en_cptdel][0] == "5" or Tab_PaqInstall[en_cptdel][0] == "6" or Tab_PaqInstall[en_cptdel][0] == "7" or Tab_PaqInstall[en_cptdel][0] == "8" or Tab_PaqInstall[en_cptdel][0] == "9" : break ch_paquetInst=ch_paquetInst+"-"+Tab_PaqInstall[en_cptdel] en_cptdel=en_cptdel+1 print ":==>Compare "+ch_paquetRecu+" avec "+ch_paquetInst if ch_paquetRecu==ch_paquetInst : ch_Inst=fnbis+" is installed" bo_Append=1 ch_url = o['entries'][nb]['id'] if bo_Append == 1 : self.data.append([str(nb)+" "+ch_Inst, ch_Paquet+" is new",ch_url]) if nb_Limit == nb : break nb=nb+1 except: t_o="sin titulo" gp2xfile=os.path.join(ch_RepFeed2, "%s.dic"%filename) dic_tit_arch[t_o]=ruta_o dic_noticias=feedparser.parse(dic_tit_arch[t_o]) dic_tit_arch[t_o]=gp2xfile try: fichero = open(gp2xfile, 'w') except IOError: print "ERROR!!" print "Please create a 'feeds_gp2x' directory" sys.exit(0) cPickle.dump(dic_noticias, fichero) fichero.close() print "Done" # Saving titles dic fichero = open(os.path.join(ch_RepFeed2, "titles.dic"), 'w') cPickle.dump(dic_tit_arch, fichero) fichero.close() ########## #Lance l'init on a tout self.initwin() def initwin(self): self.ref= None self.p = wxPanel(self, -1, style=0) # b = wxButton(self.p, -1, "Voir paquet...") # b.SetDefault() # EVT_BUTTON(self, b.GetId(), self.OnButton) self.bs = wxBoxSizer(wxVERTICAL) self.grid = CustTableGrid(self.p,self.data) self.bs.Add(self.grid, 1, wxGROW|wxALL, 5) # self.bs.Add(b) self.p.SetSizer(self.bs) # code du clic Pour plus tard ouverture du navigateur # def OnButton(self, evt): # sz= self.p.GetSize() # self.p.Destroy() # self.initwin() # self.p.SetSize(sz) # print "button selected" #------------------------------------------------------------------------------- class mApp(wxApp): def OnInit(self): frame= FrameEnCours(None) frame.Show(true) return true #------------------------------------------------------------------------------- app = mApp(0) app.MainLoop() #-------------------------------------------------------------------------------