Seite 1 von 1

leerzeichen nach URL

Verfasst: Freitag 7. September 2018, 21:08
von brainstir
hallo,

ich füge einen text mit autokey ein.
Ich muss nun den text den ich einfügen möchte nach URLs durchsuchen und nach der URL ein Leerzeichen senden, dann den restlichen text (mit lerrezichen nach einer url, falls da noch mehr urls sind etc.)
aktuell bin Ich so weit:

Code: Alles auswählen

import re
import time
a_string = 'test of testing https://www.one.com with another test https://two.com part3 http://three.com last test'
urls = re.findall('https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+', a_string)
split_string = a_string.split(urls[0])
text = (f'{split_string[0]} {urls[0]} {split_string[1]}')

x=0
for url in urls:
    clipboard.fill_clipboard(f'{split_string[0]}')
    keyboard.send_keys("<ctrl>+v")
    time.sleep(0.5)
    clipboard.fill_clipboard(f'{urls[x]}')
    keyboard.send_keys("<ctrl>+v")
    time.sleep(0.5)
    keyboard.send_keys(" ")
    time.sleep(0.5)
    split_string = (f'{split_string[x+1]}').split(f'urls[x]')
    x=x+1
Als output bekomme Ich nun

Code: Alles auswählen

 test of testing https://www.one.com  with another test https://two.com part3 http://three.com last testhttps://two.com  
Aber

Code: Alles auswählen

with another test https://two.com part3 http://three.com last test
wird als ein string eingefügt...
Ich schätze Ich mache da irgendwas mit dem indexing falsch, kann mir jemand helfen?

Re: leerzeichen nach URL

Verfasst: Freitag 7. September 2018, 21:33
von Sirius3
Dafür nimmt man re.split:

Code: Alles auswählen

parts = re.split('(https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+)', a_string)
for part in parts:
    clipboard.fill_clipboard(part)
    keyboard.send_keys("<ctrl>+v")
    time.sleep(0.5)

Re: leerzeichen nach URL

Verfasst: Samstag 8. September 2018, 23:20
von brainstir
Damit bekomme Ich ein Space nach jedem Teil:

Code: Alles auswählen

test of testing 
SPACE
https://www.one.com
SPACE
 with another test 
SPACE
https://two.com
SPACE
 part3 
SPACE
http://three.com
SPACE
 last test
SPACE
Wie kann Ich die Leertaste nur nach den URLs senden?

Re: leerzeichen nach URL

Verfasst: Sonntag 9. September 2018, 10:39
von Sirius3
Indem Du nur jedes zweite Mal ein SPACE sendest?

Re: leerzeichen nach URL

Verfasst: Sonntag 9. September 2018, 11:50
von brainstir
Ok, also so funktioniert es:

Code: Alles auswählen

#!/usr/bin/python3
import time
import re
try:
    cp_altes_clipboard = clipboard.get_clipboard()
except Exception:
    pass


fragen = '''abc
test of testing https://www.one.com with another test https://two.com part3 http://three.com last test'''


parts = re.split('(https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+)', fragen)
for index, part in enumerate(parts):
    clipboard.fill_clipboard(part)
    keyboard.send_keys("<ctrl>+v")
    if (index % 2 != 0): #odd
        time.sleep(0.2)
        keyboard.send_keys(" ") #send space after second string (URL)
    time.sleep(0.3)

try:
    clipboard.fill_clipboard("%s" % cp_altes_clipboard)
except Exception:
    clipboard.fill_clipboard("")
Ich würde das ganze gerne in eine andere .py-datei packen und ich meiner eigentlichen dann nur noch den text angeben:

Code: Alles auswählen

import neue_datei.py
fragen = '''abc
test of testing https://www.one.com with another test https://two.com part3 http://three.com last test'''
Wie kann ich dem o.g. Script in neue_datei.py sagen, dass er den inhalt der fragen-variable benutzen soll?

Ich benutze das ganze in Autokey.

