Evernote
Компания
44,85
рейтинг
21 апреля 2009 в 12:59

Разное → Evernote API или Что внутри слона?

В комментариях к нашим предыдущим записям в блоге на Хабре мы упомянули о том, что Evernote имеет собственный API. Сейчас я хочу рассказать о нем подробнее.


Когда мы только разрабатывали протокол синхронизации для Evernote, мы хотели добиться кроссплатформенности решения (веб-часть написана на Java, клиент для Windows и Windows Mobile — на C++, клиенты для Mac и iPhone на Objective C). Нужно было что-то, что позволит легко имплементировать этот протокол на разных клиентах и позволять расширять этот протокол по необходимости. Помимо этого, нам хотелось обеспечить передачу бинарных данных по данному протоколу, дабы уменьшить объем передаваемых данных. Выбор пал на Thrift, протокол, использовавшийся (и до сих пор использующийся) в Facebook, а ныне ставший опенсорсным проектом под крылом Apache Incubator. Разрабочики Evernote даже приложили свою руку к развитию проекта, исправляя ошибки и дорабатывая Java, Objective C и Perl-реализациии Thrift.

Что такое Thrift?

Thrift — это реализация RPC, позволяющая удаленно вызывать функции на сервере. Thrift состоит из трех основных вещей:
  1. бинарный протокол — способ упаковки структур данных;
  2. собственный декларативный язык описания объектов, их свойств и методов;
  3. генераторы кода для разных языков (Java, C, Ruby, Python, Perl, PHP и др.), которые на основе описанных объектов генерируют родной код, позволяющий получать объекты с сервера и вызывать их методы совершенно прозрачно.

Итак, Evernote API — это не что иное как реализация специфических для нас объектов (Пользователь, Блокнот, Заметка и т.д.) и их свойств, описанных на языке Thrift. Все существующие клиенты Evernote сами используют это API, так что здесь нет разделения на «свой-чужой». Все приложения — как наши, так и сторонние — равноправны и пользуются одними и теми же функциями.

Для чего нужен Evernote API?

Существует два основных способа исппользования API:

1) Написание клиентских приложений для Evernote. В этом случае клиентское приложение авторизуется в системе под именем и паролем конкретного пользователя и получает доступ ко всем объектам. Этот способ должен использоваться теми сервисами, которые подразумевают работу только с одним конкретным пользователем Evernote.

2) Написание модулей интеграции (плагинов) для работы сторонних сервисов с самой системой. В этом случае мы используем протокол OAuth, который дает возможность пользователям Evernote предоставлять ограниченный доступ внешним приложениям к своему аккаунту без необходимости раскрывать свой пароль. Этот способ должен использоваться теми сервисами, которые подразумевают работу с несколькими пользователями Evernote.

Идеи использования Evernote API

1) Плагин для популярного движка для блогов (типа WordPress), автоматически публикующий в блоге заметки из определенного блокнота в Evernote. Зачем? Представьте, что вы можете подготавливать посты для блога в офлайне, на любом клиенте Evernote. Там же, где и собирать информацию для своего блога. Это удобство ввода информации, предоставляемое Evernote и огромные возможности настройки внешнего вида и комментирования записей, предоставляемые движками блогов.

2) Специфические клиенты и клипперы. Например, приложение, распознающее с фотокамеры шрихкод, получающее по этому штрихкоду сведения в Интернете и формирующее заметку в Evernote. Зачем? Вы ходите по магазину, фотографируете ценники товаров (например, книг) на свой телефон, а дома в Evernote уже сравниваете понравившиеся товары, получаете по ним дополнительные сведения, цены из Интернет-магазинов. Сюда же можно отнести захват фото с веб-камер или интеграция со сканерами через TWAIN.

3) Связь с системами планирования дел. Представьте, что вы с любого клиента Evernote вводите заметки вида «завтра в одиннадцать деловая встреча в офисе», а задача с напоминанием попадает в сервис, подобный Google Calendar, Remember The Milk, который впоследствии оповестит вас о запланированном деле по SMS или электронной почте.

4) По аналогии с интеграцией Evernote и Твиттера, можно придумать сервисы импорта из ICQ, XMPP (Jabber), c помощью SMS.

Я думаю, что вы сами придумаете и другие интересные способы интеграции с Evernote, о которых мы даже не догадываемся. Уже насчитывается 900 000 пользователей Evernote по всему миру, и взаимодействие с Evernote — это хороший шанс повысить ценность вашего продукта. Про некоторые из реализованных примеров интеграции можно прочитать в нашем англоязычном блоге.

