Project ION: remove unvanted files

This commit is contained in:
Gujs 2011-10-18 00:23:26 +02:00
parent 6ff367788a
commit 7df53fc92f
30 changed files with 0 additions and 4164 deletions

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.program.repo.installer"
name="Repositories Installer"
version="1.0.3"
provider-name="Temhil and Frost (passion-xbmc.org)">
<requires>
<import addon="xbmc.python" version="1.0"/>
</requires>
<extension point="xbmc.python.pluginsource"
library="default.py">
<provides>executable</provides>
</extension>
<extension point="xbmc.addon.metadata">
<summary>Installer of Add-on Repositories for XBMC</summary>
<description>This Add-on allow to select (from XBMC Wiki) and install Repositories of XBMC Add-ons</description>
<platform>all</platform>
</extension>
</addon>

View File

@ -1,17 +0,0 @@
2011-03-21 Version 1.0.3 by Temhil
- Added Repository info window
- Set default title display option without description
2011-03-17 Version 1.0.2 by Temhil
- Added option to add or not description from title
- Added option for activating or not color of description (set it by default)
- Removed Bold Title
2011-03-15 - Version 1.0.1 by Temhil
- Added Icon (thank to Willynuisance)
- Added settings allowing to change color of description
2011-03-13 - Version 1.0.0 by Temhil and Frost
- Creation (installation part based on Frost work with script.addon.installer)

View File

@ -1,376 +0,0 @@
# -*- coding: cp1252 -*-
"""
Repository Installer Addon (plugin type) allowing to find and install addon repositories for XBMC
Changelog:
03-21-2011 Version 1.0.3 by Temhil
- Added Repository info window
- Set default title display option without description
03-17-2011 Version 1.0.2 by Temhil
- Added option to add or not description from title
- Added option for activating or not color of description (set it by default)
- Removed Bold Title
03-15-2011 Version 1.0.1 by Temhil
- Added Icon (thank to Willynuisance)
- Added settings allowing to change color of description
03-13-2011 Version 1.0.0 by Temhil and Frost
- Creation (installation part based on Frost work with script.addon.installer)
"""
REMOTE_DBG = False # For remote debugging with PyDev (Eclipse)
__script__ = "Unknown"
__plugin__ = "Repositories Installer"
__addonID__ = "plugin.program.repo.installer"
__author__ = "Temhil and Frost (http://passion-xbmc.org)"
__url__ = "http://passion-xbmc.org/index.php"
__svn_url__ = "http://passion-xbmc.googlecode.com/svn/trunk/addons/plugin.program.repository.installer/"
__credits__ = "Team XBMC Passion"
__platform__ = "xbmc media center"
__date__ = "03-21-2011"
__version__ = "1.0.3"
__svn_revision__ = 0
import os
import urllib
from traceback import print_exc
# xbmc modules
import xbmc
import xbmcplugin
import xbmcgui
import xbmcaddon
__addon__ = xbmcaddon.Addon( __addonID__ )
__settings__ = __addon__
__language__ = __addon__.getLocalizedString
__addonDir__ = __settings__.getAddonInfo( "path" )
# Remote debugger using Eclipse and Pydev
if REMOTE_DBG:
# Note pydevd module need to be copied in XBMC\system\python\Lib\pysrc
try:
import pysrc.pydevd as pydevd
pydevd.settrace('localhost', stdoutToServer=True, stderrToServer=True)
except ImportError:
sys.stderr.write("Error: " +
"You must add org.python.pydev.debug.pysrc to XBMC\system\python\Lib\pysrc")
sys.exit(1)
ROOTDIR = os.getcwd()
BASE_RESOURCE_PATH = os.path.join( ROOTDIR, "resources" )
MEDIA_PATH = os.path.join( BASE_RESOURCE_PATH, "media" )
ADDON_DATA = xbmc.translatePath( "special://profile/addon_data/%s/" % __addonID__ )
REPO_LIST_URL = "http://wiki.xbmc.org/index.php?title=Unofficial_Add-on_Repositories"
REPO_PACKAGE_DIR = "special://home/addons/packages/"
REPO_INSTALL_DIR = "special://home/addons/"
DIALOG_PROGRESS = xbmcgui.DialogProgress()
#modules custom
try:
import resources.lib.wikiparser as wikiparser
except:
print_exc()
class RepoInstallerPlugin:
"""
main plugin class
"""
# define param key names
PARAM_NAME = 'name'
PARAM_ACTION = 'action'
PARAM_URL = 'url'
VALUE_INSTALL_FROM_ZIP = 'installfromzip'
VALUE_INSTALL_FROM_REPO = 'installfromrepo'
VALUE_INSTALL_ALL = 'installfromzip'
VALUE_DISPLAY_INFO = 'displayinfo'
# Constant
colorList = ["red", "green", "yellow", "lightblue", None]
debugMode = False
shortTitleDisplay = False
def __init__( self, *args, **kwargs ):
# Parse plugin parameters
self.parameters = self._parse_params()
# Check settings
#if ( __settings__.getSetting('first_run') == 'true' ):
# #xbmcplugin.openSettings(sys.argv[0])
#else:
# self.select()
self._set_title_display()
self.select()
def create_root_dir ( self ):
print "createRootDir"
xbmcplugin.setPluginCategory( handle=int( sys.argv[ 1 ] ), category=__language__( 30001 ) )
print "Loading wiki page: %s"%REPO_LIST_URL
wikiparser.getRepoList(REPO_LIST_URL, addItemFunc=self._addLink, progressBar=None, msgFunc=None )
self._add_sort_methods( True )
self._end_of_directory( True )
def install_repo(self, repoName, repoURL):
"""
Install a repository in XBMC
-> will need XBMC restart in order to have the new Repo taken in account by XBMC
"""
continueInstall = True
dialogYesNo = xbmcgui.Dialog()
if dialogYesNo.yesno(repoName, __language__( 30100 ), __language__( 30101 )):
if continueInstall:
ri = RepoInstaller()
newRepo = ri.download( repoURL )
print newRepo
if newRepo:
fp, ok = ri.install( newRepo )
print "---"
print fp, ok
xbmc.executebuiltin( 'XBMC.UpdateAddonRepos()' )
try:
_N_ = Addon( os.path.basename( fp ) )
print "Addon %s Installed"%s_N_
ri.notification( _N_.getAddonInfo( "name" ), __language__( 24065 ).encode( "utf-8" ), 5000, _N_.getAddonInfo( "icon" ) )
except:
xbmcgui.Dialog().ok( __settings__.getAddonInfo( "name" ), __language__( 30007 ) + " : " + repoName, __language__( 30010 ) )
self._end_of_directory( True, update=False )
def select( self ):
try:
print "select"
print self.parameters
if len(self.parameters) < 1:
self.create_root_dir()
elif self.PARAM_ACTION in self.parameters.keys():
if self.parameters[self.PARAM_ACTION] == self.VALUE_INSTALL_FROM_ZIP:
repoName = self.parameters[self.PARAM_NAME]
repoURL = self.parameters[self.PARAM_URL]
#print repoName
#print repoURL
#xbmc.executebuiltin('XBMC.ActivateWindow(146)')
#xbmc.executebuiltin( "Action(Info)")
self.install_repo(repoName, repoURL)
elif self.parameters[self.PARAM_ACTION] == self.VALUE_DISPLAY_INFO:
try:
from resources.lib.DialogRepoInfo import DialogRepoInfo
repoWindow = DialogRepoInfo( "DialogRepoInfo.xml", os.getcwd(), "Default", "720p" )
del repoWindow
except:
print_exc()
self._end_of_directory( False )
else:
self._end_of_directory( True, update=False )
except:
print_exc()
self._end_of_directory( False )
def _parse_params( self ):
"""
Parses Plugin parameters and returns it as a dictionary
"""
paramDic={}
# Parameters are on the 3rd arg passed to the script
paramStr=sys.argv[2]
print paramStr
if len(paramStr)>1:
paramStr = paramStr.replace('?','')
# Ignore last char if it is a '/'
if (paramStr[len(paramStr)-1]=='/'):
paramStr=paramStr[0:len(paramStr)-2]
# Processing each parameter splited on '&'
for param in paramStr.split("&"):
try:
# Splitting couple key/value
key,value=param.split("=")
except:
key=param
value=""
key = urllib.unquote_plus(key)
value = urllib.unquote_plus(value)
# Filling dictionary
paramDic[key]=value
print paramDic
return paramDic
def _create_param_url(self, paramsDic):
"""
Create an plugin URL based on the key/value passed in a dictionary
"""
url = sys.argv[ 0 ]
sep = '?'
print paramsDic
try:
for param in paramsDic:
#TODO: solve error on name with non ascii char (generate exception)
url = url + sep + urllib.quote_plus( param ) + '=' + urllib.quote_plus( paramsDic[param] )
sep = '&'
except:
url = None
print_exc()
return url
def _set_title_display(self):
descriptInTitle =__settings__.getSetting('desintitle')
if descriptInTitle == 'true':
self.shortTitleDisplay = False
else:
self.shortTitleDisplay = True
def _addLink( self, itemInfo ):
"""
Add a link to the list of items
"""
ok=True
print itemInfo
if itemInfo["ImageUrl"]:
icon = itemInfo["ImageUrl"]
else:
#icon = "DefaultFolder.png"
#icon = "DefaultAddon.png"
icon = os.path.join(MEDIA_PATH, "DefaultAddonRepository.png")
descriptColor = self.colorList[ int( __settings__.getSetting( "descolor" ) ) ]
if self.shortTitleDisplay:
labelTxt = itemInfo["name"]
else:
labelTxt = itemInfo["name"] + ": " + self._coloring( itemInfo["description"], descriptColor )
liz=xbmcgui.ListItem( label=labelTxt, iconImage=icon, thumbnailImage=icon )
liz.setInfo( type="addons",
infoLabels={ "title": itemInfo["name"], "Plot": itemInfo["description"] } )
liz.setProperty("Addon.Name",itemInfo["name"])
liz.setProperty("Addon.Version"," ")
liz.setProperty("Addon.Summary", "")
liz.setProperty("Addon.Description", itemInfo["description"])
liz.setProperty("Addon.Type", __language__( 30011 ))
liz.setProperty("Addon.Creator", itemInfo["owner"])
liz.setProperty("Addon.Disclaimer","")
liz.setProperty("Addon.Changelog", "")
liz.setProperty("Addon.ID", "")
liz.setProperty("Addon.Status", "Stable")
liz.setProperty("Addon.Broken", "Stable")
liz.setProperty("Addon.Path","")
liz.setProperty("Addon.Icon",icon)
#dirItem.addContextMenuItem( self.Addon.getLocalizedString( 30900 ), "XBMC.RunPlugin(%s?showtimes=%s)" % ( sys.argv[ 0 ], urllib.quote_plus( repr( video[ "title" ] ) ), ) )
paramsMenu = {}
paramsMenu[self.PARAM_NAME] = itemInfo["name"]
paramsMenu[self.PARAM_ACTION] = self.VALUE_DISPLAY_INFO
urlMenu = self._create_param_url( paramsMenu )
if urlMenu:
c_items = [ ( __language__( 30012 ), "XBMC.RunPlugin(%s)" % ( urlMenu)) ]
liz.addContextMenuItems( c_items )
params = {}
params[self.PARAM_NAME] = itemInfo["name"]
params[self.PARAM_ACTION] = self.VALUE_INSTALL_FROM_ZIP
params[self.PARAM_URL] = itemInfo["repoUrl"]
urlRepo = self._create_param_url( params )
if urlRepo:
ok=xbmcplugin.addDirectoryItem( handle=int(sys.argv[1]), url=urlRepo, listitem=liz, isFolder=False )
return ok
def _end_of_directory( self, OK, update=False ):
xbmcplugin.endOfDirectory( handle=int( sys.argv[ 1 ] ), succeeded=OK, updateListing=update )#, cacheToDisc=True )#updateListing = True,
def _add_sort_methods( self, OK ):
if ( OK ):
try:
xbmcplugin.addSortMethod( handle=int( sys.argv[ 1 ] ), sortMethod=xbmcplugin.SORT_METHOD_UNSORTED )
xbmcplugin.addSortMethod( handle=int( sys.argv[ 1 ] ), sortMethod=xbmcplugin.SORT_METHOD_LABEL )
except:
print_exc()
def _coloring( self, text , color ):
if color:
if color == "red": color="FFFF0000"
if color == "green": color="FF00FF00"
if color == "yellow": color="FFFFFF00"
if color == "lightblue": color="FFB1C7EC"
colored_text = "[COLOR=%s]%s[/COLOR]" % ( color , text )
else:
colored_text = text
return colored_text
def _bold_text( self, text ):
""" FONCTION POUR METTRE UN MOT GRAS """
return "[B]%s[/B]" % ( text, )
class RepoInstaller:
"""
main plugin class
"""
def download( self, url, destination=REPO_PACKAGE_DIR ):
try:
DIALOG_PROGRESS.create( __settings__.getAddonInfo( "name" ) )
destination = xbmc.translatePath( destination ) + os.path.basename( url )
def _report_hook( count, blocksize, totalsize ):
percent = int( float( count * blocksize * 100 ) / totalsize )
DIALOG_PROGRESS.update( percent, __language__( 30005 ) % url, __language__( 30006 ) % destination )
fp, h = urllib.urlretrieve( url, destination, _report_hook )
print fp, h
return fp
except:
print_exc()
DIALOG_PROGRESS.close()
return ""
def install( self, filename ):
from resources.lib.extractor import extract
return extract( filename, xbmc.translatePath( REPO_INSTALL_DIR ) )
def notification( self, header="", message="", sleep=5000, icon=__settings__.getAddonInfo( "icon" ) ):
""" Will display a notification dialog with the specified header and message,
in addition you can set the length of time it displays in milliseconds and a icon image.
"""
xbmc.executebuiltin( "XBMC.Notification(%s,%s,%i,%s)" % ( header, message, sleep, icon ) )
#######################################################################################################################
# BEGIN !
#######################################################################################################################
if ( __name__ == "__main__" ):
try:
RepoInstallerPlugin()
except:
print_exc()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

