На днях Symbian Foundation выложили в свободный доступ несколько книг:

Previous ArticleNext Article
Технический директор IT-Dimension, компании-разработчика кросс-платформенного программного обеспечения

This post has 8 Comments

8
  1. Забавно. 2 из трех книг можно было спокойно нарыть в интернете в pdf. Ребята просто распознали текст и выложили на свой сайт.

  2. а смысл распознавать текст и потом выкладывать в pdf? lmao

  3. Ребята, вы думаете у Willey или авторов книг нет первоисточников и они рыли интернет в поисках заботливо отсканированных честными хацкерами pdf’ок, чтобы их потом распознать? Вряд ли. Они взяли ими же написаный и сверстанный docx и сконвертировали в pdf.

  4. мы глупые )))lol
    P.S. а вообще вопрос стоял в другом, зачем распозновать то текст для pdf?

  5. Если я на этот раз правильно понял вопрос – то ля того, чтобы его оттуда копировать.

  6. Ни и поисковиками он индексируется, естесственно

  7. пдф достаточно проблемно редактировать, как следствие я не вижу смысла распознавать картинку\текст чтоб потом засунуть этот текст в сложно редактируемый файл… по этому вижу 2 решения:
    а) коль распознал текст так сохранять его например в html
    б) не распознавать а засовывать страницы в пдф картинками, хотя зачем? 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

P.

Pre-Release Qt for Series 60

Вышел pre-prelease фреймворка Qt для платформы Series 60 под кодовым названием Garden.

В текущей версии доступны:

  • QtCore
  • QtTest
  • QtGui
  • QtNetwork
  • QtScript
  • QtSvg
  • QtXML

Добавлен новый стиль виджетов – QS60Style, имитирующий нативный вид на платформе Series 60.

Х.

ХабраКарма — пишем приложение на Python for S60

Хабрапользователь kAIST любезно предоставил нам статью о создании приложений для S60 на Python, использующих HabraHabr API.

После того, как мы разогрели аппетит к Python for s60 и начали учиться писать приложения, хочу предложить продолжить постигать программирование для symbain на замечательном языке программирования python.

На этот раз сделаем что нибудь полезное, а именно напишем приложение, которое будет показывать карму. Не просто показывать, а выводить поверх всех «окон» табличку, на которой будет значение кармы и разница с предыдущем значением. Помимо этого, программу будет издавать победный гонг при повышении кармы и крик отчаяния при ее понижении. Ко всему прочему, мы запустим ее, как сервер, то есть она не будет отображаться в списке запущенных программ.

Тем, кому больше важен результат, нежели процесс, милости просим в конец статьи, где вас ожидает готовое приложения HabraKarma 1.0 !!!

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

Общие принципы работы

Сама программа будет состоять из 2-х частей: сам сервер, который выполняет всю работу, и GUI, в котором мы будем настраивать работу сервера, запускать его и останавливать.

Сам сервер, запускается функцией start_server из модуля e32. Параметр у функции всего один — полный путь к питоновскому скрипту, который следует запустить в роли сервера. Да да, все так просто, но с некоторыми ограничениями.

Так как сервер работает в фоне, он не может использовать модуль appuifw, отвечающий за UI. Но нам это и не нужно, так как демонстрировать результат работы мы будет, используя модуль topwindow, который позволяет выводить изображения поверх всех «окон». Кроме этого, нам доступен еще один модуль, под названием globalui, который позволяет так же поверх всех «окон», выводить такие вещи, как разные запросы, предупреждения, уведомления и пр. Этим мы тоже воспользуемся, демонстрируя факт запуска и остановки сервера.

Еще одно ограничение, это невозможность доступа к файлам, размещенных в папке с приложением (x:/private/UID). Поэтому, если мы хотим использовать различные мультимедийные файлы, файлы настроек, мы должны положить это в какое нибудь нейтральное место, например в папку x:/system/data/AppName. Эта папка имеет атрибут «скрытый», поэтому помещенные туда картинки не будут видны в галереи, а аудио файлы в медиатеке.

Еще одна проблема, это «оторванность» сервера от основной программы. То есть запустить мы ее может, а вот узнать, запущена ли она, или остановить, при использовании стандартных модулей нельзя. В нашей программе мы поступим следующим образом:

