# -*- coding: UTF8 -*- ## UM2/FDS/SIF/FP june 2013 ## Print remote files using a types list # toutes les chaines sont en unicode (même les docstrings) from __future__ import unicode_literals ## Required Python modules import os # operate system calls. import sys # System constants. from stat import * # read files attributs. import paramiko # http://www.lag.net/paramiko/docs/paramiko.SFTPClient-class.html operate ssh session. import magic # manage file types (printable ?) import re # manage regular expression. import subprocess # spawn new processes, connect to their input/output/error pipes, and obtain their return codes. import codecs # convert to unicode file names. import locale # Environnement encoding. encoding = sys.getfilesystemencoding() ## Remote server ie Web site server hostname = '162.38.218.207' # remote hostname where SSH server is running. port = 22 username = 'sif' password = '' rsa_private_key = '/home/sif/.ssh/id_rsa' ## Directories dir_local= '/home/sif/toprint' # Local directory to store the files to print. dir_remote = '/home/sif/public_html/server/php/files' # Server side directory where files to print are available. thumbnail_dir_remote = os.path.join(dir_remote, "thumbnail") # Server side directory where pictures thumbnails are stored. file_copies_number = '/home/sif/file_copies_number' # Copies number is known in a local file. remote_file_copies_number = '/home/sif/public_html/server/php/file_copies_number' # Remote file containing the number of copies on the server side. ## local printer to use printer = 'hplaserjet1320' def agent_auth(transport, username): """ Attempt to authenticate to the given transport using any of the private keys available from an SSH agent or from a local private RSA key file (assumes no pass phrase). """ try: ki = paramiko.RSAKey.from_private_key_file(rsa_private_key) except Exception, e: print 'Failed loading' % (rsa_private_key, e) agent = paramiko.Agent() agent_keys = agent.get_keys() + (ki,) if len(agent_keys) == 0: return for key in agent_keys: print 'Trying ssh-agent key %s' % key.get_fingerprint().encode('hex'), try: transport.auth_publickey(username, key) print '... success!' return except paramiko.SSHException, e: print '... failed!', e def istext(path): """ test if file type is text """ return (re.search(r':.* text', subprocess.Popen(["file", '-L', path], stdout=subprocess.PIPE).stdout.read()) is not None) def ispdf(path): """ test if file type is PDF """ return (re.search(r':.* PDF', subprocess.Popen(["file", '-L', path], stdout=subprocess.PIPE).stdout.read()) is not None) def isimage(path): """ test if file type is IMAGE """ return (re.search(r':.* image', subprocess.Popen(["file", '-L', path], stdout=subprocess.PIPE).stdout.read()) is not None) # get host key, if we know one hostkeytype = None hostkey = None printedfiles = 0 os.system("date") try: host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts')) except IOError: try: # try ~/ssh/ too, e.g. on windows host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts')) except IOError: print '*** Unable to open host keys file' host_keys = {} if hostname in host_keys: hostkeytype = host_keys[hostname].keys()[0] hostkey = host_keys[hostname][hostkeytype] print 'Using host key of type %s' % hostkeytype # Now, connect and use paramiko Transport to negotiate SSH2 across the connection try: print 'Establishing SSH connection to:', hostname, port, '...' t = paramiko.Transport((hostname, port)) t.start_client() agent_auth(t, username) if not t.is_authenticated(): print u'RSA key auth failed! Trying password login...' t.connect(username=username, password=password, hostkey=hostkey) else: sftp = t.open_session() sftp = paramiko.SFTPClient.from_transport(t) # Here we attempt to get the file containing the number of copies from the PHP server #filestat = sftp.stat(remote_file_copies_number) #mode = sftp.stat(remote_file_copies_number).st_mode #if not S_ISDIR(mode): try: sftp.get(remote_file_copies_number, file_copies_number) except IOError: print u'ERROR', remote_file_copies_number, 'SFTP FILE TRANSFERT ERROR OCCURED!' # Here, we manage the files to print remotelist = sftp.listdir(dir_remote) # Lists all files in Web site repository for filename in remotelist: remote_file = os.path.join(dir_remote, filename) remote_file_encode = os.path.join(dir_remote, filename).encode('UTF8') thumbnail_remote_file = os.path.join(thumbnail_dir_remote, filename) thumbnail_remote_file_encode = os.path.join(thumbnail_dir_remote, filename).encode('UTF8') filestat = sftp.stat(remote_file_encode.decode('UTF8')) mode = sftp.stat(remote_file_encode.decode('UTF8')).st_mode try: f = open(file_copies_number, "r") except IOError: print u'ERROR:', file_copies_number, 'LOCAL FILE ACCESS ERROR OCCURED!' finally: copies_number = int(f.readline()); f.close() if not S_ISDIR(mode): local_file = os.path.join(dir_local, filename) local_file_encode = local_file.encode('UTF8') print u'Copying',hostname,":", remote_file, 'to ', local_file try: # TODO HERE: traiter les accents dans les noms de fichier sftp.get(remote_file_encode.decode('UTF8'),local_file_encode.decode('UTF8')) try: with open(local_file_encode.decode('UTF8')): pass print u'Removing',remote_file,'on Web site' sftp.remove(remote_file_encode.decode('UTF8')) if isimage(local_file_encode.decode('UTF8')) : print u'Removing',thumbnail_remote_file,'on Web site' sftp.remove(thumbnail_remote_file_encode.decode('UTF8')) ms = magic.open(magic.MAGIC_NONE) ms.load() type = ms.file(local_file_encode.decode('UTF8')) if ( istext(local_file_encode.decode('UTF8')) | ispdf(local_file_encode.decode('UTF8')) | isimage(local_file_encode.decode('UTF8')) ): try: printedfiles += 1 printcmd = "lp -d %s %s" % (printer,local_file_encode.decode('UTF8')) count = 0 print local_file, 'is a printable type file:', type while (count < copies_number): # print printcmd # ICI pour mise en prod # HERE to production mode os.system(printcmd) # HERE to activate the print command count = count + 1 except IOError: print u'ERROR:', local_file, 'LOCAL FILE ACCESS ERROR OCCURED!' else: print u'DENIED:', local_file, 'IS' , type, 'SO IT IS NOT PRINTABLE !' os.remove(local_file_encode.decode('UTF8')) except IOError: print u'ERROR:', local_file, 'SFTP REMOVE FILE ERROR OCCURED!' except IOError: print u'ERROR', remote_file, 'SFTP FILE TRANSFERT ERROR OCCURED!' t.close() except Exception, e: print '*** Caught exception: %s: %s' % (e.__class__, e) try: t.close() except: pass print 'Encodage:',encoding print '=' * 60 print 'Files printed:',printedfiles print 'Number of copies:',copies_number print 'All operations complete!' print '=' * 60