View File

@ -1 +0,0 @@
# Dummy file to make this directory a package.

View File

@ -1,37 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<strings>
<!-- Les strings de 30000 à 30999 sont réservées aux paramètres plug-in -->
<!--GENERAL STRINGS -->
<string id="30000">Repositories Installer</string>
<string id="30001">Add-ons Repositories</string>
<string id="30005">Downloading: %s </string>
<string id="30006">to: %s</string>
<string id="30007">Repository Installed</string>
<string id="30010">XBMC requires to restart!</string>
<string id="30011">Repository</string>
<string id="30012">Repository Info</string>
<!--CONTEXT MENU STRINGS -->
<!--DIALOG STRINGS -->
<string id="30100">Are you sure you want to Install this repository?</string>
<string id="30101">This will overwrite any repository with the same name</string>
<string id="30110">This repository is already installed</string>
<string id="30111">Do you want to continue and overwrite the existing repository?</string>
<string id="30200">Error!</string>
<string id="30201">Error during %s repository install</string>
<string id="30202">Please check the logs</string>
<!--SETTINGS STRINGS -->
<string id="30500">Appearance</string>
<string id="30501">Text color of description:</string>
<string id="30520">Red</string>
<string id="30521">Green</string>
<string id="30522">Yellow</string>
<string id="30523">Light Blue</string>
<string id="30524">None</string>
<string id="30530">Display description with title</string>
</strings>

View File

@ -1,37 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<strings>
<!-- Les strings de 30000 à 30999 sont réservées aux paramètres plug-in -->
<!--GENERAL STRINGS -->
<string id="30000">Repositories Installer</string>
<string id="30001">Repositories d'Add-ons </string>
<string id="30005">Téléchargement: %s </string>
<string id="30006">vers: %s</string>
<string id="30007">Repository Installé</string>
<string id="30010">XBMC doit redémarrer!</string>
<string id="30011">Repository</string>
<string id="30012">Infos Repository</string>
<!--CONTEXT MENU STRINGS -->
<!--DIALOG STRINGS -->
<string id="30100">Etes vous sure de vouloir installer ce repository?</string>
<string id="30101">Cela écrasera tout repository du meme nom</string>
<string id="30110">CE repository est déja installé</string>
<string id="30111">Voulez-vous continuer et écraser le repository existant?</string>
<string id="30200">Erreur!</string>
<string id="30201">Erreur durant l'installation du repository %s</string>
<string id="30202">Veuillez vérifier les logs</string>
<!--SETTINGS STRINGS -->
<string id="30500">Apparence</string>
<string id="30501">Couleur du texte de description:</string>
<string id="30520">Rouge</string>
<string id="30521">Vert</string>
<string id="30522">Jaune</string>
<string id="30523">Bleu Ciel</string>
<string id="30524">Aucune</string>
<string id="30530">Afficher la description avec le titre</string>
</strings>

View File

