[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Десктопное приложение для форума
Страницы: 1, 2, 3, 4
Winston
SoMeOnE
Цитата (SoMeOnE @ 24.06.2013 - 10:33)
linux тоже не предвидется ?)

Пока не вижу в этом необходимости. Но если много людей будут пользоваться этим приложением (а это вряд ли) и будут просьбы. То и на linux можно портировать.
killer8080
Цитата (Winston @ 24.06.2013 - 10:38)
Но если много людей будут пользоваться этим приложением (а это вряд ли) и будут просьбы.

А справится ли сервер с такими нагрузками?
Winston
Цитата (killer8080 @ 24.06.2013 - 15:50)
А справится ли сервер с такими нагрузками

Я уже придумал как на данный момент сократить количество запросов до двух (на выборку тем и сообщений).
Также если люди попросят, то я думаю, что Михаил сможет сделать страничку на которой будут выводиться и темы и сообщения, например в формате
<messages>
<message></message>
</messages>
<themes>
<theme></theme>
</themes>

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

_____________
user posted image
Zzepish
Winston
ты шикарен! только просьба- сделай плз историю уведомлений (те, которые не были прочитаны, и чтоб их удалять можно было не смотря)
Winston
Цитата (johniek_comp @ 21.07.2013 - 12:37)
прикольно, конечно, но еще бы исходники

Говнокода никогда не видел? biggrin.gif
Цитата (Zzepish @ 21.07.2013 - 13:53)
только просьба- сделай плз историю уведомлений (те, которые не были прочитаны, и чтоб их удалять можно было не смотря)

Историю непрочитанных тем имеешь ввиду?
twin
А!! Так вот кто DDOS учинил форуму! biggrin.gif

_____________
Если вам недостаточно собственных заблуждений, можно расширить их мнениями экспертов.

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
Winston
twin

Ничего подобного laugh.gif
Zzepish
Winston
ну, историю непрочитанных уведомлений)
Winston
Цитата (Zzepish @ 22.07.2013 - 18:50)
ну, историю непрочитанных уведомлений)

Можно сделать..., но я пока занят, некогда smile.gif
Zzepish
Winston
ок. Буду ждать с нетерпением))
Rand
Цитата (Winston @ 24.06.2013 - 12:53)
Да ну, это жесть будет, какие курсы, если я сам только взялся за его 

Молодец, а я за руби =) Штука интересная, сам как-то хотел подобное сделать (ибо RSS не очень здесь), но на работе у меня линух sad.gif
johniek_comp
Winston
Я думаю здесь еще есть питонисты, подскажут что не так smile.gif Учится же надо, если на питон решил перейти smile.gif smile.gif

_____________
user posted image
Frost-56
А можно исходник для изучения ?))
Winston
Раз уж так интересен исходник, то вот :)

Свернутый текст
# -*- coding: utf-8 -*-
import rfiles
from PyQt4 import QtCore, QtGui
from PyQt4.QtWebKit import QWebView, QWebPage
import http.client as http_c
import sys, os, datetime, webbrowser, re, urllib.request, sqlite3

import lxml.html
from lxml import etree

class BaseWindow(QtGui.QMainWindow):

VERSION = 'v0.1'
themesNotif = True
smsNotif = True

def __init__(self, parent = None):
QtGui.QMainWindow.__init__(self, parent)
self.centralWidget = QtGui.QWidget()
self.resize(800, 500)
self.setMinimumSize(500, 400)
self.setWindowTitle('PHPForum.ru ' + self.VERSION)

self.sb = self.statusBar()

self.path = os.getcwd()
self.rpath = os.path.normpath(self.path + '/resources/').replace('\\', '/')

self.setWindowIcon(QtGui.QIcon(':/resources/images/favicon.ico'))

self.tabs = QtGui.QTabWidget()

self.dbGetSettings()

exitMenu = QtGui.QAction(QtGui.QIcon('icons/exit.png'), 'Выход', self)
exitMenu.setShortcut('Ctrl+Q')
self.connect(exitMenu, QtCore.SIGNAL('triggered()'), QtCore.SLOT('close()'))

menubar = self.menuBar()
file = menubar.addMenu('Файл')
file.addAction(exitMenu)

