PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Kleines Skript mir großer Wirkung



axeljaeger
07-08-2002, 13:23
Wenn man unter Windows Winzip -rar oder -ace installiert, bekommt man in sein Kontextmenu für Archivdateien zwei neue Einträge:

- Entpacke in dieses Verzeichnis
- Entpacke in Unterverzeichnis (bei einem Archiv "zeugs.zip" kommt der Inhalt in einen neuen Uuterordner "zeugs")

Es ist mir bisher nicht gelungen, diese Funktionalität mit Linux/KDE nachzubauen. Das liegt haupsächlich daran,
das, wenn man einen neuen Eintrag in den Dateizuordnungen unter tar.gz anlegt, mit dem Kommando "tar -zxf", Konqueror
tar -zxf nicht mit dem aktuellen Verzeichnis als Arbeitsverzeichnis, sondern mit dem Homedirectory als Workingdir startet.
Dann landen die Daten im Homedirectory, oder das Quellarchiv wird nicht gefunden. Das zweite war, das ich natürlich nicht
"tar", sondern "Entpacke tar-Archiv" in meinem Kontextmenü stehen haben wollte. Das wollte ich mit einer .desktop-Datei
lösen, ging aber nicht, weil Konqueor versucht, die .desktop-Datei direkt auszuführen. Auch das Icon, das ich eingestellt hatte,
wurde nicht angezeigt. Außerdem sollte im Kontextmenü von jeder Datei zwei Einträge stehen:

- Zu Tar-Archiv hinzufügen (GZip)
- Zu Tar-Archiv hinzufügen (BZip2)

Das hat auch nicht funktioniert.

Fazit:

Warscheinlich brauchen wir zwei Skripte:

addtoarchive -> Zerlegt den übergebenen, absoluten Dateinamen in Pfad und Dateinamen, und ruft tar auf, um das Archiv zu
packen und im richtigen Verzeichnis abzulegen.

extractarchive -> Zerlegt den übergebenen, absoluten Dateinamen in Pfad und Dateinamen, und ruft tar auf, um das Archiv zu
entpacken und den Inhalt im richtigen Verzeichnis abzulegen.

Vielleicht könnte man sogar mithilfe von KDialog eine Progressbar anzeigen. Leider scheint dieses Programm nicht in MDK 8.2
Download-Edition enthalten zu sein, ich konnte es jedenfalls nicht finden.

Vielleicht hat ja mal jemand Lust, sich diesem Problem anzunehmen.

lankin
07-08-2002, 13:58
hai axel,

ich habe zwar nicht die musse an gui's zu basteln,
wenn es auch mit einem script geht,
aber möglicherweise kann die das
weiterhelfen.

mit der tar option "-C <zielpfad>" kannst
du tar sagen, wohin es entpacken soll.

möglich ist auch ein:
(cd ${ZIEL}; tar xzf ${PFAd}/<datei>)

damit kann man zumindest schon mal einen
teil automatisieren.

gruss
lankin

axeljaeger
07-08-2002, 14:26
Ja, nur woher nehme ich das Ziel? Das müßte man wohl aus dem absoluten Pfad der Eingabedatei auslesen.

anda_skoa
07-08-2002, 15:31
Der Pfad der Datei sollte doch durch den %f Parameter an dein Kommado erhältlich sein.

Btw, es gibt ein Tutorial zu Servicemenüs unter KDE
http://developer.kde.org/documentation/tutorials/dot/servicemenus.html

Übrigens:
"Hier entpacken..." ist schon ein Eintrg im Kontextmenü, ich nehme an von Ark.
Schau mal im ServiceMenü .desktop file von ARK nach, wie das gemacht wurde.

Ciao,
_

lankin
07-08-2002, 15:35
moin axel,

wenn du einen absoluten-path hast,
kannst du mit der tar-option: "-P"
das prob erschlagen.

