Commits

Denilson Sá committed e97bb73

Adding technicolor_gateway_restart.py, a script to restart the Technicolor
TG580v2 modem/router.

Also added command-line arguments to technicolor_gateway_adsl_info.py.

Comments (0)

Files changed (2)

technicolor_gateway_adsl_info.py

 # -*- coding: utf-8 -*-
 # vi:ts=4 sw=4 et
 
+import argparse
 import pyparsing
 import requests
 import sys
 
+
+def parse_args():
+    parser = argparse.ArgumentParser(
+        description='Print ADSL info from Technicolor TG580v2 modem/router',
+        epilog='Note that this script automatically reads authentication'
+        ' credentials from ~/.netrc, so there is no need to pass'
+        ' username/password at the command-line.',
+        formatter_class=argparse.ArgumentDefaultsHelpFormatter
+    )
+    parser.add_argument(
+        '-t', '--test',
+        action='store_true',
+        dest='run_tests',
+        help='Run the self-test (doctest) of this script'
+    )
+    parser.add_argument(
+        '-H', '--host', '--hostname',
+        action='store',
+        default='dsldevice.lan',
+        type=str,
+        dest='hostname',
+        help='The hostname or IP address for the modem'
+    )
+    parser.add_argument(
+        '-u', '-U', '--user', '--username',
+        action='store',
+        default='',
+        type=str,
+        dest='username',
+        help='Username for HTTP authentication'
+    )
+    parser.add_argument(
+        '-p', '-P', '--pass', '--password',
+        action='store',
+        default='',
+        type=str,
+        dest='password',
+        help='Password for HTTP authentication'
+    )
+    options = parser.parse_args()
+    return options
+
+
 # These pages use an embedded script to load the actual status.
 # http://192.168.1.1/atm_main.htm
 # http://192.168.1.1/atm_dsl.htm?ov=1
 
 
 def main():
-    # TODO: Add command-line arguments for hostname, username, password.
-    # TODO: Add command-line argument to run the doctests.
+    options = parse_args()
+
+    if options.run_tests:
+        run_doctests()
+
     try:
         print(
             human_readable_status(
                 parse_javascript_vars(
-                    fetch_modem_status()
+                    fetch_modem_status(hostname=options.hostname,
+                        username=options.username, password=options.password)
                 )
             )
         )
     except requests.exceptions.HTTPError as e:
         print(e.response.url)
         print(e)
+        sys.exit(1)
 
 def run_doctests():
     import doctest

technicolor_gateway_restart.py

+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# vi:ts=4 sw=4 et
+
+import argparse
+import requests
+import sys
+
+
+def parse_args():
+    parser = argparse.ArgumentParser(
+        description='Restart the Technicolor TG580v2 modem/router',
+        epilog='Note that this script automatically reads authentication'
+        ' credentials from ~/.netrc, so there is no need to pass'
+        ' username/password at the command-line.',
+        formatter_class=argparse.ArgumentDefaultsHelpFormatter
+    )
+    parser.add_argument(
+        '-f', '--force',
+        action='store_true',
+        dest='force',
+        help='Do not ask for confirmation, restart right away'
+    )
+    parser.add_argument(
+        '-H', '--host', '--hostname',
+        action='store',
+        default='dsldevice.lan',
+        type=str,
+        dest='hostname',
+        help='The hostname or IP address for the modem'
+    )
+    parser.add_argument(
+        '-u', '-U', '--user', '--username',
+        action='store',
+        default='',
+        type=str,
+        dest='username',
+        help='Username for HTTP authentication'
+    )
+    parser.add_argument(
+        '-p', '-P', '--pass', '--password',
+        action='store',
+        default='',
+        type=str,
+        dest='password',
+        help='Password for HTTP authentication'
+    )
+    options = parser.parse_args()
+    return options
+
+
+def restart_modem(hostname='dsldevice.lan', username='', password=''):
+    url = 'http://{0}/cgi-bin/restart.exe'.format(hostname)
+    referer = 'http://{0}/sys_boot.htm'.format(hostname)
+    # Explicit auth is not required, because the library can already read from
+    # ~/.netrc.
+    auth = (username, password) if username or password else None
+
+    # For some weird reason, the first request always returns 401 Unauthorized.
+    # Retrying will work, and it will continue working for a couple of minutes.
+    for i in range(2):
+        r = requests.post(url, auth=auth, headers={
+            'Referer': referer
+        })
+        # If it returns 401, let's try once more.
+        if r.status_code != 401:
+            break
+
+    r.raise_for_status()
+    return r.text
+
+
+def main():
+    options = parse_args()
+
+    if not options.force:
+        # This link provides a more complete implementation of a prompt:
+        # http://stackoverflow.com/questions/3041986/python-command-line-yes-no-input
+        answer = input('Restart modem at http://{0}/ ? [y/N] '.format(
+            options.hostname))
+        answer = answer.strip().lower()
+        if answer not in ['y', 'yes', 'yeah', 'yep']:
+            print('Aborting.')
+            sys.exit(1)
+
+    try:
+        restart_modem(hostname=options.hostname,
+            username=options.username, password=options.password)
+    except requests.exceptions.HTTPError as e:
+        print(e.response.url)
+        print(e)
+        sys.exit(1)
+
+def run_doctests():
+    import doctest
+    doctest.testmod()
+
+if __name__ == '__main__':
+    main()