self.msgThemes = msgThemes = QtGui.QAction(QtGui.QIcon(), 'О темах', self, checkable = True)
msgThemes.setChecked(self.themesNotif)


self.msgSms = msgSms = QtGui.QAction(QtGui.QIcon(), 'О SMS', self, checkable = True)
msgSms.setChecked(self.smsNotif)

self.connect(msgThemes, QtCore.SIGNAL('toggled(bool)'), lambda: self.notifMessages('themes'))
self.connect(msgSms, QtCore.SIGNAL('toggled(bool)'), lambda: self.notifMessages('sms'))


messages = menubar.addMenu('Уведомления')
messages.addAction(msgThemes)
messages.addAction(msgSms)

def notifMessages(self, type):

sql = """
UPDATE `config`
SET `value` = ?
WHERE `name` = ?
"""

if type == 'themes':
conf = 'themes_notif'
val = self.msgThemes.isChecked()
self.themesNotif = val
val = int(val)
elif type == 'sms':
conf = 'sms_notif'
val = self.msgSms.isChecked()
self.smsNotif = val
val = int(val)

self.dbConnect()
try:
self.cur.execute(sql, (val, conf,))
except:
pass
else:
self.db.commit()

self.dbClose()

@QtCore.pyqtSlot(QtGui.QSystemTrayIcon.ActivationReason)
def onTrayIconActivated(self, reason):
if reason == QtGui.QSystemTrayIcon.DoubleClick:
self.showNormal()

def createTrayIcon(self):
self.quitAction = QtGui.QAction("&Выход", self, triggered=QtGui.qApp.quit)

self.trayIconMenu = QtGui.QMenu(self)
self.trayIconMenu.addAction(self.quitAction)

self.trayIcon = QtGui.QSystemTrayIcon(self)
self.trayIcon.activated.connect(self.onTrayIconActivated)
self.trayIcon.setContextMenu(self.trayIconMenu)
self.trayIcon.setIcon(QtGui.QIcon(':/resources/images/favicon.ico'))
self.trayIcon.show()

def changeEvent(self, event):
if event.type() == QtCore.QEvent.WindowStateChange:
if self.windowState() & QtCore.Qt.WindowMinimized:
self.hide()
elif event.oldState() & QtCore.Qt.WindowMinimized:
self.showNormal()

super(BaseWindow, self).changeEvent(event)

def dbConnect(self):
self.db = sqlite3.connect('maindb.sqlite')
self.cur = self.db.cursor()

def dbClose(self):
self.cur.close()
self.db.close()

def dbGetSettings(self):
self.dbConnect()
res = None
sql = """
SELECT `name`, `value` FROM `config`
WHERE `name` IN('themes_notif', 'sms_notif')
"""
try:
self.cur.execute(sql)
except:
pass
else:
res = self.cur.fetchmany(2)

if len(res) == 2:
for el in res:
if el[0] == 'sms_notif':
self.smsNotif = bool(int(el[1]))
continue
elif el[0] == 'themes_notif':
self.themesNotif = bool(int(el[1]))
continue

self.dbClose()

class Loader(BaseWindow):

FORUM_URL = 'phpforum.ru'
connection = False

def __init__(self, parent = None):
BaseWindow.__init__(self, parent)

self.createTrayIcon()

self.setStatusIco()
self.checkConnection()

self.curThemeTime = None
self.lastSmsId = None

self.pb = QtGui.QProgressBar(self.sb)
self.pb.setTextVisible(True)
self.pb.setMaximumWidth(200)
self.pb.hide()
self.sb.addPermanentWidget(self.pb)

self.pb2 = QtGui.QProgressBar(self.sb)
self.pb2.setTextVisible(True)
self.pb2.setMaximumWidth(200)
self.pb2.hide()
self.sb.addPermanentWidget(self.pb2, 1)

self.webview = QWebView(loadProgress = self.pb.setValue, loadFinished = self.pb.hide, loadStarted = self.pb.show)
self.webviewSMS = QWebView(loadProgress = self.pb2.setValue, loadFinished = self.pb2.hide, loadStarted = self.pb2.show)

self.webview.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
self.webview.connect(self.webview.page(), QtCore.SIGNAL("linkClicked(const QUrl&)"), self.linkClicked)

self.webviewSMS.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
self.webviewSMS.connect(self.webviewSMS.page(), QtCore.SIGNAL("linkClicked(const QUrl&)"), self.linkClicked)

