2010-02-11 6 views
4

Я ищу некоторую помощь по логике, код не очень Pythonic. Я все еще участвую. Мы постоянно отображаем диск Z: в разные местоположения. Вот то, что я пытаюсь выполнитьPython - Проверить сетевую карту

1: Проверьте наличие старой карты на Z: скажу \ 192.168.1.100 \ старого
2: Карта нового местоположения в Z: сказать \ 192.168.1.200 \ нового
3: Убедитесь, что новый Z: отображение существует и до сих пор подключен
4: Если обрывается или некартированное переподключение его и зарегистрировать ее

90% коды работает, если я запускаю его как есть, она снимает отображение старый диск и отображает новый диск, но имя старого диска остается неизменным, даже если оно сопоставлено с новым местоположением, и я могу просмотреть его. Другая проблема заключается в том, что я хочу только запустить checkOldDrive один раз и просто позволить checkDrive запустить. Любые советы приветствуются.

#!/usr/bin/python 
import pywintypes 
import win32com.client 
import os.path 
import sys 
import string 
import fileinput 
import time 
import win32net 
################################################################## 
# Check for old Z: map and remove it 
# Map the new instance of Z: 
# Check if the Z: drive exists 
# if the drive exists report to status.log we are working 
# if the drive DOES NOT exist map it and report errors to the log 
################################################################### 
def checkDrive(): 
    if os.path.exists('z:'): 
     saveout = sys.stdout 
     fsock = open('status.log', 'a') 
     sys.stdout = fsock 
     print os.getenv("COMPUTERNAME"), " - ", time.ctime(), " - Connected" 
     sys.stdout = saveout 
     fsock.close() 
    else: 
     ivvinetwork = win32com.client.Dispatch('Wscript.Network') 
     network_drives = ivvinetwork.EnumNetworkDrives() 
     for mapped_drive in [network_drives.Item(i) 
          for i in range(0, network_drives.Count() -1 , 2) 
          if network_drives.Item(i)]: 
      ivvinetwork.RemoveNetworkDrive(mapped_drive, True, True) 
     drive_mapping = [ 
      ('z:', '\\\\192.168.1.100\\newmap', 'someuser', 'somepass')] 
     for drive_letter, network_path, user_name, user_pass in drive_mapping: 
      try: 
       ivvinetwork.MapNetworkDrive(drive_letter, network_path, True, user_name, user_pass) 
       saveout = sys.stdout 
       fsock = open('status.log', 'a') 
       sys.stdout = fsock 
       print os.getenv("COMPUTERNAME"), " - ", time.ctime(), " - ", drive_mapping, "Drive Has Been Mapped" 
       sys.stdout = saveout 
       fsock.close() 
      except Exception, err: 
       saveout = sys.stdout 
       fsock = open('status.log', 'a') 
       sys.stdout = fsock 
       print os.getenv("COMPUTERNAME"), " - ", time.ctime(), " - ", err 
       sys.stdout = saveout 
       fsock.close() 

def checkOldDrive(): 
    if os.path.exists('z:'): 
     ivvinetwork = win32com.client.Dispatch('Wscript.Network') 
     network_drives = ivvinetwork.EnumNetworkDrives() 
     for mapped_drive in [network_drives.Item(i) 
          for i in range(0, network_drives.Count() -1 , 2) 
          if network_drives.Item(i)]: 
      ivvinetwork.RemoveNetworkDrive(mapped_drive, True, True) 

checkOldDrive() 
checkDrive() 

ответ

3

Я собрал сценарий, основанный на том, который вы изложили, который, как я полагаю, выполняет то, что вы описали.

Я попытался сделать это так, как это было на Pythonic, и следует хорошим принципам программирования.

В частности, я сделал следующее:

  • модуляризует большую часть функциональности в многократно используемые функции
  • избежать повторений как можно больше. Я не учитывал жестко закодированный диск «Z:». Я оставляю это вам как упражнение (как вы считаете нужным).
  • учитывал определение регистрации в одном месте (так что формат и т. Д. Согласован и не повторяется). Модуль протоколирования упростил работу.
  • перенес весь код из области верхнего уровня (за исключением некоторых глобальных констант). Это позволяет сценарию запускаться напрямую или импортироваться другим скриптом в качестве модуля.
  • Добавлены некоторые строки документации, которые помогают документировать, что делает каждая функция.
  • Удерживает каждую функцию коротким кратким - поэтому ее можно легко прочитать на одном экране и в изолированном контексте.

