csdn回帖提示

aj3423 2011-07-05 08:49:44
一直是发个问题贴 然后在那刷新看有没回帖,这应该是observer模式的,有回帖了自动通知,所以写了这个东东

. 30秒刷新一次
. 有新回帖的话桌面右下角弹出提示,同时界面上第一列显示 new
. 双击打开链接
. 关闭缩小到右下角任务栏

下载:
http://download.csdn.net/source/3420200

exe达到了3m多,因为链接了几个boost静态库,其实内容只有这点
#pragma warning(disable: 4786)

#include "ui.h"

#include <windows.h>
#include <shellapi.h>

#include "SkinH.h"

Application* login;
Button* btnLogin;
Edit* editUser;
Edit* editPass;

Application* app;
SysTray* tray;
Menu* trayMenu;
ListView* lv;
TipWindow* tip;

#define CSDN "csdn"
#define MENU_QUIT 1
void menu_handler(int ret) {
if(ret == MENU_QUIT) {
app->quit();
}
}
string username;
string password;
string cookie;

#include <boost/regex.hpp>
using namespace boost;

string regex_match(const string& html, const string& pattern) {
regex reg(pattern);
smatch m;

string ret = "";
if (boost::regex_search(html, m, reg)) {
if (m[1].matched) {
ret = m[1];
}
}
return ret;
}
typedef vector<string> matches;
matches regex_match_all(const string& html, const string& pattern) {
matches m;
regex reg(pattern);
sregex_iterator itrBegin(html.begin(), html.end(), reg);
sregex_iterator itrEnd;
for(sregex_iterator itr=itrBegin; itr!=itrEnd; ++itr) {
m.push_back(itr->str());
}
return m;
}
string analyze_cookie(string& html) {
string pattern = "Set-Cookie: (UserInfo[^\r]+)\r\n";
return regex_match(html, pattern);
}

#include <stdio.h>
#include <stdlib.h>
void analyze_thread(string& html) {
string thread_pattern = "<tr ([\\s\\S]+?)</tr>";

// cout << "thread...." << endl;

matches m = regex_match_all(html, thread_pattern);
matches all;
// cout << html << endl;
// cout << "matched: " << m.size() << endl;
bool alert = false;
for_each(m.begin(), m.end(), [&lv, &alert, &all](string html) {
string link = regex_match(html, "<a href=\"([^\"]+)\"");
string title = regex_match(html, "_blank\">\\s*([^\\r]+)\\s*</a>");
int replyCount = atoi(regex_match(html, "<.span>\\s+</td>\\s+<td>\\s+(\\d+)").c_str());

all.push_back(link);

obj o;
o["link"] = link;
o["title"] = title;
o["replyCount"] = replyCount;
o["hasNewReply"] = false;

Store* ds = lv->ds;
Record* r = ds->findBy("link", link);
if(!r) {
ds->add(new Record(o));
} else {
int cnt = get<int>(r->get("replyCount"));
if(replyCount > cnt) {
alert = true;
r->set("replyCount", replyCount);
r->set("hasNewReply", true);
}
}
});
if(alert) {
tip->show();
}

Store* ds = lv->ds;
for(int row = ds->getCount() - 1; row >=0; row--) {
string link = get<string>(ds->getAt(row)->get("link"));
if(find(all.begin(), all.end(), link) == all.end()) {// if not find
ds->removeAt(row);
}
}
}


#include "net.h"
bool request_login(string user, string pass) {

Http t;
if(!t.connect("passport.csdn.net", 80)) {
return false;
}
char buf[4096];
sprintf(buf,
"GET /ajax/accounthandler.ashx?t=log&u=%s&p=%s&c=&remember=0&f=http%3A//passport.csdn.net/account/login%3Ffrom%3Dhttp%3A//community.csdn.net/ HTTP/1.1\r\n"
"Host: passport.csdn.net\r\n"
"Accept: text/plain\r\n"
"Connection: close\r\n"
"\r\n",
user.c_str(),
pass.c_str()
);
t.send(buf);
string recv = t.read();

bool success = recv.find("status\":true") != -1;
if(success) {
cookie = analyze_cookie(recv);
}
return success;
}
#include "charset.h"
bool request_threads(string user, string pass, string cookie) {
Http t;
if(!t.connect("forum.csdn.net", 80)) {
// cout << "connect forum.csdn.net error" << endl;
return false;
}
char buf[4096];
sprintf(buf,
"GET /PointForum/Forum/UserTopicList.aspx?type=TopicUserUnCheckOut&_t_=gpksnqfw HTTP/1.1\r\n"
"Host: forum.csdn.net\r\n"
"Accept: text/html\r\n"
"Accept-Charset: ISO-8859-1\r\n"
"Referer: http://community.csdn.net/WebNavigation/ForumContent.aspx\r\n"
"Cookie: UN=%s; UserName=%s; %s\r\n"
"Connection: close\r\n"
"\r\n",
username.c_str(),
username.c_str(),
cookie.c_str()
);
t.send(buf);
string recv = utf8ToGB2312(t.read());

// cout << "recv: " << recv << endl;

analyze_thread(recv);

return true;

}