self.connect(self.webview, QtCore.SIGNAL("loadProgress(int)"), self.loadProgress)

if self.connection:
QtCore.QTimer.singleShot(500, self.onLoadSms)
QtCore.QTimer.singleShot(500, self.onLoadThemes)

centralLayout = QtGui.QVBoxLayout()
centralLayout.addWidget(self.tabs, 1)
self.tabs.addTab(self.webview, "Темы");
self.tabs.addTab(self.webviewSMS,"SMS");

self.centralWidget.setLayout(centralLayout)
self.setCentralWidget(self.centralWidget)

if self.connection:
self.timers()
else:
self.timerConn()

def timers(self, start = True):
if start:
self.timerSms = QtCore.QTimer()
self.timerSms.timeout.connect(self.onLoadSms)
self.timerSms.start(1000*60)

self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.onLoadThemes)
self.timer.start(1000*60)
else:
self.timer.stop()
self.timerSms.stop()

def timerConn(self, start = True):
if start:
self.timerCon = QtCore.QTimer()
self.timerCon.timeout.connect(self.checkConnection)
self.timerCon.start(1000*10)
else:
if hasattr(self, 'timerCon') and self.timerCon.isActive():
self.timerCon.stop()
self.timers()
self.onLoadThemes()
self.onLoadSms()


def loadProgress(self, load):
if load == 100:
self.pb.hide()
else:
self.pb.show()
self.pb.setRange(0, 100)
self.pb.setValue(load)

def onLoadThemes(self):
if not self.checkConnection():
self.timers(False)
self.timerConn()
return False

self.loadThemes()
self.webview.setHtml(self.themesStr)

def onLoadSms(self):
if not self.connection:
return False

self.loadSms()
self.webviewSMS.setHtml(self.smsStr)

def themesTrayMessage(self, themeName):
icon = QtGui.QSystemTrayIcon.MessageIcon(QtGui.QSystemTrayIcon.Information)
self.trayIcon.showMessage(
'Появились новые сообщения',
'В теме: "' + themeName + '"',
icon,
3000
)

def smsTrayMessage(self, author):
icon = QtGui.QSystemTrayIcon.MessageIcon(QtGui.QSystemTrayIcon.Information)
self.trayIcon.showMessage(
'Появилось новое SMS',
'От пользователя: ' + author,
icon,
3000
)

def loadThemes(self):
con = http_c.HTTPConnection(self.FORUM_URL)
con.request('GET', 'url')
res = con.getresponse()
themesCode = res.read().decode('cp1251')

doc = lxml.html.document_fromstring(themesCode)
topics = doc.xpath('/html/body/table[@class="topic"]')

data = []
i = 0
for topic in topics:
i += 1
tStr = lxml.html.document_fromstring(etree.tostring(topic))
authorName = tStr.xpath('//a[@class="author"]/text()')
authorLink = tStr.xpath('//a[@class="author"]/@href')

lastPost = tStr.xpath('//span[@class="post_date"]/text()[1]')
lastPostTmp = re.search(r'(\d?\d\.\d\d\.\d{4})\s+-\s+(\d\d:\d\d)', str(lastPost))
lastPost = "{0} - {1}".format(str(lastPostTmp.group(2)), str(lastPostTmp.group(1)))

title = tStr.xpath('//span[@class="topic_title"]/text()')
topicLink = tStr.xpath('//a[@class="topic_link"]/@href')
topicText = tStr.xpath('//table[1]//tr[3]/td/text()')
topicId = re.search('t=(\d+)$', topicLink[0]).group(1)

try:
authorName = authorName[0]
except IndexError:
authorName = 'Guest'
authorLink = '#'
else:
authorLink = authorLink[0]

try:
topicText = topicText[0]
except IndexError:
topicText = None

data.append({
'title': title[0],
'authorName': authorName,
'authorLink': authorLink,
'lastPost': lastPost,
'topicLink': topicLink[0],
'topicText': topicText,
'topicId': topicId,
})

if len(data) > 0:
if self.curThemeTime is None:
self.curThemeTime = data[0]['lastPost']
elif self.curThemeTime != data[0]['lastPost']:
if self.themesNotif:
self.themesTrayMessage(data[0]['title'])