Ich glaube
keyboard.send_keys()
und
clipboard.fill_clipboard
sind Autokey-spezifisch.
Wie würde Ich das in python3 schreiben, weil wenn Ich die Datei in Autokey importiere, führt er die ja als Python3 und nicht mit den Autokey-bibliotheken aus, oder?

Re: leerzeichen nach URL

Verfasst: Sonntag 9. September 2018, 11:53
von Sirius3
Wenn man einen Index braucht, nimmt man enumerate:

Code: Alles auswählen

for index, part in enumerate(parts):
    print(part)
    #keyboard.send_keys("<ctrl>+v")
    if index % 2:
        print('SPACE')
    time.sleep(0.5)

Re: leerzeichen nach URL

Verfasst: Sonntag 9. September 2018, 12:26
von brainstir
Ja, habs gerade selbst gefunden :)

Wie kann Ich das ganze jetzt in eine neue datei.py packen
und in der eigentlichen datei dann nur noch
import neue datei.py
fragen ='''
Hier
ist
mein
Text'''
setzen?

Ich benutze das ganze in Autokey.

Ich glaube
keyboard.send_keys()
und
clipboard.fill_clipboard
sind Autokey-spezifisch.
Wie würde Ich das in python3 schreiben, weil wenn Ich die Datei in Autokey importiere, führt er die ja als Python3 und nicht mit den Autokey-bibliotheken aus, oder?

Re: leerzeichen nach URL

Verfasst: Sonntag 9. September 2018, 12:52
von __blackjack__
@brainstir: Du müsstest den Code in eine Funktion packen, die man dann importieren und mit `fragen` als Argument aufrufen kann.

Code: Alles auswählen

from neues_modul import die_funktion
FRAGEN = '''
Hier
ist
mein
Text'''

die_funktion(FRAGEN)
Statt `neues_modul` und `die_funktion` natürlich Namen die passender sind und dem Leser vermitteln was jeweiligen Objekte bedeuten.

Re: leerzeichen nach URL

Verfasst: Montag 10. September 2018, 16:15
von brainstir
@blackjack:

Also Ich habe jetzt folgendes in meiner .py, die ich importiere:

Code: Alles auswählen

import subprocess
import time
import sys
import os
import re
    def getClipboardData():
        p = subprocess.Popen(['xclip','-selection', 'clipboard', '-o'], stdout=subprocess.PIPE)
        retcode = p.wait()
        data = p.stdout.read()
        return data

    def setClipboardData(data):
        p = subprocess.Popen(['xclip','-selection','clipboard'], stdin=subprocess.PIPE)
        p.stdin.write(data)
        p.stdin.close()
        retcode = p.wait()

def einfuegen(fragen):
    try:
        cp_altes_clipboard = getClipboardData()
    except Exception:
        pass
    parts = re.split('(https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+)', fragen)
    for index, part in enumerate(parts):
        setClipboardData(part)
        keyboard.send_keys("<ctrl>+v")
        if (index % 2 != 0): #odd
            time.sleep(0.2)
            keyboard.send_keys(" ") #send space after second string (URL)
        time.sleep(0.3)
    try:
        setClipboardData("%s" % cp_altes_clipboard)
    except Exception:
        setClipboardData("")
Und wenn Ich das skript importiere und, dann wie von dir vorgeschlagen aufrufe, bekomme Ich diesen Fehler:

in einfuegen:
parts = re.split('(https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+)', fragen)
in split
return_compile(pattern, flags).split(string, maxsplit)
TypeError: cannot use a string pattern on a byte-like object

Ich schätze ich muss da jetzt noch irgendwo .encode() einfügen, aber wo genau?

Edit:
Wobei Ich das in dem eigentlichen skript eigentlich schon mache:

Code: Alles auswählen

#!/usr/bin/python3
from clipb import einfuegen

fragen = '''abc
test of testing https://www.one.com with another test https://two.com part3 http://three.com last test'''

einfuegen(fragen.encode())

Re: leerzeichen nach URL