ansonsten bei power-arc finde ich
z.b. ganz witzig, das mehrere pfade zum
entpacken vorgeschlagen werden.
das könnte ich mir dann mit der "-C"
vorstellen.

z.b.
Extract here: -C $(pwd)
Extract to actual path: -C $(pwd)/i$(basename $0 .tgz}
Extract to: read PFAD NAME
-C ${PFAD}/${NAME}
etw in der art.

gruss
lankin

anda_skoa
07-08-2002, 16:48
Original geschrieben von axeljaeger
Vielleicht könnte man sogar mithilfe von KDialog eine Progressbar anzeigen. Leider scheint dieses Programm nicht in MDK 8.2
Download-Edition enthalten zu sein, ich konnte es jedenfalls nicht finden.


kdialog war bisher ein Utility eines externen Entwicklers http://www.david-guembel.de/kdialog.html und wurde erst vor ein paar Wochen in den CVS importiert.
Wird wahrscheinlich ab 3.1 in kdebase sein.

Ciao,
_

axeljaeger
07-08-2002, 17:02
Das Skript ist das eine Problem, die Integration in KDE ist das andere:

Konqueror sollte schon ein Icon für Entpacken in das Menü einbinden. Außerdem soll nicht der Name des Skriptes, sondern ein vernünftiger Text, wie z.B. "In neues Unterverzeichnis entpacken" im Menü stehen. Das muß auch irgendwie gehen, geht ja auch bei anderen Programmen.

Leider bin ich unfähig, die ganzen Tipps, dir hier gegeben würden, in Skripte zu packen. Vielleicht kann ja mal jdm. der Bash etwas besser beherrscht, die entsprechenden Skripte hier posten. Ich wundere mich nur, warum sowas nicht per default in KDE enthalten ist. der Aufwand ist doch eher gering denke ich, und sowas ist ja ab WinME in Windows für Zip-Archive fest eingebaut. Wahrscheinlich wäre es sogar günstiger, sowas direkt in den Konqueor einzubauen, weil ein Skript nicht gerade die Geschwindigkeit hat. Bis KDialog hochgefahren hat, ist das Archiv wahrscheinlich schon gepackt. Gibt es denn eine Option, um tar zu sagen, das es Progressinformationen ausgeben soll?

anda_skoa
07-08-2002, 18:28
Original geschrieben von axeljaeger
Konqueror sollte schon ein Icon für Entpacken in das Menü einbinden. Außerdem soll nicht der Name des Skriptes, sondern ein vernünftiger Text, wie z.B. "In neues Unterverzeichnis entpacken" im Menü stehen. Das muß auch irgendwie gehen, geht ja auch bei anderen Programmen.


Das wird alles in dem Tutorial beschrieben, dessen URL ich gepostet habe.



Ich wundere mich nur, warum sowas nicht per default in KDE enthalten ist. der Aufwand ist doch eher gering denke ich, und sowas ist ja ab WinME in Windows für Zip-Archive fest eingebaut.


Das "Hier extrahieren" ist ja bereits in ark's servicemenu enthalten.
Die Datei heißt bei mir arkservicemenu.desktop und ist hier unter Debian in /usr/share/apps/konqueror/servicemenus



Wahrscheinlich wäre es sogar günstiger, sowas direkt in den Konqueror einzubauen, weil ein Skript nicht gerade die Geschwindigkeit hat.

Die Service Menüs sind ja eine Funktionalität von Konqueror (darum stehen sie auch in apps/konqueror)
Die Service Menu Action macht dann das dafür vorgesehen Programm.

Ciao,
_

axeljaeger
07-08-2002, 18:43
Das heist, ich muß mich nicht mehr damit beschäftigen, weil diese Funktionalität schon in KDE 3 enthalten ist? Sorry, ich hab noch KDE 2.2.2, da gibt's Servicemenüs glaube ich noch nicht.

anda_skoa
08-08-2002, 20:28
Doch, geht auch schon in KDE2
Ich hab hier nämlich auch KDE2.2.2

ich hab mal so zum testen folgendes gemacht:

