Dies ist eine mobil optimierte Seite, die schnell lädt. Wenn Sie die Seite ohne Optimierung laden möchten, dann klicken Sie auf diesen Text.

NO-IP Account-Renew Script 1.0

    Nobody is reading this thread right now.
Hab jetzt das Skript umgestellt, damit es den ConfigParser verwendet.
Die Konfiguration is nun wie in dem Beispiel:
Code:
# Konfiguration für NOIP-Account-Renew
#
# Kommentare nur am Zeilenanfang!
# Werte ohne Anführungszeichen!

# No-IP-Daten
[NOIP]
USERNAME = Benutzername
PASSWORD = PA55W0RT

# eMail-Daten
[MAIL]
FROMADRESS =
TOADRESS =
SMTPSERVER =
SMTPPORT =
SMTPPASS =

Außerdem kann man dem Skript nun eine Konfiguraionsdate übergeben. Beispiel:
NOIP-Account-Renew Myini.ini

Im Skript eingetragene Daten werden in dem Fall überschieben

Das Skript: 16.05.2021 - Login bei noip wurde geändert und das Skript funktioniert so nicht mehr! Alternative siehe Signatur
Python:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
### *|--------------------------------|* ###
### *| NO-IP Account-Renew Script 1.0 |* ###
### *|   (c) by DarkStarXxX @ DEB     |* ###
### *|--------------------------------|* ###
# Modifiziert von MegaV0lt @ DEB
# - Benötigt Python 3
# - Umstellung auf 'mechanicalsoup.StatefulBrowser()'
# - Prüfung, ob Konfig-Datei existiert
# - Umstellung auf *.ini konfiguration
# - Konfiguration (*.ini) kann als Parameter übergeben werden
# Modifiziert von SLASH @ DEB
# - Skript nutzt nun python3 direkt (#!/usr/bin/env python3)
# - Update für eMail-imports
# Modifiziert von bl0w @DEB
VERSION=210304  # JJMMDD

# Wichtiger Hinweis: Externe Konfiguration
# Die Login-Daten für No-IP und eMail können aus einer externen Datei, welche in
# der Variable "CONFIG_FILE" definiert werden muss gelesen werden.
# Bitte dort die Daten eintragen
CONFIG_FILE = 'NOIP_Account_Renew.ini'  # Im gleichen Verzeichnis wie das Skript!
#CONFIG_FILE = ''  # Kann abgeschaltet werden, in dem man CONFIG_FILE = '' setzt.
# Die Konfiguration kann dem Skript als Parameter übergeben werden:
# NOIP-Account-Renew MyIni.ini

# In dem Fall die Variablen hier ausfüllen!
USERNAME = ''    # No-IP Benutzername
PASSWORD = ''    # No-IP Passwort
FROMADRESS = ''  # eMail-Sender
TOADRESS = ''    # eMail-Empfänger
SMTPSERVER = ''  # SMTP-Serveradresse ("" zum deaktivieren)
SMTPPORT = ''    # SMTP-Port (Z. B. 25)
SMTPPASS = ''    # Server verlangt Autentification ("" zum deaktivieren)

# Vorgaben
LOG_FILE = ''  # Kein Log, wenn nächste Zeile auskommentiert ist
#LOG_FILE = '/var/log/NOIP_renew.log'  # Dateiname wird auch für die eMail verwendet
MAIL_SUBJECT = 'NO-IP Account Updater'  # Betreff der Status eMail
MAIL_BODY = 'NO-IP Account Updater Service updated your NO-IP Account for another 30 days.\nPlease check the attached Logfile\n\n'  # Text in der eMail
HOST_URL = 'https://www.noip.com/members/dns/'
RESULT_STR = []

import platform
import importlib
import mechanicalsoup
import time
import ssl
import re
if hasattr(ssl, '_create_unverified_context'):
  ssl._create_default_https_context = ssl._create_unverified_context