@ -1,121 +0,0 @@
import os
from traceback import print_exc
import xbmc
import xbmcgui
from xbmcaddon import Addon
############################################################################
#get actioncodes from keymap.xml
############################################################################
#ACTION_MOVE_LEFT = 1
#ACTION_MOVE_RIGHT = 2
#ACTION_MOVE_UP = 3
#ACTION_MOVE_DOWN = 4
#ACTION_PAGE_UP = 5
#ACTION_PAGE_DOWN = 6
#ACTION_SELECT_ITEM = 7
#ACTION_HIGHLIGHT_ITEM = 8
ACTION_PARENT_DIR = 9
ACTION_PREVIOUS_MENU = 10
#ACTION_SHOW_INFO = 11
#ACTION_PAUSE = 12
#ACTION_STOP = 13
#ACTION_NEXT_ITEM = 14
#ACTION_PREV_ITEM = 15
#ACTION_MUSIC_PLAY = 79
#ACTION_MOUSE_CLICK = 100
ACTION_CONTEXT_MENU = 117
#__settings__ = Addon( "repository.xbmc.builds" )
#__addonDir__ = __settings__.getAddonInfo( "path" )
#PROFILE_PATH = xbmc.translatePath( __settings__.getAddonInfo( "profile" ) )
#DL_INFO_PATH = os.path.join( PROFILE_PATH, "iddl_data" )
class DialogRepoInfo( xbmcgui.WindowXMLDialog ):
Addon = Addon( id=os.path.basename( os.getcwd() ) )
ACTION_CLOSE_DIALOG_LIST = [ ACTION_PARENT_DIR, ACTION_PREVIOUS_MENU, ACTION_CONTEXT_MENU ]
def __init__( self, *args, **kwargs ):
print "Creating DialogRepoInfo"
xbmcgui.WindowXMLDialog.__init__( self, *args, **kwargs )
# Get information about the repository
self._get_repo_info()
# show dialog
self.doModal()
def onInit( self ):
# Show repo info
self._show_repo_info()
def onFocus( self, controlID ):
pass
def onClick( self, controlID ):
try:
kill = None
if controlID == 199:
self._close_dialog()
# elif controlID == 99:
# pass
except:
print_exc()
def onAction( self, action ):
if action in self.ACTION_CLOSE_DIALOG_LIST:
self._close_dialog()
def _get_repo_info( self ):
# initialize our dictionary
print "_get_repo_info"
self.repo = {}
self.repo[ "Name" ] = unicode( xbmc.getInfoLabel( "ListItem.Property(Addon.Name)" ), "utf-8" )
self.repo[ "Description" ] = unicode( xbmc.getInfoLabel( "ListItem.Property(Addon.Description)" ), "utf-8" )
self.repo[ "Icon" ] = xbmc.getInfoLabel( "ListItem.Property(Addon.Icon)" )
self.repo[ "Type" ] = unicode( xbmc.getInfoLabel( "ListItem.Property(Addon.Type)" ), "utf-8" )
self.repo[ "Creator" ] = unicode( xbmc.getInfoLabel( "ListItem.Property(Addon.Creator)" ), "utf-8" )
#self.repo[ "Version" ] = unicode( xbmc.getInfoLabel( "ListItem.Property(Addon.Version)" ), "utf-8" )
self.repo[ "Version" ] = None
print self.repo[ "Name" ]
print self.repo
def _show_repo_info( self ):
# set initial apple trailer info
self._set_repo_info( name=self.repo[ "Name" ],
description=self.repo[ "Description" ],
creator=self.repo[ "Creator" ],
type=self.repo[ "Type" ],
version=self.repo[ "Version" ],
icon=self.repo[ "Icon" ],
)
def _set_repo_info( self, name="", description="", creator="", type="", version="", icon="" ):
# grab the window
wId = xbmcgui.Window( xbmcgui.getCurrentWindowDialogId() )
# set our info
wId.setProperty( "Name", name )
wId.setProperty( "Description", description )
wId.setProperty( "Creator", creator )
wId.setProperty( "Type", type )
if version:
wId.setProperty( "Version", version )
wId.setProperty( "Icon", icon )
def _close_dialog( self ):
self.close()
if ( __name__ == "__main__" ):
s = DialogRepoInfo( "DialogRepoInfo.xml", os.path.dirname( os.path.dirname( os.getcwd() ) ), "Default", "720p")
del s
#if ( __name__ == "__main__" ):
# DialogDownloadProgress( "DialogRepoInfo.xml", __addonDir__ )

View File

@ -1 +0,0 @@
# Dummy file to make this directory a package.

View File

@ -1,242 +0,0 @@
"""
extractor for zip and rar file and a future support file 7-zip.
frost
"""
# Modules general
import os
import sys
from tarfile import is_tarfile
from zipfile import is_zipfile
from traceback import print_exc
# Modules XBMC
from xbmcgui import DialogProgress
from xbmc import executebuiltin, sleep
# Modules Custom
import shutil2
DIALOG_PROGRESS = DialogProgress()
try:
#FONCTION POUR RECUPERER LES LABELS DE LA LANGUE.
_ = sys.modules[ "__main__" ].__language__
except:
lang = { 110: "Please wait...", 187: "UnRar: %i of %i items", 188: "UnZip: %i of %i items" }
def _( id ): return lang[ id ]
def is_rarfile( filename ):
RAR_ID = "Rar!\x1a\x07\x00"
buf = open( filename, "rb" ).read( len( RAR_ID ) )
return buf == RAR_ID
def get_time_sleep( filename ):
# faut vraiment laisser xbmc le temps d'extraire l'archive environ 1 seconde pour 1 mo
# plus l'archive est grosse plus cela va etre long
try:
slp = int( os.path.getsize( filename ) / 1000 )
except:
print_exc()
slp = 0
if slp < 1000: slp = 1000
return slp
def unrar( filename, destination=None, report=False ):
from rarfile import RarFile
base_dir = ""
if destination is None:
destination = os.path.dirname( filename )
try:
rar = RarFile( filename, "r" )
namelist = rar.namelist()
total_items = len( namelist ) or 1
diff = 100.0 / total_items
percent = 0
# nom du dossier racine
root_dir = namelist[ -1 ]
is_root_dir = True
# si root_dir n'est pas un dossier ou n'est pas la racine, on se base sur le nom de l'archive
#print root_dir
if not rar.getinfo( root_dir ).isdir():
is_root_dir = False
else:
for i in namelist:
#print root_dir in i, i
if not root_dir in i:
is_root_dir = False
break
if not is_root_dir:#rar.getinfo( root_dir ).isdir():
root_dir = os.path.basename( os.path.splitext( filename )[ 0 ] )
base_dir = os.path.join( destination, root_dir )
if os.path.isdir( base_dir ):
shutil2.rmtree( base_dir )
os.makedirs( base_dir )
time_sleep = get_time_sleep( filename )
# avec cette methode on extract dans le dossier ou est l'archive
ok = executebuiltin( 'XBMC.Extract(%s)' % ( filename, ) )
#sleep une seconde ou plus selon la drosseur du fichier le temps que le builtin est fini car l'action suivante
# "os.listdir" est excecuter avant la fin du builtin
sleep( time_sleep )
# si le dossier base_dir est vide on move les items de namelist dedans
if not os.listdir( base_dir ):
for item in namelist:
src = os.path.normpath( os.path.join( os.path.dirname( filename ), item ) )
dst = os.path.normpath( os.path.join( base_dir, item ) )
if not rar.getinfo( item ).isdir():
if not os.path.isdir( os.path.dirname( dst ) ):
os.makedirs( os.path.dirname( dst ) )
shutil2.move( src, dst, overwrite=True )
elif os.path.exists( src ) and not os.listdir( src ):
shutil2.rmtree( src )
#maintenant on verifier l'extraction d'xbmc avec la liste de la lib rarfile
if os.path.isdir( base_dir ):
size = 0
list_size = 0
if not root_dir in namelist:
list_size -= 1
namelist = [ os.path.split( item )[ 1 ] for item in namelist ]
for root, dirs, files in os.walk( base_dir, topdown=False ):
percent += diff
list_size += 1
for file in files:
percent += diff
list_size += 1
if report:
if DIALOG_PROGRESS.iscanceled():
break
DIALOG_PROGRESS.update( int( percent ), _( 187 ) % ( list_size, total_items ), file, _( 110 ) )
#print round( percent, 2 ), file
if file in namelist:
size += os.path.getsize( os.path.join( root, file ) )
else:
print "Error %s est dans la liste de depart!" % file
#print size
if not size:
print "Error for extracting rar: %s" % filename
rar.close()
del rar
# si list_size est pas declarer une erreur automatique est creer ;)
return base_dir, list_size == total_items
except:
print_exc()
return "", False
def unzip( filename, destination=None, report=False ):
from zipfile import ZipFile
base_dir = ""
if destination is None:
destination = os.path.dirname( filename ) #=> extraction in current directory
try:
zip = ZipFile( filename, "r" )
namelist = zip.namelist()
total_items = len( namelist ) or 1
diff = 100.0 / total_items
percent = 0
# nom du dossier racine
root_dir = namelist[ 0 ]
is_root_dir = True
# si root_dir n'est pas un dossier ou n'est pas la racine, on se base sur le nom de l'archive
#print root_dir
if not root_dir.endswith( "/" ) and ( zip.getinfo( root_dir ).file_size > 0 ):
is_root_dir = False
else:
for i in namelist:
#print root_dir in i, i
if not root_dir in i:
is_root_dir = False
break
base_dir = os.path.join( destination, root_dir.rstrip( "/" ) )
if not is_root_dir:#root_dir.endswith( "/" ) and ( zip.getinfo( root_dir ).file_size > 0 ):
root_dir = os.path.basename( os.path.splitext( filename )[ 0 ] )
destination = os.path.join( destination, root_dir )
base_dir = destination
if os.path.isdir( base_dir ):
shutil2.rmtree( base_dir )
os.makedirs( base_dir )
for count, item in enumerate( namelist ):
percent += diff
if report:
if DIALOG_PROGRESS.iscanceled():
break
DIALOG_PROGRESS.update( int( percent ), _( 188 ) % ( count + 1, total_items ), item, _( 110 ) )
#print round( percent, 2 ), item
if not item.endswith( "/" ):
root, name = os.path.split( item )
directory = os.path.normpath( os.path.join( destination, root ) )
if not os.path.isdir( directory ): os.makedirs( directory )
file( os.path.join( directory, name ), "wb" ).write( zip.read( item ) )
zip.close()
del zip
return base_dir, True
except:
print_exc()
return "", False
def extract_tarfile( filename, destination=None ):
import tarfile
base_dir = ""
try:
# is_tarfile, Return True if name is a tar archive file, that the tarfile module can read.
if tarfile.is_tarfile( filename ):
# if not destination, set destination to current filename
if destination is None:
destination = os.path.dirname( filename )
# open tarfile
tar = tarfile.open( filename )#, 'r:gz' )
# extractall, New in version 2.5 or greater
if hasattr( tar, 'extractall' ):
tar.extractall( destination )
else:
# if not extractall use standard extract
[ tar.extract( tarinfo , destination ) for tarinfo in tar ]
root_dir = tar.getnames()[ 0 ].strip( "/" )
base_dir = os.path.join( destination, root_dir )
# close tarfile
tar.close()
return base_dir, True
except:
print_exc()
return "", False
def filetype( filename ):
try:
#Check quickly whether file is rar archive.
if is_rarfile( filename ): return "is_rar"
#Quickly see if file is a ZIP file by checking the magic number.
if is_zipfile( filename ): return "is_zip"
#Return True if name points to a tar archive that we are able to handle, else return False.
if is_tarfile( filename ): return "is_tar"
except:
print_exc()
return "Inconnue"
def extract( filename, destination=None, report=False ):
type = filetype( filename )
if type == "is_zip":
return unzip( filename, destination, report )
elif type == "is_rar":
return unrar( filename, destination, report )
elif type == "is_tar":
return extract_tarfile( filename, destination )
#elif type == "is_7z":
# # test for future support 7-zip archive, not supported for a moment
# # mais il semblerais que le librairie "pylzma" marche bien, http://www.joachim-bauch.de/projects/python/pylzma/
# # reste a compiler cette lib pour xbmc linux, win32/xbox et osx semble pas etre supporter
# # Note faut compiler cette lib avec python 2.4, sinon elle sera pas compatible avec xbmc, pas certain a 100 pour 100.
# #ok = executebuiltin( 'XBMC.Extract(%s)' % ( filename, ) )
# print "L'archive '%s' n'est pas pris en charge..." % os.path.basename( filename )
else:
print "L'archive '%s' n'est pas pris en charge..." % os.path.basename( filename )
return "", False