eine ServiceMenu .desktop Datei in
.kde/share/apps/konqueror/servicemenus
erstellt, mit folgendem Inhalt



[Desktop Entry]
ServiceTypes=application/x-tgz,application/x-tarz
Actions=ExtractDir

[Desktop Action ExtractDir]
Name=Extract in directory
Exec=extractdir %f


extractdir ist ein kleines script, dass ich in ein Verzeichnis aus $PATH kopiert habe (/usr/local/bin)

Es hat diesen Inhalt



#!/bin/bash
WORKDIR=$(dirname $1)
FILENAME=$(basename $1)
DIRNAME=$FILENAME.dir
cd $WORKDIR && mkdir $DIRNAME
cd $DIRNAME && tar xvzf $1


Wenn ich auf ein tgz rechtsklicke, erscheint mein "Extract in directory" Eintrag und wenn ich den wähle erzeugt er ein Verzeichnis mit dem Namen der Datei + .dir und extrahiert das Archiv dahinhein.

Ciao,
_

fork
08-08-2002, 23:58
Das sieht ganz brauchbar aus... ;-)

Dateien entpacken
Aber ich muss schon sagen unter Fenster ist dieses noch etwas anwenderfreundlicher:

Extract to DerDateiname
D. h. er zeigt das Verzeichnisnamen an, geht das irgendwie? Unter Fenster wird das glaub' ich mit einer geladenen .dll des Packpogramms gemacht, was für eine Verschwendung, ist ja fast so schlimm wie "hello world" in perl mit use strict/warnings & diagnostics zu kompilieren. :p (Es braucht auf meinem Athlon XP 1333 12 Sekunden zu kompilieren und ist 1,7 MB gross)

fork
09-08-2002, 02:06
Hier nochwas zum Packen:
/opt/kde2/share/apps/konqueror/servicetypes/packer.desktop

[Desktop Entry]
ServiceTypes=allfiles
Actions=Pack

[Desktop Action Pack]
Name=Packen...
Exec=xterm -e /usr/local/bin/pack %U
und das script /usr/local/bin/pack(ich weiss 5 Zeilen Shell hättens auch irgendwie getan):


zu 2)
#!/usr/bin/perl

use strict;
use warnings;
use diagnostics;

use File::Basename;
use Tk;

my $all_files;
my $execute = 0;
my $ArchivName = "NeuesArchiv.tgz";
my $force = 0;
my $error;

$all_files .= "$_ " for (@ARGV);

my $window = Tk::MainWindow->new( -title => "Dateien Packen" );
my $frame1 = $window
->Frame
->pack();
my $label = $frame1
->Label( -text => "Archivname:" )
->pack( -side => "left" );
my $entry = $frame1
->Entry( -textvariable => \$ArchivName )
->pack();
my $frame2 = $window
->Frame
->pack( -pady => 5 );
my $ok = $frame2
->Button( -text => "OK", -command => \&check )
->pack( -side => "left" );
my $cancel = $frame2
->Button( -text => "Abbrechen", -command => sub { exit } )
->pack();
my $status = $window
->Label()
->pack();
MainLoop;

sub check {
if ( -f $ArchivName && $force < 1 ) {
$status ->configure( -text => "Datei schon vorhanden!",
-foreground => "darkred");
$ok ->configure( -text => "Trotzdem!" );
$force++;
}
else {
$error = 0;
if (
system( "tar -cvzf " . dirname( $ARGV[0] ) . "/$ArchivName $all_files")
)
{
$status ->configure( -text => "Fehler: $!",
-foreground => "darkred");
$ok ->configure( -text => "Na und!" );
$cancel ->configure( -text => "ich hör lieber auf..." );
}
else {
$status ->configure( -text => "Alles OK",
-foreground => "darkgreen");
$cancel ->configure( -text => "Beenden" );
$ok ->configure( -text => "Nochmal ;-)" );
}
}
}

