• Как работать с китайским POS принтером из Java в linux?

    @klirichek
    Это линейный принтер (lp). Он может просто печатать напрямую текст, который в него отправляют (т.е. просто открываете нужный порт и шлёте в него байтики).
    С помощью escape-последовательностей можно переключать принтер в графический режим и управлять дополнительными фичами, специфическими для POS (например, открывать крышку кассы. Или автоматически печатать штрих-код).
    Т.е. в простейшем случае - переводите принтер в нужную кодовую страницу с помощью esc-последовательности и потом просто шлёте в него текст в нужной кодировке.

    Если воспользоваться драйвером, то все возможности принтера сводятся к графической печати (это растровый фильтр CUPS. И, кстати @ntkt не совсем прав насчёт поддержки PostScript. PPD файлы в cups это своя собственная сущность, так у них принято описывать вообще все принтеры.) Тогда у вас появляется "стандартный" принтер с форматом бумаги шириной 58 мм. Весь рендеринг в растр берёт на себя CUPS, а фильтр лишь парсит настройки печати и затем добавляет нужные escape-последоватльности для вывода растра.

    К слову, фильтр, похоже, был написан индусами :)
    Настройки в PPD не показывает, а сам вылетает. Да и к тому же предоставлен только в виде 32-битного бинаря. Я провозился с ним пару дней, пытаясь настроить. В итоге психанул и написал свой фильтр. Он работает.

    https://github.com/klirichek/zj-58
    Ответ написан
    Комментировать
  • Выход из условия if

    @klirichek
    Оборачиваем в любой цикл. Перед закрывающей скобкой цикла ставим break.
    В условии, где нужно выйти - тоже break.
    for (;;) {
      if( ... ){
        if( .. ){
        } else {
         // здесь нужно выйти из условия
        break;
        }
      }
    break;}


    (то же самое)
    while (true) {
      if( ... ){
        if( .. ){
        } else {
         // здесь нужно выйти из условия
        break;
        }
      }
    break;}


    (то же самое)
    do {
      if( ... ){
        if( .. ){
        } else {
         // здесь нужно выйти из условия
        break;
        }
      }
    break; } while (true);


    (то же самое)
    do {
      if( ... ){
        if( .. ){
        } else {
         // здесь нужно выйти из условия
        break;
        }
      }
    } while (false);


    Ну и стОит заметить, что если не пугаться goto, то ровно так же можно заюзать и его.
    (в дизасме получится в точности то же, что и с циклами)
    Ответ написан
    1 комментарий
  • Чем сжать pdf-файл?

    @klirichek
    Всё зависит от характера изображений.
    Если это сканы печатного текста - можно распознать или пустить в djvu.
    Если это штриховая чёрно-белая графика (без полутонов) - можно пережать в CCIT-4 (факсовое сжатие) и положить назад.
    Ответ написан
    Комментировать
  • В чем отличие void от return на примере?

    @klirichek
    Какое значение из void?
    Ты же вызываешь просто:
    nn.GetJazz(12,12);
    и только потом уже, следующим оператором печатаешь поле nn.c
    Первая строчка просто вызывает метод (в данном случае - процедуру), который ничего не возвращает (т.е. "возвращает" void)
    А второй строчкой ты смотришь содержимое поля c у своего класса.
    Это РАЗНЫЕ строки; между собой никак не связанные!

    Убери у себя c=a+b и оставь просто a+b - и всё, выведется лишь сумма изнутри метода.

    Ровно так же ты можешь написать и
    sin(c=a+b)
    Это будет означать, что сперва вычислится сумма a+b, её значение будет присвоено c и одновременно возвращено как значение выражения с=a+b.
    От значения этого выражения будет взят синус. Но он никуда не будет присвоен; просто займёт проц вычислениями, а результат будет выброшен.
    В результате ты так же получишь значение c. Однако значение синуса - нет :).
    Ответ написан
    Комментировать
  • Как получить список физических жёстких дисков в системе и места их монтирования?

    @klirichek
    Запуск strace lsbkl говорит, что последний читает /sys/block и как-то интерпретирует прочитанное.
    Может вам так же попробовать, напрямую?
    Ну или исходники его посмотреть, в конце концов.
    Ответ написан
    2 комментария
  • Как в Sphinx реализовать поиск по подстроке с учетом морфологии?

    @klirichek
    Вы кроме догадок ещё выхлоп фактических ключевых слов посмотрите.
    (в api есть в резултсете; в sphinxql нужно сказать show meta сразу после select)
    Ответ написан
    Комментировать
  • Размещение MySQL + Sphinx + отдача файлов

    @klirichek
    В сфинксе io-нагрузка в основном при старте/ротации индекса. А при поиске словарь и атрибуты лежат в памяти, с диска идёт обращение на чтение только к файлам spd/spp (случайное)
    Ответ написан
    Комментировать
  • Ошибка при создании и изменении таблицы с движком SPHINX?

    @klirichek
    Индекс создали, ок. А демона запустили? Который слушает localhost:9312 и обслуживает созданный индекс?
    Ответ написан
  • Sphinx: долгая загрузка тестовой php страницы - это нормально?

    @klirichek
    Скорее всего с портом намудрили.
    Дефолтный порт API - 9312.
    А 9306 - это для sphinxql.
    Ответ написан
    Комментировать
  • Как заставить Sphinx Search искать "*" в индексе?

    @klirichek
    Кстати, enable_star тут в любом случае не очень уместно. Звёздочка в этом случае будет спец.символом.
    Даже как багу зафиксят, останется разве что создавать индекс-дубль, где enable_star=0 и вручную рулить туда запросы на чистую "*".
    Ответ написан
    Комментировать
  • Как заставить Sphinx Search искать "*" в индексе?

    @klirichek
    Слова со звёздочкой в середине ищет.
    А вот обособленную звёздочку (where match ('*')) не желает. Более того, роняет демона.
    Похоже, бага
    Ответ написан
  • Как найти вхождения сотен поисковых фраз в большом тексте (PHP, MySQL)?

    @klirichek
    В принципе, можно попробовать сделать в один проход.
    Для каждой фразы делаем ДКА состояний - чтоб ловить поступающие слова и двигать состояние вперёд, если совпадает с ожидающим следующим словом. Если слова закончились - запоминать найденную позицию и сбрасывать состояние. Если новое слово не совпадает - просто сбрасывать состояние.
    А дальше - организуем "игру в лото". Проходимся один раз по тексту от начала до конца и "объявляем" всем участвующим ДКА каждое слово. В конце залезаем в них и получаем списки "выигравших" позиций для каждой фразы.
    Это в общем. А дальше можно оптимизировать - например, сравнивать не слова, а хэшики от них.
    И не "объявлять" каждому "игроку" каждое слово, а собирать у них множество ожидаемых ими хэшиков - и если текущий попадает в множество - двигать состояния у "выигравших", а у всех остальных - сбрасывать.
    Ещё шаг - сделать не одно, а два множества. В одном - хэшики тех, что в начальном состоянии (при сбросе они не меняются -> не нужно читать значения заново). Во втором - "играющие".

    Здесь нужно побенчить по сравнению с indexof. Последний внутри себя, конечно, будет работать быстрее, чем аналогичный "самописный", однако на определённых параметрах (совокупность размера входного текста вместе с количеством и размером искомых фраз) уже может вполне его обойти за счёт меньшей сложности.
    Ответ написан
    Комментировать
  • Поиск по параметрам на Sphinx API (php): нужен пинок?

    @klirichek
    OR не поддерживается только в правой части (после where). Однако ничего не мешает сделать нужное выражение в select-листе и заалиасить.
    (вроде select ... (attr OR attr between 30 and 100) as expr... where expr...)
    Ответ написан
  • Есть ли русский стемминг и поиск с учетом морфологии под мобильные платформы?

    @klirichek
    А собрать нативно sphinx под платформу не пробовали?
    Если выбросить все источники данных, то уйдут практически все завимости.
    Морфология (лемматизатор aot) заработает. Сеть, строго говоря, не нужна (прослушки localhost или вообще unix-socket вполне хватит).
    Ответ написан
    Комментировать
  • Sphinx: получить количество значений mva-атрибута?

    @klirichek
    MVA - не vector а set.
    В нём сохраняется не всё подряд, как засунули - а только уникальные значения по возрастанию:
    - вставляете в атрибут (10,10,11,11,43,43,12,12)
    - по факту получаете там (10,11,12,43)

    У вас в принципе можно вообще сделать union и определить в индексе два поля - описание и "отзывы" (второе - joined_field из всех отзывов на данный товар) (при ft-поиске вам же неважно, какие именно отзывы; главное, чтобы те, что относятся к конкретному товару).
    id-шки отзывов (если вдруг нужны) можно положить в mva. Там же положить отдельный атрибут с их количеством.
    Получается схема вроде:
    a_product_id, f_description, f_joined_feedbacks, mva_feedbacks_ids, a_feedbacks_count
    Ответ написан
    Комментировать
  • Sphinx сопоставление индекса найденного значения одного MVA поля с другим?

    @klirichek
    Да, тут "в лоб" задача вообще не решаемая.
    у MVA НЕТ никаких индексов. Это аналог структуры Set, а не Vector. Внутри он для удобства хранится в отсортированном по возрастанию виде. Соответственно, ровно в момент когда вы поместите туда prices - дубли уберутся, сами цены отсортируются - и вся предполагаемая схема "развалится".
    Так что ваш вариант с включением цены в "primary key" - вполне хорош.
    Ещё (как вариация того же самого) можно положить цену в отдельное ft-поле (тогда в поиске получится что-то вроде '@title iPhone 5S @price 2500'. Или (ещё вариант) не в поле а в спец.токен ("price2500").
    Ответ написан
    Комментировать
  • Как реализовать алгоритм поиска по имени и/или фамилии?

    @klirichek
    Да, это напрямую паттерн для сфинкса. Никаких особых ухищрений или преобразований не потребуется. Прямо так и индексируйте - имя в одном поле, фамилию в другом. Запрос "Вася пупкин" выдаст желаемое; кроме того можно делать селективный поиск типа "@name Вася" - только по полю "name".
    Абсолютно так же добавите никнейм (просто добавите колонку в выдачу rowset при индексации; а если там какой-нибудь select * - то даже конфиг сфинкса трогать не нужно; добавите колонку в таблице, а потом переиндексируете и всё "подхватится")
    Ответ написан
    1 комментарий
  • Транслитерация в поиске

    @klirichek
    Можно charset_table настроить так, чтобы все русские буквы маппились сразу в латинницу. Проблема в том, что соответствие будет только буква-в-букву (т.е. отобразить ф->f можно, а вот ж->zh уже нет; нужно придумывать ОДНУ букву-соответствие.
    Но в вашем случае - a..zA..Z, Н->N о->o к->k и->i я->a (а также все остальные буквы)
    как раз приведёт к тому, что и Нокия и 'Nokia' - это будет одно и то же слово.
    Ответ написан
    Комментировать
  • Как настроить физический размер монитора в Ubuntu?

    @klirichek Автор вопроса
    В общем, практически получилось. За исключением одного момента, но о нём позже.

    Лезть в глобальные настройки xorg я не стал.
    Утверждение о неучёте DPI тоже оказалось не совсем верным.

    Шаг номер раз: смотрим, как оно сейчас.
    alexey@vubuntu:~$ xrandr
    Screen 0: minimum 320 x 200, current 2880 x 1024, maximum 8192 x 8192
    LVDS1 connected 1600x900+0+124 (normal left inverted right x axis y axis) 309mm x 174mm
       1600x900       60.0*+   40.0  
       1440x900       59.9  
       1360x768       59.8     60.0  
       1152x864       60.0  
       1024x768       60.0  
       800x600        60.3     56.2  
       640x480        59.9  
    VGA1 disconnected (normal left inverted right x axis y axis)
    HDMI1 connected 1280x1024+1600+0 (normal left inverted right x axis y axis) 338mm x 270mm
       1280x1024      60.0*+   75.0  
       1152x864       75.0  
       1024x768       75.1     70.1     60.0  
       832x624        74.6  
       800x600        72.2     75.0     60.3     56.2  
       640x480        72.8     75.0     66.7     60.0  
       720x400        70.1  
    DP1 disconnected (normal left inverted right x axis y axis)
    HDMI2 disconnected (normal left inverted right x axis y axis)
    HDMI3 disconnected (normal left inverted right x axis y axis)
    DP2 disconnected (normal left inverted right x axis y axis)
    DP3 disconnected (normal left inverted right x axis y axis)


    — сразу видно и разрешение, и физические размеры мониторов.
    Что мешает системе учесть физические размеры сразу? Неизвестно. Но факт в том, что они есть, и они верные.

    Шаг номер два. Вычисляем коэффициент масштабирования (ну, привык я пятоном пользоваться, как калькулятором):

    alexey@vubuntu:~$ python
    Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
    [GCC 4.6.3] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 900/174.0
    5.172413793103448
    >>> 1024/270.0
    3.7925925925925927
    >>> 5.1724/3.79259
    1.3638173385470087
    >>>
    


    Шаг номер три: применяем полученный коэффициент и смотрим, что в итоге получилось:
    alexey@vubuntu:~$ xrandr --output HDMI1 --scale 1.3638x1.3638
    alexey@vubuntu:~$ xrandr
    Screen 0: minimum 320 x 200, current 3346 x 1397, maximum 8192 x 8192
    LVDS1 connected 1600x900+0+124 (normal left inverted right x axis y axis) 309mm x 174mm
       1600x900       60.0*+   40.0  
       1440x900       59.9  
       1360x768       59.8     60.0  
       1152x864       60.0  
       1024x768       60.0  
       800x600        60.3     56.2  
       640x480        59.9  
    VGA1 disconnected (normal left inverted right x axis y axis)
    HDMI1 connected 1746x1397+1600+0 (normal left inverted right x axis y axis) 338mm x 270mm
       1280x1024      60.0*+   75.0  
       1152x864       75.0  
       1024x768       75.1     70.1     60.0  
       832x624        74.6  
       800x600        72.2     75.0     60.3     56.2  
       640x480        72.8     75.0     66.7     60.0  
       720x400        70.1  
    DP1 disconnected (normal left inverted right x axis y axis)
    HDMI2 disconnected (normal left inverted right x axis y axis)
    HDMI3 disconnected (normal left inverted right x axis y axis)
    DP2 disconnected (normal left inverted right x axis y axis)
    DP3 disconnected (normal left inverted right x axis y axis)
    


    Это уже похоже на правду!
    Остался один момент: мониторы выровнены по нижнему краю. В начальном варианте это означало, что левый смещён на (1024-900)-124 пикселя по вертикали. Теперь «большой» стал имитировать вертикальное разрешение уже 1397; стал быть смещение нужно задать в 497 пикселей:

    alexey@vubuntu:~$ xrandr --output LVDS1 --pos 0x497


    Получилось вот так:
    image

    Но один момент остался — это координаты мыши. Она по-прежнему думает, что имеет дело с 1280х1024 — и поэтому на отмасштабированном мониторе при перемещении вниз/вправо в конце концов упирается в эту невидимую границу. На картинке на большом мониторе мышь видно в её самой нижней-правой возможной позиции (т.е. там её нельзя сдвинуть ни ниже, ни правее).

    Если кто подскажет, как побороть и этот момент тоже — буду премного благодарен!
    Ответ написан