Aktuelles
Digital Eliteboard - Das Digitale Technik Forum

Registriere dich noch heute kostenlos, um Mitglied zu werden! Sobald du angemeldet bist, kannst du auf unserer Seite aktiv teilnehmen, indem du deine eigenen Themen und Beiträge erstellst und dich über deinen eigenen Posteingang mit anderen Mitgliedern unterhalten kannst! Zudem bekommst du Zutritt zu Bereichen, welche für Gäste verwehrt bleiben

Registriere dich noch heute kostenlos, um Mitglied zu werden! Sobald du angemeldet bist, kannst du auf unserer Seite aktiv teilnehmen, indem du deine eigenen Themen und Beiträge erstellst und dich über deinen eigenen Posteingang mit anderen Mitgliedern unterhalten kannst! Zudem bekommst du Zutritt zu Bereichen, welche für Gäste verwehrt bleiben

NO-IP Account-Renew Script 1.0

    Nobody is reading this thread right now.
Skript ist angepasst!
Du musst Regestriert sein, um das angehängte Bild zusehen.

Bitte testen
 

Anhänge

Du musst angemeldet sein, um die Anhangsliste zu sehen.
das Update funktioniert . Das Log wird nun geschrieben.

Kannst du für einen Laien kurz erklären...
wenn ich den Aufruf mit
root@mn-oscam:/usr/local/sbin# python3 ./NOIP-Account-Renew.py >> ok
root@mn-oscam:/usr/local/sbin# python3 ./NOIP-Account-Renew >> ok
root@mn-oscam:/usr/local/sbin# ./NOIP-Account-Renew.py >> nicht ok
root@mn-oscam:/usr/local/sbin# ./NOIP-Account-Renew >> nicht ok

man muss also immer python voranstellen ? Oder mache ich da einen Fehler?
 
Zuletzt bearbeitet:
@MegaV0lt: weisst du was jetzt noch das allerhöchste wäre: wenn man das Script mit Para,etern aufrufen könnte wie zb:
./NOIP-Account-Renew.py setting1.ini
./NOIP-Account-Renew.py setting2.ini

also ich meine als Parameter eine ini Datei mitgeben könnte ..... wie zb bei bash mit dem ./command.sh $1
ich kriegs nicht hin, mit meinen wenigen Python Kenntnissen :-(
 
Bitte testen:
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.

# 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
  browser.select_form(nr=00)
  browser.submit_selected()
  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+')
  host_id = after(str_host, '?')             # Alle Zeichen nach dem ?
  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}: {host_id} [FAILED!]', file=f1)
    print(f'{host_id} [FAILED]')
    RESULT_STR.append(host_id + ' [FAILED]')
  else:
    if LOG_FILE: print(f'{ts}: {host_id} [OK]', file=f1) # Ausgabe in das Log
    print(f'{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()
Eien übergebene ini überschreibt interne Konfiguration

Code:
[/usr/local/sbin] # NOIP-Account-Renew NOIP_Account_Renew.ini
NO-IP Account-Renew Script #210304 (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:
Hiho
vielen Dank......das Script funktioniert auch damit problemlos.
Zusammenfassend: MegaV0lt hat das Script dahingehend geändert, daß man nun auch die ini Datei mit übergeben kann.
Da man ja pro free no-ip.com Account nur eine begrenzte Anzahl an Domänen (sind es 3 oder 5?) haben darf, müsste man, wenn man mehr als diese Anzahl hat, mehrere Kopien des Scriptes haben. Man kann nun aber das Script einmal haben, damit aber verschiedene ini Dateien übergeben.

Ich habe das mal getestet und es funktioniert:

./no-ip_updater2.py slash.ini
NO-IP Account-Renew Script #210304 (Python: 3.7.3)
Lade Konfiguration aus: jan.ini
Log-In… OK!
Gefundene Hosts: 5. Starte Update…
host_id=xxx567 [OK]
host_id=xxxxx02x3 [OK]
host_id=xxxxx02x8 [OK]
host_id=5x2xxxxx [OK]
host_id=5x7xxxxx [OK]


./no-ip_updater2.py slash2.ini
NO-IP Account-Renew Script #210304 (Python: 3.7.3)
Lade Konfiguration aus: thomas.ini
Log-In… OK!
Gefundene Hosts: 1. Starte Update…
host_id=65xxxxx8x [OK]

E-Mail versenden funktioniert und auch das loggen funktioniert einwandfrei.
Auch wenn man im Script selbst die Logindaten hinterlegt hat, wird beim Aufruf mit ini Datei die INI als Setting genommen.
Klasse Arbeit, vielen Dank
 
Zuletzt bearbeitet:
Hallo,

ich habe meinen Raspi die letzten Monate auf Raspian BUSTER upgedatet und heute festgestellt, dass zwar das Script ohne Fehler durchläuft, jedoch kein Update auf der NO-IP Seite gemacht wird.
Email kommt, jedoch wird im Email_Log nicht das aktuelle Datum geschrieben.
Kann mir bitte jemand sagen, wo der Fehler liegt?

#!/usr/bin/env python
# -*- coding: utf-8 -*-
### *|--------------------------------|* ###
### *| NO-IP Account-Renew Script 1.0 |* ###
### *| (c) by DarkStarXxX @ DEB |* ###
### *|--------------------------------|* ###
# Modifiziert von MegaV0lt @ DEB
# Modifiziert von SLASH @ DEB
VERSION=190312

# 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.
# Besonderheit: Die Datei im Dateisystem muss die Endung ".py" haben.
# Bitte dort die Daten eintragen (Im gleichen Verzeichnis wie das Skript!)
CONFIG_FILE = "" # Ohne .py (Im gleichen Verzeichnis wie das Skript!)
# Kann abgeschaltet werden, in dem man CONFIG_FILE = "" setzt. In dem Fall die
# Variablen hier ausfüllen!
USERNAME = "XXX" # No-IP Benutzername
PASSWORD = "XXX" # No-IP Passwort
FROMADRESS = "XXX" # eMail-Sender
TOADRESS = "XXX" # eMail-Empfänger
SMTPSERVER = "XXX" # SMTP-Serveradresse ("" zum deaktivieren)
SMTPPORT = "XXX" # SMTP-Port (Z. B. 25)
SMTPPASS = "XXX" # 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 = " "
RESULT_STR = []

import importlib
import mechanize
import time
import ssl
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, brow):
global RESULT_STR
brow.select_form(nr=00) ; brow.submit()
# Check if OK
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+')
host_id = after(str_host, "?") # Alle Zeichen nach dem ?
if brow.response().read().find("Update will be applied") >= 0:
if LOG_FILE: print >> f1,ts,host_id + " [OK]" # Ausgabe in das Log
print(host_id + " [OK]") # Ausgabe auf der Konsole (und cron)
RESULT_STR.append(host_id + " [OK]") # Für die eMail
else:
if LOG_FILE: print >> f1,ts,host_id + " [FAILED]"
print(host_id + " [FAILED]")
RESULT_STR.append(host_id + " [FAILED]")
return

