<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: pipe code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sun, 27 Jul 2008 06:47:31 GMT</pubDate>
    <description>DZone Snippets: pipe code</description>
    <item>
      <title>Thread Process //Pascal class</title>
      <link>http://snippets.dzone.com/posts/show/5729</link>
      <description>A thread class to open processes on windows and retrieve its output (input isn't supported but it's easy to add).&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;unit Process;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, Windows, Classes, TLHelp32;&lt;br /&gt;&lt;br /&gt;const&lt;br /&gt;  INITIALIZATION_TIMEOUT = 10000;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TStringArray = array of string;&lt;br /&gt;  TProcessArray = array of Cardinal;&lt;br /&gt;  TExceptionEvent = procedure(Sender: TObject; Exception: Exception) of object;&lt;br /&gt;  EProcessError = class(Exception);&lt;br /&gt;&lt;br /&gt;  TProcessThread = class(TThread)&lt;br /&gt;  private&lt;br /&gt;    FException: Exception;&lt;br /&gt;    FWatching, FStarted, FSuspended: Boolean;&lt;br /&gt;    FDirectory, FPath, FCommandLine, FEnvironment: PChar;&lt;br /&gt;    FData: string;&lt;br /&gt;    FOnProcessTerminated, FOnDataAvailable: TNotifyEvent;&lt;br /&gt;    InputRead, InputWrite, OutputRead, OutputWrite: THandle;&lt;br /&gt;    FMainProcess: PROCESS_INFORMATION;&lt;br /&gt;    FOnException: TExceptionEvent;&lt;br /&gt;    FOnProcessStarted: TNotifyEvent;&lt;br /&gt;    function GetPriority: TThreadPriority;&lt;br /&gt;    procedure SetPriority(const Value: TThreadPriority);&lt;br /&gt;    procedure FreeResources;&lt;br /&gt;  protected&lt;br /&gt;    procedure CallDataAvailable; virtual;&lt;br /&gt;    procedure CallProcessTerminated; virtual;&lt;br /&gt;    procedure CallProcessOpened; virtual;&lt;br /&gt;    procedure CallException; virtual;&lt;br /&gt;    procedure Execute; override;&lt;br /&gt;  public&lt;br /&gt;    constructor Create(Path, CommandLine, Directory: string; Environment: TStrings = nil; Watch: Boolean = True);&lt;br /&gt;    destructor Destroy; override;&lt;br /&gt;&lt;br /&gt;    function IsProcessAlive: Boolean;&lt;br /&gt;    procedure Resume;&lt;br /&gt;    procedure Suspend;&lt;br /&gt;    property OnDataAvailable: TNotifyEvent read FOnDataAvailable write FOnDataAvailable;&lt;br /&gt;    property OnProcessTerminated: TNotifyEvent read FOnProcessTerminated write FOnProcessTerminated;&lt;br /&gt;    property OnProcessStarted: TNotifyEvent read FOnProcessStarted write FOnProcessStarted;&lt;br /&gt;    property OnException: TExceptionEvent read FOnException write FOnException;&lt;br /&gt;    property Data: string read FData;&lt;br /&gt;    property Process: PROCESS_INFORMATION read FMainProcess;&lt;br /&gt;    property Priority: TThreadPriority read GetPriority write SetPriority;&lt;br /&gt;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TProcessLineThread = class;&lt;br /&gt;  TOnNewLineEvent = procedure(ProcessLine:  TProcessLineThread; const Line: string) of object;&lt;br /&gt;  TProcessLineThread = class(TProcessThread)&lt;br /&gt;  private&lt;br /&gt;    FCurrentLine: string;&lt;br /&gt;    FOnNewLine: TOnNewLineEvent;&lt;br /&gt;    procedure DataAvailable(Sender: TObject);&lt;br /&gt;    procedure Finished(Sender: TObject);&lt;br /&gt;  public&lt;br /&gt;    constructor Create(Path, CommandLine, Directory: string; Environment: TStrings = nil);&lt;br /&gt;    property OnNewLine: TOnNewLineEvent read FOnNewLine write FOnNewLine;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;function KillProcess(const Process: Cardinal): Boolean;&lt;br /&gt;function GetChildrenProcesses(const Process: Cardinal; const IncludeParent: Boolean = True): TProcessArray;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;const&lt;br /&gt;  Priorities: array [TThreadPriority] of Integer =&lt;br /&gt;   (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL,&lt;br /&gt;    THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL,&lt;br /&gt;    THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL);&lt;br /&gt;&lt;br /&gt;function GetChildrenProcesses(const Process: Cardinal; const IncludeParent: Boolean): TProcessArray;&lt;br /&gt;var&lt;br /&gt;  Snapshot: Cardinal;&lt;br /&gt;  ProcessList: PROCESSENTRY32;&lt;br /&gt;  Current: Integer;&lt;br /&gt;begin&lt;br /&gt;  Current := 0;&lt;br /&gt;  SetLength(Result, 1);&lt;br /&gt;  Result[0] := Process;&lt;br /&gt;  repeat&lt;br /&gt;    ProcessList.dwSize := SizeOf(PROCESSENTRY32);&lt;br /&gt;    Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);&lt;br /&gt;    if (Snapshot = INVALID_HANDLE_VALUE) or not Process32First(Snapshot, ProcessList) then&lt;br /&gt;      Continue;&lt;br /&gt;    repeat&lt;br /&gt;      if ProcessList.th32ParentProcessID = Result[Current] then&lt;br /&gt;      begin&lt;br /&gt;        SetLength(Result, Length(Result) + 1);&lt;br /&gt;        Result[Length(Result) - 1] := ProcessList.th32ProcessID;&lt;br /&gt;      end;&lt;br /&gt;    until Process32Next(Snapshot, ProcessList) = False;&lt;br /&gt;    Inc(Current);&lt;br /&gt;  until Current &gt;= Length(Result);&lt;br /&gt;  if not IncludeParent then&lt;br /&gt;    Result := Copy(Result, 2, Length(Result));&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function KillProcess(const Process: Cardinal): Boolean;&lt;br /&gt;var&lt;br /&gt;  Handle: Cardinal;&lt;br /&gt;  List: TProcessArray;&lt;br /&gt;  I: Integer;&lt;br /&gt;begin&lt;br /&gt;  Result := True;&lt;br /&gt;  List := GetChildrenProcesses(Process);&lt;br /&gt;  for I := Length(List) - 1 downto 0 do&lt;br /&gt;    if Result then&lt;br /&gt;    begin&lt;br /&gt;      Handle := OpenProcess(PROCESS_TERMINATE, false, List[I]);&lt;br /&gt;      Result := (Handle &lt;&gt; 0) and TerminateProcess(Handle, 0) and CloseHandle(Handle);&lt;br /&gt;    end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TProcessThread }&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.CallDataAvailable;&lt;br /&gt;begin&lt;br /&gt;  if Assigned(FOnDataAvailable) then&lt;br /&gt;    FOnDataAvailable(Self);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.Resume;&lt;br /&gt;var&lt;br /&gt;  SuspendCount: Integer;&lt;br /&gt;begin&lt;br /&gt;  if FStarted then&lt;br /&gt;  begin&lt;br /&gt;    FStarted := True;&lt;br /&gt;    SuspendCount := ResumeThread(FMainProcess.hThread);&lt;br /&gt;    CheckThreadError(SuspendCount &gt;= 0);&lt;br /&gt;    if SuspendCount = 1 then&lt;br /&gt;      FSuspended := False;&lt;br /&gt;  end;&lt;br /&gt;  inherited Resume;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TProcessThread.GetPriority: TThreadPriority;&lt;br /&gt;begin&lt;br /&gt;  if FStarted then&lt;br /&gt;  begin&lt;br /&gt;    CheckThreadError(GetThreadPriority(FMainProcess.hThread) &lt;&gt; THREAD_PRIORITY_ERROR_RETURN);&lt;br /&gt;  end;&lt;br /&gt;  Result := inherited Priority;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TProcessThread.IsProcessAlive: Boolean;&lt;br /&gt;var&lt;br /&gt;  Status: Cardinal;&lt;br /&gt;begin&lt;br /&gt;  GetExitCodeProcess(FMainProcess.hProcess, Status);&lt;br /&gt;  Result := Status = STILL_ACTIVE;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.SetPriority(const Value: TThreadPriority);&lt;br /&gt;begin&lt;br /&gt;  if FStarted then&lt;br /&gt;    CheckThreadError(SetThreadPriority(FMainProcess.hThread, Priorities[Value]));&lt;br /&gt;  inherited Priority := Value;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.Suspend;&lt;br /&gt;var&lt;br /&gt;  OldSuspend: Boolean;&lt;br /&gt;begin&lt;br /&gt;  if FStarted then&lt;br /&gt;  begin&lt;br /&gt;    OldSuspend := FSuspended;&lt;br /&gt;    try&lt;br /&gt;      FSuspended := True;&lt;br /&gt;      CheckThreadError(Integer(SuspendThread(FMainProcess.hThread)) &gt;= 0);&lt;br /&gt;    except&lt;br /&gt;      FSuspended := OldSuspend;&lt;br /&gt;      raise;&lt;br /&gt;    end;&lt;br /&gt;  end;&lt;br /&gt;  inherited Suspend;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.CallException;&lt;br /&gt;begin&lt;br /&gt;  if Assigned(FOnException) then&lt;br /&gt;    FOnException(Self, FException);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.CallProcessOpened;&lt;br /&gt;begin&lt;br /&gt;  if Assigned(FOnProcessStarted) then&lt;br /&gt;    FOnProcessStarted(Self);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.CallProcessTerminated;&lt;br /&gt;begin&lt;br /&gt;  if Assigned(FOnProcessTerminated) then&lt;br /&gt;    FOnProcessTerminated(Self);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;constructor TProcessThread.Create(Path, CommandLine, Directory: string; Environment: TStrings; Watch: Boolean);&lt;br /&gt;var&lt;br /&gt;  Len, I: Integer;&lt;br /&gt;begin&lt;br /&gt;  inherited Create(True);&lt;br /&gt;&lt;br /&gt;  if (Length(CommandLine) &gt; 0) and (Length(Path) &gt; 0) then&lt;br /&gt;    CommandLine := ' ' + CommandLine;&lt;br /&gt;&lt;br /&gt;  if Length(Path) &gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    GetMem(FPath, Length(Path) + 1);&lt;br /&gt;    StrCopy(FPath, PChar(Path));&lt;br /&gt;  end;&lt;br /&gt;  if Length(CommandLine) &gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    GetMem(FCommandLine, Length(CommandLine) + 1);&lt;br /&gt;    StrCopy(FCommandLine, PChar(CommandLine));&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  if Length(Directory) &gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    GetMem(FDirectory, Length(Directory) + 1);&lt;br /&gt;    StrCopy(FDirectory, PChar(Directory));&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  FWatching := Watch;&lt;br /&gt;&lt;br /&gt;  if Assigned(Environment) then&lt;br /&gt;  begin&lt;br /&gt;    GetMem(FEnvironment, 1);&lt;br /&gt;    Len := 1;&lt;br /&gt;    for I := 0 to Environment.Count - 1 do&lt;br /&gt;    begin&lt;br /&gt;      Inc(Len, Length(Environment[I]) + 1);&lt;br /&gt;      ReallocMem(FEnvironment, Len);&lt;br /&gt;      SetEnvironmentVariable(PChar(Environment.Names[I]), PChar(Environment.ValueFromIndex[I]));&lt;br /&gt;      StrCopy(FEnvironment + Len - Length(Environment[I]) - 2, PChar(Environment[I]));&lt;br /&gt;    end;&lt;br /&gt;    (FEnvironment + Len - 1)^ := #0;&lt;br /&gt;    FreeMem(FEnvironment);&lt;br /&gt;    FEnvironment := nil;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;destructor TProcessThread.Destroy;&lt;br /&gt;begin&lt;br /&gt;  FreeMem(FPath);&lt;br /&gt;  FreeMem(FCommandLine);&lt;br /&gt;  FreeMem(FDirectory);&lt;br /&gt;  FreeResources;&lt;br /&gt;  if Assigned(FEnvironment) then&lt;br /&gt;    FreeMem(FEnvironment);&lt;br /&gt;  inherited;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.Execute;&lt;br /&gt;const&lt;br /&gt;  MAX_BUFFER = 512 * 1024;&lt;br /&gt;var&lt;br /&gt;  MaxBytes, Available, BytesRead: Cardinal;&lt;br /&gt;  Buffer: array[0..MAX_BUFFER] of Char;&lt;br /&gt;&lt;br /&gt;  function Read: Boolean;&lt;br /&gt;  begin&lt;br /&gt;    Result := True;&lt;br /&gt;    FillChar(Buffer, MAX_BUFFER, #0);&lt;br /&gt;    PeekNamedPipe(OutputRead, @Buffer, MAX_BUFFER, @BytesRead, @Available, nil);&lt;br /&gt;&lt;br /&gt;    if BytesRead &lt; MAX_BUFFER then&lt;br /&gt;    begin&lt;br /&gt;      MaxBytes := BytesRead;&lt;br /&gt;    end&lt;br /&gt;    else&lt;br /&gt;      MaxBytes := MAX_BUFFER;&lt;br /&gt;&lt;br /&gt;    if MaxBytes &gt; 0 then&lt;br /&gt;      if ReadFile(OutputRead, Buffer, MaxBytes, BytesRead, nil) then&lt;br /&gt;      begin&lt;br /&gt;        if BytesRead &gt; 0 then&lt;br /&gt;        begin&lt;br /&gt;          FData := StrPas(Buffer);&lt;br /&gt;          Synchronize(CallDataAvailable);&lt;br /&gt;        end;&lt;br /&gt;      end&lt;br /&gt;      else&lt;br /&gt;        Result := False;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  Startup: STARTUPINFO;&lt;br /&gt;  SecurityDescriptor: SECURITY_DESCRIPTOR;&lt;br /&gt;  SecurityAttributes: SECURITY_ATTRIBUTES;&lt;br /&gt;begin&lt;br /&gt;  try&lt;br /&gt;    ZeroMemory(@Startup, SizeOf(STARTUPINFO));&lt;br /&gt;    Startup.cb := SizeOf(STARTUPINFO);&lt;br /&gt;    ZeroMemory(@SecurityDescriptor, SizeOf(SECURITY_DESCRIPTOR));&lt;br /&gt;    ZeroMemory(@SecurityAttributes, SizeOf(SECURITY_ATTRIBUTES));&lt;br /&gt;    InputRead := 0;&lt;br /&gt;    InputWrite := 0;&lt;br /&gt;    OutputRead := 0;&lt;br /&gt;    OutputWrite := 0;&lt;br /&gt;&lt;br /&gt;    if Win32Platform = VER_PLATFORM_WIN32_NT then&lt;br /&gt;    begin&lt;br /&gt;      InitializeSecurityDescriptor(@SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);&lt;br /&gt;      SetSecurityDescriptorDacl(@SecurityDescriptor, True, nil, False);&lt;br /&gt;      SecurityAttributes.lpSecurityDescriptor := @SecurityDescriptor;&lt;br /&gt;    end&lt;br /&gt;    else&lt;br /&gt;      SecurityAttributes.lpSecurityDescriptor := nil;&lt;br /&gt;    SecurityAttributes.nLength := SizeOf(SECURITY_ATTRIBUTES);&lt;br /&gt;    SecurityAttributes.bInheritHandle := True;&lt;br /&gt;    if not CreatePipe(OutputRead, OutputWrite, @SecurityAttributes, 0)&lt;br /&gt;    or not CreatePipe(InputRead, InputWrite, @SecurityAttributes, 0) then&lt;br /&gt;      raise EProcessError.Create('Error while opening pipes');&lt;br /&gt;&lt;br /&gt;    SetHandleInformation(OutputRead, HANDLE_FLAG_INHERIT, 0);&lt;br /&gt;    SetHandleInformation(InputWrite, HANDLE_FLAG_INHERIT, 0);&lt;br /&gt;&lt;br /&gt;    GetStartupInfo(Startup);&lt;br /&gt;    Startup.dwFlags := STARTF_USESHOWWINDOW OR STARTF_USESTDHANDLES;&lt;br /&gt;&lt;br /&gt;    Startup.hStdOutput := OutputWrite;&lt;br /&gt;    Startup.hStdError := OutputWrite;&lt;br /&gt;    Startup.hStdInput := InputRead;&lt;br /&gt;&lt;br /&gt;    FlushFileBuffers(OutputWrite);&lt;br /&gt;    FlushFileBuffers(OutputRead);&lt;br /&gt;    FlushFileBuffers(InputRead);&lt;br /&gt;    FlushFileBuffers(InputWrite);&lt;br /&gt;&lt;br /&gt;    Startup.wShowWindow := SW_HIDE;&lt;br /&gt;&lt;br /&gt;    if not CreateProcess(FPath, FCommandLine, nil, nil, True, CREATE_NEW_CONSOLE OR NORMAL_PRIORITY_CLASS, FEnvironment, FDirectory, Startup, FMainProcess) then&lt;br /&gt;      raise EProcessError.Create('Error while starting Process: ' + SysErrorMessage(GetLastError) + ':' + FPath + ':' + FCommandLine + ':' + FDirectory);&lt;br /&gt;    WaitForInputIdle(FMainProcess.hProcess, INITIALIZATION_TIMEOUT);&lt;br /&gt;    FStarted := True;&lt;br /&gt;    SetPriority(GetPriority);&lt;br /&gt;    Synchronize(CallProcessOpened);&lt;br /&gt;    &lt;br /&gt;    if not FWatching then&lt;br /&gt;      Exit;&lt;br /&gt;&lt;br /&gt;    repeat&lt;br /&gt;      if not Read then&lt;br /&gt;        Break;&lt;br /&gt;    until not IsProcessAlive or Terminated;&lt;br /&gt;    Read;&lt;br /&gt;&lt;br /&gt;    if not IsProcessAlive then&lt;br /&gt;      Synchronize(CallProcessTerminated);&lt;br /&gt;      &lt;br /&gt;  except&lt;br /&gt;    on E: Exception do&lt;br /&gt;    begin&lt;br /&gt;      FException := E;&lt;br /&gt;      Synchronize(CallException);&lt;br /&gt;    end;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.FreeResources;&lt;br /&gt;begin&lt;br /&gt;  KillProcess(FMainProcess.dwProcessId);&lt;br /&gt;&lt;br /&gt;  if OutputRead &lt;&gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    CloseHandle(OutputRead);&lt;br /&gt;    OutputRead := 0;&lt;br /&gt;  end;&lt;br /&gt;  if OutputWrite &lt;&gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    CloseHandle(OutputWrite);&lt;br /&gt;    OutputWrite := 0;&lt;br /&gt;  end;&lt;br /&gt;  if InputWrite &lt;&gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    CloseHandle(InputWrite);&lt;br /&gt;    InputWrite := 0;&lt;br /&gt;  end;&lt;br /&gt;  if InputRead &lt;&gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    CloseHandle(InputRead);&lt;br /&gt;    InputRead := 0;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{  TProcessLineThread }&lt;br /&gt;&lt;br /&gt;constructor  TProcessLineThread.Create(Path, CommandLine, Directory: string; Environment: TStrings);&lt;br /&gt;begin&lt;br /&gt;  inherited Create(Path, CommandLine, Directory, Environment);&lt;br /&gt;  OnDataAvailable := DataAvailable;&lt;br /&gt;  OnTerminate := Finished;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure  TProcessLineThread.DataAvailable(Sender: TObject);&lt;br /&gt;var&lt;br /&gt;  I, L: Integer;&lt;br /&gt;begin&lt;br /&gt;  I := 0;&lt;br /&gt;  L := Length(Data);&lt;br /&gt;  while I &lt; L do&lt;br /&gt;  begin&lt;br /&gt;    Inc(I);&lt;br /&gt;    if Data[I] in [#13, #10] then&lt;br /&gt;    begin&lt;br /&gt;      if (I &lt; L) and (Data[I+1] in [#13, #10]) then&lt;br /&gt;        Inc(I);&lt;br /&gt;      if Assigned(FOnNewLine) then&lt;br /&gt;        FOnNewLine(Self, FCurrentLine);&lt;br /&gt;      FCurrentLine := '';&lt;br /&gt;    end&lt;br /&gt;    else&lt;br /&gt;      FCurrentLine := FCurrentLine + Data[I];&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure  TProcessLineThread.Finished(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;  if (FCurrentLine &lt;&gt; '') and Assigned(FOnNewLine) then&lt;br /&gt;    FOnNewLine(Self, FCurrentLine);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Mon, 07 Jul 2008 07:25:12 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5729</guid>
      <author>jonasraoni (Jonas Raoni Soares Silva)</author>
    </item>
    <item>
      <title>gzip pipe</title>
      <link>http://snippets.dzone.com/posts/show/5644</link>
      <description>#! /usr/bin/python&lt;br /&gt;&lt;br /&gt;from gzip import GzipFile&lt;br /&gt;from StringIO import StringIO&lt;br /&gt;&lt;br /&gt;class GZipPipe(StringIO) :&lt;br /&gt;    """This class implements a compression pipe suitable for asynchronous &lt;br /&gt;    process.&lt;br /&gt;&lt;br /&gt;    Only one buffer of data is read/compressed at a time.&lt;br /&gt;    The process doesn't read the whole file at once : This improves performance&lt;br /&gt;    and prevent hight memory consumption for big files."""&lt;br /&gt;&lt;br /&gt;    # Size of the internal buffer&lt;br /&gt;    CHUNCK_SIZE = 1024 &lt;br /&gt;&lt;br /&gt;    def __init__(self, source = None, name = "data") :&lt;br /&gt;        """Constructor&lt;br /&gt;        &lt;br /&gt;        @param source   Source data to compress (as a stream/File/Buffer - anything with a read() method)&lt;br /&gt;        @param name     Name of the data within the zip file"""&lt;br /&gt;        &lt;br /&gt;        # Source file&lt;br /&gt;        self.source = source&lt;br /&gt;&lt;br /&gt;        # OEF reached for source ?&lt;br /&gt;        self.source_eof = False&lt;br /&gt;&lt;br /&gt;        # Buffer&lt;br /&gt;        self.buffer = ""&lt;br /&gt;&lt;br /&gt;        StringIO.__init__(self)&lt;br /&gt;&lt;br /&gt;        # Inherited constructor&lt;br /&gt;&lt;br /&gt;        # Init ZipFile that writes to us (the StringIO buffer)&lt;br /&gt;        self.zipfile = GzipFile(name, 'wb', 9, self)&lt;br /&gt;    &lt;br /&gt;    def write(self, data) :&lt;br /&gt;        """The write mzthod shouldn't be called from outside.&lt;br /&gt;        A GZipFile was created with this current object as a output buffer anbd it &lt;br /&gt;        fills it whenever we write to it (calling the read method of this object will do it for you)&lt;br /&gt;        """&lt;br /&gt;        &lt;br /&gt;        self.buffer += data&lt;br /&gt;&lt;br /&gt;    def read(self, size = -1) :&lt;br /&gt;        """Calling read() on a zip pipe will suck data from the source stream.&lt;br /&gt;&lt;br /&gt;        @param  size Maximum size to read - Read whole compressed file if not specified.&lt;br /&gt;        @return Compressed data"""&lt;br /&gt;&lt;br /&gt;        # Feed the zipped buffer by writing source data to the zip stream&lt;br /&gt;        while ((len(self.buffer) &lt; size) or (size == -1)) and not self.source_eof :&lt;br /&gt;           &lt;br /&gt;            # No source given in input&lt;br /&gt;            if self.source == None: break&lt;br /&gt;&lt;br /&gt;            # Get a chunk of source data&lt;br /&gt;            chunk = self.source.read(GZipPipe.CHUNCK_SIZE)&lt;br /&gt;            &lt;br /&gt;            # Feed the source zip file (that fills the compressed buffer)&lt;br /&gt;            self.zipfile.write(chunk)&lt;br /&gt;            &lt;br /&gt;            # End of source file ?&lt;br /&gt;            if (len(chunk) &lt; GZipPipe.CHUNCK_SIZE) :&lt;br /&gt;                self.source_eof = True&lt;br /&gt;                self.zipfile.flush()&lt;br /&gt;                self.zipfile.close()&lt;br /&gt;                break&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        # We have enough data in the buffer (or source file is EOF): Give it to the output&lt;br /&gt;        if size == 0:&lt;br /&gt;            result = ""&lt;br /&gt;        if size &gt;= 1 :&lt;br /&gt;            result = self.buffer[0:size]&lt;br /&gt;            self.buffer = self.buffer[size:]&lt;br /&gt;        else : # size &lt; 0 : All requested&lt;br /&gt;            result = self.buffer&lt;br /&gt;            self.buffer = ""&lt;br /&gt;&lt;br /&gt;        return result&lt;br /&gt;&lt;br /&gt;</description>
      <pubDate>Sun, 15 Jun 2008 08:50:59 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5644</guid>
      <author>cdvddt (Raphael Jolivet)</author>
    </item>
    <item>
      <title>Twitter bot weatherlisbon</title>
      <link>http://snippets.dzone.com/posts/show/4159</link>
      <description>This little bash script shows how to use curl, grep, tail, sed and perl one-liners in order to compose a bleeding-edge twitter bot.&lt;br /&gt;This one returns daily weather forecasts for Lisbon city based on the BBC weather forecast rss feed.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#! /bin/sh&lt;br /&gt;&lt;br /&gt;#Goto here&lt;br /&gt;here=/home/guillaume/Personal&lt;br /&gt;cd $here&lt;br /&gt;&lt;br /&gt;#BBC Lisbon weather id&lt;br /&gt;id=0048&lt;br /&gt;&lt;br /&gt;#BBC weather RSS feed address&lt;br /&gt;feed="http://feeds.bbc.co.uk/weather/feeds/rss/5day/world/${id}.xml"&lt;br /&gt;&lt;br /&gt;#City&lt;br /&gt;city=lisbon&lt;br /&gt;&lt;br /&gt;#temporary file&lt;br /&gt;file="weather${city}"&lt;br /&gt;&lt;br /&gt;#Weather twitter bot&lt;br /&gt;twitbot=weatherlisbon:*******&lt;br /&gt;&lt;br /&gt;#Timestamp the log file&lt;br /&gt;echo .&gt;&gt; $file.log&lt;br /&gt;date &gt;&gt; $file.log&lt;br /&gt;&lt;br /&gt;#Read the RSS feed and filter it&lt;br /&gt;curl $feed | grep 'title' | tail -n 1 | perl -wlne'm/title&gt;(.*)&lt;\/title/i &amp;&amp; print $1' | sed -e "s/&amp;#xB0;//g" &gt; $file.txt&lt;br /&gt;&lt;br /&gt;#Read the forecast into a weather variable&lt;br /&gt;read weather &lt; $file.txt&lt;br /&gt;&lt;br /&gt;#Twit the weather variable away&lt;br /&gt;curl --basic --user $twitbot --data status="$weather" http://twitter.com/statuses/update.xml &gt;&gt; $file.log&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Mon, 18 Jun 2007 21:37:40 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4159</guid>
      <author>griflet (guillaume riflet)</author>
    </item>
    <item>
      <title>Making md5sum.exe Work with Paths in Python</title>
      <link>http://snippets.dzone.com/posts/show/4139</link>
      <description>On Windows systems, md5sum.exe is a nice little program to generate MD5 sums. However, whoever created this application forgot to add the ability to recognize paths in the file given to md5sum.exe. For example, say you want to md5 a file called test.txt.&lt;br /&gt;&lt;br /&gt;C:\test&gt;dir&lt;br /&gt; Directory of C:\test&lt;br /&gt;&lt;br /&gt;06/13/2007  03:52 PM    &lt;DIR&gt;          .&lt;br /&gt;06/13/2007  03:52 PM    &lt;DIR&gt;          ..&lt;br /&gt;06/13/2007  03:52 PM                 0 test.txt&lt;br /&gt;               1 File(s)              0 bytes&lt;br /&gt;&lt;br /&gt;C:\test&gt;md5sum test.txt&lt;br /&gt;d41d8cd98f00b204e9800998ecf8427e *test.txt&lt;br /&gt;&lt;br /&gt;Groovy, cool...&lt;br /&gt;&lt;br /&gt;However, if you try the same thing from some other directory (where text.txt does not live) you get the following:&lt;br /&gt;&lt;br /&gt;C:\&gt;md5sum c:/test/test.txt&lt;br /&gt;md5sum: test.txt: No such file or directory&lt;br /&gt;&lt;br /&gt;Sucky, eh?&lt;br /&gt;You could always find a different program to do md5sum. Or, if you don't want to do this, you can spawn a pipe to "cmd", navigate to the correct directory, and then run md5sum.&lt;br /&gt;&lt;br /&gt;Here's the code in python to do just that.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# define your file name and path&lt;br /&gt;file_name = "afile.txt"&lt;br /&gt;file_path = "c:\\afolder"&lt;br /&gt;&lt;br /&gt;# setup the md5sum command (assuming md5sum.exe location is in PATH)&lt;br /&gt;md5_cmd = "md5sum \"" + file_path "\\" + file_name + "\"\n"&lt;br /&gt;&lt;br /&gt;# open the command shell&lt;br /&gt;fromchild, tochild = popen2.popen4("cmd")&lt;br /&gt;&lt;br /&gt;#push the directory change and md5sum commands to the shell &lt;br /&gt;tochild.write("c:\nchdir " + my_path + "\n" + md5_cmd + "exit\n")&lt;br /&gt;tochild.close()&lt;br /&gt;&lt;br /&gt;#get the output from the shell session&lt;br /&gt;out = fromchild.read()&lt;br /&gt;&lt;br /&gt;#split the output so that we may extract the md5sum&lt;br /&gt;output = string.split(out)&lt;br /&gt;&lt;br /&gt;#grab the md5sum  &lt;br /&gt;md5sum_local = ""&lt;br /&gt;for item in output:&lt;br /&gt;    matchmd5local = re.match("([0-9a-fA-F]{32})",item)&lt;br /&gt;    if matchmd5local:&lt;br /&gt;        md5sum_local = matchmd5local.groups()&lt;br /&gt;        md5sum_local = md5sum_local[0]&lt;br /&gt;&lt;br /&gt;if md5sum_local:&lt;br /&gt;    print_status("MD5: Local checksum = " + md5sum_local + "\n")&lt;br /&gt;else:&lt;br /&gt;    print_status("ERROR: could not obtain local md5sum for " + my_file + "\n")&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Wed, 13 Jun 2007 23:10:02 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4139</guid>
      <author>minitotoro (Natalie)</author>
    </item>
  </channel>
</rss>