# Funktion: update_host() - Für jeden Host "Modify" klicken
def update_host(str_host, browser):
  global RESULT_STR
  host_id = after(str_host, '=')             # Alle Zeichen nach dem ?
  if LOG_FILE:
    ts = time.strftime("%d.%m.%Y %H:%M:%S")  # Zeitstempel für das Log (19.10.2016 12:51:30)
    f1 = open(LOG_FILE, 'a+')

  browser.select_form(nr=00) ; browser.submit_selected()
  response = browser.get_current_page()
  if response.find('Update will be applied') == 'None' :  # Prüfen, ob es geklappt hat
    if LOG_FILE: print(f'{ts}: Update für Host-ID: {host_id} [FEHLER]', file=f1)
    print(f'Update für Host-ID: {host_id} [FEHLER]')
    RESULT_STR.append(host_id + ' [FEHLER]')
  else:
    if LOG_FILE: print(f'{ts}: Update für Host-ID: {host_id} [OK]', file=f1)  # Ausgabe in das Log
    print(f'Update für Host-ID: {host_id} [OK]')                 # Ausgabe auf der Konsole (und cron)
    RESULT_STR.append(host_id + ' [OK]')     # Für die eMail
  return

# Funktion: after() - Liefert Zeichenkette nach Zeichen a
def after(value, a):
  pos_a = value.rfind(a)           # Position des gesuchten Zeichens
  if pos_a == -1: return value     # Nicht gefunden: Ganzer Wert zurück!
  adjusted_pos_a = pos_a + len(a)  # Alles nach dem gefundenen Zeichen
  if adjusted_pos_a >= len(value): return ''
  return value[adjusted_pos_a:]

# Browser Optionen
browser = mechanicalsoup.StatefulBrowser(
  soup_config={'features': 'lxml'},  # Use the lxml HTML parser
  raise_on_404=True,
  user_agent='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.2228.0 Safari/537.36',
)

### Start
print(f'NO-IP Account-Renew Script #{VERSION} (Python: {platform.python_version()})')

# Wenn eine  *.ini als Parameter übergeben wurde, diese verwenden
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('filename', nargs='?', action='store')
args = parser.parse_args()
if args.filename is not None: CONFIG_FILE = args.filename

if CONFIG_FILE:
  from pathlib import Path
  my_conf = Path(CONFIG_FILE)
  if my_conf.is_file():  # Datei vorhanden?
    print('Lade Konfiguration aus:', my_conf)
    import configparser
    config = configparser.ConfigParser()
    config.read(my_conf)  # *.ini
    USERNAME = config['NOIP']['USERNAME'] ; PASSWORD = config['NOIP']['PASSWORD']
    FROMADRESS = config['MAIL']['FROMADRESS'] ; TOADRESS = config['MAIL']['TOADRESS']
    SMTPSERVER = config['MAIL']['SMTPSERVER'] ; SMTPPORT = config['MAIL']['SMTPPORT']
    SMTPPASS = config['MAIL']['SMTPPASS']
  else: print(f'FEHLER: Konfiguration {my_conf} nicht gefunden!') ; quit()

# Prüfen, ob USERNAME und PASSWORT konfiguriert sind
if not USERNAME: print('FEHLER: USERNAME ist nicht konfiguriert!') ; quit()
if not PASSWORD: print('FEHLER: PASSWORD ist nicht konfiguriert!') ; quit()

# Seite öffnen
print('Log-In… ', end='')
browser.open(HOST_URL)

# Login
browser.select_form()
browser['username'] = USERNAME
browser['password'] = PASSWORD
browser.submit_selected()

# Login OK?
response = browser.get_current_page()
if response.find('Dashboard') == 'None': print('FEHLER!') ; quit()
else: print('OK!')

# Links in Array speichern
mylink = []  # Leeres Array
for link in browser.links():
  if link.text == 'Modify': mylink += [link]

# Anzeigen wie viele Links gefunden wurden
number_of_hosts = len(mylink)
print(f'Gefundene Hosts: {number_of_hosts}. Starte Update…')

# Links klicken und Updaten
for link in mylink:
  target = link.attrs['href']
  browser.open_relative(target)  # Zur Seeite gehen
  update_host(target, browser)   # Host updaten


####### SMTP Section ############
if not SMTPSERVER: quit()  # Nur wenn SMTPSERVER gesetzt ist

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders

