Seite 1 von 2

Script ausführen mit Pfad als Argument

Verfasst: Freitag 15. November 2019, 18:28
von vierpunktzwo
Hallo Erleuchtete!

Ich habe ein mehr oder weniger primitives Problem...

Ich versuche ein vorgegebenes Script unter Windows auszuführen und scheitere durchgehend.
Man muss dazu sagen, ich habe absolut nichts mit Coding zu tun, muss aber bis morgen 1700 Notizen aus der Google keep app nach evernote portieren.
Da Evernote die exportierten Google Notizen aber nicht ohne weiteres importieren kann, hat ein findiger User ein kleines python script geschrieben, das diese Inkompatibilität beheben soll. Dafür werden sämtliche exportierten Notizen geöffnet und an entsprechender Stelle in der HTML Datei gewisse Änderungen vorgenommen. Eigentlich nichts bewegendes. Aber ich bekomme es nicht einmal gestartet :lol:

Egal was ich mache, entweder bekomme ich invalid argument, syntax error oder path doesn't exist als Fehlermeldung.

Es handelt sich um folgendes Script:

https://gitlab.com/charlescanato/google ... converter/


Ich habe Python 3.8 installiert und unter CMD in win10 den Befehl laut README "keep-to-enex.original ordnername/*.html" eingegeben.

Was mach ich falsch?

Re: Script ausführen mit Pfad als Argument

Verfasst: Freitag 15. November 2019, 18:37
von __deets__
Genaue Kommandozeile, genaue und gesamte Fehlermeldung. Nicht irgendeine Umschreibung. Da kann man dann auch nur sagen “machst irgendwas falsch”.

Re: Script ausführen mit Pfad als Argument

Verfasst: Freitag 15. November 2019, 18:50
von __blackjack__
Ich vermute mal das mit dem "*.html" wird unter Windows CMD nicht gehen. Unix-Shells expandieren das * zu dem ganzen Dateinamen bevor das Programm aufgerufen wird, für Windows CMD ist das einfach nur ein Zeichen das so als Argument weitergegeben wird.

Bei 1700 Dateien könnte es aber auch unter Shells die * expandieren problematisch werden weil Befehlszeilen nicht beliebig lang werden können.

Inhaltlich wäre zu dem Programm zu sagen das da HTML zu einem XML umgebaut wird durch reguläre Ausdrücke und Zeichenkettenoperationen. Robust ist was anderes. Ich würde auf jeden Fall die Originale aufbewahren. 🙂

Re: Script ausführen mit Pfad als Argument

Verfasst: Freitag 15. November 2019, 20:07
von vierpunktzwo

Code: Alles auswählen