Сервер, при запуске создает файл c названием habra_flag в корне диска D. При завершении работы сервера, этот файл удалим. Теперь, при запуске оболочки, проверим, существует ли искомый файл. Если да, значит сервер считаем запущенным. Кроме этого, нужна возможность остановки сервера. Для этого, в этот самый файл запишем, что нибудь, а на сервере, в цикле, будем проверять. Если длинна файла больше нуля, останавливаем работу.

У некоторых возможно появится вопрос, что за диск D, на который м собираемся писать файл habra_flag. Это ram диск, небольшого объема, который очищается при перезагрузки. Используя его, мы убиваем двух зайцев: при перезагрузки телефона, ручного завершения нашего сервера, файл с флагом исчезнет, и файловая система на ram диске имеет большую производительность. Для более сложного взаимодействия с сервером, можно использовать сокеты.

Пишем UI

Мордой приложения, которое будет запускаться по «клику» на иконку программы, будет класс Form, который практически от и до описан в этой вики статье. Выглядит это вот так:

ХабраКарма - GUI

#coding:utf-8
from appuifw import *
import e32
import os
# папка, в которой лежат файлы настроек, медиа файлы и пр.
data_path=os.getcwd()[]+u':\\System\\data\\HabraKarma\\'

class Main:
    def __init__(self):
        app.screen='normal'
        # читаем файл настроек, который является словарем,
        # тупо сохраненным через repr :)
        self.settings=eval(open(data_path+'set.dat').read())
        # Список полей для нашей формы, вставляем сохраненные значения в ее поля.
        self.fields=[
                (u'Хабраюзер','text',self.settings['user']),
                (u"Автообновление (мин.)",'number', self.settings['time']),
                (u"Включить звук?", 'combo', ([u'Да',u'Нет'], int(self.settings['sound']))),
                (u"Считать разницу", 'combo', ([u'С начала работы',u'С последнего обновления'], int(self.settings['diff']))),
                (u"Положение X",'number', self.settings['X']),
                (u"Положение Y",'number', self.settings['Y']),

                ]
        # создаем форму с флагами
        self.form=Form(self.fields,flags=FFormDoubleSpaced|FFormEditModeOnly)
        # задаем функцию, которая будет сохранять значения из формы
        self.form.save_hook=self.save
        # если сервер уже запущен, то в меню должно быть "остановить" и наоборот
        if os.path.exists(u'd:\\habra_flag'):
            self.form.menu=[(u'Остановить',self.stop)]
        else:
            self.form.menu=[(u'Запустить',self.start_server)]
        # "выполняем" форму, то есть она будет показана на экране, до тех пор пока
        # из нее не выйдем.
        self.form.execute()
        # после выхода из формы, проверяем запущен ли сервер и предлагаем его запустить
        if not os.path.exists(u'd:\\habra_flag'):
            if query(u'Запустить?','query'):
                self.start_server()

    def start_server(self):
        # собственно функция запуска сервера
        self.form.menu=[(u'Остановить',self.stop)]
        e32.start_server(data_path+'server.py')

    def stop(self):
        # функция остановки сервера.
        self.form.menu=[(u'Запустить',self.start_server)]
        open(u'd:\\habra_flag','w').write('stop')

    def save(self,arg=None):
        # берем значения из формы и сохраняем их в файл настроек.
        self.settings['user']=arg[][2]
        self.settings['time']=arg[1][2]
        self.settings['sound']=arg[2][2][1]
        self.settings['diff']=arg[3][2][1]
        self.settings['X']=arg[4][2]
        self.settings['Y']=arg[5][2]
        open(data_path+'set.dat','w').write(repr(self.settings))
        return True

a=Main()

Осталось написать сервер 🙂

#-*-coding:utf-8-*-
import os
import e32
import sys
# перенаправляем ошибки в файл.
sys.stderr=open('d:\\err.txt','w')
import globalui as ui
import topwindow
from graphics import *
import urllib
import audio
open(u'd:\\habra_flag','w').write('')

data_path=os.getcwd()[]+u':\\System\\data\\HabraKarma\\'
# показывам, что мы запустились.
ui.global_note(u'Хабрастарт!')