string getCurrentDir() {
char dir[256];
::GetCurrentDirectory(sizeof(dir), dir);
return string(dir);
}
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <fstream>
void saveStore(Store* ds, string file) {
std::ofstream ofs(file);
boost::archive::text_oarchive oa(ofs);
oa << *ds;
ofs.close();
}
void restoreStore(Store* ds, string file) {
std::ifstream ifs(file, std::ios::binary);
if(ifs.fail()) {
return;
}
boost::archive::text_iarchive ia(ifs);
ia >> *ds;
ifs.close();
}

#include "thread/thread.h"
class Schedule : public Thread<Schedule> {
private:
public:
void operator()() {
while(true) {
boost::this_thread::interruption_point();
loop();
boost::this_thread::sleep(boost::posix_time::millisec(30*1000));
}
}
void loop() {
request_threads(username, password, cookie);
saveStore(lv->ds, getCurrentDir()+"/cache");
}
} schedule;

void do_login() {
string user = editUser->getText();
string pass = editPass->getText();

if(request_login(user, pass)) {
login->quit();
username = user;
password = pass;
} else {
::MessageBox(0, "username/password incorrect", "", 0);
}
}

bool on_main_win_show(Component*) {
return true;
}
bool onDblClick(ListView* lv, int row) {
Record* r = lv->ds->getAt(row);
string link = get<string>(r->get("link"));

r->set("hasNewReply", false);
ShellExecute(NULL, "open", link.c_str(), NULL, NULL, SW_SHOW);
return true;
}

string hasNewRenderer(obj_value raw, int row, Record* r) {
return get<bool>(raw) ? "new" : "";
}

#include "ini.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
SkinH_Attach();

ini _ini(getCurrentDir() + "/user.ini");

username = _ini.getString("username");
password = _ini.getString("password");

// cout << "user: " << username << endl;
// cout << "pasw: " << password << endl;

if(username.compare("") == 0) {
login = new Application("login", CW_USEDEFAULT, CW_USEDEFAULT, 200, 100, LAYOUT_HBOX);
editUser = new Edit("");
editPass = new Edit("");
btnLogin = new Button("ok", 0, 0, 0, 0, 1);
btnLogin->handler = do_login;

Panel* p = new Panel("", 0, 0, 0, 0, 3, LAYOUT_ROW);
p->addAll(label("user:", editUser), label("pass:", editPass), NULL);
login->addAll(p, btnLogin, NULL);
login->create();
login->show();
login->wait();

delete login;
} else {
request_login(username, password);
}

tip = new TipWindow("", 0, 0, 150, 110);
tip->setText("new reply on csdn");
tip->create();

lv = new ListView();
ColumnModel* cm = new ColumnModel();
cm->addCol("new?", "hasNewReply", 70, COLUMN_TYPE_BOOL, hasNewRenderer);
cm->addCol("Title", "title", 300);
lv->setCM(cm);
lv->on("dblclick", new delegate2<bool, ListView*, int>(&onDblClick));

app = new Application(CSDN, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, LAYOUT_FIT);
app->add(lv);
app->create();
app->setIcon(::LoadIcon(::GetModuleHandle(0), "ICON_MAIN"));

tray = new SysTray(CSDN);
trayMenu = new Menu();
trayMenu->handler = menu_handler;

trayMenu->add("quit", MENU_QUIT);

tray->bindApp(app);
tray->bindMenu(trayMenu);

restoreStore(lv->ds, getCurrentDir()+"/cache");
lv->refresh();

schedule.start();

app->show();
app->wait();

saveStore(lv->ds, getCurrentDir()+"/cache");

_ini.setString("username", username);
_ini.setString("password", password);


delete tray;
delete trayMenu;
delete app;
delete tip;
return 0;
}



...全文
67 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
MoXiaoRab 2011-07-05
  • 打赏
  • 举报
回复
呵呵,VC做这个浪费啊
aj3423 2011-07-05
  • 打赏
  • 举报
回复
每天回帖即可获得10分可用分!

2,586

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 资源
社区管理员
  • 资源
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