MyException - 我的异常网
当前位置:我的异常网» VC/MFC » csdn回帖提示,该怎么处理

csdn回帖提示,该怎么处理

www.MyException.Cn  网友分享于:2013-01-21  浏览:12次
csdn回帖提示
一直是发个问题贴 然后在那刷新看有没回帖,这应该是observer模式的,有回帖了自动通知,所以写了这个东东

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

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

exe达到了3m多,因为链接了几个boost静态库,其实内容只有这点
C/C++ code
#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;
}




文章评论

10个调试和排错的小建议
10个调试和排错的小建议
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
中美印日四国程序员比较
中美印日四国程序员比较
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
我的丈夫是个程序员
我的丈夫是个程序员
旅行,写作,编程
旅行,写作,编程
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
程序员和编码员之间的区别
程序员和编码员之间的区别
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
每天工作4小时的程序员
每天工作4小时的程序员
漫画:程序员的工作
漫画:程序员的工作
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
Java程序员必看电影
Java程序员必看电影
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
那些争议最大的编程观点
那些争议最大的编程观点
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
编程语言是女人
编程语言是女人
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
我是如何打败拖延症的
我是如何打败拖延症的
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
 程序员的样子
程序员的样子
程序员应该关注的一些事儿
程序员应该关注的一些事儿
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
代码女神横空出世
代码女神横空出世
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
鲜为人知的编程真相
鲜为人知的编程真相
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
一个程序员的时间管理
一个程序员的时间管理
总结2014中国互联网十大段子
总结2014中国互联网十大段子
程序员的鄙视链
程序员的鄙视链
老程序员的下场
老程序员的下场
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有