Наверняка, есть еще кое-что для улучшения, но я протестировал этот скрипт, и он функциональный. Он должен предоставить хорошие уроки, а также помочь вам выполнить свою задачу. Наслаждаться.

#!/usr/bin/env python 
import os 
import time 
import win32com.client 
import logging 

old_mappings = [ 
    r'\\192.168.1.100\old', 
    ] 
new_mapping = r'\\192.168.1.200\new' 
LOG_FILENAME = 'status.log' 

def main(): 
    """ 
    Check to see if Z: is mapped to the old server; if so remove it and 
    map the Z: to the new server. 

    Then, repeatedly monitor the Z: mapping. If the Z: drive exists, 
    report to status.log that we are working. Otherwise, re-map it and 
    report errors to the log. 
    """ 
    setupLogging() 
    replaceMapping() 
    monitorMapping() 

def replaceMapping(): 
    if removeMapping(): 
     createNewMapping() 

def setupLogging(): 
    format = os.environ['COMPUTERNAME'] + " - %(asctime)s - %(message)s" 
    logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG, format=format) 

def getCredentials(): 
    """ 
    Return one of three things: 
    - an empty tuple 
    - a tuple containing just a username (if a password is not required) 
    - a tuple containing username and password 
    """ 
    return ('someuser', 'somepass') 

def createNewMapping(): 
    network = win32com.client.Dispatch('WScript.Network') 
    params = (
     'Z:', # drive letter 
     new_mapping, # UNC path 
     True, # update profile 
     ) 
    params += getCredentials() 
    try: 
     network.MapNetworkDrive(*params) 
     msg = '{params} - Drive has been mapped' 
     logging.getLogger().info(msg.format(**vars())) 
    except Exception as e: 
     msg = 'error mapping {params}' 
     logging.getLogger().exception(msg.format(**vars())) 

def monitorMapping(): 
    while True: 
     # only check once a minute 
     time.sleep(60) 
     checkMapping() 

def checkMapping(): 
    if getDriveMappings()['Z:'] == new_mapping: 
     msg = 'Drive is still mapped' 
     logging.getLogger().info(msg.format(**vars())) 
    else: 
     replaceMapping() 

# From Python 2.6.4 docs 
from itertools import izip_longest 
def grouper(n, iterable, fillvalue=None): 
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" 
    args = [iter(iterable)] * n 
    return izip_longest(fillvalue=fillvalue, *args) 

def getDriveMappings(): 
    """ 
    Return a dictionary of drive letter to UNC paths as mapped on the 
    system. 
    """ 
    network = win32com.client.Dispatch('WScript.Network') 
    # http://msdn.microsoft.com/en-us/library/t9zt39at%28VS.85%29.aspx 
    drives = network.EnumNetworkDrives() 
    # EnumNetworkDrives returns an even-length array of drive/unc pairs. 
    # Use grouper to convert this to a dictionary. 
    result = dict(grouper(2, drives)) 
    # Potentially several UNC paths will be connected but not assigned 
    # to any drive letter. Since only the last will be in the 
    # dictionary, remove it. 
    if '' in result: del result[''] 
    return result 

def getUNCForDrive(drive): 
    """ 
    Get the UNC path for a mapped drive. 
    Throws a KeyError if no mapping exists. 
    """ 
    return getDriveMappings()[drive.upper()] 

def removeMapping(): 
    """ 
    Remove the old drive mapping. If it is removed, or was not present, 
    return True. 
    Otherwise, return False or None. 
    """ 
    mapped_drives = getDriveMappings() 
    drive_letter = 'Z:' 
    if not drive_letter in mapped_drives: 
     return True 
    if mapped_drives[drive_letter] in old_mappings: 
     network = win32com.client.Dispatch('WScript.Network') 
     force = True 
     update_profile = True 
     network.RemoveNetworkDrive(drive_letter, force, update_profile) 
     return True 
    # return None 

if __name__ == '__main__': 
    main() 
+0

Я просто понял, что есть большая ошибка при использовании попарного. Это не правильная функция, и это случилось только в моей среде, потому что у меня была только одна буква диска. Я исправлю это и опубликую и отредактирую в ближайшее время. –

+0

Спасибо за 'getDriveMappings()' и 'getUNCForDrive()' для извлечения информации с помощью win32 api, это именно то, что я искал с тех пор ... :-) – tim

Смежные вопросы