View File

@ -1,488 +0,0 @@
# rarfile.py, http://grue.l-t.ee/~marko/src/rarfile/
#
# Copyright (c) 2005 Marko Kreen <marko@l-t.ee>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
import os, re
from struct import pack, unpack
from binascii import crc32
from cStringIO import StringIO
# whether to speed up decompression by using tmp archive
_use_extract_hack = 1
# command line to use for extracting
_extract_cmd = 'unrar p -inul "%s" "%s"'
#
# rar constants
#
RAR_ID = "Rar!\x1a\x07\x00"
# block types
RAR_BLOCK_MARK = 0x72 # r
RAR_BLOCK_MAIN = 0x73 # s
RAR_BLOCK_FILE = 0x74 # t
RAR_BLOCK_OLD_COMMENT = 0x75 # u
RAR_BLOCK_OLD_EXTRA = 0x76 # v
RAR_BLOCK_OLD_SUB = 0x77 # w
RAR_BLOCK_OLD_RECOVERY = 0x78 # x
RAR_BLOCK_OLD_AUTH = 0x79 # y
RAR_BLOCK_SUB = 0x7a # z
RAR_BLOCK_ENDARC = 0x7b # {
# main header flags
RAR_MAIN_VOLUME = 0x0001
RAR_MAIN_COMMENT = 0x0002
RAR_MAIN_LOCK = 0x0004
RAR_MAIN_SOLID = 0x0008
RAR_MAIN_NEWNUMBERING = 0x0010
RAR_MAIN_AUTH = 0x0020
RAR_MAIN_RECOVERY = 0x0040
RAR_MAIN_PASSWORD = 0x0080
RAR_MAIN_FIRSTVOLUME = 0x0100
# file header flags
RAR_FILE_SPLIT_BEFORE = 0x0001
RAR_FILE_SPLIT_AFTER = 0x0002
RAR_FILE_PASSWORD = 0x0004
RAR_FILE_COMMENT = 0x0008
RAR_FILE_SOLID = 0x0010
RAR_FILE_DICTMASK = 0x00e0
RAR_FILE_DICT64 = 0x0000
RAR_FILE_DICT128 = 0x0020
RAR_FILE_DICT256 = 0x0040
RAR_FILE_DICT512 = 0x0060
RAR_FILE_DICT1024 = 0x0080
RAR_FILE_DICT2048 = 0x00a0
RAR_FILE_DICT4096 = 0x00c0
RAR_FILE_DIRECTORY = 0x00e0
RAR_FILE_LARGE = 0x0100
RAR_FILE_UNICODE = 0x0200
RAR_FILE_SALT = 0x0400
RAR_FILE_VERSION = 0x0800
RAR_FILE_EXTTIME = 0x1000
RAR_FILE_EXTFLAGS = 0x2000
RAR_ENDARC_NEXT_VOLUME = 0x0001
RAR_ENDARC_DATACRC = 0x0002
RAR_ENDARC_REVSPACE = 0x0004
# flags common to all blocks
RAR_SKIP_IF_UNKNOWN = 0x4000
RAR_LONG_BLOCK = 0x8000
# Host OS types
RAR_OS_MSDOS = 0
RAR_OS_OS2 = 1
RAR_OS_WIN32 = 2
RAR_OS_UNIX = 3
#
# Public interface
#
def is_rarfile(fn):
'''Check quickly whether file is rar archive.'''
buf = open(fn, "rb").read(len(RAR_ID))
return buf == RAR_ID
class RarInfo:
'''An entry in rar archive.'''
def isdir(self):
'''Returns True if the entry is a directory.'''
if self.type == RAR_BLOCK_FILE:
return (self.flags & RAR_FILE_DIRECTORY) == RAR_FILE_DIRECTORY
return False
class RarFile:
'''Rar archive handling.'''
def __init__(self, rarfile, mode="r", charset=None, info_callback=None):
self.rarfile = rarfile
self.charset = charset
self.info_list = []
self.is_solid = 0
self.uses_newnumbering = 0
self.uses_volumes = 0
self.info_callback = info_callback
self.got_mainhdr = 0
self._gen_volname = self._gen_oldvol
if mode != "r":
raise Exception("Only mode=r supported")
self._parse()
def namelist(self):
'''Return list of filenames in rar'''
res = []
for f in self.info_list:
res.append(f.filename)
return res
def infolist(self):
'''Return rar entries.'''
return self.info_list
def getinfo(self, fname):
'''Return RarInfo for fname.'''
fx = fname.replace("/", "\\")
for f in self.info_list:
if fname == f.filename or fx == f.filename:
return f
def read(self, fname):
'''Return decompressed data.'''
inf = self.getinfo(fname)
if not inf:
raise Exception("No such file")
if inf.isdir():
raise Exception("No data in directory")
if inf.compress_type == 0x30:
res = self._extract_clear(inf)
elif _use_extract_hack and not self.is_solid and not self.uses_volumes:
res = self._extract_hack(inf)
else:
res = self._extract_unrar(self.rarfile, inf)
return res
def close(self):
pass
def printdir(self):
for f in self.info_list:
print f.filename
# store entry
def _process_entry(self, item):
# RAR_BLOCK_NEWSUB has files too: CMT, RR
if item.type == RAR_BLOCK_FILE:
# use only first part
if (item.flags & RAR_FILE_SPLIT_BEFORE) == 0:
self.info_list.append(item)
if self.info_callback:
self.info_callback(item)
# read rar
def _parse(self):
fd = open(self.rarfile, "rb")
id = fd.read(len(RAR_ID))
if id != RAR_ID:
raise Exception("Not a Rar")
volume = 0 # first vol (.rar) is 0
more_vols = 0
while 1:
h = self._parse_header(fd)
if not h:
if more_vols:
volume += 1
fd = open(self._gen_volname(volume), "rb")
more_vols = 0
if fd:
continue
break
h.volume = volume
if h.type == RAR_BLOCK_MAIN and not self.got_mainhdr:
if h.flags & RAR_MAIN_NEWNUMBERING:
self.uses_newnumbering = 1
self._gen_volname = self._gen_newvol
self.uses_volumes = h.flags & RAR_MAIN_VOLUME
self.is_solid = h.flags & RAR_MAIN_SOLID
self.got_mainhdr = 1
elif h.type == RAR_BLOCK_ENDARC:
more_vols = h.flags & RAR_ENDARC_NEXT_VOLUME
# store it
self._process_entry(h)
# skip data
if h.add_size > 0:
fd.seek(h.add_size, 1)
def _parse_header(self, fd):
h = self._parse_block_header(fd)
if h and (h.type == RAR_BLOCK_FILE or h.type == RAR_BLOCK_SUB):
self._parse_file_header(h)
return h
# common header
def _parse_block_header(self, fd):
HDRLEN = 7
h = RarInfo()
h.header_offset = fd.tell()
buf = fd.read(HDRLEN)
if not buf:
return None
t = unpack("<HBHH", buf)
h.header_crc, h.type, h.flags, h.header_size = t
h.header_unknown = h.header_size - HDRLEN
if h.header_size > HDRLEN:
h.data = fd.read(h.header_size - HDRLEN)
else:
h.data = ""
h.file_offset = fd.tell()
if h.flags & RAR_LONG_BLOCK:
h.add_size = unpack("<L", h.data[:4])[0]
else:
h.add_size = 0
# no crc check on that
if h.type == RAR_BLOCK_MARK:
return h
# check crc
if h.type == RAR_BLOCK_MAIN:
crcdat = buf[2:] + h.data[:6]
elif h.type == RAR_BLOCK_OLD_AUTH:
crcdat = buf[2:] + h.data[:8]
else:
crcdat = buf[2:] + h.data
calc_crc = crc32(crcdat) & 0xFFFF
# return good header
if h.header_crc == calc_crc:
return h
# crc failed
print "CRC mismatch! ofs =", h.header_offset
# instead panicing, send eof
return None
# read file-specific header
def _parse_file_header(self, h):
HDRLEN = 4+4+1+4+4+1+1+2+4
fld = unpack("<LLBLLBBHL", h.data[ : HDRLEN])
h.compress_size = long(fld[0]) & 0xFFFFFFFFL
h.file_size = long(fld[1]) & 0xFFFFFFFFL
h.host_os = fld[2]
h.CRC = fld[3]
h.date_time = self._parse_dos_time(fld[4])
h.extract_version = fld[5]
h.compress_type = fld[6]
h.name_size = fld[7]
h.mode = fld[8]
pos = HDRLEN
if h.flags & RAR_FILE_LARGE:
h1, h2 = unpack("<LL", h.data[pos:pos+8])
h.compress_size |= long(h1) << 32
h.file_size |= long(h2) << 32
pos += 8
name = h.data[pos : pos + h.name_size ]
pos += h.name_size
if h.flags & RAR_FILE_UNICODE:
nul = name.find("\0")
h.filename = name[:nul]
u = _UnicodeFilename(h.filename, name[nul + 1 : ])
h.unicode_filename = u.decode()
else:
h.filename = name
h.unicode_filename = None
if self.charset:
h.unicode_filename = name.decode(self.charset)
else:
# just guessing...
h.unicode_filename = name.decode("iso-8859-1", "replace")
if h.flags & RAR_FILE_SALT:
h.salt = h.data[pos : pos + 8]
pos += 8
else:
h.salt = None
# unknown contents
if h.flags & RAR_FILE_EXTTIME:
h.ext_time = h.data[pos : ]
else:
h.ext_time = None
h.header_unknown -= pos
return h
def _parse_dos_time(self, stamp):
sec = stamp & 0x1F; stamp = stamp >> 5
min = stamp & 0x3F; stamp = stamp >> 6
hr = stamp & 0x1F; stamp = stamp >> 5
day = stamp & 0x1F; stamp = stamp >> 5
mon = stamp & 0x0F; stamp = stamp >> 4
yr = (stamp & 0x7F) + 1980
return (yr, mon, day, hr, min, sec)
# new-style volume name
def _gen_newvol(self, volume):
# allow % in filenames
fn = self.rarfile.replace("%", "%%")
m = re.search(r"([0-9][0-9]*)[^0-9]*$", fn)
if not m:
raise Exception("Cannot construct volume name")
n1 = m.start(1)
n2 = m.end(1)
fmt = "%%0%dd" % (n2 - n1)
volfmt = fn[:n1] + fmt + fn[n2:]
return volfmt % (volume + 1)
# old-style volume naming
def _gen_oldvol(self, volume):
if volume == 0: return self.rarfile
i = self.rarfile.rfind(".")
base = self.rarfile[:i]
if volume <= 100:
ext = ".r%02d" % (volume - 1)
else:
ext = ".s%02d" % (volume - 101)
return base + ext
# read uncompressed file
def _extract_clear(self, inf):
volume = inf.volume
buf = ""
cur = None
while 1:
f = open(self._gen_volname(volume), "rb")
if not cur:
f.seek(inf.header_offset)
while 1:
cur = self._parse_header(f)
if cur.type in (RAR_BLOCK_MARK, RAR_BLOCK_MAIN):
if cur.add_size:
f.seek(cur.add_size, 1)
continue
if cur.filename == inf.filename:
buf += f.read(cur.add_size)
break
raise RuntimeException("file not found?")
# no more parts?
if (cur.flags & RAR_FILE_SPLIT_AFTER) == 0:
break
volume += 1
return buf
# put file compressed data into temporary .rar archive, and run
# unrar on that, thus avoiding unrar going over whole archive
def _extract_hack(self, inf):
BSIZE = 32*1024
size = inf.compress_size + inf.header_size
rf = open(self.rarfile, "rb")
rf.seek(inf.header_offset)
tmpname = os.tempnam() + ".rar"
tmpf = open(tmpname, "wb")
# create main header: crc, type, flags, size, res1, res2
mh = pack("<HBHHHL", 0x90CF, 0x73, 0, 13, 0, 0)
tmpf.write(RAR_ID + mh)
while size > 0:
if size > BSIZE:
buf = rf.read(BSIZE)
else:
buf = rf.read(size)
tmpf.write(buf)
size -= len(buf)
tmpf.close()
buf = self._extract_unrar(tmpname, inf)
os.unlink(tmpname)
return buf
# extract using unrar
def _extract_unrar(self, rarfile, inf):
fn = inf.filename
# linux unrar wants '/', not '\'
fn = fn.replace("\\", "/")
# shell escapes
fn = fn.replace("`", "\\`")
fn = fn.replace('"', '\\"')
fn = fn.replace("$", "\\$")
cmd = _extract_cmd % (rarfile, fn)
fd = os.popen(cmd, "r")
buf = fd.read()
err = fd.close()
if err > 0:
raise Exception("Error reading file")
return buf
class _UnicodeFilename:
def __init__(self, name, encdata):
self.std_name = name
self.encdata = encdata
self.pos = self.encpos = 0
self.buf = StringIO()
def enc_byte(self):
c = self.encdata[self.encpos]
self.encpos += 1
return ord(c)
def std_byte(self):
return ord(self.std_name[self.pos])
def put(self, lo, hi):
self.buf.write(chr(lo) + chr(hi))
self.pos += 1
def decode(self):
hi = self.enc_byte()
flagbits = 0
while self.encpos < len(self.encdata):
if flagbits == 0:
flags = self.enc_byte()
flagbits = 8
flagbits -= 2
t = (flags >> flagbits) & 3
if t == 0:
self.put(self.enc_byte(), 0)
elif t == 1:
self.put(self.enc_byte(), hi)
elif t == 2:
self.put(self.enc_byte(), self.enc_byte())
else:
n = self.enc_byte()
if n & 0x80:
c = self.enc_byte()
for i in range((n & 0x7f) + 2):
lo = (self.std_byte() + c) & 0xFF
self.put(lo, hi)
else:
for i in range(n + 2):
self.put(self.std_byte(), 0)
return self.buf.getvalue().decode("utf-16le", "replace")
# ignore os.tempnam() warning
try:
import warnings
warnings.filterwarnings(action = 'ignore', category = RuntimeWarning,
module = 'rarfile')
except Exception, det:
pass

