2121# tested on Python 3.4+ 
2222# requires: grab (http://grablib.org/) 
2323# 
24- # Christoph Haunschmidt 2016-03 
24+ # Christoph Haunschmidt, started  2016-03 
2525
2626import  argparse 
27+ import  datetime 
2728import  os 
2829import  re 
2930import  sys 
30- import  datetime 
3131
3232import  grab 
3333
34- 
35- __version__  =  '2016-03-12.3' 
34+ __version__  =  '2019-05-07.1' 
3635
3736CONTENT_DISPOSITION_FILENAME_RE  =  re .compile (r'^.*filename="(?P<filename>[^"]+)".*$' )
3837DEFAULT_PREFIX_FORMAT  =  r'%Y-%m-%d--%H-%M-%S-UTC_' 
3938
4039
40+ def  is_login_successful (g ):
41+     return  g .doc .text_search ("frame_content" ) or  g .doc .text_search ("server_export.php" )
42+ 
43+ 
44+ def  open_frame_if_phpmyadmin_3 (g ):
45+     frame_url_selector  =  g .doc .select ("id('frame_content')/@src" )
46+     if  frame_url_selector .exists ():
47+         g .go (frame_url_selector .text ())
48+ 
49+ 
4150def  download_sql_backup (url , user , password , dry_run = False , overwrite_existing = False , prepend_date = True , basename = None ,
4251                        output_directory = os .getcwd (), exclude_dbs = None , compression = 'none' , prefix_format = None ,
4352                        timeout = 60 , http_auth = None , server_name = None , ** kwargs ):
@@ -56,10 +65,11 @@ def download_sql_backup(url, user, password, dry_run=False, overwrite_existing=F
5665        g .doc .set_input_by_id ('input_servername' , server_name )
5766    g .submit ()
5867
59-     try :
60-         g .doc .text_assert ('server_export.php' )
61-     except  Exception  as  e :
62-         raise  ValueError ('Could not login - did you provide the correct username / password? ({})' .format (e ))
68+     if  not  is_login_successful (g ):
69+         raise  ValueError ('Could not login - did you provide the correct username / password?' )
70+ 
71+     open_frame_if_phpmyadmin_3 (g )
72+ 
6373    export_url  =  g .doc .select ("id('topmenu')//a[contains(@href,'server_export.php')]/@href" ).text ()
6474    g .go (export_url )
6575
@@ -104,34 +114,38 @@ def download_sql_backup(url, user, password, dry_run=False, overwrite_existing=F
104114if  __name__  ==  '__main__' :
105115    parser  =  argparse .ArgumentParser (
106116        description = 'Automates the download of SQL dump backups via a phpMyAdmin web interface.' ,
107-         epilog = 'Written by Christoph Haunschmidt, version: {}' .format (__version__ ))
117+         epilog = 'Written by Christoph Haunschmidt et al. , version: {}' .format (__version__ ))
108118
109119    parser .add_argument ('url' , metavar = 'URL' , help = 'phpMyAdmin login page url' )
110120    parser .add_argument ('user' , metavar = 'USERNAME' , help = 'phpMyAdmin login username' )
111121    parser .add_argument ('password' , metavar = 'PASSWORD' , help = 'phpMyAdmin login password' )
112122    parser .add_argument ('-o' , '--output-directory' , default = os .getcwd (),
113-         help = 'output directory for the SQL dump file (default: the current working directory)' )
123+                          help = 'output directory for the SQL dump file (default: the current working directory)' )
114124    parser .add_argument ('-p' , '--prepend-date' , action = 'store_true' , default = False ,
115-         help = 'prepend current UTC date & time to the filename; see the --prefix-format option for custom formatting' )
125+                         help = 'prepend current UTC date & time to the filename; ' 
126+                              'see the --prefix-format option for custom formatting' )
116127    parser .add_argument ('-e' , '--exclude-dbs' , default = '' ,
117-         help = 'comma-separated list of database names to exclude from the dump' )
118-     parser .add_argument ('-s' , '--server-name' , default = None , help = 'mysql server hostname to supply if enabled as field on login page' )
128+                         help = 'comma-separated list of database names to exclude from the dump' )
129+     parser .add_argument ('-s' , '--server-name' , default = None ,
130+                         help = 'mysql server hostname to supply if enabled as field on login page' )
119131    parser .add_argument ('--compression' , default = 'none' , choices = ['none' , 'zip' , 'gzip' ],
120-         help = 'compression method for the output file - must be supported by the server (default: %(default)s)' )
132+                          help = 'compression method for the output file - must be supported by the server (default: %(default)s)' )
121133    parser .add_argument ('--basename' , default = None ,
122-         help = 'the desired basename (without extension) of the SQL dump file (default: the name given by phpMyAdmin); ' 
123-         'you can also set an empty basename "" in combination with --prepend-date and --prefix-format' )
134+                         help = 'the desired basename (without extension) of the SQL dump file (default: the name given ' 
135+                              'by phpMyAdmin); you can also set an empty basename "" in combination with ' 
136+                              '--prepend-date and --prefix-format' )
124137    parser .add_argument ('--timeout' , type = int , default = 60 ,
125-         help = 'timeout in seconds for the requests (default: %(default)s)' )
138+                          help = 'timeout in seconds for the requests (default: %(default)s)' )
126139    parser .add_argument ('--overwrite-existing' , action = 'store_true' , default = False ,
127-         help = 'overwrite existing SQL dump files (instead of appending a number to the name)' )
140+                          help = 'overwrite existing SQL dump files (instead of appending a number to the name)' )
128141    parser .add_argument ('--prefix-format' , default = '' ,
129-         help = str ('the prefix format for --prepend-date (default: "{}"); in Python\' s strftime format. ' 
130-                  'Must be used with --prepend-date to be in effect' .format (DEFAULT_PREFIX_FORMAT .replace ('%' , '%%' ))))
142+                         help = str ('the prefix format for --prepend-date (default: "{}"); in Python\' s strftime format. ' 
143+                                  'Must be used with --prepend-date to be in effect' .format (
144+                             DEFAULT_PREFIX_FORMAT .replace ('%' , '%%' ))))
131145    parser .add_argument ('--dry-run' , action = 'store_true' , default = False ,
132-         help = 'dry run, do not actually download any file' )
146+                          help = 'dry run, do not actually download any file' )
133147    parser .add_argument ('--http-auth' , default = None ,
134-         help = 'Basic http  authentication, using format "username:password"' )
148+                          help = 'Basic HTTP  authentication, using format "username:password"' )
135149
136150    args  =  parser .parse_args ()
137151
@@ -146,4 +160,4 @@ def download_sql_backup(url, user, password, dry_run=False, overwrite_existing=F
146160        sys .exit (1 )
147161
148162    print ('{} saved SQL dump to: {}' .format (('Would have'  if  args .dry_run  else  'Successfully' ), dump_fn ),
149-         file = sys .stdout )
163+            file = sys .stdout )
0 commit comments