axeljaeger
09-08-2002, 09:07
Wird das auch mit KDE 2.2.2 funktionieren?

anda_skoa
09-08-2002, 09:40
@fork
Cooles Script, werde ich ausprobieren, sobald ich zuhause bin.
Allerdings sollte man den Parameter vielleicht besser auf %F ändern, %U ist eine Listen von URLs.
Kann dein Script URLs handhaben?

@axeljaeger
forks servicemenu befindert sich laut seiner Nachricht in /opt/kde2 :)

Außerdem macht ja das Perlscript die ganze Arbeit und Perl dürfte unabhängig von der jeweiligen KDE Version sein :D

Ciao,
_

fork
09-08-2002, 13:34
tobias@ax301:~> rpm -q kdebase
kdebase-2.2.1-33
tobias@ax301:~>


> Kann dein Script URLs handhaben?
Wuesste nicht das tar damit umgehen kann, aber beim testen scheint das kein Unterschied zu Dateinamen zu machen. Hab's reingeschrieben weil's in der Ark Vorlage auch drin war.

anda_skoa
09-08-2002, 13:47
Original geschrieben von fork
> Kann dein Script URLs handhaben?

Wuesste nicht das tar damit umgehen kann, aber beim testen scheint das kein Unterschied zu Dateinamen zu machen. Hab's reingeschrieben weil's in der Ark Vorlage auch drin war.

Hmm, wahrscheinlich ist bei file:// der übergeben Teil das selbe.
Bei echten URLs könnte es anders sein, hab da aber auch noch nicht experientiert.

Ciao,
_

axeljaeger
09-08-2002, 15:51
Ich hab sie ausprobiert, eure Scripts. Sie scheinen alle gut zu funktionieren. Ich sollte eigentlich zufrieden sein, hab ich doch jetzt, was ich wollte. Aber ich bin noch nicht ganz fertig:

Das wäre pack.desktop

[Desktop Action Pack]
Exec=/home/axel/bin/pack %U
Name=Packen...

[Desktop Entry]
Actions=Pack
Icon=/usr/share/apps/ark/icons/hicolor/22x22/actions/ark_addfile.png
ServiceTypes=allfiles

und das unpack.desktop:

[Desktop Action ExtractDir]
Exec=extractdir %f
Name=In Verzeichnis entpacken

[Desktop Entry]
Actions=ExtractDir
Icon=/usr/share/apps/ark/icons/hicolor/22x22/actions/ark_extract.png
ServiceTypes=application/x-tgz,application/x-tarz

Leider werden die Icons nicht angezeigt, das mag aber an KDE 2 liegen.
Ich musste das Verzeichnis

/home/axel/.kde/share/apps/konqueror/servicemenus

erst anlegen, und voila, bei dem nächsten Login war auch der Eintrag "Entpacken..." von Ark da.

Die UI vom Pack-Skript verwendet kein Qt, das ist mir aufgefallen. Qt wäre wahrscheinlich auch zu langsam. Diese UI dagegen ist sehr schnell, bin ich gar nicht so gewöhnt. Ich hab das xterm ausgebaut, weil ich nicht mehr Fenster haben wollte, als unbedingt nötig. Nur leider hat man dann auch keine Informationen mehr, wie lange das Packen wohl noch dauert. Ist es möglich, die Ausgaben, die normalerweise im XTerm angezeigt werden, in die UI zu integrieren? Ansonsten macht die UI den Anschein, als sei sie abgestürzt. Es findet auch kein Repaint statt. Wenn das nicht geht, konnte man vielleicht einfach ein Label machen "Packing...", das man weis, es dauert eben noch.

So eine UI wäre auch für das Unpack-Skript schön, das der Anwender weis, da tut sich irgendwas.