View File

@ -1,305 +0,0 @@
"""Utility functions for copying files and directory trees.
XXX The functions here don't copy the resource fork or other metadata on Mac.
shutil2 (22/12/08)
by Frost and Temhil
Version unofficial of shutil, shutil2 is based on current SVN revision 65644.
This version includes 'overwrite' file and 'reportcopy' during process
"""
import os
import sys
import stat
from os.path import abspath
import fnmatch
__all__ = ["copyfileobj","copyfile","copymode","copystat","copy","copy2",
"copytree","move","rmtree","Error"]
class Error(EnvironmentError):
pass
try:
WindowsError
except NameError:
WindowsError = None
# exception raised when copied size does not match content-length
class ContentTooShortError(IOError):
def __init__(self, message, content):
IOError.__init__(self, message)
self.content = content
def copyfileobj(fsrc, fdst, reportcopy=None, size=1, length=16*1024):
"""copy data from file-like object fsrc to file-like object fdst"""
result = "", str(size)
read = 0
blocknum = 0
if reportcopy:
reportcopy(blocknum, length, size)
while 1:
buf = fsrc.read(length)
if not buf:
break
read += len(buf)
fdst.write(buf)
blocknum += 1
if reportcopy:
reportcopy(blocknum, length, size)
# raise exception if actual size does not match
if size >= 0 and read < size:
raise ContentTooShortError("copying incomplete: got only %i out "
"of %i bytes" % (read, size), result)
def _samefile(src, dst):
# Macintosh, Unix.
if hasattr(os.path,'samefile'):
try:
return os.path.samefile(src, dst)
except OSError:
return False
# All other platforms: check for same pathname.
return (os.path.normcase(os.path.abspath(src)) ==
os.path.normcase(os.path.abspath(dst)))
def copyfile(src, dst, reportcopy=None, overwrite=False):
"""Copy data from src to dst"""
if _samefile(src, dst):
raise Error, "`%s` and `%s` are the same file" % (src, dst)
fsrc = None
fdst = None
try:
fsrc = open(src, 'rb')
if os.path.exists(dst) and overwrite:
os.remove(dst)
fdst = open(dst, 'wb')
try: size = os.stat(src)[6]/1024.0
except: size = 1
copyfileobj(fsrc, fdst, reportcopy, size)
finally:
if fdst:
fdst.close()
if fsrc:
fsrc.close()
def copymode(src, dst):
"""Copy mode bits from src to dst"""
if hasattr(os, 'chmod'):
st = os.stat(src)
mode = stat.S_IMODE(st.st_mode)
os.chmod(dst, mode)
def copystat(src, dst):
"""Copy all stat info (mode bits, atime, mtime, flags) from src to dst"""
st = os.stat(src)
mode = stat.S_IMODE(st.st_mode)
if hasattr(os, 'utime'):
os.utime(dst, (st.st_atime, st.st_mtime))
if hasattr(os, 'chmod'):
os.chmod(dst, mode)
if hasattr(os, 'chflags') and hasattr(st, 'st_flags'):
os.chflags(dst, st.st_flags)
def copy(src, dst, reportcopy=None, overwrite=False):
"""Copy data and mode bits ("cp src dst").
The destination may be a directory.
"""
if os.path.isdir(dst):
dst = os.path.join(dst, os.path.basename(src))
copyfile(src, dst, reportcopy, overwrite)
copymode(src, dst)
def copy2(src, dst, reportcopy=None, overwrite=False):
"""Copy data and all stat info ("cp -p src dst").
The destination may be a directory.
"""
if os.path.isdir(dst):
dst = os.path.join(dst, os.path.basename(src))
copyfile(src, dst, reportcopy, overwrite)
copystat(src, dst)
def ignore_patterns(*patterns):
"""Function that can be used as copytree() ignore parameter.
Patterns is a sequence of glob-style patterns
that are used to exclude files"""
def _ignore_patterns(path, names):
ignored_names = []
for pattern in patterns:
ignored_names.extend(fnmatch.filter(names, pattern))
return set(ignored_names)
return _ignore_patterns
def copytree(src, dst, symlinks=False, ignore=None, reportcopy=None, overwrite=False):
"""Recursively copy a directory tree using copy2().
The destination directory must not already exist.
If exception(s) occur, an Error is raised with a list of reasons.
If the optional symlinks flag is true, symbolic links in the
source tree result in symbolic links in the destination tree; if
it is false, the contents of the files pointed to by symbolic
links are copied.
The optional ignore argument is a callable. If given, it
is called with the `src` parameter, which is the directory
being visited by copytree(), and `names` which is the list of
`src` contents, as returned by os.listdir():
callable(src, names) -> ignored_names
Since copytree() is called recursively, the callable will be
called once for each directory that is copied. It returns a
list of names relative to the `src` directory that should
not be copied.
XXX Consider this example code rather than the ultimate tool.
"""
names = os.listdir(src)
if ignore is not None:
ignored_names = ignore(src, names)
else:
ignored_names = set()
if not os.path.exists(dst) or not overwrite:
os.makedirs(dst)
errors = []
for name in names:
if name in ignored_names:
continue
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
if symlinks and os.path.islink(srcname):
linkto = os.readlink(srcname)
os.symlink(linkto, dstname)
elif os.path.isdir(srcname):
copytree(srcname, dstname, symlinks, ignore, reportcopy, overwrite)
else:
copy2(srcname, dstname, reportcopy, overwrite)
# XXX What about devices, sockets etc.?
except (IOError, os.error), why:
errors.append((srcname, dstname, str(why)))
# catch the Error from the recursive copytree so that we can
# continue with other files
except Error, err:
errors.extend(err.args[0])
try:
copystat(src, dst)
except OSError, why:
if WindowsError is not None and isinstance(why, WindowsError):
# Copying file access times may fail on Windows
pass
elif overwrite:
pass
else:
errors.extend((src, dst, str(why)))
if errors:
raise Error, errors
def rmtree(path, ignore_errors=False, onerror=None):
"""Recursively delete a directory tree.
If ignore_errors is set, errors are ignored; otherwise, if onerror
is set, it is called to handle the error with arguments (func,
path, exc_info) where func is os.listdir, os.remove, or os.rmdir;
path is the argument to that function that caused it to fail; and
exc_info is a tuple returned by sys.exc_info(). If ignore_errors
is false and onerror is None, an exception is raised.
"""
if ignore_errors:
def onerror(*args):
pass
elif onerror is None:
def onerror(*args):
raise
try:
if os.path.islink(path):
# symlinks to directories are forbidden, see bug #1669
raise OSError("Cannot call rmtree on a symbolic link")
except OSError:
onerror(os.path.islink, path, sys.exc_info())
# can't continue even if onerror hook returns
return
names = []
try:
names = os.listdir(path)
except os.error, err:
onerror(os.listdir, path, sys.exc_info())
for name in names:
fullname = os.path.join(path, name)
try:
mode = os.lstat(fullname).st_mode
except os.error:
mode = 0
if stat.S_ISDIR(mode):
rmtree(fullname, ignore_errors, onerror)
else:
try:
os.remove(fullname)
except os.error, err:
onerror(os.remove, fullname, sys.exc_info())
try:
os.rmdir(path)
except os.error:
onerror(os.rmdir, path, sys.exc_info())
def _basename(path):
# A basename() variant which first strips the trailing slash, if present.
# Thus we always get the last component of the path, even for directories.
return os.path.basename(path.rstrip(os.path.sep))
def move(src, dst, reportcopy=None, overwrite=False):
"""Recursively move a file or directory to another location. This is
similar to the Unix "mv" command.
If the destination is a directory or a symlink to a directory, the source
is moved inside the directory. The destination path must not already
exist.
If the destination already exists but is not a directory, it may be
overwritten depending on os.rename() semantics.
If the destination is on our current filesystem, then rename() is used.
Otherwise, src is copied to the destination and then removed.
A lot more could be done here... A look at a mv.c shows a lot of
the issues this implementation glosses over.
"""
real_dst = dst
if os.path.isdir(dst):
real_dst = os.path.join(dst, _basename(src))
if os.path.exists(real_dst):
raise Error, "Destination path '%s' already exists" % real_dst
try:
os.rename(src, real_dst)
except OSError:
if os.path.isdir(src):
if destinsrc(src, dst):
raise Error, "Cannot move a directory '%s' into itself '%s'." % (src, dst)
#copytree(src, dst, symlinks=True)
copytree(src, dst, True, reportcopy, overwrite)
rmtree(src)
else:
copy2(src, real_dst, reportcopy, overwrite)
os.unlink(src)
def reportcopy(blocknum, blocksize, totalsize):
# Report during remote transfers
print "Block number: %d, Block size: %d, Total size: %d" % (
blocknum, blocksize, totalsize)
def destinsrc(src, dst):
return abspath(dst).startswith(abspath(src))