msg = MIMEMultipart()

msg['From'] = FROMADRESS ; msg['To'] = TOADRESS
msg['Subject'] = MAIL_SUBJECT

body = MAIL_BODY
for var in RESULT_STR:
  body = str(body) + str(var) + '\n'

msg.attach(MIMEText(body, 'plain'))

if LOG_FILE:
  filename = after(LOG_FILE, '/')  # Dateiname ohne Pfad
  attachment = open(LOG_FILE, 'rb')
  part = MIMEBase('application', 'octet-stream')
  part.set_payload((attachment).read())
  encoders.encode_base64(part)
  part.add_header('Content-Disposition', 'attachment; filename= %s' % filename)
  msg.attach(part)

# Example: Server Address and TCP Port - Exmaple: '192.168.1.1' , 25
server = smtplib.SMTP(SMTPSERVER, SMTPPORT)
server.starttls()

# Server verlangt Autentification (Nur wenn SMTPPASS gesetzt ist)
if SMTPPASS: server.login(FROMADRESS, SMTPPASS)

text = msg.as_string()
server.sendmail(FROMADRESS, TOADRESS, text)
server.quit()

Im Skript gibt man nun die Konfig normal mit Dateiendung (*.ini) an.

Code:
[/usr/local/sbin] # python ./NOIP-Account-Renew
NO-IP Account-Renew Script #210302 (Python: 3.7.3)
Lade Konfiguration aus: NOIP_Account_Renew.ini
Log-In… OK!
Gefundene Hosts: 3. Starte Update…
host_id=***90 [OK]
host_id=***97 [OK]
host_id=***07 [OK]
 
Zuletzt bearbeitet:
Wow, lieben Dank!
Das funktioniert direkt und mit Ausgabe wie gewünscht
Danke Dir
 
Hallo @ll,
bitte nicht hauen .... aber könnte mir jemand nochmal schreiben, welche Datei wo reingesetzt werden muss?
Vielen Dank im Voraus!
 
Hallo
Bin ich der einzige der folgende Fehlermeldungen bekommt ?
Ich rufe das Script mit 'python3 renew.py' auf (auf dem System ist python2.7 auch noch installiert)
Das noip.com update wird korrekt ausgeführt, nur beim versenden der e-Mail kommt eine Fehlermeldung beim laden der e-Mail Module
Traceback (most recent call last):
File "./renew.py", line 139, in <module>
from email.MIMEMultipart import MIMEMultipart
ModuleNotFoundError: No module named 'email.MIMEMultipart'


Wenn man in den Zeilen 138-142 die Zeilen folgendermassen abändert:
Vorher:
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email import encoders

Nachher:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders


dann funktioniert auch das Mail versenden.
Oder liegt das daran, daß ich hier verschiedene Python Versionen (2 & 3) installiert habe ?

Btw: Habe ich das richtig verstanden daß das nun ein Python3 Script ist , weil mechanicalsoup nur unter python3 läuft ?
Wenn ja, warum kann man nicht in Zeile 1 aus: #!/usr/bin/env python dann #!/usr/bin/env python3 machen , oder funktioniert das dann nicht mehr, wenn auf einem System nur python3 installiert ist ?
 
Zuletzt bearbeitet:
Ich verwende den Mail-Teil nicht. Ich baue den neuen Code mal ein.
Oben aktualisiert ;-)
 