ABer ich freue mich erstmal, das mein Gedanken überhaupt so viel Feedback gefunden hat. Früher musste ich immer eine Konsole aufmachen, tar -zxf <tgzfile> schreiben, und dürfte die Konsole danach wieder zumachen. Das ist auf jeden Fall schon mal ein Schritt in die richtige Richtung. Hat jdm. Kontakt zum KDE-Team, das sie so etwas in KDE einbauen? Evtl. könnte Ark einen Kommandozeilenparameter kriegen, so ist das ja auch unter Windows gelöst. Da würde es dann eine QT-UI mit Progressbar geben.

Eine zweite Version des Pack-Skriptes für bzip2 wäre auch nicht schlecht, ich verwende unter der Konsole eigentlich nur bz2. Da müßte man einfach anstatt tar -czf einfach tar -cjf aufrufen.

anda_skoa
09-08-2002, 16:08
Original geschrieben von axeljaeger

Name=Packen...

Name=In Verzeichnis entpacken


Name= ist ansich in der Standardsprache (meist Englisch).
Name[de]= wäre für deutsch.

Ist für dich privat kein Unterschied, aber wenn einen ServiceMenu Eintrag mal weitergeben willst, ist es so einfacher das anzupassen, ohne vorhandenes zu löschen oder zu überschreiben.



So eine UI wäre auch für das Unpack-Skript schön, das der Anwender weis, da tut sich irgendwas.


Das Script war nur als Demonstration der ServiceMenu Sache gedacht.
Ich hab bischen experimentiert, um statt tar ark zu verwenden, aber leider ignoriert ark das aktuelle Verzeichnis und bietet als Ausgangsverzeichnis der Extraktion das Verzeichnis des tgz an.



ABer ich freue mich erstmal, das mein Gedanken überhaupt so viel Feedback gefunden hat. Früher musste ich immer eine Konsole aufmachen, tar -zxf <tgzfile> schreiben, und dürfte die Konsole danach wieder zumachen. Das ist auf jeden Fall schon mal ein Schritt in die richtige Richtung. Hat jdm. Kontakt zum KDE-Team, das sie so etwas in KDE einbauen? Evtl. könnte Ark einen Kommandozeilenparameter kriegen, so ist das ja auch unter Windows gelöst. Da würde es dann eine QT-UI mit Progressbar geben.


Ja, ein --extractto dir Parameter wäre nicht schlecht :)
Für solche Sachen ist es das beste, man geht auf http:://bugs.kde.org/ und macht einen Bugreport mit Severity "wishlist" für das jewielige Programm.

Ciao,
_

fork
09-08-2002, 17:23
> Qt wäre wahrscheinlich auch zu langsam. Diese UI dagegen ist sehr schnell
Qt finde ich angenehmer, und die paar microsekunden mehr kann ich warten. Aber "Tk" ist im Moment die beste Möglichkeit grafische Oberflächen darzustellen, bis ich mehr Wissen habe.

> --extractto
Meinst Du damit das ein Dialog aufgeht wohin das Archiv entpackt wird? Das sollte ja kein Problem sein einfach ein die Option an "tar -C" zu übergeben

> xterm ausgebaut
Das kleine Programm zeigt nicht immer eine vernünftige(überhaupt keine) Fehlermeldung an deswegen ist das drin geblieben.

> Ist es möglich, die Ausgaben, die normalerweise im XTerm angezeigt werden, in die UI zu
> integrieren?
Möglich ist alles.

> Status wenigstens durch Packing... anzeigen
Wenn ich Zeit und Lust habe mich intensiver mit "Tk"-Grundlagen zu beschäftigen dürfte ich das hinkriegen, leider wird mein Programm unterbrochen wenn ich einen Systemaufruf ausführe. Bin aber im Moment wo anders dran, ausserdem ist Sommer und es gibt Orte in Deutschland wo die Flüsse nicht aus dem Himmel fliessen. ;-)

> Früher musste ich immer eine Konsole aufmachen, tar -zxf <tgzfile> schreiben
weniger als 5 Sub-Konsolen in "konsole" sind bei mir sowieso nicht offen ;-)

> tar/bzip2 anstatt tar -czf einfach tar -cjf aufrufen
Das steht jedem frei zu ändern.

