#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright: Flopp # # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import cookielib import urllib import urllib2 import os import re import sys from optparse import OptionParser, OptionGroup, OptionValueError from datetime import date OCDLPY_VERSION="ocdl.py v0.3a 2012-11-03" def create_directory( d ) : if not os.path.isdir( d ) : if options.be_verbose : print ( " -- dir '%s' does not exist" % (d) ) print ( " -- trying to create dir '%s'" % (d) ) try : os.makedirs( d ) except OSError as e: print ( "ERROR: cannot create dir '%s'" % (d) ) print ( " -- ", e ) raise Exception def naming_style_callback( option, opt_str, value, parser ) : if not value in [ "ID", "ID+DATE", "NAME", "NAME+DATE" ] : raise OptionValueError( "bad STYLE value for option '%s': '%s'" % ( opt_str, value ) ) setattr( parser.values, option.dest, value ) additional_help=""" ocdl.py logs in to opencaching.de using login credentials which are stored | | in '~/.ocdl/config.txt' (the actual directory is configurable using the | | '--configdir' command line option). | | | | You can use the command line option '--setup' to create the configuration | | directory and to initialize the config file with your login credentials. | | | | Alternatively, you can manually create the configuration directory and | | the config file: | | Make sure the directory '~/.ocdl/' (or whatever you chose by | | '--configdir') exists and contains the file 'config.txt' with the | | following two lines: | | | | OCDE_LOGIN='username' | | OCDE_PASSWORD='password' | | | | where username and password are your login credentials for opencaching.de | | | | | | Moreover, ocdl.py stores the login cookie 'cookies.txt' in the selected | | config directory for future logins. | """ parser = OptionParser( usage = "%prog [options] [ID...]", version = OCDLPY_VERSION, epilog = additional_help ) parser.add_option( "-s", "--setup", action="store_true", dest="perform_setup", default=False, help="create the necessary directories; ask the user for login credentials" ) parser.add_option( "-c", "--configdir", metavar="CONFIGDIR", dest="config_dir", default="~/.ocdl", help="specify directory for config files (cookies, login information); default is '~/.ocdl'" ) parser.add_option( "-l", "--list", action="store_true", dest="list_only", default=False, help="list available queries, do not download them" ) parser.add_option( "-n", "--name", metavar="STYLE", action="callback", callback=naming_style_callback, type="string", dest="naming_style", default="ID", help="select naming style of downloaded queries, STYLE={ ID, ID+DATE, NAME, NAME+DATE }, default is 'ID'" ) parser.add_option( "-d", "--dir", metavar="TARETDIR", dest="target_dir", default=".", help="select target directory for downloaded queries; default is the current directory" ) parser.add_option( "-v", "--verbose", action="store_true", dest="be_verbose", default=False, help="print verbose status messages" ) (options, args) = parser.parse_args() cookie_jar = cookielib.LWPCookieJar() opener = urllib2.build_opener( urllib2.HTTPCookieProcessor( cookie_jar ) ) urllib2.install_opener( opener ) headers = {'User-agent' : 'OCDL.py'} def store_credentials( filename, login, password ) : try : f = open( filename, "w" ) f.write( "OCDE_LOGIN='%s'\n" % (login.encode('utf-8')) ) f.write( "OCDE_PASSWORD='%s'\n" % (password.encode('utf-8')) ) except IOError as e: if options.be_verbose : print ( " -- WARNING: unable to write to file '%s'" % (filename) ) print ( " -- ", e ) except Exception as e: if options.be_verbose : print ( " -- WARNING: unable to write to file '%s'" % (filename) ) print ( " -- ", e ) def load_credentials( filename ) : if not os.path.isfile( filename ) : if options.be_verbose : print ( " -- file '%s' does not exist" % (filename) ) return (None,None) try : f = open( filename, "r" ) lines = f.readlines() # OCDE_LOGIN='username' # OCDE_PASSWORD='password' login=None password=None for line in lines : line=line.strip() if line == "" : continue elif line.startswith( "#" ) : continue elif line.startswith( "OCDE_LOGIN='" ) : if not( login is None ) : if options.be_verbose : print ( " -- WARNING: duplicate 'OCDE_LOGIN' lines in file '%s'" % (filename) ) return (None,None) if not( len(line)>12 ) or not( line.endswith("'") ) : if options.be_verbose : print ( " -- WARNING: bad 'OCDE_LOGIN' line in file '%s': %s" % (filename, line) ) return (None,None) login = line[12:-1] elif line.startswith( "OCDE_PASSWORD='" ) : if not( password is None ) : if options.be_verbose : print ( " -- WARNING: duplicate 'OCDE_PASSWORD' lines in file '%s'" % (filename) ) return (None,None) if not( len(line)>15 ) or not( line.endswith("'") ) : if options.be_verbose : print ( " -- WARNING: bad 'OCDE_PASSWORD' line in file '%s': %s" % (filename, line) ) return (None,None) password = line[15:-1] else : if options.be_verbose : print ( " -- WARNING: bad line in file '%s': %s" % (filename, line) ) return (None,None) if (login is None) or (password is None) : if options.be_verbose : print ( " -- WARNING: no 'OCDE_LOGIN' or 'OCDE_PASSWORD' lines in file '%s'" % (filename) ) return (None,None) return (login.decode('utf-8'), password.decode('utf-8')) except IOError as e: if options.be_verbose : print ( " -- WARNING: unable to parse file '%s'" % (filename) ) print ( " -- ", e ) return (None,None) except Exception as e: if options.be_verbose : print ( " -- WARNING: unable to parse file '%s'" % (filename) ) print ( " -- ", e ) return (None,None) def parse_queries( data ) : res = [] for m in re.finditer( r'([^<]+)