self.curThemeTime = data[0]['lastPost']

themesStr = """
<!DOCTYPE html>
<html>
<head>
<link
rel="stylesheet" type="text/css" href="qrc:/resources/css/style.css">
</head>
<body>
<a
href="http://phpforum.ru/">На главную</a> |
<a href="http://phpforum.ru/index.php?act=Search&CODE=getnew">Новые сообщения</a>
<div><hr></div>

"""
for info in data:

if info['authorName'] == 'Guest':
author = 'Guest'
else:
author = '<a href="{authorLink}" title="ТС">{authorName}</a>'.format(**info)

themesStr += """
<div class="topic">
<span
class="title"><a href="{topicLink}">{title}</a></span>
<span
class="author">{author}</span>
<span
class="time">{lastPost}</span>
</div>
<br>

""".format(author = author, **info)

themesStr += """
</body>
</html>

"""
self.themesStr = themesStr

def loadSms(self):
con = http_c.HTTPConnection(self.FORUM_URL)
con.request('GET', 'url')
res = con.getresponse()
smsCode = res.read().decode('cp1251')
data = []

smsCode = smsCode.replace(" encoding='windows-1251'", '')
root = etree.XML(smsCode)

for mes in root.xpath('//message'):
authorName = mes.xpath('author/text()')[0]
authorId = mes.xpath('author/@id')[0]
messageText = mes.xpath('messageText/text()')[0]
messageId = mes.xpath('messageText/@id')[0]
messageColor = mes.xpath('messageText/@color')[0]
messageTime = mes.xpath('time/text()')[0]

messageTime = datetime.datetime.fromtimestamp(int(messageTime))
messageTime = messageTime.strftime('%H:%M %d/%m')

data.append({
'authorName': authorName,
'authorId': authorId,
'messageText': messageText,
'messageId': messageId,
'messageColor': messageColor,
'messageTime': messageTime,
})

data = sorted(data, key=lambda k: k['messageId'])

if len(data) > 0:
lastIndex = len(data) - 1

if self.lastSmsId is None:
self.lastSmsId= data[lastIndex]['messageId']
elif self.lastSmsId != data[lastIndex]['messageId'] or (self.lastSmsId is None and int(data[lastIndex]['messageId']) > 0):
if self.smsNotif:
self.smsTrayMessage(data[lastIndex]['authorName'])

self.lastSmsId = data[lastIndex]['messageId']

smsStr = """
<!DOCTYPE html>
<html>
<head>
<link
rel="stylesheet" type="text/css" href="qrc:/resources/css/style.css">
</head>
<body>
<a
href="http://phpforum.ru/index.php?&act=Shoutbox">Написать сообщение</a>
<div><hr></div>

"""
for info in data:
smsStr += """
<div class="sms">
<span
class="author"><a href="http://phpforum.ru/index.php?&showuser={authorId}">{authorName}</a></span>
<span
class="time">{messageTime}</span>
<span
class="sms_link"><a href="http://phpforum.ru/index.php?act=Shoutbox&shout={messageId}">#{messageId}</a></span>
<div><hr></div>
<div
class="message" style="color:{messageColor}">{messageText}</div>
</div>
<br>

""".format(**info)

smsStr += """
</body>
</html>

"""

self.smsStr = smsStr

def checkConnection(self):
try:
urllib.request.urlopen('http://' + self.FORUM_URL, timeout = 30)
self.connection = True
self.timerConn(False)
self.changeStatusIco()
return True
except urllib.request.URLError:
self.connection = False
self.changeStatusIco(False)
return False

def setStatusIco(self):
self.statusIco = QtGui.QLabel()
self.statusIco.setFrameStyle(QtGui.QFrame.NoFrame)
self.statusIco.setPixmap(QtGui.QPixmap(':/resources/images/not_con.png'))
self.sb.addWidget(self.statusIco)

def changeStatusIco(self, isConn = True):
if isConn:
self.statusIco.setPixmap(QtGui.QPixmap(':/resources/images/is_con.png'))
else:
self.statusIco.setPixmap(QtGui.QPixmap(':/resources/images/not_con.png'))

def linkClicked(self, url):
webbrowser.open(str(url.toString()))


if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Loader()
window.show()
sys.exit(app.exec_())
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.