С чего начать?

Попробовать наше API очень просто — скачайте нужный SDK на этой странице, в котором есть примеры использования и интерфейсные библиотеки и отправьте там же запрос на получение API-ключа, вкратце написав о себе (название проекта, для чего API нужен и как будет использоваться). После получения ключа можно смело экспериментировать с нашим API на специальном тестовом сервере-«песочнице», не боясь сделать что-то не то. Обратите внимание, что для работы в «песочнице» там надо завести отдельный аккаунт пользователя Evernote, ибо на этом сервере используется своя база пользователей, не пересекающаяся с основной.

Не забывайте посещать наш форум для разработчиков и задавать там любые вопросы по API. Или спрашивайте здесь — постараемся помочь.

Отдельно стоит отметить, что лицензия на Evernote API не ограничивает разработчиков в способе распространения приложений. Это могут быть бесплатные и коммерческие разработки, open-source проекты и проекты с закрытыми исходниками. Тут все остается на ваше усмотрение.

Пример кода

Напоследок приведу пример кода на Python, авторизующего пользователя по его имени и паролю, читающего из STDIN тело заметки и создающего заметку на сервере:
  1. #!/usr/bin/python
  2. # coding=utf-8
  3.  
  4. # импортируем модули (поставляются с Evernote API)
  5. import time
  6. import thrift.transport.THttpClient as THttpClient
  7. import thrift.protocol.TBinaryProtocol as TBinaryProtocol
  8. import evernote.edam.userstore.UserStore as UserStore
  9. import evernote.edam.userstore.constants as UserStoreConstants
  10. import evernote.edam.notestore.NoteStore as NoteStore
  11. import evernote.edam.type.ttypes as Types
  12.  
  13. # настраиваем параметры сервера
  14. edamHost = "sandbox.evernote.com" # сервер-"песочница", на котором можно эксперименитровать
  15. edamPort = 443
  16.  
  17. # настраиваем параметры авторизации
  18. consumerKey = "your-api-key-here!" # ключ, полученный от Evernote
  19. consumerSecret = "your-api-secret-here!" # секретная часть ключа, полученного от Evernote
  20. username = "your-username" # имя пользователя в Evernote (на сервере sandbox.evernote.com)
  21. password = "your-password" # пароль пользователя в Evernote
  22.  
  23. # создаем подключение по HTTP к UserStore (хранилищу объектов типа Пользователь)
  24. userStoreHttpClient = THttpClient.THttpClient(edamHost, edamPort, "/edam/user")
  25. userStoreProtocol = TBinaryProtocol.TBinaryProtocol(userStoreHttpClient)
  26. userStore = UserStore.Client(userStoreProtocol)
  27.  
  28. # убеждаемся, что версия нашего клиента не устарела
  29. versionOK = userStore.checkVersion("Python EDAMTest",
  30.     UserStoreConstants.EDAM_VERSION_MAJOR,
  31.     UserStoreConstants.EDAM_VERSION_MINOR)
  32.  
  33. print "Is my EDAM protocol version up to date? ", str(versionOK)
  34. if not versionOK:
  35.     exit(1)
  36.  
  37. # авторизуем пользователя по имени и паролю
  38. authResult = userStore.authenticate(username, password, consumerKey, consumerSecret)
  39. # получаем объект User
  40. user = authResult.user
  41.  
  42. # получаем токен авторизации для последующих запросов к серверу
  43. authToken = authResult.authenticationToken
  44.  
  45. print "Authentication was successful for ", user.username
  46. print "Authentication token = ", authToken
  47.  
  48. # создаем подключение по HTTP к NoteStore (хранилищу объектов типа Заметка)
  49. noteStoreUri = "/edam/note/" + user.shardId
  50. noteStoreHttpClient = THttpClient.THttpClient(edamHost, edamPort, noteStoreUri)
  51. noteStoreProtocol = TBinaryProtocol.TBinaryProtocol(noteStoreHttpClient)
  52. noteStore = NoteStore.Client(noteStoreProtocol)
  53.  
  54. # получаем список блокнотов
  55. notebooks = noteStore.listNotebooks(authToken)
  56.  
  57. # выводим перечень блокнотов в STDOUT и попутно выясняем,
  58. # какой из блокнотов является блокнотом по умолчанию
  59. print "Found ", len(notebooks), " notebooks:"
  60. for notebook in notebooks:
  61.     print " * ", notebook.name
  62.     if notebook.defaultNotebook:
  63.         defaultNotebook = notebook
  64.  
  65. # переходим к созданию заметки в блокноте по умолчанию
  66.  
  67. print
  68. print "Creating a new note in default notebook: ", defaultNotebook.name
  69. print
  70.  
  71. # создаем новый объект типа Заметка
  72. note = Types.Note()
  73.  
  74. # указываем блокнот для данной заметки
  75. note.notebookGuid = defaultNotebook.guid
  76.  
  77. # формируем заголовок
  78. note.title = raw_input("Note title? ").strip()
  79.  
  80. # формируем тело заметки в формате ENML (по сути это XHTML с некоторыми особенностями)
  81. note.content = '<?xml version="1.0" encoding="UTF-8"?>'
  82. note.content += '<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml.dtd">'
  83. note.content += '<en-note>'
  84. note.content += raw_input("Well-formed XHTML note content? ").strip() # вводим XTML из STDIN
  85. note.content += '</en-note>'
  86.  
  87. # задаем текущее время как время создания и модификации заметки
  88. note.created = int(time.time() * 1000) # время указывается в миллисекундах
  89. note.updated = note.created
  90.  
  91. # собственно, создаем заметку на сервере
  92. createdNote = noteStore.createNote(authToken, note)
  93.  
  94. print "Created note: ", str(createdNote)