-----

Generell ist das aber mal ein besserer Ansatz, keine grossartige GUI sondern einfach nur Packen/Entpacken fertig. Vielleicht noch irgendwo eine Optionsschaltfläche...

Oder gleich Kaptain nehmen und den für tar nur richtig aufrufen, das hört sich interessant an.
-> http://kaptain.sourceforge.net

axeljaeger
09-08-2002, 17:32
Mir ist eingefallen, wie man eine Progressbar implementieren kann:
Es gibt eine Option für tar, -t, die den Inhalt der Datei anzeigt. Hat zwar bei nicht funktioniert, vielliecht hab ich es auch nur falsch bedient.
Man kan tar außerdem mit -v dazu bringen, die Dateien anzuzeigen die gerade entpackt werden.
Wenn man jetzt die Dateien zählt, die entpackt werden, diese Zahl mit 100 malnimmt und durch
die Anzahl aller Dateien teilt, hätte man die Progressbar.

currentcount * 100 / all

Ich würde das auch mal mit Qt und C++ versuchen, wenn das mit TkTCL nicht geht und ihr das
für sinnvoll haltet, ich weis nicht, wie es da mit der Performance aussieht.
Man könnte ja auch ein Label machen und mit "|" füllen, wenn es in TkTCL keine Progressbar
gibt.

axeljaeger
09-08-2002, 20:44
ich hab mal angefangen, eine QT-Version zu schreiben, hab dann aber aufgehört, weil mir das System abgeschmiert ist. Es sollte theoretissch funktionieren, es ist nur noch ein Segfault drin. GDB sagt, das irgendwo strlen von libc.so.6 aufgerufen wird. Vielleicht will ja mla jmd. den Quelltext als Basis nehmen und weitermachen.




#include <qprogressdialog.h>
#include <qapplication.h>
#include <qprocess.h>

#include <iostream>

class Untar : public QProgressDialog
{
Q_OBJECT
public:
Untar(QString filename);
~Untar(){};
public slots:
void cprocsst();
void procsst();
void untar();
protected:
int filecount;
int currentfile;
QString workingdir, singlefilename;
};

Untar::Untar(QString filename) : QProgressDialog()
{
filecount = 0;
currentfile = 0;

workingdir = filename.mid(0,filename.findRev("/"));
singlefilename = filename.mid(filename.findRev("/"));

connect(this, SIGNAL(cancelled()), qApp, SLOT(quit()));

QProcess* countproc = new QProcess(this);

countproc->addArgument("tar");
countproc->addArgument(((filename.endsWith(".bz2")) ? "-jt": "-zt"));
countproc->addArgument(filename);

connect(countproc, SIGNAL(readyReadStdout()), this, SLOT(cprocsst()));
connect(countproc, SIGNAL(processExited()), this, SLOT(untar()));

connect(countproc, SIGNAL(readyReadStderr()), qApp, SLOT(quit()));

if(! countproc->start())
qApp->quit();
}
void Untar::cprocsst()
{
filecount++;
qDebug("void Untar::cprocsst()");
}
void Untar::procsst()
{
setProgress(currentfile * 100 / filecount);
}
void Untar::untar()
{
qDebug("Untar started");

QProcess* proc = new QProcess(this);

proc->addArgument("tar");
proc->addArgument((singlefilename.endsWith(".bz2") ? "-jxf": "-zxf"));
proc->addArgument(singlefilename);
proc->setWorkingDirectory(workingdir);

connect(proc, SIGNAL(readyReadStdout()), this, SLOT(procsst()));
connect(proc, SIGNAL(processExited()), qApp, SLOT(quit()));

proc->start();
}

#include "untar.moc.cpp"

int main(int argc, char **argv)
{
if(argc != 2)
return(0);
QApplication app(argc, argv);
Untar t(app.argv()[1]);
t.resize(400,100);
app.setMainWidget(&t);
t.show();
return(app.exec());
}