1 Востаннє редагувалося Q-bart (03.05.2015 18:51:57)

Тема: Моя перша програма (Python, PyQt)

Доброго дня!
Мій перший результат вивчення PyQt.
Перш ніж писати систему тестування, я вирішив написати просту програму, для сповіщення нових повідомлень на  Replace (перше хотів для сповіщення нових листів з пошти, але там стоїть антибот, і не можна було авторизуватися Grab'ом).
Програма виводить сповіщення коли в темі(посилання на яку, вводить користувач), з'являється нове повідомлення. Запит відбувається кожні 15 секунд, я реалізував це безкінечним циклом та функцією time.sleep(15), тобто програма зупиняється на 15 с.

код
#!/usr/bin/python2.7
#-*- coding: utf-8 -*-
# <----Requirements---->
# PyQt4
# grab
# pycurl
# lxml
# </----Requirements---->

import sys
from grab import Grab
from PyQt4 import QtGui, QtCore
import time


class window(QtGui.QWidget):
    def __init__(self, parent = None):
        QtGui.QWidget.__init__(self, parent)

        self.setGeometry(100, 100, 500, 200)
        self.setWindowTitle('Replace')
        self.label = QtGui.QLabel(u'Введіть посилання на тему з Українського форуму програмістів')
        self.hello = QtGui.QLabel(u'Вітаю!')
        self.hello.setAlignment(QtCore.Qt.AlignCenter)
        self.explane = QtGui.QLabel(u'''Програма відстежує наявність нових повідомлень з тем на
Українському форумі програмістів
REPLACE.org.ua''')
        self.link = QtGui.QLineEdit()
        self.submit = QtGui.QPushButton('Submit')

        self.Layout = QtGui.QVBoxLayout()
        self.Layout.addWidget(self.hello)
        self.Layout.addWidget(self.explane)
        self.Layout.addWidget(self.label)


        self.filds = QtGui.QHBoxLayout()
        self.filds.addWidget(self.link)
        self.filds.addWidget(self.submit)

        self.setLayout(self.Layout)
        self.Layout.addLayout(self.filds)
        self.connect(self.submit, QtCore.SIGNAL("clicked()"), self.submit_def)

    def submit_def(self):
        introduced = self.link.text() #введене посилання
        if introduced[-1:] != '/':
            introduced = introduced + '/' #Додаємо слеш, якщо немає
        for i in reversed(range(self.filds.count())):  #Видаляєм вміст вікна
            self.filds.itemAt(i).widget().deleteLater()
        for i in reversed(range(self.Layout.count())):
             if type(self.Layout.itemAt(i)) != QtGui.QHBoxLayout:
                self.Layout.itemAt(i).widget().deleteLater()
        label = QtGui.QLabel(u'Програма сповістить вас, коли будуть нові повідомлення')
        self.Layout.addWidget(label)
        self.showMinimized()
        self.tracking(introduced)


    def tracking(self, link):
        self.link = link
        g = Grab()
        g.go(self.link)
        try :                                          # Дізнаємось 1 сторінка чи більше
            self.pages = g.doc.select('//p[@class="paging"]/a')
            self.pages = self.pages.text()
        except Exception:
            self.pages = 1

        if self.pages != 1:       # Якщо сторінок більше ніж 1, формуєм посилання на останню сторінку
            self.pages = g.doc.select('//div[@class="h1"]/h1/small')
            self.pages = self.pages.text()
            self.last_page1 = self.pages[14:-1]
            self.last_page1 = int(self.last_page1)
            self.link_for_last_p1 = self.link + 'page/' + str(self.last_page1)+'/' # посилання на останню сторінку
        else:
            self.last_page1 = 1
            self.link_for_last_p1 = self.link

        g = Grab()
        g.go(self.link_for_last_p1)              #переходим на останню сторінку
        self.messages = g.xpath_list('//h3[@class="hn post-ident"]/span[@class="post-num"]')
        self.message_last1 = self.messages[-1].text   # Номер останнього повідомлення

        self.request = Requests(self.link_for_last_p1, self.message_last1, self.last_page1, self.link)
        self.request.start()  # Новий потік

        self.connect(self.request, QtCore.SIGNAL("mysignal(QString)"), self.open_window,
                     QtCore.Qt.QueuedConnection)

    def open_window(self ):  

        modal_w = popup_window()
        modal_w.show()
        modal_w.exec_()



class Requests(QtCore.QThread):
    def __init__(self, link_for_last_p, message_last, last_page, link, parent=None):
        self.link_for_last_p = link_for_last_p
        self.message_last = message_last
        self.last_page = last_page
        self.link = link
        QtCore.QThread.__init__(self, parent)


    def run(self):         #Потік
        while True:
            time.sleep(15)
            g = Grab()
            g.go(self.link_for_last_p)
            self.messages = g.xpath_list('//h3[@class="hn post-ident"]/span[@class="post-num"]')
            self.current_message = self.messages[-1].text



            if int(self.message_last) % 20 == 0:   #Якщо останнє повідомл. ділиться націло на 20
                self.last_page += 1                # то значить - кінець сторінки
                self.link_for_last_p = self.link + 'page/' + str(self.last_page)+'/' # формуєм посилання нової сторінки

            if int(self.current_message) > int(self.message_last):
                self.message_last = self.current_message
                self.emit(QtCore.SIGNAL("mysignal(QString)"), self.link_for_last_p) #Відкриваєм нове вікно




class popup_window(QtGui.QWidget):         # вікно сповіщення
    def __init__(self, parent = None):
        QtGui.QWidget.__init__(self, parent)

        self.setWindowFlags(QtCore.Qt.Popup)
        self.resize(400, 100)

        self.new_mes_Label = QtGui.QLabel(u'<center>Нове повідомлення</center>')
        self.hyperlink = QtGui.QLabel(u'<center><a href="http://replace.org.ua/search/recent/">Останні активні теми</a></center>')
        self.hyperlink.setOpenExternalLinks(True)


        self.box = QtGui.QHBoxLayout()
        self.logo_label = QtGui.QLabel('<img src="logo.png" align="center">')
        self.box.addWidget(self.logo_label)

        self.text = QtGui.QVBoxLayout()
        self.text.addWidget(self.new_mes_Label)
        self.text.addWidget(self.hyperlink)
        self.setLayout(self.box)
        self.box.addLayout(self.text)
        self.desktop_1 = QtGui.QApplication.desktop()
        self.taskBarHeight = (self.desktop_1.screenGeometry().height() -
            self.desktop_1.availableGeometry().height())
        x = self.desktop_1.width() - self.frameSize().width() - 10
        y = self.desktop_1.height() - self.frameSize().height() - self.taskBarHeight - 10
        self.setGeometry(x, y,400, 100)
        QtGui.QSound("hello.wav").play()


app = QtGui.QApplication(sys.argv)
main = window()
main.show()
sys.exit(app.exec_())
Скріни

http://s7.сайт-злодій/uploads/images/2015/05/79d20e4e5e8e8531328124e8fe145f56.png
http://s7.сайт-злодій/uploads/images/2015/05/11bf5ba5dcba2d0a88b78a34242b3b66.png


Прошу оцінити. Підказати, що правильно робив, що ні, як можна інакше.
Написана на Python2.7.9, PyQt4, grab, pycurl, lxml. (На Python3 не встановлювався grab...)


P.S посилання треба вводити на тему (http://replace.org.ua/topic/16/) а, не на окреме повідомлення(http://replace.org.ua/post/29/#p29)

Post's attachments

New messages.rar 149.93 kb, 325 downloads since 2015-05-03 

Подякували: Joker, Djalin, Chemist-i, A.N.Onim, Monolith, DOP6

2

Re: Моя перша програма (Python, PyQt)

1. Було би непогано підігнати код під стандарти PEP8 (можна прогнати tox'ом). Той же токс, до речі, у поєднанні з virtualenv файно підходить для задоволення залежностей.
2. "filds" чи "fields"?
3. З Git уже знайомі?  Github був би зручнішим ресурсом для розшарювання коду (у мене, скажімо, цей архів не відкривається).
4. "g" - не найкраща назва змінної. Імена класів варто з великої літери починати.

3 Востаннє редагувалося Djalin (03.05.2015 18:17:49)

Re: Моя перша програма (Python, PyQt)

у мене відкрився, але програма відкривається пітоном = хоча права я виставив


варто було б у архів додати скрипт для встановлення всього необхідного

а при спробі виконати у едіторі - викликала краш
http://replace.org.ua/misc.php?action=pun_attachment&amp;item=840&amp;download=0

До речі варто в скрипті прописати версію пайтону - у мене по замовчуванню таки третій

#!/usr/bin/python2.7

після цього лаявся лише на відсутність грабу

Post's attachments

Screenshot - 03.05.15 - 19:10:39.png 37.53 kb, 376 downloads since 2015-05-03 

Подякували: Q-bart1

4 Востаннє редагувалося Q-bart (03.05.2015 18:32:42)

Re: Моя перша програма (Python, PyQt)

Bartash написав:

1. Було би непогано підігнати код під стандарти PEP8 (можна прогнати tox'ом). Той же токс, до речі, у поєднанні з virtualenv файно підходить для задоволення залежностей.
2. "filds" чи "fields"?
3. З Git уже знайомі?  Github був би зручнішим ресурсом для розшарювання коду (у мене, скажімо, цей архів не відкривається).
4. "g" - не найкраща назва змінної. Імена класів варто з великої літери починати.

1 - навіть, не знав що є такі стандарти, буду вчити
2 - виправлю
3 - на github зареєстрований, що таке git не знаю, зараз пошукаю..
4 так писало в документації, думав, що так буде за стандартами... Забув, що класи з великої букви, виправлю..

5

Re: Моя перша програма (Python, PyQt)

Djalin написав:

варто було б у архів додати скрипт для встановлення всього необхідного

Який то скрипт, вперше чую, що то таке?

Djalin написав:

До речі варто в скрипті прописати версію пайтону - у мене по замовчуванню таки третій

#!/usr/bin/python2.7

В мене теж дві версії, спочатку так і прописував, а потім почав використовувати IDE і потреба зникла, додам

6 Востаннє редагувалося Djalin (03.05.2015 19:17:40)

Re: Моя перша програма (Python, PyQt)

хм.. IDE ніяк не варіант :)

для убунти це десь буде так

#!/bin/bash
sudo apt-get install Python2.7.9 PyQt4 grab pycurl lxml
Подякували: Q-bart1

7 Востаннє редагувалося Q-bart (03.05.2015 19:23:04)

Re: Моя перша програма (Python, PyQt)

Djalin написав:

хм.. IDE ніяк не варіант :)

для убунти це десь буде так

#!/bin/bash
sudo apt-get install Python2.7.9 PyQt4 grab pycurl lxml

То ніби, щоб програма сама встановила все необхідне?
Для віндовс, щоб встановити якусь з цих бібліотек, я використовував

pip install grab

То може команда буде така:

#!/bin/bash
pip install grab, PyQt4, pycurl, lxm
Подякували: Djalin1

8 Востаннє редагувалося Q-bart (04.05.2015 10:06:49)

Re: Моя перша програма (Python, PyQt)

Додав репозитарій на GitHub.
https://github.com/Q-bart/new-messages-Replace
Та як додати зображення, музику, (що має програватися при відкритті вікна), на GitHub?

9

Re: Моя перша програма (Python, PyQt)

@Q-Bart

"Бєз гіта і жизнь нє та":).
Вивчіть - корисно буде, бо без нього з гітхабом працювати можна, але сумно.:)

Прихований текст

http://не-дійсний-домен/images/20090312/5f2z1by6xrrs.jpg

10

Re: Моя перша програма (Python, PyQt)

Привіт Python вивчаю недовго,можливо не те щось пораджу,але можливо скачай пайтон з офіційного сайту ,у самого постівно не міг відкрити,скачавши пайтон з оффіційного сайту все пішло гаразд