View File

@ -1,71 +0,0 @@
"""
Module retrieving repositories info from XBMC Wiki
by Temhil
"""
from BeautifulSoup import SoupStrainer
from BeautifulSoup import BeautifulSoup
from traceback import print_exc
import re
import urllib
#
# Constants
#
#__settings__ = sys.modules[ "__main__" ].__settings__
#__language__ = sys.modules[ "__main__" ].__language__
def getRepoList(pageUrl, destination=None, addItemFunc=None, progressBar=None, msgFunc=None ):
"""
Retrieve Blogs list passing each item to the cb addItemFunc
return Next page URL
"""
#print "getRepoList"
result = "OK"
# Get HTML page...
htmlSource = urllib.urlopen( pageUrl ).read()
#print htmlSource
# Parse response...
beautifulSoup = BeautifulSoup( htmlSource )
itemRepoList = beautifulSoup.findAll("tr")
print itemRepoList
for repo in itemRepoList:
try:
#print repo
#print "----"
repoInfo = {}
tdList = repo.findAll ("td")
if tdList:
repoInfo["name"] = tdList[0].a.string.strip()
repoInfo["description"] = tdList[1].string.strip()
repoInfo["owner"] = tdList[2].string.strip()
repoInfo["repoUrl"] = tdList[3].a["href"]
try:
repoInfo["ImageUrl"] = tdList[4].a["href"]
except:
repoInfo["ImageUrl"] = None
#print repoInfo
#if progressBar != None:
if addItemFunc != None:
if repoInfo["repoUrl"].endswith("zip"):
addItemFunc( repoInfo )
else:
print "Invalid URL for the repository %s - URL=%s"%(repoInfo["name"], repoInfo["repoUrl"])
except:
print "getRepoList - error parsing html - impossible to retrieve Blog info"
print_exc()
result = "ERROR"
return result
if ( __name__ == "__main__" ):
print "Wiki parser test"
repoListUrl = "http://wiki.xbmc.org/index.php?title=Unofficial_Add-on_Repositories"
print repoListUrl
getRepoList(repoListUrl)

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<settings>
<!-- GENERAL -->
<category label="$LOCALIZE[128]">
<setting label="30500" type="lsep" />
<setting label="30530" type="bool" id="desintitle" default="false" />
<setting label="30501" type="enum" id="descolor" enable="eq(-1,true)" lvalues="30520|30521|30522|30523|30524" default="4" />
</category>
</settings>

