1. Обзор
В этой лаборатории вы узнаете, как использовать Google Slides в качестве специального инструмента для презентаций для анализа наиболее распространенных лицензий на программное обеспечение. Вы будете запрашивать весь открытый исходный код на GitHub с помощью API BigQuery и создавать набор слайдов с помощью API Google Slides для представления своих результатов. Пример приложения создан с использованием Node.js, но одни и те же основные принципы применимы к любой архитектуре.
Что вы узнаете
- Создание презентаций с использованием Slides API
- Использование BigQuery для получения информации о большом наборе данных
- Копирование файла с помощью Google Drive API
Что вам понадобится
- Node.js установлен
- Доступ к Интернету и веб-браузеру
- Аккаунт Google
- Проект облачной платформы Google
2. Получите пример кода
Вы можете загрузить весь пример кода на свой компьютер...
…или клонируйте репозиторий GitHub из командной строки.
git clone https://github.com/googleworkspace/slides-api.git
Репозиторий содержит набор каталогов, представляющих каждый этап процесса, на случай, если вам понадобится ссылка на рабочую версию.
Вы будете работать с копией, расположенной в start
каталоге, но при необходимости вы можете обращаться к остальным или копировать файлы из них.
3. Запустите пример приложения.
Во-первых, давайте запустим и запустим сценарий Node. После загрузки кода следуйте инструкциям ниже, чтобы установить и запустить приложение Node.js:
- Откройте терминал командной строки на своем компьютере и перейдите в
start
каталог codelab. - Введите следующую команду, чтобы установить зависимости Node.js.
npm install
- Введите следующую команду для запуска сценария:
node .
- Обратите внимание на приветствие, в котором показаны шаги этого проекта.
-- Start generating slides. -- TODO: Get Client Secrets TODO: Authorize TODO: Get Data from BigQuery TODO: Create Slides TODO: Open Slides -- Finished generating slides. --
Вы можете увидеть наш список TODO в slides.js
, license.js
и auth.js
Обратите внимание, что мы используем обещания JavaScript для объединения шагов, необходимых для завершения приложения, поскольку каждый шаг зависит от завершения предыдущего шага.
Если вы не знакомы с промисами, не волнуйтесь, мы предоставим весь необходимый вам код. Короче говоря, промисы дают нам возможность обрабатывать асинхронную обработку более синхронно.
4. Получите секреты клиента
Чтобы использовать API-интерфейсы Slides, Bigquery и Drive, мы создадим клиент OAuth и учетную запись службы.
Настройка консоли разработчиков Google
- Используйте этот мастер , чтобы создать или выбрать проект в консоли разработчиков Google и автоматически включить API. Нажмите «Продолжить» , затем «Перейти к учетным данным» .
- На странице «Добавить учетные данные в проект» нажмите кнопку «Отмена» .
- В верхней части страницы выберите вкладку экрана согласия OAuth . Выберите адрес электронной почты , введите название продукта
Slides API Codelab
и нажмите кнопку «Сохранить» .
Включите API BigQuery, Drive и Slides.
- Выберите вкладку «Панель мониторинга» , нажмите кнопку «Включить API» и включите следующие 3 API:
- API BigQuery
- API Google Диска
- API Google Слайдов
Скачать секрет клиента OAuth (для слайдов и диска)
- Выберите вкладку «Учетные данные» , нажмите кнопку «Создать учетные данные» и выберите идентификатор клиента OAuth .
- Выберите тип приложения «Другое» , введите имя
Google Slides API Codelab
и нажмите кнопку «Создать» . Нажмите «ОК» , чтобы закрыть появившееся диалоговое окно. - Нажмите кнопку file_download (Загрузить JSON) справа от идентификатора клиента.
- Переименуйте секретный файл в
client_secret.json
и скопируйте его в каталоги start/ и Finish/ .
Скачать секрет сервисного аккаунта (для BigQuery)
- Выберите вкладку «Учетные данные» , нажмите кнопку «Создать учетные данные» и выберите « Ключ учетной записи службы» .
- В раскрывающемся списке выберите «Новая учетная запись службы» . Выберите имя
Slides API Codelab Service
для своего сервиса. Затем нажмите «Роль» , прокрутите до BigQuery и выберите «Просмотр данных BigQuery» и «Пользователь задания BigQuery» . - В качестве типа ключа выберите JSON .
- Нажмите Создать . Ключевой файл будет автоматически загружен на ваш компьютер. Нажмите «Закрыть» , чтобы выйти из появившегося диалогового окна.
- Переименуйте секретный файл в
service_account_secret.json
и скопируйте его в каталоги start/ и Finish/ .
Получить секреты клиента
В start/auth.js
заполним метод getClientSecrets
.
авторизация.js
const fs = require('fs'); /** * Loads client secrets from a local file. * @return {Promise} A promise to return the secrets. */ module.exports.getClientSecrets = () => { return new Promise((resolve, reject) => { fs.readFile('client_secret.json', (err, content) => { if (err) return reject('Error loading client secret file: ' + err); console.log('loaded secrets...'); resolve(JSON.parse(content)); }); }); }
Теперь мы загрузили секреты клиента. Учетные данные будут переданы следующему обещанию. Запустите проект с помощью node .
чтобы убедиться в отсутствии ошибок.
5. Создайте клиент OAuth2.
Чтобы создать слайды, давайте добавим аутентификацию в API Google, добавив следующий код в наш файл auth.js. Эта аутентификация запросит доступ к вашей учетной записи Google для чтения и записи файлов на Google Диске, создания презентаций в Google Slides и выполнения запросов только для чтения из Google BigQuery. (Примечание: мы не меняли getClientSecrets
)
авторизация.js
const fs = require('fs'); const readline = require('readline'); const openurl = require('openurl'); const googleAuth = require('google-auth-library'); const TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE) + '/.credentials/'; const TOKEN_PATH = TOKEN_DIR + 'slides.googleapis.com-nodejs-quickstart.json'; // If modifying these scopes, delete your previously saved credentials // at ~/.credentials/slides.googleapis.com-nodejs-quickstart.json const SCOPES = [ 'https://www.googleapis.com/auth/presentations', // needed to create slides 'https://www.googleapis.com/auth/drive', // read and write files 'https://www.googleapis.com/auth/bigquery.readonly' // needed for bigquery ]; /** * Loads client secrets from a local file. * @return {Promise} A promise to return the secrets. */ module.exports.getClientSecrets = () => { return new Promise((resolve, reject) => { fs.readFile('client_secret.json', (err, content) => { if (err) return reject('Error loading client secret file: ' + err); console.log('loaded secrets...'); resolve(JSON.parse(content)); }); }); } /** * Create an OAuth2 client promise with the given credentials. * @param {Object} credentials The authorization client credentials. * @param {function} callback The callback for the authorized client. * @return {Promise} A promise to return the OAuth client. */ module.exports.authorize = (credentials) => { return new Promise((resolve, reject) => { console.log('authorizing...'); const clientSecret = credentials.installed.client_secret; const clientId = credentials.installed.client_id; const redirectUrl = credentials.installed.redirect_uris[0]; const auth = new googleAuth(); const oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl); // Check if we have previously stored a token. fs.readFile(TOKEN_PATH, (err, token) => { if (err) { getNewToken(oauth2Client).then(() => { resolve(oauth2Client); }); } else { oauth2Client.credentials = JSON.parse(token); resolve(oauth2Client); } }); }); } /** * Get and store new token after prompting for user authorization, and then * fulfills the promise. Modifies the `oauth2Client` object. * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for. * @return {Promise} A promise to modify the oauth2Client credentials. */ function getNewToken(oauth2Client) { console.log('getting new auth token...'); openurl.open(oauth2Client.generateAuthUrl({ access_type: 'offline', scope: SCOPES })); console.log(''); // \n return new Promise((resolve, reject) => { const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question('Enter the code from that page here: ', (code) => { rl.close(); oauth2Client.getToken(code, (err, token) => { if (err) return reject(err); oauth2Client.credentials = token; let storeTokenErr = storeToken(token); if (storeTokenErr) return reject(storeTokenErr); resolve(); }); }); }); } /** * Store token to disk be used in later program executions. * @param {Object} token The token to store to disk. * @return {Error?} Returns an error or undefined if there is no error. */ function storeToken(token) { try { fs.mkdirSync(TOKEN_DIR); fs.writeFileSync(TOKEN_PATH, JSON.stringify(token)); } catch (err) { if (err.code != 'EEXIST') return err; } console.log('Token stored to ' + TOKEN_PATH); }
6. Настройте BigQuery
Изучите BigQuery (необязательно)
BigQuery позволяет нам запрашивать огромные наборы данных за считанные секунды. Давайте воспользуемся веб-интерфейсом, прежде чем делать программный запрос. Если вы никогда раньше не настраивали BigQuery, выполните действия, описанные в этом кратком руководстве .
Откройте Cloud Console , чтобы просмотреть данные GitHub, доступные в BigQuery, и выполнить собственные запросы. Давайте узнаем самые популярные лицензии на программное обеспечение на GitHub, написав этот запрос и нажав кнопку «Выполнить» .
bigquery.sql
WITH AllLicenses AS ( SELECT * FROM `bigquery-public-data.github_repos.licenses` ) SELECT license, COUNT(*) AS count, ROUND((COUNT(*) / (SELECT COUNT(*) FROM AllLicenses)) * 100, 2) AS percent FROM `bigquery-public-data.github_repos.licenses` GROUP BY license ORDER BY count DESC LIMIT 10
Мы только что проанализировали миллионы публичных репозиториев на GitHub и выявили самые популярные лицензии. Прохладный! Теперь давайте настроим выполнение того же запроса, но на этот раз программно.
Настройка BigQuery
Замените код в файле license.js
. Функция bigquery.query
вернет обещание .
лицензия **.js**
const google = require('googleapis'); const read = require('read-file'); const BigQuery = require('@google-cloud/bigquery'); const bigquery = BigQuery({ credentials: require('./service_account_secret.json') }); // See codelab for other queries. const query = ` WITH AllLicenses AS ( SELECT * FROM \`bigquery-public-data.github_repos.licenses\` ) SELECT license, COUNT(*) AS count, ROUND((COUNT(*) / (SELECT COUNT(*) FROM AllLicenses)) * 100, 2) AS percent FROM \`bigquery-public-data.github_repos.licenses\` GROUP BY license ORDER BY count DESC LIMIT 10 `; /** * Get the license data from BigQuery and our license data. * @return {Promise} A promise to return an object of licenses keyed by name. */ module.exports.getLicenseData = (auth) => { console.log('querying BigQuery...'); return bigquery.query({ query, useLegacySql: false, useQueryCache: true, }).then(bqData => Promise.all(bqData[0].map(getLicenseText))) .then(licenseData => new Promise((resolve, reject) => { resolve([auth, licenseData]); })) .catch((err) => console.error('BigQuery error:', err)); } /** * Gets a promise to get the license text about a license * @param {object} licenseDatum An object with the license's * `license`, `count`, and `percent` * @return {Promise} A promise to return license data with license text. */ function getLicenseText(licenseDatum) { const licenseName = licenseDatum.license; return new Promise((resolve, reject) => { read(`licenses/${licenseName}.txt`, 'utf8', (err, buffer) => { if (err) return reject(err); resolve({ licenseName, count: licenseDatum.count, percent: licenseDatum.percent, license: buffer.substring(0, 1200) // first 1200 characters }); }); }); }
Попробуйте console.log
некоторые данные внутри обратного вызова нашего промиса, чтобы понять структуру наших объектов и увидеть работу кода в действии.
7. Создайте слайды
Теперь самое интересное! Давайте создадим слайды, вызвав методы create
и batchUpdate
API Slides. Наш файл следует заменить следующим:
слайды.js
const google = require('googleapis'); const slides = google.slides('v1'); const drive = google.drive('v3'); const openurl = require('openurl'); const commaNumber = require('comma-number'); const SLIDE_TITLE_TEXT = 'Open Source Licenses Analysis'; /** * Get a single slide json request * @param {object} licenseData data about the license * @param {object} index the slide index * @return {object} The json for the Slides API * @example licenseData: { * "licenseName": "mit", * "percent": "12.5", * "count": "1667029" * license:"<body>" * } * @example index: 3 */ function createSlideJSON(licenseData, index) { // Then update the slides. const ID_TITLE_SLIDE = 'id_title_slide'; const ID_TITLE_SLIDE_TITLE = 'id_title_slide_title'; const ID_TITLE_SLIDE_BODY = 'id_title_slide_body'; return [{ // Creates a "TITLE_AND_BODY" slide with objectId references createSlide: { objectId: `${ID_TITLE_SLIDE}_${index}`, slideLayoutReference: { predefinedLayout: 'TITLE_AND_BODY' }, placeholderIdMappings: [{ layoutPlaceholder: { type: 'TITLE' }, objectId: `${ID_TITLE_SLIDE_TITLE}_${index}` }, { layoutPlaceholder: { type: 'BODY' }, objectId: `${ID_TITLE_SLIDE_BODY}_${index}` }] } }, { // Inserts the license name, percent, and count in the title insertText: { objectId: `${ID_TITLE_SLIDE_TITLE}_${index}`, text: `#${index + 1} ${licenseData.licenseName} — ~${licenseData.percent}% (${commaNumber(licenseData.count)} repos)` } }, { // Inserts the license in the text body paragraph insertText: { objectId: `${ID_TITLE_SLIDE_BODY}_${index}`, text: licenseData.license } }, { // Formats the slide paragraph's font updateParagraphStyle: { objectId: `${ID_TITLE_SLIDE_BODY}_${index}`, fields: '*', style: { lineSpacing: 10, spaceAbove: {magnitude: 0, unit: 'PT'}, spaceBelow: {magnitude: 0, unit: 'PT'}, } } }, { // Formats the slide text style updateTextStyle: { objectId: `${ID_TITLE_SLIDE_BODY}_${index}`, style: { bold: true, italic: true, fontSize: { magnitude: 10, unit: 'PT' } }, fields: '*', } }]; } /** * Creates slides for our presentation. * @param {authAndGHData} An array with our Auth object and the GitHub data. * @return {Promise} A promise to return a new presentation. * @see https://developers.google.com/apis-explorer/#p/slides/v1/ */ module.exports.createSlides = (authAndGHData) => new Promise((resolve, reject) => { console.log('creating slides...'); const [auth, ghData] = authAndGHData; // First copy the template slide from drive. drive.files.copy({ auth: auth, fileId: '1toV2zL0PrXJOfFJU-NYDKbPx9W0C4I-I8iT85TS0fik', fields: 'id,name,webViewLink', resource: { name: SLIDE_TITLE_TEXT } }, (err, presentation) => { if (err) return reject(err); const allSlides = ghData.map((data, index) => createSlideJSON(data, index)); slideRequests = [].concat.apply([], allSlides); // flatten the slide requests slideRequests.push({ replaceAllText: { replaceText: SLIDE_TITLE_TEXT, containsText: { text: '{{TITLE}}' } } }) // Execute the requests slides.presentations.batchUpdate({ auth: auth, presentationId: presentation.id, resource: { requests: slideRequests } }, (err, res) => { if (err) { reject(err); } else { resolve(presentation); } }); }); });
8. Открытие слайдов
Наконец, давайте откроем презентацию в браузере. Обновите следующий метод в slides.js
.
слайды.js
/** * Opens a presentation in a browser. * @param {String} presentation The presentation object. */ module.exports.openSlidesInBrowser = (presentation) => { console.log('Presentation URL:', presentation.webViewLink); openurl.open(presentation.webViewLink); }
Запустите проект в последний раз, чтобы увидеть окончательный результат.
9. Поздравляем!
Вы успешно создали Google Slides на основе данных, проанализированных с помощью BigQuery. Ваш скрипт создает презентацию с использованием API Google Slides и BigQuery для анализа наиболее распространенных лицензий на программное обеспечение.
Возможные улучшения
Вот несколько дополнительных идей для еще более привлекательной интеграции:
- Добавляйте изображения на каждый слайд
- Поделитесь своими слайдами по электронной почте с помощью API Gmail.
- Настройте слайд шаблона в качестве аргумента командной строки.
Узнать больше
- Прочтите документацию для разработчиков Google Slides API .
- Задавайте вопросы и ищите ответы на Stack Overflow под тегом google-slides-api .