AutoHotkey Community

It is currently May 27th, 2012, 4:05 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: PHP forum topic monitor
PostPosted: June 11th, 2011, 6:21 pm 
Offline

Joined: June 11th, 2011, 6:11 pm
Posts: 1
I¨m working on a PHP script which is meant to regularly check a dedicated email address for Topic Reply Notifications, when a new notification arrives the script opens the link in the email, grabs the latest post and saves that post to a local HTML file. I needed a topic for testing purposes....


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 11th, 2011, 7:00 pm 
Offline
User avatar

Joined: May 18th, 2010, 3:10 pm
Posts: 1179
Location: Sweden
Actually, I have a script under development for that too, but it monitors a specific label instead. Do you want me to share? :)

_________________
~sumon Appifyer AHK Nova halted Recommended: AHK_L (Why?)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 12th, 2011, 2:13 am 
Offline

Joined: September 15th, 2009, 1:14 am
Posts: 562
sumon wrote:
Do you want me to share? :)

Sharing is caring. ;)

_________________
Disclaimer: I'm not an expert by any means; I just try to help out where I can.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 12th, 2011, 3:06 am 
Offline
User avatar

Joined: May 18th, 2010, 3:10 pm
Posts: 1179
Location: Sweden
codybear wrote:
sumon wrote:
Do you want me to share? :)

Sharing is caring. ;)


I actually dislike that saying (no offense), because it implies that one does not care if one does not share (source code). There are sometimes valid reasons for not wanting to share, and just because intellectual property can be copied as opposed to loaned, used or taken, doesn't mean it's less of a property.

Anyway, since the development of this app is halted and I could use all the inspiration I need to (or see someone else develop it - and share *winks*) I'll post the code in its' current form. Beware, as you need to input username (without the @gmail part) and password for it to work. This one also require Notify() - I also modded it to have a static width, and was originally intended to be scheduled with Appifyer, but Appifyer can't schedule apps yet.

So, in other words, you will mostly want to focus on the CheckGmail label, and how I use it to retrieve data from Gmails RSS stream, and extract relevant information using RegEx.

Anyway, I care (always):

Code:
/*
   < MAILY>
   Version:
   Author: Simon Strålberg [sumon @ Autohotkey forums, simon . stralberg @ gmail . com]
   Autohotkey version: AHK_L (Unicode, x32)
   Dependencies:
      - (?) Notify.ahk by gwarble & more [http://www.autohotkey.com/forum/viewtopic.php?t=48668]
      
   CHANGELOG:
   v.
      - 0.7 initial release
      -
   
   TODO:
      - Commandline support in the form of %1% being label (or "Gmail"), %2% number of hits to return
      -

   LICENSE: If no license documentation exists, [http://www.autohotkey.net/~sumon/license.html]
   Script created using Autohotkey [http://www.autohotkey.com]
   
   THANKS TO:
   firace for "Extremely fast gmail checker" [http://www.autohotkey.com/forum/viewtopic.php?t=61762]
   rippa for helping me with the RegEx
   
   
*/
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance, Force

/*****************
** Autoexecute  **
******************
*/

if (!FileExist("data\favicon.ico"))
{
   FileCreateDir, data
   UrlDownloadToFile, http://mail.google.com/favicon.ico, data\favicon.ico
}

/****************
** Subroutines **
*****************
*/

DefineVars:
user := "YOURGMAILACCOUNTNAME", password = "YOURGMAILPASSWORD"
user := (user ? user : user_default), user_default := user ; If you for example wanted to set and retrieve the data from an ini, or whatever
password := (password ? password : password_default), password_default := password
maxcheck := (maxcheck ? maxcheck : 5) ; Max number of emails to display
timeout := (timeout ? timeout : 10)
label := "AHK" ; The label of your inbox to check. Leave blank to check your inbox

CheckGMail:
If (User AND Password)
   URLDownloadToFile, https://%user%:%password%@mail.google.com/mail/feed/atom/%label%, gmail.xml
else
   URLDownloadToFile, https://mail.google.com/mail/feed/atom/%label%, gmail.xml ; Requires a