class Habra:

    def __init__(self):
        # открываем изображения
        self.habr_img=Image.open(data_path+'habr.png')
        self.update_img=Image.open(data_path+'update.png')
        # читаем настройки
        self.settings=eval(open(data_path+'set.dat').read())
        self.last_karma=eval(open(data_path+'karma.dat').read())
        # открываем звука
        self.bad_sound=audio.Sound.open(data_path+'bad.wav')
        self.good_sound=audio.Sound.open(data_path+'good.wav')
        self.loop=True
        # создаем окно TopWindow
        self.top=topwindow.TopWindow()
        # указываем закругление
        self.top.corner_type='corner5'
        self.top.size=(170,35)
        # ставим позицию из файла настроек
        self.top.position=(self.settings['X'],self.settings['Y'])
        self.top.show()
        self.karma_screen()
        self.mainloop()

    def stop(self):
        self.loop=False
        self.top.hide()

    def karma_screen(self):
        # функция, вызываемая для обновления
        self.update_screen()
        e32.ao_sleep(0.2)
        # тянем инфу с харба api
        data=urllib.urlopen('http://habrahabr.ru/api/profile/'+self.settings['user']).read()
        # меня наверное запинают, но я не хочу тянуть в этом
        # случае библиотеку для парсинга xml
        karma=float(data.split('<karma>')[1].split('</karma>')[])
        # сравниваем новую карму со старой и
        # в зависимости от ситуации собираем текст, указываем цвет
        # и играем звук, если это задано в настройках
        if self.last_karma<karma:
            karma_diff=u'(+'+str(abs(self.last_karma-karma))+u')'
            karma_color=0x009f31
            if not self.settings['sound']:
                self.good_sound.play()
        elif self.last_karma>karma:
            karma_diff=u'(-'+str(abs(self.last_karma-karma))+u')'
            karma_color=0xc30202
            if not self.settings['sound']:
                self.bad_sound.play()
        else:
            karma_diff=u''
            karma_color=0xffffff

        if self.settings['diff']:
            self.last_karma=karma
        open(data_path+'karma.dat','w').write(repr(karma))

        # здесь мы узнаем, сколько пикселей по ширине бужет занимать текст
        karma_width=self.img.measure_text(unicode(karma))[][2]
        diff_width=self.img.measure_text(karma_diff)[][2]
        # а дальше дело техники :)
        self.img=Image.new((45+karma_width+diff_width,35))
        self.top.size=(self.img.size[],35)
        self.img.text((35,25),unicode(karma))

        self.img.text((35+karma_width+5,25),karma_diff,fill=karma_color)
        self.img.blit(self.habr_img)
        self.top.add_image(self.img,(,))

    def update_screen(self):
        # это будет выводится во время обновления
        self.img=Image.new((165,35))
        self.top.size=(self.img.size[],35)
        self.img.blit(self.update_img)
        self.img.text((35,25),u'Обновляется')
        self.top.add_image(self.img,(,))

    def mainloop(self):
        # и пускаем главный цикл сервера
        interval=self.settings['time']*60
        count=
        while self.loop:
            # если нам так приказали, останавливаем сервер
            if open(u'd:\\habra_flag').read():
                os.remove(u'd:\\habra_flag')
                ui.global_note(u'Хабрастоп!')
                self.loop=False
            count+=1
            # если пришло время, обнавляем карму.
            if count>interval:
                count=
                self.karma_screen()
            e32.ao_sleep(1)

habr=Habra()

Осталось собрать все это дело в sis и наблюдать за кармой 🙂

Исходники, вместе с картинками, звуками, иконкой можно взять ЗДЕСЬ. В ensymble в опциях сборки прописывать:
–extrasdir=data –lang=RU –icon=путь_к_иконке

И забираем результат…

Итак, представляю вашему вниманию приложение HabraKarma для symbain 9.x
Установите приложение, введите ваш username, настройте время обновления, положение окна. Теперь можно запустить сервер, который будет отображать поверх всех окон вашу карму. После этого, программу можно закрыть, окно останется до тех пор, пока вы его не выключите, зайдя опять в программу.

Скачиваем ОТСЮДА (sis, 56 кб, подписи не требует)

Не забывайте, что для работы необходим Python Runtime не ниже версии 1.9.7 (скачать).
Python и программу ставить на один и тот же диск!
©