# Funktion: after - Liefert Zeichenkette nach Zeichen a
def after(value, a):
# Find and validate first part
pos_a = value.rfind(a)
if pos_a == -1: return value # Nicht gefunden: Ganzer Wert zurück!
# Returns chars after the found string.
adjusted_pos_a = pos_a + len(a)
if adjusted_pos_a >= len(value): return ""
return value[adjusted_pos_a:]

# Browser options
br = mechanize.Browser()
br.set_handle_equiv(True) ; br.set_handle_robots(False)
br.set_handle_redirect(True) ; br.set_handle_referer(True)
br.addheaders = [('User-agent', 'Chrome')]
br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)

### Start
print "NO-IP Account-Renew Script #%s" % VERSION
if CONFIG_FILE:
myconf = importlib.import_module(CONFIG_FILE, package=None)
USERNAME = myconf.USERNAME ; PASSWORD = myconf.PASSWORD
FROMADRESS = myconf.FROMADRESS ; TOADRESS = myconf.TOADRESS
SMTPSERVER = myconf.SMTPSERVER ; SMTPPORT = myconf.SMTPPORT
SMTPPASS = myconf.SMTPPASS

# 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
br.open(HOST_URL)

# Login
br.select_form(nr=0)
br.form["username"] = USERNAME ; br.form["password"] = PASSWORD
br.submit()

# Nicht mehr nötig, da die alternative Seite abgeschaltet wurde (August 2018)
#br.find_link(text='Manage Hosts')
#req = br.click_link(text='Manage Hosts')
#br.open(req)

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

# Links klicken und Updaten
for link in mylink:
req = br.click_link(link)
br.open(req)
update_host(link.url, br)

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

import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase 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()
 

Anhänge

Du musst angemeldet sein, um die Anhangsliste zu sehen.
Die Hosts werden glaube ich in den letzten 7 Tagen erst bestätigt, wenn die ablaufen, dann aktualisiert das Script diese.
 
Achso, ist das eine Neuerung gegenüber dem Ursprungsscript?

Edit: Wenn ich bewusst einen falschen User oder Pass eingebe, kommt auch keine Fehlermeldung.
Irgendwo ist da gerade der Wurm drinnen...
 
Zuletzt bearbeitet:
eigentlich nicht, läuft hier genau so und ich benutze jetzt nicht das neueste, hab noch die Version 18 irgendwas.
Gerade noch auf No-Ip geschaut, 15 Tage verbleiben, Script läuft
 
Script ist nun aktuell.
Nun erscheint folgende Fehlermedung:

File "/usr/local/bin/NOIP-Account-Renew", line 47, in <module>
import mechanicalsoup
ModuleNotFoundError: No module named 'mechanicalsoup'


pip3 install mechanicalsoup bringt Fehlermeldung:

-bash: pip3: command not found
 
Zuletzt bearbeitet:
Zurück
Oben