def get_db_user_and_password(self): # get these by running a MediaWiki maintenance script; # yes, this means you need a full installation of MediaWiki # (but not web service) in order to use these methods command_list = MultiVersion.mw_script_as_array(self.config, "getConfiguration.php") pull_vars = ["wgDBuser", "wgDBpassword"] command = "{php} {command} --wiki={dbname} --format=json --regex='{vars}'" command = command.format( php=MiscUtils.shell_escape(self.config.php), command=" ".join(command_list), dbname=MiscUtils.shell_escape(self.db_name), vars="|".join(pull_vars)) results = RunSimpleCommand.run_with_output(command, shell=True).strip() settings = json.loads(results.decode('utf-8')) db_user = settings['wgDBuser'] db_password = settings['wgDBpassword'] return db_user, db_password
def get_last_lines_from_n(self, fileobj, runner, count): if not fileobj.filename or not exists(runner.dump_dir.filename_public_path(fileobj)): return None dumpfile = DumpFile(self.wiki, runner.dump_dir.filename_public_path(fileobj, self.wiki.date), fileobj, self.verbose) pipeline = dumpfile.setup_uncompression_command() tail = self.wiki.config.tail if not exists(tail): raise BackupError("tail command %s not found" % tail) tail_esc = MiscUtils.shell_escape(tail) pipeline.append([tail, "-n", "+%s" % count]) # without shell proc = CommandPipeline(pipeline, quiet=True) proc.run_pipeline_get_output() if (proc.exited_successfully() or (proc.get_failed_cmds_with_retcode() == [[-signal.SIGPIPE, pipeline[0]]]) or (proc.get_failed_cmds_with_retcode() == [[signal.SIGPIPE + 128, pipeline[0]]])): last_lines = proc.output() return last_lines
def get_first_500_lines(self): if self.first_lines: return self.first_lines if not self.filename or not exists(self.filename): return None pipeline = self.setup_uncompression_command() if not exists(self._wiki.config.head): raise BackupError("head command %s not found" % self._wiki.config.head) head = self._wiki.config.head head_esc = MiscUtils.shell_escape(head) pipeline.append([head, "-500"]) # without shell proc = CommandPipeline(pipeline, quiet=True) proc.run_pipeline_get_output() if (proc.exited_successfully() or (proc.get_failed_cmds_with_retcode() == [[-signal.SIGPIPE, pipeline[0]]]) or (proc.get_failed_cmds_with_retcode() == [[signal.SIGPIPE + 128, pipeline[0]]])): self.first_lines = proc.output() return self.first_lines
def build_recombine_command_string(self, runner, files, output_file, compression_command, uncompression_command, end_header_marker="</siteinfo>"): output_filename = runner.dump_dir.filename_public_path(output_file) partnum = 0 recombines = [] if not exists(runner.wiki.config.head): raise BackupError("head command %s not found" % runner.wiki.config.head) head = runner.wiki.config.head if not exists(runner.wiki.config.tail): raise BackupError("tail command %s not found" % runner.wiki.config.tail) tail = runner.wiki.config.tail if not exists(runner.wiki.config.grep): raise BackupError("grep command %s not found" % runner.wiki.config.grep) grep = runner.wiki.config.grep # we assume the result is always going to be run in a subshell. # much quicker than this script trying to read output # and pass it to a subprocess output_filename_esc = MiscUtils.shell_escape(output_filename) head_esc = MiscUtils.shell_escape(head) tail_esc = MiscUtils.shell_escape(tail) grep_esc = MiscUtils.shell_escape(grep) uncompression_command_esc = uncompression_command[:] for command in uncompression_command_esc: command = MiscUtils.shell_escape(command) for command in compression_command: command = MiscUtils.shell_escape(command) if not files: raise BackupError("No files for the recombine step found in %s." % self.name()) for file_obj in files: # uh oh FIXME # f = MiscUtils.shell_escape(file_obj.filename) fpath = runner.dump_dir.filename_public_path(file_obj) partnum = partnum + 1 pipeline = [] uncompress_this_file = uncompression_command[:] uncompress_this_file.append(fpath) pipeline.append(uncompress_this_file) # warning: we figure any header (<siteinfo>...</siteinfo>) # is going to be less than 2000 lines! pipeline.append([head, "-2000"]) pipeline.append([grep, "-n", end_header_marker]) # without shell proc = CommandPipeline(pipeline, quiet=True) proc.run_pipeline_get_output() if ((proc.output()) and (proc.exited_successfully() or proc.get_failed_cmds_with_retcode() == [[-signal.SIGPIPE, uncompress_this_file]] or proc.get_failed_cmds_with_retcode() == [[signal.SIGPIPE + 128, uncompress_this_file]])): (header_end_num, junk_unused) = proc.output().split(":", 1) # get header_end_num else: raise BackupError("Could not find 'end of header' marker for %s" % fpath) recombine = " ".join(uncompress_this_file) header_end_num = int(header_end_num) + 1 if partnum == 1: # first file, put header and contents recombine = recombine + " | %s -n -1 " % head elif partnum == len(files): # last file, put footer recombine = recombine + (" | %s -n +%s" % (tail, header_end_num)) else: # put contents only recombine = recombine + (" | %s -n +%s" % (tail, header_end_num)) recombine = recombine + " | %s -n -1 " % head recombines.append(recombine) recombine_command_string = ("(" + ";".join(recombines) + ")" + "|" + "%s %s" % (compression_command, output_filename)) return recombine_command_string