Автор: @elephant
Evernote
рейтинг 44,85
Компания прекратила активность на сайте

Комментарии (27)

  • –9
    нафиг питон, давай на бейсике
    • +32
      10 BEEP
      20 GOTO 10
    • 0
      Что ж вам всем бейсик так не нравится…
  • 0
    Эх. Клево-клево, только без клиента для Linux грустно очень. Одна из немногих программ, которую действительно бы хотелось. Ну, Q10 еще, ну и Google Chrome, который на подходе) Для меня этих трех программ хватило бы на все мои нужды по учебе и работе)
    • +1
      У меня такое подозрение что пример на Питоне как раз под линуксом будет прекрасно работать.
      Его доработка — дело техники
    • +3
      Ну так API есть, так что ждём появления желающих реализовать :)
    • 0
      А можно полюбопытствовать, что это за Q10 такая?
  • 0
    А можно форум разделить?
    По языкам. Было бы здорово.
    • 0
      По языкам программирования или на английский/русский?
      • 0
        И так и так :)
        • 0
          Если хочется задавать вопросы по API на русском, то можно воспользоваться общим русскоязычным форумом, трафик там небольшой: forum.evernote.com/phpbb/viewforum.php?f=44

          Примерно то же соображение и про разделение на языки программирования: пока трафик в форуме разработчиков небольшой, мы держим один форум (тем более что вопросы у разработчиков обычно схожи и применимы к разным языкам программирования). Когда тем будет много, возможно, разнесем на подфорумы.
  • +4
    P.S. При разработке API ни одного слона не пострадало ;)

    Жуткая картинка.
    • +1
      Картинка, на самом деле, из рекламы Scrabble: samuellam1.wordpress.com/2008/12/01/dabble-in-scrabble/
      :)
    • 0
      Что-то я не верю, что не пострадало. Слона как следует «порезали»
  • +2
    за что вы так слоника, беееедненький
  • +5
    реально неприятная картинка
    • +1
      Напомнило:

  • +1
    Можно дак же для fring модуль написать для работы с evernote. Он своё API для создания аддонов тоже раздаёт и уже достаточно много аддонов полезных написано.
    • 0
      А почему бы тогда сразу для симбы скажем на питоне клиент не написать?
      • 0
        Тогда уж лучше нативный клиент. Тем более что для C++ Thrift-bindings есть уже готовые.
        • 0
          Ну, на питоне по проще и быстрее будет!
  • +2

    А внутри слоника еще один слоник! :-)
  • +3
    Картинка побила по бредовости все виденные мною на Хабре.
  • +3
    Гринписа на вас нехватает!
  • 0
    Подскажите, как возможно написание клиента под Win32 на C++, если на сайте thrift написано, что «you won't be able to compile and run the generated C++ code under Windows» (тут wiki.apache.org/thrift/ThriftInstallationWin32). Все попытки скомпилировать у меня действительно не увенчались успехом. Зачем тогда API под C++?
    • 0
      Зачем тогда API под C++?

      Для линуксоидов! Там тоже есть С++ :)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разное