Thread Wie Verzeichnisstruktur aus HTML-Daten erstellen (3 answers)
Opened by MarkusH at 2013-02-12 15:25

MarkusH
 2013-02-12 15:25
#165736 #165736
User since
2012-04-08
161 Artikel
BenutzerIn
[default_avatar]
Hallo, ich mal wieder.

Zur Vorgeschichte: Siemens hat für ihre PLM-Produkte das Anmelden am Downloadserver geändert, so dass mit einem FTP-Programm kein Einloggen mehr möglich ist. Das Runterladen über HTTP ist mühsam, zeitintensiv und manchmal klappt das ganze auch nicht.

Ich bin nun gestern auf die glorreiche Idee gekommen, mittels Perlscript die Daten zu holen und mit dem lokalen Verzeichnis zu synchronisieren.

Das Script soll folgende Aufgaben erfüllen:
1. Einloggen auf dem Server -- funktioniert bereits
2. Verzeichnisstruktur erstellen -- Thema von diesem Threads
3. Verzeichnisstruktur mit lokaler Verzeichnisstruktur vergleichen -- offen
4. fehlende Dateien in lokalen Verzeichnissen runterladen -- offen

Das Hauptprogramm:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/perl -w
use strict;

use Data::Dumper;
use SPLMget;

my $loginData = {
                gtacUsername => '',
                gtacPassword => '',
                gtacURL => 'http://ftp.ugs.com',
                sgtacURL => 'https://ftp.ugs.com',
                cookie => ''
                };

my @location = [];

my $plm = SPLMget->new;

if ($plm->login($loginData)) {
    $location[0] = 'tecnomatix/';
    my $url = join('/', $loginData->{gtacURL}, $location[0]);
    my $data = $plm->readFilesAndDirs($url);
}


Und das Modul:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package SPLMget;
use strict;
use warnings;
use Data::Dumper;

use LWP::UserAgent;


my $ua = LWP::UserAgent->new();
$ua->agent('Perl LWP-UserAgent');

sub login {
    my $class = shift;
    my $logindata = shift;
    
    my $response = sendGETrequest($class, $logindata->{gtacURL});    
    return 0 if (!$response->is_error);
    
    my $postData = 'credential_0=' . "$logindata->{gtacUsername}" .'&credential_1=' . "$logindata->{gtacPassword}" . '&destination=%2F&protocol=http';
    $response = sendPOSTrequest($class, $logindata->{sgtacURL}, $postData);
    return 0 if (!$response->is_redirect);     
    $class->{COOKIE} = $response->header('Set-Cookie');

    $response = sendGETrequest($class, $logindata->{gtacURL});    
    return 1;
}
sub readFilesAndDirs {
    my $class = shift;
    my $loc = shift;
    
    my $items = [];
    
    my $response = sendGETrequest($class, $loc);    
    return 0 if (!$response->is_success);
    
    my $content = $response->content;
    
    my ($h,$b) = split('<a name="top"></a>', $content);
    my ($table, $c) = split('<a href="#top">', $b);
    my @rows = $table =~ /\<tr\>(.+?)\<\/tr\>/gs;
    
    foreach my $row (@rows) {
        $row =~ s/\n//g;
        next if ($row !~ /\<td/);
        my ($dummy, $path, $type, $date, $link, $linkDesc) = undef;
        ($dummy, $path, $type, $date) = $row =~ /\<td(?:.*?)\>(.*?)\<\/td\>/g;
        if (defined $path) {
            next if ($path =~ /\.\./);
            ($link, $linkDesc) = $path =~ /^\<a href\=\"(http(?:.+?))\"\>(\w+)\/\<\/a\>$/;
            if (defined $link) {
                if ($type eq 'Directory') {
                    $type = 1;
                }
                else {
                    $type = 0;
                }
                my $item = {
                    DATE => $date,
                    isDIR => $type,
                    LINK => $link,
                    DESCRIPTION => $linkDesc
                };
                push $items, $item;
            }            
        }
    }
    print Dumper $items;
    return $items
}

sub sendGETrequest {
    my $class = shift;
    my $url = shift;
    
    my $getRequest = HTTP::Request->new(GET => $url);
    $getRequest->push_header('Accept-Encoding' => 'gzip, deflate');
    $getRequest->push_header('Connection' => 'keep-alive');
    $getRequest->push_header('Accept' => 'image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*');
    $getRequest->push_header('Cookie' => $class->{COOKIE}) unless ($class->{COOKIE} eq '');

    my $response = $ua->request($getRequest);
    return $response;
}
sub sendPOSTrequest {
    my $class = shift;
    my $url = shift;
    my $postData = shift;

    my $postRequest = HTTP::Request->new(POST => $url);
    $postRequest->content_type('application/x-www-form-urlencoded');
    $postRequest->push_header('Accept-Encoding' => 'gzip, deflate');
    $postRequest->push_header('Connection' => 'keep-alive');
    $postRequest->push_header('Accept' => 'image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*');
    $postRequest->content($postData);

    my $response = $ua->request($postRequest);
    return $response;
}

sub new {
    my $class = shift;
    my $self = bless {}, $class;
    
    $self->{COOKIE} = '';
 
    return $self;
}


1;


Damit erhalte ich mit Dumper folgende Struktur (gekürzt):
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$VAR1 = [
{
'LINK' => 'http://ftp.ugs.com/tecnomatix/CAD_Translators/',
'isDIR' => 1,
'DATE' => '2009-07-15 12:07:23',
'DESCRIPTION' => 'CAD_Translators'
},
{
'LINK' => 'http://ftp.ugs.com/tecnomatix/Machining_Line_Planner/',
'isDIR' => 1,
'DATE' => '2008-08-18 06:44:54',
'DESCRIPTION' => 'Machining_Line_Planner'
},
...
];

Die zugehörige HTML-Seite ist als Bild beigefügt.

In meiner Vorstellung soll der komplette Verzeichnisbaum folgendes aussehen haben (gekürzt):
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$VAR1 = [
{
'LINK' => 'http://ftp.ugs.com/tecnomatix/CAD_Translators/',
'isDIR' => 1,
'DATE' => '2009-07-15 12:07:23',
'DESCRIPTION' => 'CAD_Translators',
'FOLDER' => [
{
'LINK' => linkZuUnterverzeichnis,
'isDIR' => 1,
'DATE' => Zeitstempel,
'DESCRIPTION' => Beschreibung,
'FOLDER' => [Inhalt Unterverzeichnis]
},
{
'LINK' => linkZuDatei1,
'isDIR' => 0,
'DATE' => Zeitstempel,
'DESCRIPTION' => Beschreibung,
},...
]
},
];


Die Verzeichnisse haben alle das gleiche Format, so dass ich fie Funktion readFilesAndDirs wieder verwenden könnte. Wie muß ich die Rekursion programmieren?. Und ich hab auch keinen Schimmer, wie ich die Daten dann zusammenbauen muß. Gibt es vielleicht hierzu schon ein fertiges Modul?
Sollte ich für Verzeichnisse eine eigene Klasse programmieren und die dann immer aufrufen, wenn isDir=1 ist?

Bitte um Unterstützung!

Editiert von MarkusH: Formatierungstags aus codeblock 2 entfernt
Anhänge
image/png
771 x 610
FTP.png

Last edited: 2013-02-13 07:41:15 +0100 (CET)
$q =~ /(bb|[^b]{2})/

View full thread Wie Verzeichnisstruktur aus HTML-Daten erstellen