C:\keep>keep.py alt/*.html
Traceback (most recent call last):
  File "C:\keep\keep.py", line 135, in <module>
    mungefile(arg)
  File "C:\keep\keep.py", line 33, in mungefile
    fp = open(fn, 'r')
OSError: [Errno 22] Invalid argument: 'alt/*.html'
Das ist das Resultat.

Die Originale hab ich natürlich noch in der Google Notizen App. Arbeite hier nur mit den Exporten.

Wie löse ich denn die Problematik mit dem Sternchen unter Windows?

Re: Script ausführen mit Pfad als Argument

Verfasst: Freitag 15. November 2019, 21:03
von Fire Spike

Code: Alles auswählen

for i in pathlib.Path("dein_pfad").glob("*.html"):
    blabla()

Re: Script ausführen mit Pfad als Argument

Verfasst: Samstag 16. November 2019, 05:59
von vierpunktzwo
Du meinst, ich muss das Script ergänzen? Oo

Re: Script ausführen mit Pfad als Argument

Verfasst: Samstag 16. November 2019, 10:06
von Fire Spike
das pfad problem solltest du so beheben können:

Code: Alles auswählen

#!/usr/bin/env python3

import sys
import re
import parsedatetime as pdt
import time

cal = pdt.Calendar()

r1 = re.compile('<div class="listitem checked"><div class="bullet">&#9745;</div>.*?<div class="text">(.*?)</div></div>')
r2 = re.compile('<div class="listitem"><div class="bullet">&#9744;</div>.*?<div class="text">(.*?)</div></div>')
r3 = re.compile('<div class="labels"><span class="label">([^<]*)</span>')

def mungefile(fn):
    for path in pathlib.Path(fn).glob("*.html"):
        fp = open(path, 'r')
        fp.readline()
        fp.readline()
        title = fp.readline().strip()
        title = title.replace('<title>', '').replace('</title>', '')

        fp.readline()
        fp.readline()
        t = fp.readline()
        tags = ''
        if 'archived' in t:
            tags = '<tag>archived</tag>'
        fp.readline()
        date = fp.readline().strip().replace('</div>', '')
        dt, flat = cal.parse(date)
        iso = time.strftime('%Y%m%dT%H%M%SZ',
                            time.gmtime(time.mktime(dt)))

        extratitle = fp.readline()
        content = fp.readline().replace('<div class="content">', '')

        for line in fp:
            line = line.strip()
            if line == '</div></body></html>':
                break
            content += line + '\n'

        content = content.replace('<br>', '<br/>')
        content = content.replace('\n', '\0')

        while True:
            m = r1.search(content)
            if not m:
                break
            content = content[:m.start()] + '<en-todo checked="true"/>' + m.group(1) + '<br/>' + content[m.end():]

        while True:
            m = r2.search(content)
            if not m:
                break
            content = content[:m.start()] + '<en-todo checked="false"/>' + m.group(1) + '<br/>' + content[m.end():]

        m = r3.search(content)
        if m:
            content = content[:m.start()]
            tags = '<tag>' + m.group(1) + '</tag>'

        content = content.replace('\0', '\n')

        # remove final div close
        content = content.strip()
        if content.endswith('</div>'):
            content = content[:-6]

        fp.close()

        print ('''
      <note>
        <title>{title}</title>
        <content><![CDATA[<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">{content}</en-note>]]></content>
        <created>{iso}</created>
        <updated>{iso}</updated>
        {tags}
        <note-attributes>
          <latitude>0</latitude>
          <longitude>0</longitude>
          <source>google-keep</source>
          <reminder-order>0</reminder-order>
        </note-attributes>
      </note>
    '''.format(**locals()))

print ('''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export3.dtd">
<en-export export-date="20180502T065115Z" application="Evernote" version="Evernote Mac 6.10 (454269)">''')
for arg in sys.argv[1:]:
    mungefile(arg)
print ('''</en-export>''')
befehl :

Code: Alles auswählen

keep-to-enex.original ordnername

Re: Script ausführen mit Pfad als Argument

Verfasst: Samstag 16. November 2019, 10:53
von Sirius3
Wenn man schon möglichst wenig am Code ändern möchte, dann würde man die Monsterfunktion nicht anfassen und nur unten die Schleife anpassen:

Code: Alles auswählen

for arg in sys.argv[1:]:
    for path in Path().glob(arg):
        mungefile(path)

Re: Script ausführen mit Pfad als Argument

Verfasst: Samstag 16. November 2019, 13:38
von Fire Spike
noch ein bisschen verschönert

Code: Alles auswählen

#!/usr/bin/env python3

import sys
import re
import parsedatetime as pdt
import time

cal = pdt.Calendar()

r1 = re.compile('<div class="listitem checked"><div class="bullet">&#9745;</div>.*?<div class="text">(.*?)</div></div>')
r2 = re.compile('<div class="listitem"><div class="bullet">&#9744;</div>.*?<div class="text">(.*?)</div></div>')
r3 = re.compile('<div class="labels"><span class="label">([^<]*)</span>')

def mungefile(path):
    with open(path, 'r') as file
        file.readline()
        file.readline()
        title = file.readline().strip()
        title = title.replace('<title>', '').replace('</title>', '')

        file.readline()
        file.readline()
        t = file.readline()
        tags = ''
        if 'archived' in t:
            tags = '<tag>archived</tag>'
        file.readline()
        date = file.readline().strip().replace('</div>', '')
        dt, flat = cal.parse(date)
        iso = time.strftime('%Y%m%dT%H%M%SZ',
                            time.gmtime(time.mktime(dt)))

        extratitle = file.readline()
        content = file.readline().replace('<div class="content">', '')

        for line in file:
            line = line.strip()
            if line == '</div></body></html>':
                break
            content += line + '\n'

        content = content.replace('<br>', '<br/>')
        content = content.replace('\n', '\0')

        while True:
            m = r1.search(content)
            if not m:
                break
            content = content[:m.start()] + '<en-todo checked="true"/>' + m.group(1) + '<br/>' + content[m.end():]

        while True:
            m = r2.search(content)
            if not m:
                break
            content = content[:m.start()] + '<en-todo checked="false"/>' + m.group(1) + '<br/>' + content[m.end():]

        m = r3.search(content)
        if m:
            content = content[:m.start()]
            tags = '<tag>' + m.group(1) + '</tag>'

        content = content.replace('\0', '\n')

        # remove final div close
        content = content.strip()
        if content.endswith('</div>'):
            content = content[:-6]

    print('''
      <note>
        <title>{title}</title>
        <content><![CDATA[<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">{content}</en-note>]]></content>
        <created>{iso}</created>
        <updated>{iso}</updated>
        {tags}
        <note-attributes>
          <latitude>0</latitude>
          <longitude>0</longitude>
          <source>google-keep</source>
          <reminder-order>0</reminder-order>
        </note-attributes>
      </note>
    '''.format(**locals()))

print('''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export3.dtd">
<en-export export-date="20180502T065115Z" application="Evernote" version="Evernote Mac 6.10 (454269)">''')

for arg in sys.argv[1:]:
    for path in Path().glob(arg):
        mungefile(path)
        
print("</en-export>")

Re: Script ausführen mit Pfad als Argument

Verfasst: Sonntag 17. November 2019, 17:56
von vierpunktzwo
Danke Spike, allerdings zweifle ich langsam an einem positiven Ausgang :?

Nach deiner Anpassung erhalte ich folgendes:

Code: Alles auswählen

C:\keep>keep.py alt
  File "C:\keep\keep.py", line 15
    with open(path, 'r') as file
                               ^
SyntaxError: invalid syntax

C:\keep>
Zur Erläuterung wollte ich noch kurz erklären worum es geht...

Den Termin gestern konnte ich ja nun leider ohnehin nicht mehr halten. Daher erstmal ruhig angehen.

In unserem Unternehmen nutzen wir seit zwei Jahren Google Notizen als eine Art Karteisystem... Wir warten und überprüfen bei unseren Kunden Geräte. Im Anschluss daran müssen wir je Gerät 2 Protokolle erstellen. Eines, welches Messungen beinhaltet und ein weiteres das sich um den Zustand der Geräte dreht. In den Jahren bevor ich diesem Unternehmen beigetreten bin, wurde das Notieren der Mängel und Messergebnisse rudimentär mittels Handzetteln gelöst. Ich habe dann vor einigen Jahren begonnen, diese Geräte mittels Google Notizen zu erfassen. Je Gerät eine Notiz, die mindestens die Seriennummer, Messwerte und Angaben zum Zustand des Gerätes beinhaltet. Zusätzlich, falls verfügbar, wird ein Bild vom Typenschild angehängt. Denn Google Notizen erfasst die Bilder mit einer OCR Texterkennung und ermöglicht ein späteres Durchsuchen der Geräte nach den dort abgebildeten Angaben. Sehr praktisch... Die bei Google Notizen erstellbaren "Labels" nutzen wir zur Abgrenzung der einzelnen Kunden. Dadurch kommt auch ein wenig Struktur in die Sache.

Unsere Wartungen haben sich dahingehend im Ablauf verändert, dass ich nun die App öffne, an ein Gerät gehe, das gerade zugänglich ist (in Großküchen nicht unbedingt alle zu jederzeit gerade nicht in Nutzung) und die Seriennummer im Suchfeld von Google Notizen eingebe. Dann wird die Notiz von genau diesem Gerät aus dem Vorjahr angezeigt und ich kann meine Bemerkungen dazu machen und Messwerte eintragen.

Nach der Wartung können wir zeitgleich im Google Notizen Webinterface unsere Geräte aufrufen und die Erkenntisse zu Papier bringen.

Wir stießen nun aber an die Grenze von max 50 Labels die erstellt werden können, daher der Wechsel zu Evernote Premium. Allerdings wäre der Verlust der bereits erstellten Notizen natürlich ein herber solcher... Daher habe ich mich an Euch gewandt. Ich konnte zwar das Script im Web finden, aber bin scheinbar der Einzige, der es nicht gebacken bekommt :roll:

Re: Script ausführen mit Pfad als Argument

Verfasst: Sonntag 17. November 2019, 19:03
von __blackjack__
Da fehlt der Doppelpunkt am Ende der Zeile.

Re: Script ausführen mit Pfad als Argument

Verfasst: Sonntag 17. November 2019, 19:17
von Fire Spike
@vierpunktzwo
Ups! Rechtschreibfehler, Doppelpunkt fehlt :oops: :oops: :oops:

Re: Script ausführen mit Pfad als Argument

Verfasst: Sonntag 17. November 2019, 21:25
von vierpunktzwo
Ihr meint also

with open(path, 'r') as file

muss eigentlich

with open(path, 'r') as file:

heißen?


Dann bekomme ich



Code: Alles auswählen

C:\keep>keep.py alt
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export3.dtd">
<en-export export-date="20180502T065115Z" application="Evernote" version="Evernote Mac 6.10 (454269)">
Traceback (most recent call last):
  File "C:\keep\keep.py", line 90, in <module>
    for path in Path().glob(arg):
NameError: name 'Path' is not defined

Re: Script ausführen mit Pfad als Argument

Verfasst: Sonntag 17. November 2019, 21:32
von __deets__
Da fehlt ein “from pathlib import Path” zu Beginn des Skriptes.

Re: Script ausführen mit Pfad als Argument

Verfasst: Sonntag 17. November 2019, 21:53
von Fire Spike
Was kommt wenn man nicht testet? Lauter Fehler!☠

Re: Script ausführen mit Pfad als Argument

Verfasst: Sonntag 17. November 2019, 22:00
von vierpunktzwo

Code: Alles auswählen

C:\keep>keep.py alt
Traceback (most recent call last):
  File "C:\keep\keep.py", line 7, in <module>
    from pathlib import path
ImportError: cannot import name 'path' from 'pathlib' (C:\Users\vierpunktzwo\AppData\Local\Programs\Python\Python38-32\lib\pathlib.py)
Ich will Euch ja echt nicht nerven... :lol:

Re: Script ausführen mit Pfad als Argument

Verfasst: Sonntag 17. November 2019, 22:04
von __deets__
Du musst schon genau lesen und reproduzieren was ich geschrieben habe. Groß- und Kleinschreibung sind relevant in Python.

Re: Script ausführen mit Pfad als Argument

Verfasst: Sonntag 17. November 2019, 22:05
von vierpunktzwo
Ok, Path groß geschrieben... Mein Fehler. Aber dann bekomme ich nen Permission denied. :roll:

Code: Alles auswählen

C:\keep>keep.py alt
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export3.dtd">
<en-export export-date="20180502T065115Z" application="Evernote" version="Evernote Mac 6.10 (454269)">
Traceback (most recent call last):
  File "C:\keep\keep.py", line 92, in <module>
    mungefile(path)
  File "C:\keep\keep.py", line 16, in mungefile
    with open(path, 'r') as file :
PermissionError: [Errno 13] Permission denied: 'alt'

Re: Script ausführen mit Pfad als Argument

Verfasst: Sonntag 17. November 2019, 22:06
von Fire Spike
Hast du lesezugriff auf die datei?

Re: Script ausführen mit Pfad als Argument

Verfasst: Sonntag 17. November 2019, 22:08
von vierpunktzwo
Auf welche jetzt? Aber ich hab hier auf alles Zugriff auf der Festplatte