Einzelnen Beitrag anzeigen

GeMo

Registriert seit: 25. Jan 2006
80 Beiträge
 
Delphi 7 Professional
 
#1

Problem mit Indy und der Rapidshare-Api

  Alt 27. Dez 2010, 10:10
Hallo Leute!
Ich arbeite zu Testzwecken derzeit an einer Implementierung der Rapidshare.com-Api für Premiumdownloads.
Bisher klappt das auch alles ganz gut.

Man kopiert sich die Links in die Zwischenablage, anschliessend werden sie automatisch gefiltert und alle relevanten Informationen dazu per Indy.get() downgeloaded (Prüfung des Dateistatus auf dem Server).

Hier ist der Parser-Code:
Delphi-Quellcode:
procedure TMainForm.parseLinks(x : String);
var
  y : String;
  i, j : Integer;
  errorCount : Integer;
  origList : TStringList;
  newList : TList;
  tmp, url, httpAnswer : String;
  newLink : TRSLink;
  inList : Boolean;
begin
  // AUSLESEN DER LINKS
  origList := TStringList.Create;
  x := StringReplace(x, #13, ' ', [rfReplaceAll, rfIgnoreCase]);
  x := StringReplace(x, #10, '', [rfReplaceAll, rfIgnoreCase]);
  x := x + ' ';
  errorCount := 0;

  while(pos('rapidshare.com/files/', x) > 0) do
  begin
    x := copy(x, pos('rapidshare.com/files/', x), length(x));
    tmp := copy(x, 0, pos(' ', x)- 1);
    origList.add(tmp);
    x := copy(x, length(tmp) + 1, length(x));
  end;

  //origList.Delimiter := ' ';
  //origList.DelimitedText := x;
  newList := TList.Create;
  for i := 0 to origList.Count - 1 do
  begin
    x := origList.Strings[i];
    newLink := TRSLink.create;
    newLink.URL := x;
    newList.Add(newLink);
  end;

    ////////////////////////////////////////
    // LINKS BEARBEITEN
    ////////////////////////////////////////
    for i := 0 to newList.Count - 1 do
    begin
      Application.ProcessMessages;
      newLink := TRSLink(newList.Items[i]);
      x := newLink.URL;
      x := copy(x, pos('//', x) + 2, length(x));
      x := copy(x, pos('/', x) + 1, length(x));
      x := copy(x, pos('/', x) + 1, length(x));
      y := copy(x, pos('/', x) + 1, length(x));
      x := copy(x, 0, pos('/', x) - 1);
      newLink.FileID := x;
      newLink.FileName := y;

      ////////////////////////////////////////
      // RS.COM API - HOSTNAMEN ABRUFEN
      ////////////////////////////////////////
      Application.ProcessMessages;
      URL := API_LINK + 'sub=checkfiles';
      URL := URL + '&files=' + newLink.FileID;
      URL := URL + '&filenames=' + newLink.FileName;

      // Dateistatus abfragen...
      httpAnswer := '';
      httpAnswer := idHTTP.Get(URL);

      // ... und verarbeiten
      if(pos('ERROR:', httpAnswer) < 1) then
      begin
        // SIZE IN BYTES
        httpAnswer := copy(httpAnswer, length(newLink.FileID) + length(newLink.FileName) + 3, length(httpAnswer));
        newLink.SizeInBytes := StrToInt(copy(httpAnswer, 0, pos(',', httpAnswer) - 1));
        // SERVER-ID
        httpAnswer := copy(httpAnswer, pos(',', httpAnswer) + 1, length(httpAnswer));
        newLink.ServerID := copy(httpAnswer, 0, pos(',', httpAnswer) - 1);
        // STATUS
        httpAnswer := copy(httpAnswer, pos(',', httpAnswer) + 1, length(httpAnswer));
        newLink.Status := StrToInt(copy(httpAnswer, 0, pos(',', httpAnswer) - 1));
        // SHORT HOST
        httpAnswer := copy(httpAnswer, pos(',', httpAnswer) + 1, length(httpAnswer));
        newLink.ShortHost := copy(httpAnswer, 0, pos(',', httpAnswer) - 1);

        // STATUS AUSGABE
        case newLink.Status of
          0 : newLink.StatusStr := ARR_FileStatus[0];
          1 : newLink.StatusStr := ARR_FileStatus[1];
          3 : newLink.StatusStr := ARR_FileStatus[2];
          4 : newLink.StatusStr := ARR_FileStatus[3];
          5 : newLink.StatusStr := ARR_FileStatus[3];
          50..99 : newLink.StatusStr := ARR_FileStatus[1];
          100..200: newLink.StatusStr := ARR_FileStatus[1];
          else newLink.StatusStr := ARR_FileStatus[5];
        end;
        newLink.Percent := 0;
      end
      else
      begin
        inc(errorCount);
      end;
      L_Status.Caption := 'Status: getting Fileinfo... ' + IntToStr(i + 1) + ' / ' + IntToStr(newList.Count);
      L_Status.Caption := L_Status.Caption + ' - Errors: ' + IntToStr(errorCount);
    end;

    for i := 0 to newList.Count - 1 do
    begin
      newLink := TRSLink(newList.Items[i]);
      inList := false;
      for j := 0 to ARR_Links.Count - 1 do
      begin
        if(newLink.URL = TRSLink(ARR_Links.Items[j]).URL) then
        begin
          inList := true;
          break;
        end;
      end;
      if(inList = false) then
      begin
        ARR_Links.Add(TRSLink(newList.Items[i]));
      end;
    end;

    ////////////////////////////////////////
    // FREIGABE
    ////////////////////////////////////////
    newList.Free;
    origList.Free;
end;
Wie gesagt:
Diese Prozedur scheint richtig zu arbeiten. Allerdings nur solange, wie man sich die Links direkt irgendwoher kopiert.

Und jetzt zu meinem Problem:
Da nur ein Rauskopieren der Links ziemlich wenig ist für ein Programm, habe ich eine Möglichkeit eingebaut um RSDF-Container Dateien zu laden.

Um diese zu entschlüsseln schicke ich die RSDF-Datei per "Indy.Post()" an einen Server und verarbeite die Antwort des Servers.

POST-Methode:
Delphi-Quellcode:
procedure TMainform.DecryptRSDFFile();
var
  Stream : TIdMultiPartFormDataStream;
  httpAnswer, new : String;
begin
  Stream := TIdMultiPartFormDataStream.Create;
  try
    try
      idHTTP.Request.ContentType := 'multipart/form-data';
      Stream.AddFile('rsdffile', 'D:\test.rsdf', 'multipart/form-data');
      httpAnswer := idHTTP.Post('http://wirpo032.bplaced.net/rsdf/rsdf_decrypt.php', Stream);
      sleep(5);
    except
      ShowMessage('Error parsing RSDF-File!');
    end;
    httpAnswer := httpAnswer + #13;
    new := httpAnswer;
    new := copy(new, pos('<div id="links">', new) + length('<div id="links">'), length(new));
    new := copy(new, 0, pos('</div>', new) - 1);
    new := StringReplace(new, chr(9), '', [rfReplaceAll]);
    new := StringReplace(new, ' ', '', [rfReplaceAll, rfIgnoreCase]);
    new := StringReplace(new, '<br><br>', '<br>', [rfReplaceAll, rfIgnoreCase]);
    new := StringReplace(new, '<br>', ' ', [rfReplaceAll, rfIgnoreCase]);
    new := StringReplace(new, #13#10, ' ', [rfReplaceAll, rfIgnoreCase]);
    new := StringReplace(new, #13, ' ', [rfReplaceAll, rfIgnoreCase]);
    new := StringReplace(new, #10, ' ', [rfReplaceAll, rfIgnoreCase]);
    new := copy(new, 6, length(new));
    new := 'http' + new;
    parseLinks(new);
  finally
    Stream.Free;
  end;
end;
Das schicken der Datei klappt einwandfrei und die Links werden auch wirklich entschlüsselt in den String "httpAnswer" gespeichert.

Allerdings kommt meine "parseLinks()"-Routine nicht mit dem Verarbeiten der Post-Antwort klar.. Es scheint so, als ob Indy noch Extrazeichen in die Antwort einbaut und diese mir alles zerschiessen...

Konkret liegt das Problem irgendwo zwischen dem "Indy.Post()" und dem anschliessenden "Indy.Get()" in der Parse-Funktion..
Die Antwort der API in "parseLinks()" spuckt nämlich immer einen Errorstring aus, sobald ich die RSDF-Datei encrypte.
Die Links an sich sind jedoch stets korrekt (URL-Variable). Dies konnte ich rausfinden, indem ich sie einfach kopiert habe und im Browser geöffnet habe..

Ich habe jetzt schon bald 2 Tage damit verbracht die Routinen neu zu schreiben, hab bis jetzt allerdings keine Lösung gefunden..

Ich hoffe ihr könnt mir dabei helfen!

Geändert von GeMo (27. Dez 2010 um 10:13 Uhr)
  Mit Zitat antworten Zitat