View File

@ -1,476 +0,0 @@
<window id="146">
<defaultcontrol always="true">9000</defaultcontrol>
<coordinates>
<system>1</system>
<posx>185</posx>
<posy>60</posy>
<origin x="185" y="10">!IsEmpty(ListItem.Property(Addon.broken))</origin>
</coordinates>
<include>dialogeffect</include>
<controls>
<control type="group">
<include>VisibleFadeEffect</include>
<visible>!Window.isVisible(AddonSettings) + !Window.IsActive(TextViewer)</visible>
<control type="image">
<description>background image</description>
<posx>0</posx>
<posy>0</posy>
<width>920</width>
<height>600</height>
<texture border="40">DialogBack.png</texture>
</control>
<control type="image">
<posx>260</posx>
<posy>10</posy>
<width>620</width>
<height>578</height>
<texture border="5">black-back2.png</texture>
</control>
<control type="image">
<posx>260</posx>
<posy>10</posy>
<width>610</width>
<height>100</height>
<aspectratio>stretch</aspectratio>
<texture>GlassTitleBar.png</texture>
</control>
<control type="button">
<description>Close Window button</description>
<posx>810</posx>
<posy>9</posy>
<width>64</width>
<height>32</height>
<label>-</label>
<font>-</font>
<onclick>PreviousMenu</onclick>
<texturefocus>DialogCloseButton-focus.png</texturefocus>
<texturenofocus>DialogCloseButton.png</texturenofocus>
<onleft>3</onleft>
<onright>3</onright>
<onup>3</onup>
<ondown>3</ondown>
<visible>system.getbool(input.enablemouse)</visible>
</control>
<control type="label">
<description>header label</description>
<posx>280</posx>
<posy>20</posy>
<width>580</width>
<height>30</height>
<font>font30_title</font>
<label>24003</label>
<align>left</align>
<aligny>center</aligny>
<textcolor>white</textcolor>
<shadowcolor>black</shadowcolor>
</control>
<control type="image">
<posx>35</posx>
<posy>40</posy>
<width>200</width>
<height>200</height>
<aspectratio>keep</aspectratio>
<!--texture>$INFO[ListItem.Icon]</texture-->
<texture>$INFO[Window.Property(Icon)]</texture>
</control>
<control type="label">
<description>Addon Title value</description>
<posx>280</posx>
<posy>80</posy>
<width>580</width>
<height>30</height>
<align>left</align>
<aligny>center</aligny>
<font>font13caps</font>
<!-- >label>[B]$INFO[ListItem.Property(Addon.Name)][/B]</label-->
<label>[B]$INFO[Window.Property(Name)][/B]</label>
<textcolor>white</textcolor>
<scroll>true</scroll>
</control>
<control type="group">
<posx>270</posx>
<posy>130</posy>
<control type="label">
<description>Type txt</description>
<posx>150</posx>
<posy>0</posy>
<width>140</width>
<height>25</height>
<label>$LOCALIZE[146]</label>
<align>right</align>
<aligny>center</aligny>
<font>font13_title</font>
<textcolor>blue</textcolor>
</control>
<control type="label">
<description>Type Value</description>
<posx>160</posx>
<posy>0</posy>
<width>440</width>
<height>25</height>
<label fallback="416">$INFO[Window.Property(Type)]</label>
<align>left</align>
<aligny>center</aligny>
<font>font13</font>
<scroll>true</scroll>
</control>
<control type="label">
<description>Author txt</description>
<posx>150</posx>
<posy>30</posy>
<width>140</width>
<height>25</height>
<label>$LOCALIZE[21863]:</label>
<align>right</align>
<aligny>center</aligny>
<font>font13_title</font>
<textcolor>blue</textcolor>
</control>
<control type="label">
<description>Author Value</description>
<posx>160</posx>
<posy>30</posy>
<width>440</width>
<height>25</height>
<label fallback="416">$INFO[Window.Property(Creator)]</label>
<align>left</align>
<aligny>center</aligny>
<font>font13</font>
<scroll>true</scroll>
</control>
<control type="label">
<description>Version txt</description>
<posx>150</posx>
<posy>60</posy>
<width>140</width>
<height>25</height>
<label>$LOCALIZE[24051]</label>
<align>right</align>
<aligny>center</aligny>
<font>font13_title</font>
<textcolor>blue</textcolor>
</control>
<control type="label">
<description>Version Value</description>
<posx>160</posx>
<posy>60</posy>
<width>440</width>
<height>25</height>
<label fallback="416">$INFO[Window.Property(Version)]</label>
<align>left</align>
<aligny>center</aligny>
<font>font13</font>
<scroll>true</scroll>
</control>
<!-- control type="label">
<description>Rating txt</description>
<posx>150</posx>
<posy>90</posy>
<width>140</width>
<height>25</height>
<label>$LOCALIZE[563]:</label>
<align>right</align>
<aligny>center</aligny>
<font>font13_title</font>
<textcolor>blue</textcolor>
</control>
<control type="image">
<description>Rating value</description>
<posx>160</posx>
<posy>90</posy>
<width>160</width>
<height>32</height>
<texture>LeftRating/$INFO[ListItem.Property(Addon.StarRating)]</texture>
</control -->
<!--control type="label">
<description>Summary txt</description>
<posx>150</posx>
<posy>90</posy>
<width>140</width>
<height>25</height>
<label>$LOCALIZE[20037]:</label>
<align>right</align>
<aligny>center</aligny>
<font>font13_title</font>
<textcolor>blue</textcolor>
</control>
<control type="fadelabel">
<description>Summary Value</description>
<posx>160</posx>
<posy>90</posy>
<width>440</width>
<height>25</height>
<label fallback="416">$INFO[ListItem.Property(Addon.Summary)]</label>
<align>left</align>
<aligny>center</aligny>
<font>font13</font>
<scrollout>false</scrollout>
<pauseatend>2000</pauseatend>
</control-->
<control type="image">
<posx>0</posx>
<posy>160</posy>
<width>600</width>
<height>4</height>
<texture>separator.png</texture>
</control>
<control type="label">
<description>Description txt</description>
<posx>0</posx>
<posy>170</posy>
<width>300</width>
<height>25</height>
<label>$LOCALIZE[21821]</label>
<align>left</align>
<aligny>center</aligny>
<font>font13</font>
<textcolor>blue</textcolor>
</control>
<control type="group">
<!--visible>!IsEmpty(ListItem.Property(Addon.Disclaimer))</visible-->
<control type="label">
<description>Description Page Count</description>
<posx>600</posx>
<posy>170</posy>
<width>300</width>
<height>25</height>
<label>$INFO[Container(400).CurrentPage, $LOCALIZE[31024] [COLOR=blue]([/COLOR]]$INFO[Container(400).NumPages,/,[COLOR=blue])[/COLOR]]</label>
<align>right</align>
<aligny>center</aligny>
<font>font12</font>
<textcolor>grey</textcolor>
</control>
<control type="textbox" id="400">
<description>Description</description>
<posx>10</posx>
<posy>195</posy>
<width>580</width>
<height>160</height>
<font>font12</font>
<align>-</align>
<textcolor>white</textcolor>
<!--label>$INFO[ListItem.Property(Addon.Description)]</label-->
<label>$INFO[Window.Property(Name)]</label>
<pagecontrol>60</pagecontrol>
</control>
<control type="scrollbar" id="60">
<posx>610</posx>
<posy>190</posy>
<width>25</width>
<height>175</height>
<texturesliderbackground border="0,14,0,14">ScrollBarV.png</texturesliderbackground>
<texturesliderbar border="0,14,0,14">ScrollBarV_bar.png</texturesliderbar>
<texturesliderbarfocus border="0,14,0,14">ScrollBarV_bar_focus.png</texturesliderbarfocus>
<textureslidernib>ScrollBarNib.png</textureslidernib>
<textureslidernibfocus>ScrollBarNib.png</textureslidernibfocus>
<onleft>9000</onleft>
<onright>61</onright>
<showonepage>false</showonepage>
<orientation>vertical</orientation>
</control>
<!--control type="label">
<description>Disclaimer txt</description>
<posx>0</posx>
<posy>370</posy>
<width>600</width>
<height>25</height>
<label>$LOCALIZE[24052]</label>
<align>left</align>
<aligny>center</aligny>
<font>font13</font>
<textcolor>orange</textcolor>
</control>
<control type="textbox">
<description>Disclaimer</description>
<posx>10</posx>
<posy>395</posy>
<width>580</width>
<height>40</height>
<font>font12</font>
<align>-</align>
<textcolor>white</textcolor>
<label>$INFO[ListItem.Property(Addon.Disclaimer)]</label>
<autoscroll time="2000" delay="3000" repeat="5000">true</autoscroll>
</control-->
</control>
<control type="group">
<!--visible>IsEmpty(ListItem.Property(Addon.Disclaimer))</visible-->
<control type="label">
<description>Description Page Count</description>
<posx>600</posx>
<posy>170</posy>
<width>300</width>
<height>25</height>
<label>$INFO[Container(401).CurrentPage, $LOCALIZE[31024] [COLOR=blue]([/COLOR]]$INFO[Container(401).NumPages,/,[COLOR=blue])[/COLOR]]</label>
<align>right</align>
<aligny>center</aligny>
<font>font12</font>
<textcolor>grey</textcolor>
</control>
<control type="textbox" id="401">
<description>Description</description>
<posx>10</posx>
<posy>195</posy>
<width>580</width>
<height>250</height>
<font>font12</font>
<align>-</align>
<textcolor>white</textcolor>
<label>$INFO[ListItem.Property(Addon.Description)]</label>
<pagecontrol>61</pagecontrol>
</control>
<control type="scrollbar" id="61">
<posx>610</posx>
<posy>190</posy>
<width>25</width>
<height>250</height>
<texturesliderbackground border="0,14,0,14">ScrollBarV.png</texturesliderbackground>
<texturesliderbar border="0,14,0,14">ScrollBarV_bar.png</texturesliderbar>
<texturesliderbarfocus border="0,14,0,14">ScrollBarV_bar_focus.png</texturesliderbarfocus>
<textureslidernib>ScrollBarNib.png</textureslidernib>
<textureslidernibfocus>ScrollBarNib.png</textureslidernibfocus>
<onleft>60</onleft>
<onright>9000</onright>
<showonepage>false</showonepage>
<orientation>vertical</orientation>
</control>
</control>
</control>
<control type="group" id="9000">
<posx>10</posx>
<posy>280</posy>
<!--control type="button" id ="6">
<description>Enable Addon button</description>
<posx>0</posx>
<posy>0</posy>
<width>255</width>
<height>51</height>
<textoffsetx>20</textoffsetx>
<label>24022</label>
<font>font13_title</font>
<align>right</align>
<texturenofocus border="5">MenuItemNF.png</texturenofocus>
<texturefocus border="5">MenuItemFO.png</texturefocus>
<onleft>60</onleft>
<onright>60</onright>
<onup>10</onup>
<ondown>7</ondown>
</control>
<control type="button" id="7">
<description>Disable Addon button</description>
<posx>0</posx>
<posy>50</posy>
<width>255</width>
<height>51</height>
<textoffsetx>20</textoffsetx>
<label>24021</label>
<font>font13_title</font>
<align>right</align>
<texturenofocus border="5">MenuItemNF.png</texturenofocus>
<texturefocus border="5">MenuItemFO.png</texturefocus>
<onleft>60</onleft>
<onright>60</onright>
<onup>6</onup>
<ondown>9</ondown>
</control>
<control type="button" id="9">
<description>Addon Settings</description>
<posx>0</posx>
<posy>100</posy>
<width>255</width>
<height>51</height>
<textoffsetx>20</textoffsetx>
<label>24020</label>
<font>font13_title</font>
<align>right</align>
<texturenofocus border="5">MenuItemNF.png</texturenofocus>
<texturefocus border="5">MenuItemFO.png</texturefocus>
<onleft>60</onleft>
<onright>60</onright>
<onup>7</onup>
<ondown>8</ondown>
</control>
<control type="button" id="8">
<description>Update Addon button</description>
<posx>0</posx>
<posy>150</posy>
<width>255</width>
<height>51</height>
<textoffsetx>20</textoffsetx>
<label>24069</label>
<font>font13_title</font>
<align>right</align>
<texturenofocus border="5">MenuItemNF.png</texturenofocus>
<texturefocus border="5">MenuItemFO.png</texturefocus>
<onleft>60</onleft>
<onright>60</onright>
<onup>9</onup>
<ondown>10</ondown>
</control>
<control type="button" id="10">
<description>Changelog button</description>
<posx>0</posx>
<posy>200</posy>
<width>255</width>
<height>51</height>
<textoffsetx>20</textoffsetx>
<label>24036</label>
<font>font13_title</font>
<align>right</align>
<texturenofocus border="5">MenuItemNF.png</texturenofocus>
<texturefocus border="5">MenuItemFO.png</texturefocus>
<onleft>60</onleft>
<onright>60</onright>
<onup>8</onup>
<ondown>6</ondown>
</control -->
</control>
<control type="group">
<visible>!IsEmpty(ListItem.Property(Addon.broken))</visible>
<posx>0</posx>
<posy>600</posy>
<control type="image">
<description>background image</description>
<posx>0</posx>
<posy>0</posy>
<width>920</width>
<height>100</height>
<texture border="20">OverlayDialogBackground.png</texture>
</control>
<control type="image">
<description>Icon image</description>
<posx>18</posx>
<posy>18</posy>
<width>64</width>
<height>64</height>
<texture>DefaultIconError.png</texture>
</control>
<control type="label">
<description>header label</description>
<posx>100</posx>
<posy>15</posy>
<width>800</width>
<height>25</height>
<font>font13_title</font>
<label>24096</label>
<align>left</align>
<aligny>center</aligny>
<textcolor>selected</textcolor>
<shadowcolor>black</shadowcolor>
</control>
<control type="textbox">
<description>Reason label</description>
<posx>100</posx>
<posy>35</posy>
<width>800</width>
<height>50</height>
<font>font13</font>
<label>$INFO[ListItem.Property(Addon.broken)]</label>
<align>left</align>
<textcolor>white</textcolor>
<shadowcolor>black</shadowcolor>
</control>
</control>
</control>
</controls>
</window>