Verfasst: Montag 10. September 2018, 17:38
von __blackjack__
@brainstir: Wenn `fragen` Bytes sind, dann muss auch der reguläre Ausdruck als Bytes angeben werden. Oder beides müssen Zeichenketten sein. Muss halt zusammen passen.

Re: leerzeichen nach URL

Verfasst: Montag 10. September 2018, 20:53
von brainstir
@blackjack

und wie mache Ich das?
Was ist denn davon Bytes und was ist String? Wo sehe Ich das?
Ich habe nicht viel Erfahrung mit Python.
Ich weiss nur, dass Ich so ein Problem vorher auch hatte und als Ich dann statt fragen fragen.encode() benutzt ha be, ging es.
Wo muss das da genau hin?

Re: leerzeichen nach URL

Verfasst: Montag 10. September 2018, 21:14
von __blackjack__
Das hier 'hallo' ist eine Zeichenkette. Also ursprünglich ist `fragen` eine Zeichenkette, bis Du sie dann mit `encode()` als Bytes kodierst. Der reguläre Ausdruck ist eine Zeichenkette. Ein literales Bytes-Objekt hat ein kleines b vor den Anführungszeichen, also beispielsweise b'hallo' ist ein Bytes-Objekt. Wo da jetzt was hin muss, kommt darauf an was Du machen willst. Normalerweise dekodiert man Bytes so früh wie möglich in Zeichenketten, und Zeichenketten so spät wie möglich in Bytes. Am besten lässt man das auch von anderen erledigen. `Popen()`-Objekten kann man beispielsweise ein `encoding`-Argument übergeben, und dann kann man Zeichenketten schreiben und lesen.

Re: leerzeichen nach URL

Verfasst: Dienstag 11. September 2018, 20:01
von brainstir
Also das Problem scheint hier zu liegen:

Code: Alles auswählen

def setClipboardData(data):
    p = subprocess.Popen(['xclip','-selection','clipboard'], stdin=subprocess.PIPE)
    p.stdin.write(data)
    p.stdin.close()
    retcode = p.wait()
speziell bei

Code: Alles auswählen

    p.stdin.write(data)
bekomme Ich
a bytes-like object is required, not 'str'


Wie mache Ich jetzt aus data ein byte-like objekt?
Ich habs mit
p.stdin.write(b'data')
und
def setClipboardData(b'data'):
probiert, aber es kommt immer noch die selbe fehlermeldung...

Wo ändere Ich das?

Re: leerzeichen nach URL

Verfasst: Dienstag 11. September 2018, 20:32
von __blackjack__
@brainstir: Du bekommst ziemlich sicher bei beiden Varianten *nicht* die selbe Fehlermeldung. Im ersten Fall bekommst Du gar keine Fehlermeldung, aber es macht nicht das was Du willst, und die zweite Variante ist kein gültiges Python, da fällt schon der Compiler drüber.

Also noch mal: `Popen` kann man auch eine Kodierung übergeben, dann ist `stdin` eine Textdatei und keine Binärdatei.

Re: leerzeichen nach URL

Verfasst: Mittwoch 12. September 2018, 22:22
von Sirius3
Sicherer ist es, die Clipboard-Daten als Bytes zu lassen.

Code: Alles auswählen

def get_clipboard_data():
    return subprocess.check_output(['xclip','-selection', 'clipboard', '-o'])

def set_clipboard_data(data):
    p = subprocess.Popen(['xclip','-selection','clipboard'], stdin=subprocess.PIPE)
    p.communicate(data)

def einfuegen(fragen):
    try:
        clipboard_data = get_clipboard_data()
    except subprocess.CalledProcessError:
        clipboard_data = ""
    parts = re.split('(https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+)', fragen)
    for index, part in enumerate(parts):
        set_clipboard_data(part.encode())
        keyboard.send_keys("<ctrl>+v")
        if index % 2: #odd
            # send space after second string (URL)
            time.sleep(0.2)
            keyboard.send_keys(" ") 
        time.sleep(0.3)
    set_clipboard_data(clipboard_data)