Возникла передо мной такая задача: мы храним таблицу соответсвия мака, ip и имени ПК в гуглодоксе, она и поддерживается в актуальном состоянии. DHCP сервер работает на FreeBSD, соответственно файл с настройками сервера вполне себе текстовый. И чтобы не обновлять данные и там и там был сделан скриптик. Наверняка можно было бы сделать проще, в некоторых случаях даже понятно как (например в функции csv2dhcp), но для небольшой таблицы я заморачиваться не стал.
Для работы понадобится pyquery и второй питон (считаем, что это у Вас уже есть). Кроме того, нам нужна библиотека для доступа к Google API.
Итак, по порядку:
- Заходим на страницу
- Выбираем Drive API и Python/Command Line
- Нажимаем на Настроить проект
- Вводим имя проекта, Далее
- По двум появившимся ссылкам скачиваем starter application и client secret, которым заменяем такой же файл в распакованном архиве
- Редактируем файл sample.py
Ниже будет код. Функцию csv2dhcp писал сам, ods2csv взял отсюда, остальное из документации по Google API. Немножно моих комментариев в коде.
Если будут комментарии/улучшения - буду благодарен
# -*- coding: utf-8 -*-
#
# Copyright (C) 2012 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Command-line skeleton application for Drive API.
Usage:
$ python sample.py
You can also get help on all the command-line flags the program understands
by running:
$ python sample.py --help
To get detailed log output run:
$ python sample.py --logging_level=DEBUG
Для работы надо поставить gdata:
#$ pip install gdata
$ pip install pyquery
Подключение API:
https://developers.google.com/drive/quickstart-python
"""
import gflags
import httplib2
import logging
import os
import sys
from apiclient.discovery import build
from oauth2client.file import Storage
from oauth2client.client import AccessTokenRefreshError
from oauth2client.client import flow_from_clientsecrets
from oauth2client.tools import run
from apiclient import errors
FLAGS = gflags.FLAGS
# CLIENT_SECRETS, name of a file containing the OAuth 2.0 information for this
# application, including client_id and client_secret.
# You can see the Client ID and Client secret on the API Access tab on the
# Google APIs Console <https://code.google.com/apis/console>
CLIENT_SECRETS = 'client_secrets.json'
# Helpful message to display if the CLIENT_SECRETS file is missing.
MISSING_CLIENT_SECRETS_MESSAGE = """
WARNING: Please configure OAuth 2.0
To make this sample run you will need to download the client_secrets.json file
and save it at:
%s
""" % os.path.join(os.path.dirname(__file__), CLIENT_SECRETS)
# Временные файлы, куда сохраняется скачаный файл и конвертированый в csv
TEMP_FILE = '/home/ishayahu/IP range.ods'
TEMP_FILE2 = '/home/ishayahu/IP range.csv'
# Имя итогового файла
dhcp_file_name = '/home/ishayahu/dhcp'
# Set up a Flow object to be used for authentication.
# Add one or more of the following scopes. PLEASE ONLY ADD THE SCOPES YOU
# NEED. For more information on using scopes please see
# <https://developers.google.com/+/best-practices>.
FLOW = flow_from_clientsecrets(CLIENT_SECRETS,
scope=[
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.apps.readonly',
'https://www.googleapis.com/auth/drive.metadata.readonly',
'https://www.googleapis.com/auth/drive.file',
'https://www.googleapis.com/auth/drive.scripts',
'https://www.googleapis.com/auth/drive.readonly',
],
message=MISSING_CLIENT_SECRETS_MESSAGE)
# The gflags module makes defining command-line options easy for
# applications. Run this program with the '--help' argument to see
# all the flags that it understands.
gflags.DEFINE_enum('logging_level', 'ERROR',
['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
'Set the level of logging detail.')
def retrieve_all_files(service):
"""Retrieve a list of File resources.
Args:
service: Drive API service instance.
Returns:
List of File resources.
"""
result = []
page_token = None
while True:
try:
param = {}
if page_token:
param['pageToken'] = page_token
files = service.files().list(**param).execute()
result.extend(files['items'])
page_token = files.get('nextPageToken')
if not page_token:
break
except errors.HttpError, error:
print 'An error occurred: %s' % error
break
return result
def download_file(service, drive_file):
"""Download a file's content.
Args:
service: Drive API service instance.
drive_file: Drive File instance.
Returns:
File's content if successful, None otherwise.
"""
#download_url = drive_file.get('downloadUrl')
# Так как файл в родом формате для гугла, то скачать его нельзя и
# downloadUrl просто отсутствует. Поэтому используем ссылки для экспорта
download_url = drive_file[u'exportLinks'][u'application/x-vnd.oasis.opendocument.spreadsheet']
if download_url:
resp, content = service._http.request(download_url)
if resp.status == 200:
#print 'Status: %s' % resp
return content
else:
print 'An error occurred: %s' % resp
return None
else:
# The file doesn't have any content stored on Drive.
return None
def ods2csv(filepath):
# комментарии тут: http://python-example.blogspot.ru/2012/10/how-to-convert-ods-to-csv.html
import sys,zipfile,re,os,csv
from pyquery import PyQuery as pq
from lxml.cssselect import CSSSelector
xml = zipfile.ZipFile(filepath).read('content.xml')
def rep_repl(match):
return '<table:table-cell>%s' %match.group(2) * int(match.group(1))
def repl_empt(match):
n = int(match.group(1))
pat = '<table:table-cell/>'
return pat*n if (n<100) else pat
p_repl = re.compile(r'<table:table-cell [^>]*?repeated="(\d+)[^/>]*>(.+?table-cell>)')
p_empt = re.compile(r'<table:table-cell [^>]*?repeated="(\d+)[^>]*>')
xml = re.sub(p_repl, rep_repl, xml)
xml = re.sub(p_empt, repl_empt, xml)
d = pq(xml, parser='xml')
ns={'table': 'urn:oasis:names:tc:opendocument:xmlns:table:1.0'}
selr = CSSSelector('table|table-row', namespaces=ns)
selc = CSSSelector('table|table-cell', namespaces=ns)
rowxs = pq(selr(d[0]))
data = []
for ir,rowx in enumerate(rowxs):
cells = pq(selc(rowx))
if cells.text():
data.append([cells.eq(ic).text().encode('utf-8') for ic in range(len(cells))])
root,ext=os.path.splitext(filepath)
with open(''.join([root,'.csv']),'wb') as f:
for row in data:
dw = csv.writer(f)
dw.writerow(row)
def csv2dhcp(filepath):
dhcp_file=open(dhcp_file_name,'w')
for line in open(filepath,'r'):
if len(line.strip().split(','))>=6 and line.strip().split(',')[2]:
dhcp_file.write("host %s { hardware ethernet %s; fixed-address 192.168.1.%s; }\n" % (line.strip().split(',')[5],line.strip().split(',')[2],line.strip().split(',')[1]))
dhcp_file.close()
def main(argv):
# Let the gflags module process the command-line arguments
try:
argv = FLAGS(argv)
except gflags.FlagsError, e:
print '%s\\nUsage: %s ARGS\\n%s' % (e, argv[0], FLAGS)
sys.exit(1)
# Set the logging according to the command-line flag
logging.getLogger().setLevel(getattr(logging, FLAGS.logging_level))
# If the Credentials don't exist or are invalid, run through the native
# client flow. The Storage object will ensure that if successful the good
# Credentials will get written back to a file.
storage = Storage('sample.dat')
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = run(FLOW, storage)
# Create an httplib2.Http object to handle our HTTP requests and authorize it
# with our good Credentials.
http = httplib2.Http()
http = credentials.authorize(http)
service = build('drive', 'v2', http=http)
try:
print "Login success! Starting to work."
for entry in retrieve_all_files(service):
# Пролистываем список всех файлов (как ещё получить нужный не знаю)
# IP range - имя нужного мне файла
if entry[u'title']=='IP range':
print "Writing content to %s" % TEMP_FILE
open(TEMP_FILE,'w').write(download_file(service, entry))
print "Converting ods to csv"
ods2csv(TEMP_FILE)
csv2dhcp(TEMP_FILE2)
os.remove(TEMP_FILE)
os.remove(TEMP_FILE2)
# For more information on the Drive API API you can visit:
#
# https://developers.google.com/drive/
#
# For more information on the Drive API API python library surface you
# can visit:
#
# https://google-api-client-libraries.appspot.com/documentation/drive/v2/python/latest/
#
# For information on the Python Client Library visit:
#
# https://developers.google.com/api-client-library/python/start/get_started
except AccessTokenRefreshError:
print ("The credentials have been revoked or expired, please re-run"
"the application to re-authorize")
if __name__ == '__main__':
main(sys.argv)
Комментариев нет:
Отправить комментарий