/*
* FBPwn
*
* http://code.google.com/p/fbpwn
*
* Copyright (C) 2011 - FBPwn
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fbpwn.plugins.core;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomNodeList;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import fbpwn.core.AuthenticatedAccount;
import fbpwn.core.FacebookAccount;
import fbpwn.core.FacebookTask;
import fbpwn.core.FacebookTaskState;
import fbpwn.plugins.ui.DictionaryBuilderDialog;
import fbpwn.ui.FacebookGUI;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;
public class DictionaryBuilderTask extends FacebookTask {
private boolean SearchPhotos = false;
private boolean SearchWallPosts = false;
private int WallPages = 0;
private int minimumWordLength = 3;
private DictionaryBuilderTask task;
private ArrayList<String> Dictionary;
public DictionaryBuilderTask(FacebookGUI FacebookGUI,
FacebookAccount facebookProfile,
AuthenticatedAccount authenticatedProfile,
File workingDirectory) {
super(FacebookGUI, facebookProfile, authenticatedProfile, workingDirectory);
task = this;
}
public void setSearchPhotos(boolean SearchPhotos) {
this.SearchPhotos = SearchPhotos;
}
public void setSearchWallPosts(boolean SearchWallPosts) {
this.SearchWallPosts = SearchWallPosts;
}
@Override
public boolean run() {
try {
setMessage("Initiating Module");
setTaskState(FacebookTaskState.Running);
getFacebookGUI().updateTaskProgress(this);
Dictionary = new ArrayList<String>();
WebClient tempWebClient = getAuthenticatedProfile().getBrowser();
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
DictionaryBuilderDialog dialog = new DictionaryBuilderDialog(null, true, task);
WallPages = dialog.ShowDictionaryBuilderSelectionDialog();
}
});
} catch (InterruptedException ex) {
Logger.getLogger(AddVictimsFriends.class.getName()).log(Level.SEVERE, "Exception in thread: " + Thread.currentThread().getName(), ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(AddVictimsFriends.class.getName()).log(Level.SEVERE, "Exception in thread: " + Thread.currentThread().getName(), ex);
}
if (SearchPhotos) {
setMessage("Searching under Photos");
getFacebookGUI().updateTaskProgress(this);
ArrayList<String> albums = getFacebookTargetProfile().getAlbumsURLs();
for (int i = 0; i < albums.size(); i++) {
setMessage("Searching in Album " + (i + 1) + "/" + albums.size());
getFacebookGUI().updateTaskProgress(this);
HtmlPage albumPage = tempWebClient.getPage(albums.get(i));
processAlbum(albumPage);
}
}
if (SearchWallPosts) {
String MobileWallPage = getFacebookTargetProfile().getProfilePageURL().replace("www", "m");
HtmlPage VictimWallPage = tempWebClient.getPage(MobileWallPage);
int index = 0;
while (index != WallPages) {
HtmlElement storiesArea = VictimWallPage.getElementById("m_stream_stories");
DomNodeList<HtmlElement> stories = storiesArea.getElementsByTagName("span");
for (int i = 0; i < stories.size(); i++) {
if (stories.get(i).getAttribute("dir").equals("rtl")) {
StringTokenizer token = new StringTokenizer(stories.get(i).getTextContent());
while (token.hasMoreTokens()) {
String word = token.nextToken();
if (!Dictionary.contains(word)) {
Dictionary.add(word);
}
}
}
}
DomNodeList<HtmlElement> anchors = storiesArea.getElementsByTagName("a");
for(int i=0;i<anchors.size();i++)
{
if(anchors.get(i).getAttribute("class").equals("sec") && anchors.get(i).getTextContent().contains("Comments"))
{
HtmlPage postPage = tempWebClient.getPage("http://m.facebook.com"+anchors.get(i).getAttribute("href"));
processPosts(postPage);
}
}
try {
VictimWallPage = VictimWallPage.getAnchorByText("See More Posts").click();
} catch (Exception ex) {
break;
}
setMessage("Searched in " + (index + 1) + "/"
+ (WallPages == -1 ? "all" : WallPages)
+ " Wall page(s)");
if (WallPages != -1) {
setPercentage(((double) (index + 1) / WallPages) * 100);
}
getFacebookGUI().updateTaskProgress(this);
if (checkForCancel()) {
return true;
}
index++;
}
}
PrintWriter pw = new PrintWriter(new File(getDirectory().getAbsolutePath() + System.getProperty("file.separator") + "Dictionary.txt"), "UTF-8");
setMessage("Writing password dictionary");
setPercentage(0.0);
getFacebookGUI().updateTaskProgress(this);
for (int i = 0; i < Dictionary.size(); i++) {
if(Dictionary.get(i).length() >= minimumWordLength)
{
pw.println(Dictionary.get(i));
}
}
pw.flush();
pw.close();
} catch (IOException ex) {
Logger.getLogger(DictionaryBuilderTask.class.getName()).log(Level.SEVERE, null, ex);
} catch (FailingHttpStatusCodeException ex) {
Logger.getLogger(DictionaryBuilderTask.class.getName()).log(Level.SEVERE, null, ex);
}
setMessage("Finished");
setTaskState(FacebookTaskState.Finished);
setPercentage(100.0);
getFacebookGUI().updateTaskProgress(this);
return true;
}
private void processPosts(HtmlPage postPage)
{
DomNodeList<HtmlElement> divisions = postPage.getElementsByTagName("div");
for (int i = 0; i < divisions.size(); i++) {
if (divisions.get(i).getAttribute("class").equals("row aclb apl")) {
String textContent = divisions.get(i).getFirstChild().getTextContent();
String profileName = divisions.get(i).getFirstChild().getFirstChild().getTextContent();
StringTokenizer token = new StringTokenizer(textContent.replace(profileName, ""));
while (token.hasMoreTokens()) {
String word = token.nextToken();
if (!Dictionary.contains(word)) {
Dictionary.add(word);
}
}
}
}
}
private void processAlbum(HtmlPage albumPage) throws FileNotFoundException, UnsupportedEncodingException, IOException {
ArrayList<String> photos = new ArrayList<String>(); //Array of Images links
DomNodeList<HtmlElement> anchors; //All anchors in album page
while (true) {
// Extracting images links
HtmlElement body = albumPage.getElementById("contentArea");
anchors = body.getElementsByTagName("a");
for (int j = 0; j < anchors.size(); j++) {
if (anchors.get(j).getAttribute("href").contains("fbid")) {
photos.add(anchors.get(j).getAttribute("href").replace("www", "m"));
}
}
//checking for Additional images in this album
try {
albumPage = getAuthenticatedProfile().getBrowser().getPage("http://m.facebook.com" + albumPage.getElementById("m_more_item").getElementsByTagName("a").get(0).getAttribute("href"));
} catch (Exception ex) {
break;
}
if (checkForCancel()) {
return;
}
}
//harvesting comments under images in dictionary
for (int j = 0; j < photos.size(); j++) {
//opening Image Page that containg it's comments
HtmlPage photoPage = getAuthenticatedProfile().getBrowser().getPage(photos.get(j));
DomNodeList<HtmlElement> divisions = photoPage.getElementsByTagName("div");
for (int i = 0; i < divisions.size(); i++) {
if (divisions.get(i).getAttribute("class").equals("row aclb apl")) {
String textContent = divisions.get(i).getFirstChild().getTextContent();
String profileName = divisions.get(i).getFirstChild().getFirstChild().getTextContent();
StringTokenizer token = new StringTokenizer(textContent.replace(profileName, ""));
while (token.hasMoreTokens()) {
String word = token.nextToken();
if (!Dictionary.contains(word)) {
Dictionary.add(word);
}
}
}
}
setPercentage((double) (j + 1) / photos.size() * 100);
getFacebookGUI().updateTaskProgress(this);
if (checkForCancel()) {
return;
}
}
}
@Override
public void init() {
}
@Override
public String toString() {
return "Build Password Dictionary";
}
}