FileEncoding, UTF-8
FileRead, gmailXML, gmail.xml
RegExMatch(gmailXML, "<fullcount>(.*)</fullcount>", FullCount), FullCount := FullCount1
RegExMatch(gmailXML, "<title>(.*?)</title>", PageTitle), PageTitle := PageTitle1
   StringReplace, PageTitle, PageTitle, ', `', All
RegExMatch(title, "'(.*)'", Label), Label := Label1

pos:=1
While pos:=RegExMatch(gmailXML, "s)<entry>(.*?)</entry>", RX_Entry, pos+StrLen(RX_Entry))
   Entry%A_Index% := RX_Entry1

PageText := (Label ? "Label: " . Label : PageTitle)
MsgText := (MsgText = 1 ? " unread message" : " unread messages")
InboxNN := Notify(PageText, FullCount . MsgText, TimeOut, "AC=Clicked", "data\favicon.ico")
%InboxNN% := "https://mail.google.com/mail/?shva=1#inbox"
   
LoopCount := (FullCount > MaxCheck ? MaxCheck : FullCount)
Loop, %LoopCount%
{
   RegExMatch(Entry%A_Index%, "<title>(.*)</title>", Title), Title%A_Index% := Title1
   RegExMatch(Entry%A_Index%, "href=""(.*?)""", URL), URL%A_Index% := URL1
   RegExMatch(Entry%A_Index%, "<summary>(.*)</summary>", Summary), Summary%A_Index% := Summary1
   StringReplace, URL%Index%, URL%Index%, &amp;, &, All ; The & gets **** up somewhere, return it now
}
; Now, reverse the order and display, to get the mails in the right order
Loop, %LoopCount%
{
   Index := LoopCount-A_Index+1 ; Counts down from Loopcount
   NN := Notify(Title%Index%, Summary%Index%, TimeOut, "AC=Clicked")
   %NN% := URL%Index% ; So the URL is clickable
}

FileDelete gmail.xml
Return

 Clicked:
 Run % %A_Gui% ; Runs the link provided by the variable assigned to the Notify() GUIs
return


PS. I put in a reservation for the app name "Maily" ;)

_________________
~sumon Appifyer AHK Nova halted Recommended: AHK_L (Why?)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 13th, 2011, 7:44 am 
Offline

Joined: January 12th, 2007, 4:30 am
Posts: 531
Location: Norway
So I see you've meet my monitor bot already, no need for introduction then. sumon thanks for sharing your code, it looks good!

If someone with more experience in PHP than I, could look through through this and correct and improve the script, that would be nice. I've tried to add comments to make it easier to debug. Alternatively, if anyone could recommend a helpful PHP forum where I could post the same script.

Code:
//This script checks a dedicated email account for "Topic Reply Notifications" from the AutoHotkey forum.
//When an email is received, the script retrieves the URL of the topic that has been updated.
//"&postorder=des" is appended to the URL to sort the posts descendingly, this way the latest post is first and easier to extract.
//Curl is used to get the HTML source which is then parsed by regex and string functions to retrieve and return the latest post.
//An HTML file is then created containing the latest post. This HTML file can then be used on a website to show the latest post related to a given AHK script.

//I've had some big problems to get this script to work. The Body of the email is still slightly garbled, despite using the function
//quoted_printable_decode to clean it up. I had to adapt the regex pattern accordingly and appending "&postorder=des" is problematic. PHP seems to substite
//instead of append and I think it's because of the ampersand which has special meaning in PHP. Can it be escaped? I tried using CHRs instead.

