o k`Ѱ@sdZddlmZddlZddlZddlZddlZddlZddl Z ddl m Z ddl m Z mZddlmZddlmZddlmZdd lmZmZmZdd lmZmZdd lmZmZdd lm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&dd l'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-ddl.m/Z/m0Z0m1Z1m2Z2ddl3m4Z4ddl5m6Z6ddl7m8Z8m9Z9m:Z:m;Z;mZ>m?Z?ddl@mAZAddlBmCZCddlDmEZEddlFmGZGmHZHmIZImJZJmKZKmLZLddlMmNZNmOZOddlPmQZQddlRmSZSgdZTdZUGddde+eVZWGddde(e)ZXiZYeCZZ[d$d d!Z\Gd"d#d#e(Z]dS)%z(Trac Environment model and related APIs.)contextmanagerN)RawConfigParser)PIPEPopen)mkdtemp)urlsplit)log)AdminCommandErrorIAdminCommandProvider get_dir_list)IEnvironmentSetupParticipantISystemInfoProvider) CacheManagercached) BoolOption ChoiceOption ConfigSection Configuration IntOptionOption PathOption) ComponentComponentManagerExtensionPoint TracBaseError TracError implements)DatabaseManagerQueryContextManagerTransactionContextManagerparse_connection_uri) copy_tables)load_components)as_boolbackup_config_filecopytree create_file get_pkginfo is_path_belowlazymakedirs) close_fds) threading)pytz)exception_to_unicodepath_to_unicodeprinterr printferr printfoutprintout)_N_)Chrome)Href) Environmentr open_environmentzTrac Environment Version 1c@seZdZdZdS) BackupErrorzsr:cseZdZdZeedZeeZee Z e ddZ e ddddZed d dd Zed d d dZed dd dZed dddZeddddZeddddZeddddZeddddZeddd d!Zedd"ed#d$Zedd%d&d'Zed(d)ej ej!d*d d+Z"ed(d,d-d.Z#ed(d/ej$ej%d0d d+Z&ed(d1d2d3Z'd gdfd4d5Z(d6d7Z)e*d8d9Z+e,d:d;Z-e,dd?Z/d@dAZ0dBdCZ1e*dDdEZ2dFdGZ3fdHdIZ4e5ddJdKZ6dLdMZ7e*dNdOZ8e,dPdQZ9e,dRdSZ:ddTdUZ;gdfdVdWZe*d\d]Z?d^d_Z@e*d`daZAe*dbdcZBdddeZCe*dfdgZDe*dhdiZEe*djdkZFe*dldmZGe*dndoZHe*dpdqZIe*drdsZJdtduZKdvdwZLddxdyZMeNdzd{ZOeNd|d}ZPd~dZQdddZRddZSdddZTe*ddZUe*ddZVddZWZXS)r8aTrac environment manager. Trac stores project information in a Trac environment. It consists of a directory structure containing among other things: * a configuration file, * project-specific templates and plugins, * the wiki and ticket attachments files, * the SQLite database file (stores tickets, wiki pages...) in case the database backend is SQLite T componentsa Enable or disable components provided by Trac and plugins. The component to enable/disable is specified by the option name. The enabled state is determined by the option value: setting the value to `enabled` or `on` will enable the component, any other value (typically `disabled` or `off`) will disable the component. The option name is either the fully qualified name of the component or the module/package prefix of the component. The former enables/disables a specific component, while the latter enables/disables any component in the specified package/module. Consider the following configuration snippet: {{{#!ini [components] trac.ticket.report.ReportModule = disabled acct_mgr.* = enabled }}} The first option tells Trac to disable the [TracReports report module]. The second option instructs Trac to enable all components in the `acct_mgr` package. The trailing wildcard is required for module/package matching. To view the list of active components, go to the ''Plugins'' section of ''About Trac'' (requires `CONFIG_VIEW` [TracPermissions permission]). See also: TracPlugins inherit plugins_dira+Path to the //shared plugins directory//. Plugins in that directory are loaded in addition to those in the directory of the environment `plugins`, with this one taking precedence. Non-absolute paths are relative to the Environment `conf` directory. tracbase_urlzBase URL of the Trac site. This is used to produce documents outside of the web browsing context, such as URLs in notification e-mails that point to Trac resources. use_base_url_for_redirectFaOptionally use `[trac] base_url` for redirects. In some configurations, usually involving running Trac behind a HTTP proxy, Trac can't automatically reconstruct the URL that is used to access it. You may need to use this option to force Trac to use the `base_url` setting also for redirects. This introduces the obvious limitation that this environment will only be usable when accessible from that URL, as redirects are frequently used. secure_cookieszRestrict cookies to HTTPS connections. When true, set the `secure` flag on all cookies so that they are only sent to the server on HTTPS connections. Use this if your Trac instance is only accessible through HTTPS. anonymous_session_lifetime90zLifetime of the anonymous session, in days. Set the option to 0 to disable purging old anonymous sessions. (''since 1.0.17'')projectnamez My ProjectzName of the project.descrzMy example projectz!Short description of the project.urlawURL of the project web site. This is usually the domain in which the `base_url` resides. For example, the project URL might be !https://myproject.com, with the Trac site (`base_url`) residing at either !https://trac.myproject.com or !https://myproject.com/trac. The project URL is added to the footer of notification e-mails. adminz.E-Mail address of the project's administrator.admin_trac_url.zBase URL of a Trac instance where errors in this Trac should be reported. This can be an absolute or relative URL, or '.' to reference this Trac instance. An empty value will disable the reporting buttons. footerznVisit the Trac open source project at
https://trac.edgewall.org/z!Page footer text (right-aligned).iconzcommon/trac.icozURL of the icon of the project.logginglog_typezbLogging facility to use. Should be one of (`none`, `file`, `stderr`, `syslog`, `winlog`).)case_sensitivelog_fileztrac.logzIf `log_type` is `file`, this should be a path to the log-file. Relative paths are resolved relative to the `log` directory of the environment. log_levelzpLevel of verbosity in log. Should be one of (`CRITICAL`, `ERROR`, `WARNING`, `INFO`, `DEBUG`). log_formatNaCustom logging format. If nothing is set, the following will be used: `Trac[$(module)s] $(levelname)s: $(message)s` In addition to regular key names supported by the [http://docs.python.org/library/logging.html Python logger library] one could use: - `$(path)s` the path for the current environment - `$(basename)s` the last path component of the current environment - `$(project)s` the project name Note the usage of `$(...)s` instead of `%(...)s` as the latter form would be interpreted by the !ConfigParser itself. Example: `($(thread)d) Trac[$(basename)s:$(module)s] $(levelname)s: $(message)s` cCsht|tjtj||_d|_d|_|r*||||j D]}| q!dS| | dS)aInitialize the Trac environment. :param path: the absolute path to the Trac environment :param create: if `True`, the environment is created and otherwise, the environment is expected to already exist. :param options: A list of `(section, name, value)` tuples that define configuration options :param default_data: if `True` (the default), the environment is populated with default data when created. N) r__init__ospathnormpathnormcaserconfigcreatesetup_participantsenvironment_createdverify setup_config)selfr\r`options default_datasetup_participantr?r?r@rZs     zEnvironment.__init__cCsd|jj|jfS)Nz<%s %r>) __class__r;r\rer?r?r@__repr__szEnvironment.__repr__cCstj|jS)z3The environment name. :since: 1.2 )r[r\basenamerjr?r?r@rLzEnvironment.namecCs|S)zProperty returning the `Environment` object, which is often required for functions and methods that take a `Component` instance. r?rjr?r?r@envszEnvironment.envcCs6g}|jD] }||pgqtt|dddS)zList of `(name, version)` tuples describing the name and version information of external packages used by Trac and plugins. cSs|ddk|dfS)NrTrac)lower)argsr?r?r@*sz)Environment.system_info..)key)system_info_providersextendget_system_infosortedset)reinfoproviderr?r?r@ system_info!s  zEnvironment.system_infoccsZd|jfVdtjfVdtjfVtdurdtjfVt|dr+|j|jfVdSdS)NroPython setuptoolsr-webfrontend_version) trac_versionsysversionr} __version__r-hasattr webfrontendr~rjr?r?r@rv.s     zEnvironment.get_system_infocCs||_|j|_|j|_dS)aInitialize additional member variables for components. Every component activated through the `Environment` object gets three member variables: `env` (the environment object), `config` (the environment configuration) and `log` (a logger object).N)rnr_r)re componentr?r?r@component_activated7s zEnvironment.component_activatedcCs&|}t|ts|jd|j}|S)NrQ) isinstancestrr<r;rp)re name_or_classrLr?r?r@_component_nameBs zEnvironment._component_namecCs6i}|jD]\}}|d}t|||<q|S)Nz.*)components_sectionrfrstriprpr#)re_rulesrLvaluer?r?r@_component_rulesHs zEnvironment._component_rulescCsx||}|j}|}|r)||}|dur|S|d}|dkr!n|d|}|s |dr:|d r:|d p;dS)aImplemented to only allow activation of components that are not disabled in the configuration. This is called by the `ComponentManager` base class when a component is about to be activated. If this method returns `False`, the component does not get activated. If it returns `None`, the component only gets activated if it is located in the `plugins` directory of the environment. NrQrtrac.z trac.test.z trac.tests.)rrgetrfind startswith)reclscomponent_namerulescnameenabledidxr?r?r@is_component_enabledPs&      z Environment.is_component_enabledcs d|j||<t|dS)zEnable a component or module.TN)rrsuperenable_componentrerrir?r@rmszEnvironment.enable_componentc cszdVWdSty'}z|jd|t||rWYd}~dSd}~wtyH}z|jd|t|dd|r=WYd}~dSd}~ww)amTraps any runtime exception raised when working with a component and logs the error. :param component: the component responsible for any error that could happen inside the context :param reraise: if `True`, an error is logged but not suppressed. By default, errors are suppressed. NzComponent %s failed with %sT traceback)rrwarningr. Exceptionerror)rerreraiseer?r?r@component_guardrs(   zEnvironment.component_guardc Csz$ttj|jddd}|}Wdn1swYWnty<}z ttd|jt |dd}~ww|t krIttd|ddS) zSVerify that the provided path points to a valid Trac environment directory.VERSIONutf-8encodingNz+No Trac environment found at %(path)s %(e)s)r\rz(Unknown Trac environment type '%(type)s')type) openr[r\joinreadlinerrrr4r._VERSION)reftagrr?r?r@rcs& zEnvironment.verifycCs t|S)aReturn an object (typically a module) containing all the backend-specific exception types as attributes, named according to the Python Database API (http://www.python.org/dev/peps/pep-0249/). To catch a database exception, use the following pattern:: try: with env.db_transaction as db: ... except env.db_exc.IntegrityError as e: ... )rget_exceptionsrjr?r?r@db_excs zEnvironment.db_exccCt|S)aReturn a context manager (`~trac.db.api.QueryContextManager`) which can be used to obtain a read-only database connection. Example:: with env.db_query as db: cursor = db.cursor() cursor.execute("SELECT ...") for row in cursor.fetchall(): ... Note that a connection retrieved this way can be "called" directly in order to execute a query:: with env.db_query as db: for row in db("SELECT ..."): ... :warning: after a `with env.db_query as db` block, though the `db` variable is still defined, you shouldn't use it as it might have been closed when exiting the context, if this context was the outermost context (`db_query` or `db_transaction`). If you don't need to manipulate the connection itself, this can even be simplified to:: for row in env.db_query("SELECT ..."): ... )rrjr?r?r@db_querys"zEnvironment.db_querycCr)adReturn a context manager (`~trac.db.api.TransactionContextManager`) which can be used to obtain a writable database connection. Example:: with env.db_transaction as db: cursor = db.cursor() cursor.execute("UPDATE ...") Upon successful exit of the context, the context manager will commit the transaction. In case of nested contexts, only the outermost context performs a commit. However, should an exception happen, any context manager will perform a rollback. You should *not* call `commit()` yourself within such block, as this will force a commit even if that transaction is part of a larger transaction. Like for its read-only counterpart, you can directly execute a DML query on the `db`:: with env.db_transaction as db: db("UPDATE ...") :warning: after a `with env.db_transaction` as db` block, though the `db` variable is still available, you shouldn't use it as it might have been closed when exiting the context, if this context was the outermost context (`db_query` or `db_transaction`). If you don't need to manipulate the connection itself, this can also be simplified to:: env.db_transaction("UPDATE ...") )rrjr?r?r@db_transactions&zEnvironment.db_transactioncCsDddlm}|||t|||dur t|jdSdS)zClose the environment.r)RepositoryManagerN)trac.versioncontrol.apirshutdownrr)retidrr?r?r@rs zEnvironment.shutdownc Csptj|j}tj|sttd|dtj|jr(t|jr(ttdtj|js5t|jt|jt|j t|j t|j t tj |jdtdt tj |jddt|jt|j}|D] \}}}||||qr||tdd |Ds|j||jt |jd |t|}||r|d Sd S) aCreate the basic directory structure of the environment, initialize the database and populate the configuration file with default values. If options contains ('inherit', 'file'), default values will not be loaded; they are expected to be provided by that file or other options. :raises TracError: if the base directory of `path` does not exist. :raises TracError: if `path` exists and is not empty. zDBase directory '%(env)s' does not exist. Please create it and retry.)rnz"Directory exists and is not empty.r READMEzcThis directory contains a Trac environment. Visit https://trac.edgewall.org/ for more information. css"|] \}}}||fdkVqdS))rBfileNr?).0sectionoptionrr?r?r@ (sz%Environment.create...sampleN)r[r\dirnameexistsrr4listdirmkdir htdocs_dirlog_dirrC templates_dirr&rrconf_dirrconfig_file_pathrxsaverdanyr_ set_defaults_update_sample_configrinit_dbinsert_default_data) rerfrgbase_dirr_rrLrdbmr?r?r@r`sH            zEnvironment.createcCt|dS)zLReturns the current version of the database. :since 1.0.2: database_versionrget_database_versionrjr?r?r@r7szEnvironment.database_versioncCr)zReturns the version of the database at the time of creation. In practice, for a database created before 0.11, this will return `False` which is "older" than any db version number. :since 1.0.2: initial_database_versionrrjr?r?r@database_initial_version@s z$Environment.database_initial_versioncCs ddlm}m}t|d|S)z9Returns the version of Trac. :since: 1.2 r)corerr)rErrr'r)rerrr?r?r@rLszEnvironment.trac_versioncCsPt|jd|ji|_|jjsttd|jd||j}t ||o$|fdS)zLoad the configuration file.envnamez/The configuration file is not found at %(path)sr\N) rrrLr_rrr4 setup_logshared_plugins_dirr")rerCr?r?r@rdTszEnvironment.setup_configcCstj|jdS)zPath of the trac.ini file.ztrac.ini)r[r\rrrjr?r?r@r_szEnvironment.config_file_pathcCs&tj|jstj|j|jS|jS)zPath to the log file.)r[r\isabsrWrrrjr?r?r@ log_file_pathdszEnvironment.log_file_pathcGs2|j}|D] }tj||}qtjtj|SN)r\r[rr^realpath)redirsr\dirr?r?r@_get_path_to_dirkszEnvironment._get_path_to_dircCs |ddS)zKAbsolute path to the attachments directory. :since: 1.3.1 files attachmentsrrjr?r?r@attachments_dirqs zEnvironment.attachments_dircC |dS)zEAbsolute path to the conf directory. :since: 1.0.11 confrrjr?r?r@ry zEnvironment.conf_dircCr)zEAbsolute path to the files directory. :since: 1.3.2 rrrjr?r?r@ files_dirrzEnvironment.files_dircCr)zGAbsolute path to the htdocs directory. :since: 1.0.11 htdocsrrjr?r?r@rrzEnvironment.htdocs_dircCr)zDAbsolute path to the log directory. :since: 1.0.11 rrrjr?r?r@rrzEnvironment.log_dircCr)zHAbsolute path to the plugins directory. :since: 1.0.11 pluginsrrjr?r?r@rCrzEnvironment.plugins_dircCr)zJAbsolute path to the templates directory. :since: 1.0.11 templatesrrjr?r?r@rrzEnvironment.templates_dircCs>||j|j|j|j\|_}|j||jd|jdS)z"Initialize the logging sub-system.z_-------------------------------- environment startup [Trac %s] --------------------------------N) create_loggerrUrrXrYr addHandlerryr)re log_handlerr?r?r@rs  zEnvironment.setup_logcCs\dt|jd}|r$|ddd|jd|jd|j}tj |||||dS) NzTrac.%srz$(z%(z%(path)sz %(basename)sz %(project)s)format) hashlibsha1r\encode hexdigestreplacerL project_namerlogger_handler_factory)rerUrWrXrYlog_idr?r?r@rs     zEnvironment.create_loggercCs|r|jSt|jS)a Returns information about all known users, i.e. users that have logged in to this Trac environment and possibly set their name and email. By default this function returns an iterator that yields one tuple for every user, of the form (username, name, email), ordered alpha-numerically by username. When `as_dict` is `True` the function returns a dictionary mapping username to a (name, email) tuple. :since 1.2: the `as_dict` parameter is available. )_known_users_dictiter _known_users)reas_dictr?r?r@get_known_userss zEnvironment.get_known_userscCr)Na SELECT DISTINCT s.sid, n.value, e.value FROM session AS s LEFT JOIN session_attribute AS n ON (n.sid=s.sid AND n.authenticated=1 AND n.name = 'name') LEFT JOIN session_attribute AS e ON (e.sid=s.sid AND e.authenticated=1 AND e.name = 'email') WHERE s.authenticated=1 ORDER BY s.sid )rrjr?r?r@rs zEnvironment._known_userscCsdd|jDS)NcSs"i|] }|d|d|dfqS)rr?)rur?r?r@ s"z1Environment._known_users_dict..)rrjr?r?r@rszEnvironment._known_users_dictcCs |`|`dS)zClear the known_users cache.N)rrrjr?r?r@invalidate_known_users_cachesz(Environment.invalidate_known_users_cachecCst||S)zCreate a backup of the database. :param dest: Destination file; if not specified, the backup is stored in a file called db_name.trac_version.bak )rbackup)redestr?r?r@rrmzEnvironment.backupc Cs|jD]M}z/|j|dd|r$|jd| WdWdSWdn1s.wYWqtyP}zttd|jj |jj t |dd}~wwdS)z4Return whether the environment needs to be upgraded.Trz,Component %s requires an environment upgradeNz;Unable to check for upgrade of %(module)s.%(name)s: %(err)s)modulerLerrF) rarenvironment_needs_upgraderrrrr4rir<r;r.)re participantrr?r?r@ needs_upgrades, zEnvironment.needs_upgradec Csg}|jD]"}|j|dd|r||Wdn1s"wYq|s,dS|rGz||WntyF}zt||d}~ww|D]1}|jd||j|dd | Wdn1shwYt |}|j dkrz| qI| |`dS)zUpgrade database. :param backup: whether or not to backup before upgrading :param backup_dest: name of the backup file :return: whether the upgrade was performed Tr Nzupgrading %s...zsqlite::memory:)rarr appendrrr:rryupgrade_environmentrconnection_urirrr)rer backup_dest upgradersr rrr?r?r@upgrades:     zEnvironment.upgradecCstt|jjjS)zThe application root path)r7rabs_hrefbaser\rjr?r?r@hrefszEnvironment.hrefcCs|js |jdt|jS)zThe application URLzQ[trac] base_url option not set in configuration, generated links may be incorrect)rFrrr7rjr?r?r@r"s  zEnvironment.abs_hrefc Cstj|jd}tj|sdSt|}|z|Wnty>}z|j d|t |ddWYd}~dSd}~ww|j d|dS)Nrz/Couldn't write sample configuration file (%s)%sTrzRWrote sample configuration file with the new settings and their default values: %s) r[r\rrisfilerrrEnvironmentErrorrrr.ry)refilenamer_rr?r?r@r*s    z!Environment._update_sample_config)Fr)FN)Yr;r<r=r>rr requiredrrtr rarrrrrrFrbase_url_for_redirectrHrrIrproject_description project_url project_adminproject_admin_trac_urlr5project_footer project_iconrr LOG_TYPESLOG_TYPE_ALIASESrUrW LOG_LEVELSLOG_LEVEL_ALIASESrXrYrZrkr)rLpropertyrnr{rvrrrrrrrrcrrrrr`rrrrdrrrrrrrrrCrrrrrrrrrrrrrr __classcell__r?r?rr@r8Bs !                 #  '9                 "  r8Fc Cs@|std}|sttd|r\t?t|}|r/|jr/|j d| t|=d}|dur [new_env]aConvert database Converts the database backend in the environment in which the command is run (in-place), or in a new copy of the environment. For an in-place conversion, the data is copied to the database specified in and the [trac] database setting is changed to point to the new database. The new database must be empty, which for an SQLite database means the file should not exist. The data in the existing database is left unmodified. For a database conversion in a new copy of the environment, the environment in which the command is executed is copied and the [trac] database setting is changed in the new environment. The existing environment is left unmodified. Be sure to create a backup (see `hotcopy`) before converting the database, particularly when doing an in-place conversion. deployz z2Extract static resources from Trac and all pluginshotcopyz [--no-database]zMake a hot backup copy of an environment The database is backed up to the 'db' directory of the destination, unless the --no-database option is specified. rz [--no-backup]a=Upgrade database to current version The database is backed up to the directory specified by [trac] backup_dir (the default is 'db'), unless the --no-backup option is specified. The shorthand alias -b can also be used to specify --no-backup. )_complete_convert_db_do_convert_db _do_deploy _do_hotcopy _do_upgraderjr?r?r@get_admin_commands}s" z#EnvironmentAdmin.get_admin_commandsNcCs|r|||S||Sr)_do_convert_db_in_new_env_do_convert_db_in_place)redburir0r?r?r@r7s  zEnvironmentAdmin._do_convert_dbcCst|dkr t|dSdS)Nrr)lenr )rerqr?r?r@r6s  z%EnvironmentAdmin._complete_convert_dbc Cstj|}tj|d}tj|d}t|j}|jD]7}t|p$g}|s)q|D]'\}} | s2q+tj| } tj||}tj | rRt || rRt t d| dq+qt |ddt |ddtt d|jD]A}t|pqg}|svqitd|j|jjf|D]&\}} | sqtj| } td | tj | rtj||}t| |ddqqit |ddtt d |jtjtd } d D]8} tj|d | }|jd| dd} |j| | dd}t|ddd }||Wdn1swYqdS)Nrzcgi-binzResources cannot be deployed to a target directory that is equal to or below the source directory '%(source)s'. Please choose a different target directory and try again.)sourceT) overwritezCopying resources from:z %s.%sz zCreating scripts.)rn executablerepr)cgifcgiwsgirz deploy_trac.)textwrr)r[r\r]rr6rntemplate_providerslistget_htdocs_dirsrr(r r4r*r3r<rir;r%rrBrC load_templaterender_template_stringrwrite)rertarget chrome_target script_targetchromerzpathsrsrootr@datascripttemplaterGoutr?r?r@r8sj               zEnvironmentAdmin._do_deployc Cs|dvrttd|dddtj|rttdt|dttdt|jjt|d |jj d d }| d d \}}g}|dkretj |jjtj |}|d|d|d|dg}|re|||jjy}|d|ddz t|jj|d |dWn;tjy}z.d } ttd|jdD]\} } } | | vrtd| qtd| t| fqWYd}~nd}~wwd} |dkr|sttdtj |dd|} |j| Wdn1swYttd| S)N)Nz --no-databasezInvalid argument '%(arg)s')argT show_usagez+hotcopy can't overwrite existing '%(dest)s')rz!Hotcopying %(src)s to %(dst)s ...)srcdstrEdatabase:rsqlitez-journalz -stmtjrnlz-shmz-walzUPDATE systemz! SET name=NULL WHERE name IS NULL)symlinksskipz       z(EnvironmentAdmin._do_convert_db_in_placec st|jjdtfddD}||d<tdd|D}Gdddt}||d|d }| t |j t |jj |j ttjd d |d fttttd }|jdd\}}Wdn1skwY|jdkr}td||ft|S)Nrc3s0|]}|D] \}}||f|fVq qdSr)itemsrrrLrparserr?r@rmsz/EnvironmentAdmin._create_env..)rEr^css"|] \\}}}|||fVqdSrr?rr?r?r@rqs c@seZdZdZdZddZdS)z8EnvironmentAdmin._create_env..MigrateEnvironmentTFcs0||tfdddDsdSt||S)Nc3s|]}|VqdSr)r)rmodrLr?r@rzsz`EnvironmentAdmin._create_env..MigrateEnvironment.is_component_enabled..)rztracopt.F)rrr8rrr?rr@rxs   zMEnvironmentAdmin._create_env..MigrateEnvironment.is_component_enabledN)r;r<r=abstractrrr?r?r?r@MigrateEnvironmentts rT)r`rfz-mztrac.admin.consoler)stdinstdoutstderrr+rD)inputrz-upgrade command failed (stdout %r, stderr %r))rreadrnrdictsectionsrwrr8rr[rprCrgr%rrrBrr+ communicate returncoder) rer0r>rfrrnprocrrr?rr@rsjs8     zEnvironmentAdmin._create_envcCst|j|||||dSr)r!rn)rerxrzr{ryrwr?r?r@ruszEnvironmentAdmin._copy_tablescCstd|jj|jj|jj|jjfD]2}tj|}tj |j|}td|ddtj |r4t |tj |r@t ||tdqdS)NzCopying directories:z %s directory... F)newlinezdone.)r2rnrrrrCr[r\rlrr|rgr~r%)rerxr\rLr]r?r?r@rvs        z"EnvironmentAdmin._copy_directoriesr)r;r<r=r>rr r;r7r6r8r9r:r<r=rsrurvr?r?r?r@r2vs + 7 4!% r2)NF)^r> contextlibrros.pathr[r}rgrr configparserr subprocessrrtempfiler urllib.parserrErtrac.admin.apir r r trac.apir r trac.cacherr trac.configrrrrrrr trac.corerrrrrr trac.db.apirrrr trac.db.convertr! trac.loaderr" trac.utilr#r$r%r&r'r(r)r*trac.util.compatr+trac.util.concurrencyr,trac.util.datefmtr-trac.util.textr.r/r0r1r2r3trac.util.translationr4r5trac.web.chromer6 trac.web.hrefr7__all__r RuntimeErrorr:r8r,Lockr+r9r2r?r?r?r@sT     $   (      ~ 7