Zuletzt bearbeitet:
Super vielen Dank.....
Also. die Gross/Kleinschreibung bei den Modulen hat dann bei mir mit python3 funktioniert, vorher nicht.
Bei der Änderung in Zeile 1 (#!/usr/bin/env python oder #!/usr/bin/env python3)
Da beim RaspberryPi mit Raspbian automatisch python2 mit installiert wird, wird das script entweder mit dem Befehl: python3 ./script.py aufgerufen
wenn man es nur mit ./script.py aufruft, wird automatisch das default python2 genutzt was dann eben nicht funktioniert.
Wenn man in die 1. Zeile statt #!/usr/bin/env python dann #!/usr/bin/env python3 angibt, weiss das System welches Python genutzt werdne soll und der aufruf ./script.py funktioniert korrekt

so und jetzt hoffe ich mal, das ich hier nicht kompletten nonsense geschrieben habe, da ich mich mir python nicht so gut auskenne
....und bin ich wirklich der einzige, der das Mail Modul nutzt ? Das macht doch alles so einfach.
In die crontab: 06 00 1,15 * * /root/Scripts/no-ip_updater2.py > /dev/null 2>&1
dann wird automatisch 2 mal im Monat der Account renewed und man bekommt die Bestätigung per Mai ob es geklappt hat.....
 
Zuletzt bearbeitet von einem Moderator:
Ich nutze die Mail-Funktion seit Beginn

aber weil das Script seither ohne Probleme läuft, war ich da auch nicht mehr dran
 
@MegaV0lt: Bei mir kommt die Mail direkt von cron.
Naja, aber in der Mail steht ja dann auch nur, daß der Cron den Job gestartet hat. Das Resultat ob das Updaten okay war, ist dann aber nicht in der Mail, oder ?

@Smiley007: aber weil das Script seither ohne Probleme läuft, war ich da auch nicht mehr dran
Stimmt, als ich aber meinen Raspi neu installiert hatte, musste ich ziemliche Glimmzüge machen um mechanize noch installiert zu bekommen. Die alte Version des Scripts von vor 2 Jahren funktioniert bei mir auch noch......aber hin und wieder mal was neues ausprobieren
....aber prima, wenn das Teil weiter Entwickelt wird....ich nutze es um hier 12 Domains up zu daten .......
 
Die Mail von Cron enthält alles, was das Skript ausgibt.
Du musst Regestriert sein, um das angehängte Bild zusehen.

Wichtig ist, dass cron Mails senden kann und dass im cronjob kein >/dev/null steht
 

Anhänge

Du musst angemeldet sein, um die Anhangsliste zu sehen.
Ahh alles klar, macht Sinn.......mein postfix ist disabled ......cron kann keine Mails senden.
okay, der einzige Vorteil bei dem Build-In Mailer ist dann die Tatsache, daß auch bei manuellem Aufruf des Scripts eine Mail gesendet wird.
 
Ich bekomme folgende Fehlermeldung wenn ich das schreiben des Log nach /var/log/Dateiname aktiviere..

# Vorgaben
LOG_FILE = '' # Kein Log, wenn nächste Zeile auskommentiert ist
LOG_FILE = '/var/log/NOIP_renew_2021.log' # Dateiname wird auch für die eMail verwendet
MAIL_SUBJECT = 'NO-IP Account Updater' # Betreff der Status eMail
MAIL_BODY = 'NO-IP Account Updater Service updated your NO-IP Account for another 30 days.\nPlease check the attached Logfile\n\n' # Text in der eMail
HOST_URL = ' '
RESULT_STR = []

die Log datei wird angelegt jedoch ist sie natürlich leer.
root@mn-oscam:/usr/local/sbin# ./NOIP_renew_2021.py
NO-IP Account-Renew Script #210203 (Python: 3.8.5)
Lade Konfiguration aus: NOIP_renew_2021.ini
Log-In… OK!
Gefundene Hosts: 3. Starte Update…
Traceback (most recent call last):
File "./NOIP_renew_2021.py", line 134, in <module>
update_host(target, browser) # Host updaten
File "./NOIP_renew_2021.py", line 66, in update_host
if LOG_FILE: print >> f1,ts,host_id + ' [OK]' # Ausgabe in das Log
TypeError: unsupported operand type(s) for >>: 'builtin_function_or_method' and '_io.TextIOWrapper'. Did you mean "print(<message>, file=<output_s tream>)"?

wenn ich ohne Log schreiben arbeite funktioniert das Updatescript tadellos.
 
Da ich das nicht verwende ist mir das noch nicht aufgefallen. Das schau ich mir morgen mal an... Muss sicher angepasst werden wegen Python3
 
Für die Nutzung dieser Website sind Cookies erforderlich. Du musst diese akzeptieren, um die Website weiter nutzen zu können. Erfahre mehr…