<?php
$mb = imap_open("{imap.SERVER.com:143}", "EMAIL@ADDRESS.COM", "fakepassword") or die("can't connect: " . imap_last_error()); //Open imap connection.
$messageCount = imap_num_msg($mb); //Loop through all emails
for( $MID = 1; $MID <= $messageCount; $MID++ )
{
   //$matches = array();
   $EmailHeaders = imap_headerinfo( $mb, $MID ); //Should add filter to process only "Topic Reply Notification" from AHK forum
   $Body = quoted_printable_decode(imap_body($mb, $MID)); //Get email body and make it legible
   $pattern = '/http:\/\/www.autohotkey.com\/forum\/viewtopic.php\?p.*#(.*)/'; //Regex pattern. Should be '/(http:\/\/www.autohotkey.com\/forum\/viewtopic.php\?p=.*)#/' but in the URL in $Body contains ".php?pE" instead of ".php?p="
   preg_match($pattern, $Body, $matches);
   $UpdatedTopicURL = 'http://www.autohotkey.com/forum/viewtopic.php' . chr(63) . 'p' . chr(61) . $matches[1] . chr(38) . 'postorder' . chr(61) . 'des'; //should be 'http:\/\/www.autohotkey.com\/forum\/viewtopic.php\?p=' . $matches[1] . '&postorder=des' but I think the ampersand symbol in the last concatenation screws everything up
   $success = GetLatestPost($UpdatedTopicURL,$LatestPost); //Get latest post
   if ($success==1)
   {
    echo $LatestPost;
    $BytesWritten = file_put_contents("LatestPost.html",$LatestPost); //Create html file with latest post
    //if ($BytesWritten > 0) imap_delete($mb, $MID); //The final version of the script could delete incoming emails after having processed them.
   }
   else
   {
    echo "GetLatestPost failed: " . $success . "<BR>";
   }
}

imap_close($mb); //Close connection to imap

//Given a URL to an AHK forum topic, this function parses the HTML source to extract and return the latest post. This function can be improved but seems to work OKAY.
function GetLatestPost($ThreadLink, &$LatestPost,$MaxLength = 10000)
{
 $curl = curl_init();
 $options = array(
            CURLOPT_URL => $ThreadLink,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_USERAGENT => "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 (.NET CLR 4.0.20506)" // In case it blocks strange UserAgents
);
curl_setopt_array($curl, $options);
$Page = curl_exec($curl);
//echo $Page;


//Fetch author of post
$PosOne=stripos($Page,'<span class="name">');
$PosTwo=stripos($Page,'<b>',$PosOne);
$PosTwo = $PosTwo + 3;
$PosThree=stripos($Page,'</b>',$PosOne);
$PosLength = $PosThree - $PosTwo;
$AuthorOfPost = substr($Page,$PosTwo,$PosLength);


//Fetch date and time of post
$PosOne=stripos($Page,'<span class="postdetails">Posted:',$PosThree);
$PosOne = $PosOne + 34;
$PosTwo=stripos($Page,'<span class="gen">',$PosOne);
$PosLength = $PosTwo - $PosOne;
$DateTimeOfPost = substr($Page,$PosOne,$PosLength);
$UnixDateTimeOfPost = strtotime($DateTimeOfPost);
$DateOfPost = date("Y-m-d",$UnixDateTimeOfPost);


//Fetch body of post
$PosOne=stripos($Page,'<span class="postbody">');
$PosOne = $PosOne + 23;
$PosTwo=stripos($Page,'</span><span class="gensmall">',$PosOne);
$PosLength = $PosTwo - $PosOne;
$BodyOfPost = substr($Page,$PosOne,$PosLength);
$BodyOfPost = str_ireplace("images/smiles","http://www.autohotkey.com/forum/images/smiles",$BodyOfPost);
$LengthOfPost = strlen($BodyOfPost);
if (strlen($BodyOfPost) > $MaxLength) $BodyOfPost = substr($BodyOfPost,0,$MaxLength) . "...";
$BodyOfPost = $BodyOfPost . '[<a href="' . $ThreadLink . '&postorder=des">Open Forum</a>]';
//echo "Author: " . $AuthorOfPost . "<BR>" . "Posted: " . $DateOfPost . "<BR>" . "BodyOfPost: " . $BodyOfPost;
//echo "<B>" . $AuthorOfPost . " (" . $DateOfPost . "): </B>". $BodyOfPost;

 if ($PosLength>0)
 {
  $retval = 1;
  $LatestPost = "<B>" . $AuthorOfPost . " (" . $DateOfPost . "): </B>". $BodyOfPost;
 }
 else
 {
  $retval = 0;
 }
 
return $retval;
}
?>


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 23rd, 2011, 4:36 pm 
Offline

Joined: August 28th, 2009, 11:17 am
Posts: 599
Location: Brighton, UK
There are few points in that, that could be improved. But it's pretty good.

I personally use sitepoint.com for all my PHP needs. The peeps there are friendly and helpful.

David

_________________
With mixed feelings I am stepping down from all moderation responsibilities: http://www.autohotkey.com/forum/viewtopic.php?t=82906


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: gamax92 and 3 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group