Pull to refresh

Импорт словаря в Lingualeo.com

Reading time 3 min
Views 23K


Предыстория


Для импорта слов в Lingualeo.com есть несколько решений:

  • Приложения для браузера или телефонов:
  • Добавление слов на сайте.

Минусы этих способов в том, что вносить слова можно только по одному. Нам необходима реализация, которая позволит добавлять несколько слов за раз.

Должно же быть API?


Официального api найти не удалось. НО! Есть расширения для браузера, а это отличный способ найти внутренний api для сервиса.
Заходим в Google Chrome и топаем на сайт сервиса. Внизу страницы предлагаются приложения и расширения. Выбираем для Chrome. Браузер устанавливает расширение в папку Extensions (полный путь не указываю, зависит от OS). Внутри директории будет несколько папок с хешами в виде названий. Выбираем последнюю по дате. Внутри можно найти файл config.js — в нем и хранятся все пути к API проекта. Нас интересуют только три из них:

  • /api/login
  • /gettranslates
  • /addword

На чем писать?


Выбрал python, т.к. устанавливается по умолчанию на большинство OS. Модули берем те, которые не требуют дополнительной установки. Реализуем решение для работы с api.

service.py
import urllib
import urllib2
import json
from cookielib import CookieJar


class Lingualeo:
    def __init__(self, email, password):
        self.email = email
        self.password = password
        self.cj = CookieJar()

    def auth(self):
        url = "http://api.lingualeo.com/api/login"
        values = {
            "email": self.email,
            "password": self.password
        }

        return self.get_content(url, values)

    def add_word(self, word, tword, context):
        url = "http://api.lingualeo.com/addword"
        values = {
            "word": word,
            "tword": tword,
            "context": context,
        }
        self.get_content(url, values)

    def get_translates(self, word):
        url = "http://api.lingualeo.com/gettranslates?word=" + urllib.quote_plus(word)

        try:
            result = self.get_content(url, {})
            translate = result["translate"][0]
            return {
                "is_exist": translate["is_user"],
                "word": word,
                "tword": translate["value"].encode("utf-8")
            }
        except Exception as e:
            return e.message

    def get_content(self, url, values):
        data = urllib.urlencode(values)

        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj))
        req = opener.open(url, data)

        return json.loads(req.read())


Изначальное решение было только для текстовых файлов. Каждое слово должно быть на новой строке. Но в процессе написания кода, решил добавить реализацию для Kindle, т.к. переодически с него тоже необходимо забирать слова.

handler.py
class Word:
    text = '';
    context = '';

    def __init__(self, text):
        self.text = text

class Base(object):
    data = []

    def __init__(self, source):
        self.source = source

    def get(self):
        return self.data

    def read(self):
        raise NotImplementedError('Not implemented yet')


class Kindle(Base):
    def read(self):
        conn = sqlite3.connect(self.source)
        sql = 'select word, usage from words LEFT JOIN LOOKUPS ON words.id = LOOKUPS.word_key where words.lang="en" GROUP BY word ORDER BY word;'
        for row in conn.execute(sql):
            if isinstance(row[0], unicode):
                word = Word(row[0])
                if isinstance(row[1], unicode):
                    word.context = row[1]
                self.data.append(word)
        conn.close()


class Text(Base):
    def read(self):
        f = open(self.source)
        for word in f.readlines():
            self.data.append(Word(word))
        f.close()


И реализация самого скрипта для экспорта/импорта слов:

export.py
import handler
import config
import service
import sys

email = config.auth.get('email')
password = config.auth.get('password')

export_type = sys.argv[1]

if export_type == 'text':
    word_handler = handler.Text(config.sources.get('text'))
elif export_type == 'kindle':
    word_handler = handler.Kindle(config.sources.get('kindle'))
else:
    raise Exception('unsupported type')

word_handler.read()

lingualeo = service.Lingualeo(email, password)
lingualeo.auth()

for word_dto in word_handler.get():
    word = word_dto.text.lower().encode('utf-8')
    translate = lingualeo.get_translates(word)

    if translate["is_exist"]:
        print "Already exists: " + word.strip()
    else:
        context = word_dto.context.encode('utf-8')
        lingualeo.add_word(word, translate["tword"], context)
        print "Add word: " + word.strip()


Запуск и установка


Скачиваем код с github. Создаем файл config.py из config.py.dist. Прописываем путь до файла со словами. В случаем с kindle до sqlite базы внутри kindle.

python export.py text #Для текстовых файлов
python export.py kindle #Для kindle

Исходники


GitHub: lingualeo.export.
Tags:
Hubs:
+10
Comments 16
Comments Comments 16

Articles