Commit 47ba6458 authored by Alexander Ross Melnick's avatar Alexander Ross Melnick
Browse files
parents e4dd965a fabbb989
Loading
Loading
Loading
Loading
+37 −7
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ import util.JsonMaker;
import util.PhraseExtractor;
import util.SentenceExtractor;
import util.StringFileWriter;
import Translator.DirectTranslator;
import StateMachine.*;


@@ -89,15 +90,16 @@ public class Corrector implements GUIListener {
        DBinterface dbInterface = new DBinterface();
        DirectedGraph graph = basicGraphClass.getGraph();
        StringFileWriter stringWriter = StringFileWriter.of("corrected.txt");
        Corrector corrector = new Corrector(SentenceExtractor.of(argPars.getFileName()));
        
            
        StringFileWriter.deleteFile("correction_details.txt");
        if(argPars.isCheckFile()){
            SentenceExtractor extractor = SentenceExtractor.of(argPars.getFileName());
            List<String> extractedSentences = extractor.getSentences();
            if(argPars.isCorrectionGUI()){    
                    Corrector corrector = new Corrector(SentenceExtractor.of(argPars.getFileName()));
                    corrector.start();
            }else{
                SentenceExtractor extractor = SentenceExtractor.of(argPars.getFileName());
                List<String> extractedSentences = extractor.getSentences();
                for (String sentence : extractedSentences) {
                    System.out.println("Sentence: " + sentence);
                    String tempString = dbInterface.correctTokenInDatabase(sentence.toLowerCase(), graph, 2, true);
@@ -114,7 +116,10 @@ public class Corrector implements GUIListener {
                System.err.println("An error occurred while writing to the file: " + e.getMessage());
            }
        }else if(argPars.isCheckSentence()){

            if(argPars.isCorrectionGUI()){  
                Corrector corrector = new Corrector(SentenceExtractor.of(argPars.getSentence()));  
                corrector.start();
            }else{
                System.out.println("Sentence: " + argPars.getSentence());
                stringWriter.appendString(dbInterface.correctTokenInDatabase(argPars.getSentence().toLowerCase(), graph, 2, true));
                try {
@@ -125,6 +130,31 @@ public class Corrector implements GUIListener {
                }
                System.out.println("##########################################################");
            }
        }else if(argPars.isTranslateDutch()){
            DirectTranslator directTranslator = DirectTranslator.make();
            directTranslator.loadWordMapFromFile("SQLite/word_map.txt");
            if(argPars.isCheckFile()){
                SentenceExtractor extractor = SentenceExtractor.of(argPars.getFileName());
                List<String> extractedSentences = extractor.getSentences();
                for (String sentence : extractedSentences) {
                    System.out.println("Sentence: " + sentence);
                    String tempString = directTranslator.replaceWordsInSentence(sentence.toLowerCase());
                    stringWriter.appendString(tempString);
                    System.out.println("##########################################################");
                }
            }else{
                
                System.out.println("Sentence: " + argPars.getSentence());
                stringWriter.appendString(directTranslator.replaceWordsInSentence(argPars.getSentence().toLowerCase()));
                System.out.println("##########################################################");
            }
            try {
                stringWriter.writeToFile();
                System.out.println("Corrected version has been written to the file.");
            } catch (IOException e) {
                System.err.println("An error occurred while writing to the file: " + e.getMessage());
            }
        }
          
    }
}
+7 −0
Original line number Diff line number Diff line
aa a
cc c
dd d
bb e
ee f
gg g
hh h
+58 −0
Original line number Diff line number Diff line
package Translator;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class DirectTranslator {

    private Map<String, String> wordMap;

    private DirectTranslator() {
        wordMap = new HashMap<>();
    }

    public static DirectTranslator make(){
        return new DirectTranslator();
    }

    public void loadWordMapFromFile(String filePath) {
        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                String[] words = line.split("\\s+");
                if (words.length == 2) {
                    wordMap.put(words[0], words[1]);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String replaceWordsInSentence(String sentence) {
        StringBuilder replacedSentence = new StringBuilder();
        String[] words = sentence.split("(?<=\\p{Punct}|\\s)|(?=\\p{Punct}|\\s)");
        for (String word : words) {
            if (wordMap.containsKey(word)) {
                replacedSentence.append(wordMap.get(word));
            } else {
                replacedSentence.append(word);
            }
        }
        // Remove extra space at the end and ensure no space before punctuation
        return replacedSentence.toString().trim().replaceAll("\\s(?=\\p{Punct})", "");
    }

    public static void main(String[] args) {
        DirectTranslator wordReplacement = new DirectTranslator();
        wordReplacement.loadWordMapFromFile("SQLite/word_map.txt");

        String sentence = "aa, bb! cc dd, ee? ff.";
        String replacedSentence = wordReplacement.replaceWordsInSentence(sentence);
        System.out.println("Original sentence: " + sentence);
        System.out.println("Replaced sentence: " + replacedSentence);
    }
}
+23 −3
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ public class ArgumentParser {
    private boolean correctionGUI;
    private boolean updateHashTable;
    private boolean validateUpdates;
    private boolean translateDutch;

    ArgumentParser(String[] args) {
        checkSentence = false;
@@ -23,6 +24,7 @@ public class ArgumentParser {
        validateUpdates = false;
        checkGUI = false;
        correctionGUI = false;
        translateDutch = false;
        parseArguments(Arrays.asList(args));
    }

@@ -65,15 +67,18 @@ public class ArgumentParser {
                    case "--validateUpdates":
                        validateUpdates = true;
                        break;
                    case "--checkGUI":
                    case "--checkerGUI":
                        checkGUI = true;
                        break;
                    case "--correctionGUI":
                    case "--correctorGUI":
                        correctionGUI = true;
                        break;
                    case "--translateDutch":
                        translateDutch = true;
                        break;
                    // Add cases for other arguments here
                    default:
                        // Handle unknown arguments or simply ignore them
                        System.out.println("Invalis options. Please use --help to see how to use the tool.");
                        break;
                }
            }
@@ -87,6 +92,18 @@ public class ArgumentParser {

    private void printHelp() {
        System.out.println("Help information:");
        System.out.println("    Corrector Options:");
        System.out.println("        --file <filename>: this option should be used if you want to pass your input as file.");
        System.out.println("        --sentence <sentence>: this option should be used if you want to pass your input as a small sentence.");
        System.out.println("        --correctorGUI: this option can be used if you want a GUI for the corrector to select between possible suggestions.");
        System.out.println("        --translateDutch <sentence>: this option should be used if you want to translate from English to Dutch.");
        System.out.println("    Checker Options:");
        System.out.println("        --file <filename>: this option should be used if you want to pass your input as file.");
        System.out.println("        --sentence <sentence>: this option should be used if you want to pass your input as a small sentence.");
        System.out.println("        --checkerGUI: this option can be used if you want a GUI for the checker to see the highlighted sentences.");
        System.out.println("        --updateToken: this option should be used alongside a file as input to update new tokens for the database. This option may take hours based on the size of crawled file.");
        System.out.println("        --updateHashTable: this option should be used alongside a file as input to update n-grams weights for the database. This option may take a few minutes.");
        System.out.println("        --validateUpdates: this option can be used to check the correctness of the database for tokens. This will pops up a window.");
        // Add help information here
    }

@@ -120,4 +137,7 @@ public class ArgumentParser {
    public boolean isCorrectionGUI(){
        return correctionGUI;
    }
    public boolean isTranslateDutch(){
        return translateDutch;
    }
}
+9 −2
Original line number Diff line number Diff line
@@ -12,18 +12,25 @@ Reza Sajjadi

### Implementation Description
A high-level description of the implementation, with particular emphasis on the design decisions related to data structures and algorithms
Our crawler works as follows: URLs to crawl, URLs that have been crawl, and dissallowed domains are saved in HashSets. We used HashSets because they enforce uniqueness (we do not want to crawl the same URL multiple times) and operate in O(1) time for adding, removing, and contains operations. Seed URLs are added either by command line arguments or from a specified file. The seeds are loaded into the HashMap. From there, until we run out of URLs to crawl or hit our page crawl limit, we crawl each page one at a time. The crawl algorithm works as follows: the next URL is removed from the HashSet. We then check if its domain is known to allow crawling. If the domain has not been crawled before, we check the website's robots.txt file to see what pages are allowed to be crawled and save those preferences so we can respect them later. If the  has been crawled before, then then we simply check if the URL is in the allowed Domains HashSet. If it is not allowed, the URL is skipped. If it is allowed, we then update the wait delay and write to a file as much data as allowed per website (default 1KB). After a page is finished being crawled (and we are below the crawled page limit), the crawler fetches the next page and the process repeats. 

### Implemented Features
- Provide real-time status and statistics ( e.g., what URL is being processed, rate of processing, size of storage, etc.) feedback for the crawler. [10%]
    - Description of how it was implemented with an emphasis on data structures and algorithms used
    - Implemented by calculating statistics as the crawler crawls each page. We report the length of the page processed in bytes, the total amount of data crawled thus far, the number of links extracted from the page, the number of pages crawled, the number of URLs left available to crawl, the current crawling rate in pages per second, the current crawling rate in links extracted per second, and the current crawling rate in bytes per second. Usage: use "--stats" argument for the crawler.  
- Provide a list of reasonable corrections to a suspicious text, ranked in order of how different they are from the original text. [15%]
    - Description of how it was implemented with an emphasis on data structures and algorithms used
- Graphical User Interface that highlights suspicious and non-suspicious textual elements in a given text. [15%]
    - Description of how it was implemented with an emphasis on data structures and algorithms used
- Extend your crawler to crawling social media posts of some large network ( e.g., Twitter, Facebook, LinkedIn, Truth, MeWe…). [15%]
    - Implemented by adding a social media platform as a seed to our crawler. We are using Tumblr as our social media platform. It is considered a major platform with more than 500 million monthly users. Choosing a social media platform was difficult since most platforms no longer allow crawling as a safeguard against their data being used to train LLMs. After careful examination of possible sites, we decided that Tumblr was the best choice that still allowed crawlers. Usage: use "--social" argument for the crawler.
- Provide a graphical human feedback system for deciding among possible phrase corrections, with feedback into the suspicion levels reported by the system. [15%]
    - Description of how it was implemented with an emphasis on data structures and algorithms used
- Develop and Android client for your checker. [15%]
    - For the most part, the Android client of the checker is interfacing with the Checker CLI tool to produce its output in a pop-up window on the app. To do this, the Checker tool was modified so that it did not write the checked result to a JSON file (and instead kept it as a JSON string) as well as not require CLI arguments for the script to function. In addition, helper class functions were used to display the output to the user in the app.
- Extend your system to a language in which none of the team members have fluency. [15% per language, up to 3] - 1x
    - We added the ability to crawl Dutch websites by adding a Dutch webpage seed to our crawler. Usage: use "--dutchSeed" argument for the crawler. Additional Dutch websites to crawl can be specified by adding their URLs to a file and using the "--file [filename.txt]" argument for the crawler. 
- Provide a reasonable translation from English to another language based on common language structures. [30%] 
    - We added the ability to translation from Dutch to English and from English to Dutch. We accomplished this by crawling a Dutch to English online dictionary and translating the words literally. Usage: use ""--dutchDict" argument with crawler to re-crawl the dictionary. 

#### Changed Features from Initial Defense Report

@@ -42,7 +49,7 @@ https://docs.oracle.com/javase/tutorial/networking/urls/index.html
- Folder with All testing Code:

## Work Breakdown
Webcrawler by Alex Melnick 
Webcrawler, Webcrawler stats, Webcrawler social media, Extend system to other language (partial), Provide a reasonable translation (partial) by Alex Melnick 

Data Parser, Android App by Michael Harkess

Loading