1 changed files with 180 additions and 0 deletions
@ -0,0 +1,180 @@ |
|||
|
|||
package controller; |
|||
|
|||
import model.Paper; |
|||
import repository.DataRepository; |
|||
import strategy.*; |
|||
import view.ConsoleView; |
|||
import java.io.*; |
|||
import java.util.Arrays; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
public class CrawlerController { |
|||
private ConsoleView view; |
|||
private DataRepository repository; |
|||
private boolean running; |
|||
|
|||
public CrawlerController(ConsoleView view, DataRepository repository) { |
|||
this.view = view; |
|||
this.repository = repository; |
|||
this.running = true; |
|||
} |
|||
|
|||
public void start() { |
|||
view.showWelcome(); |
|||
} |
|||
|
|||
public void showMenu() { |
|||
view.showMenu(); |
|||
} |
|||
|
|||
public void showHelp() { |
|||
view.showHelp(); |
|||
} |
|||
|
|||
public void crawl(int platform) throws Exception { |
|||
if (platform == 1) crawlWeather(); |
|||
else if (platform == 2) crawlEarthquake(); |
|||
else if (platform == 3) crawlNews(); |
|||
else if (platform == 4) { crawlWeather(); crawlEarthquake(); crawlNews(); } |
|||
else view.showError("Invalid selection"); |
|||
} |
|||
|
|||
private void crawlWeather() throws Exception { |
|||
view.showMessage("Crawling weather data..."); |
|||
CrawlStrategy strategy = new ChangshaWeatherStrategy(); |
|||
List papers = strategy.crawl(); |
|||
List headers = Arrays.asList("Date", "Weather", "HighTemp", "LowTemp", "Wind"); |
|||
repository.saveToCSV(papers, strategy.getOutputFileName(), headers); |
|||
view.showMessage("Saved to " + strategy.getOutputFileName()); |
|||
} |
|||
|
|||
private void crawlEarthquake() throws Exception { |
|||
view.showMessage("Crawling earthquake data..."); |
|||
CrawlStrategy strategy = new EarthquakeStrategy(); |
|||
List papers = strategy.crawl(); |
|||
List headers = Arrays.asList("Time", "Magnitude", "Latitude", "Longitude", "Depth", "Location"); |
|||
repository.saveToCSV(papers, strategy.getOutputFileName(), headers); |
|||
view.showMessage("Saved to " + strategy.getOutputFileName()); |
|||
} |
|||
|
|||
private void crawlNews() throws Exception { |
|||
view.showMessage("Crawling news data..."); |
|||
CrawlStrategy strategy = new NewsRankStrategy(); |
|||
List papers = strategy.crawl(); |
|||
List headers = Arrays.asList("Rank", "Title", "HotIndex", "Link"); |
|||
repository.saveToCSV(papers, strategy.getOutputFileName(), headers); |
|||
view.showMessage("Saved to " + strategy.getOutputFileName()); |
|||
} |
|||
|
|||
public void listData() { |
|||
List files = repository.listDataFiles(); |
|||
view.showDataList(files); |
|||
} |
|||
|
|||
public void generateVisualizations() { |
|||
view.showMessage("Generating visualization pages..."); |
|||
try { |
|||
generateWeatherVisualization(); |
|||
generateEarthquakeVisualization(); |
|||
generateNewsVisualization(); |
|||
view.showMessage("Visualizations generated in visualization/ directory!"); |
|||
} catch (IOException e) { |
|||
view.showError("Failed: " + e.getMessage()); |
|||
} |
|||
} |
|||
|
|||
private void generateWeatherVisualization() throws IOException { |
|||
List data = repository.loadCSV("changsha_weather_2026.csv"); |
|||
File visDir = new File("visualization"); |
|||
if (!visDir.exists()) visDir.mkdirs(); |
|||
File file = new File("visualization", "weather.html"); |
|||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); |
|||
try { |
|||
writer.write("<!DOCTYPE html>\n<html>\n<head>\n<meta charset='UTF-8'>\n<title>Changsha Weather 2026</title>\n<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>\n<style>\nbody{font-family:Arial;margin:0;padding:20px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);}\n.container{max-width:1200px;margin:0 auto;background:#fff;padding:30px;border-radius:15px;box-shadow:0 10px 40px rgba(0,0,0,0.2);}\nh1{text-align:center;color:#333;margin-bottom:30px;}\n</style></head><body><div class='container'><h1>Changsha Weather 2026</h1><canvas id='weatherChart'></canvas></div><script>const ctx=document.getElementById('weatherChart').getContext('2d');const labels=["); |
|||
for (int i = 0; i < data.size(); i++) { |
|||
Map row = (Map) data.get(i); |
|||
if (i > 0) writer.write(","); |
|||
writer.write("'" + row.get("Date") + "'"); |
|||
} |
|||
writer.write("];const highTemps=["); |
|||
for (int i = 0; i < data.size(); i++) { |
|||
Map row = (Map) data.get(i); |
|||
if (i > 0) writer.write(","); |
|||
writer.write(String.valueOf(row.get("HighTemp"))); |
|||
} |
|||
writer.write("];const lowTemps=["); |
|||
for (int i = 0; i < data.size(); i++) { |
|||
Map row = (Map) data.get(i); |
|||
if (i > 0) writer.write(","); |
|||
writer.write(String.valueOf(row.get("LowTemp"))); |
|||
} |
|||
writer.write("];new Chart(ctx,{type:'line',data:{labels:labels,datasets:[{label:'High',data:highTemps,borderColor:'rgb(255,99,132)',backgroundColor:'rgba(255,99,132,0.1)',tension:0.4,fill:true},{label:'Low',data:lowTemps,borderColor:'rgb(54,162,235)',backgroundColor:'rgba(54,162,235,0.1)',tension:0.4,fill:true}]},options:{responsive:true,plugins:{title:{display:true,text:'Temperature'}}}});</script></body></html>"); |
|||
} finally { |
|||
writer.close(); |
|||
} |
|||
} |
|||
|
|||
private void generateEarthquakeVisualization() throws IOException { |
|||
List data = repository.loadCSV("earthquake_2026.csv"); |
|||
File file = new File("visualization", "earthquake.html"); |
|||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); |
|||
try { |
|||
writer.write("<!DOCTYPE html>\n<html>\n<head>\n<meta charset='UTF-8'>\n<title>Earthquake Data 2026</title>\n<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>\n<style>\nbody{font-family:Arial;margin:0;padding:20px;background:linear-gradient(135deg,#1a2a6c 0%,#b21f1f 50%,#fdbb2d 100%);}\n.container{max-width:1400px;margin:0 auto;}\n.panel{background:#fff;padding:30px;border-radius:15px;box-shadow:0 10px 40px rgba(0,0,0,0.2);margin-bottom:30px;}\nh1{text-align:center;color:#fff;margin-bottom:30px;}\ntable{width:100%;border-collapse:collapse;margin-top:20px;}\nth,td{padding:12px;border:1px solid #ddd;text-align:center;}\nth{background:#f5f5f5;}\n</style></head><body><div class='container'><h1>Earthquake Data 2026</h1><div class='panel'><canvas id='magnitudeChart'></canvas></div><div class='panel'><table><tr><th>Time</th><th>Magnitude</th><th>Location</th></tr>"); |
|||
for (int i = 0; i < data.size(); i++) { |
|||
Map row = (Map) data.get(i); |
|||
writer.write("<tr><td>" + row.get("Time") + "</td><td>" + row.get("Magnitude") + "</td><td>" + row.get("Location") + "</td></tr>"); |
|||
} |
|||
writer.write("</table></div></div><script>const magnitudes=["); |
|||
for (int i = 0; i < data.size(); i++) { |
|||
Map row = (Map) data.get(i); |
|||
if (i > 0) writer.write(","); |
|||
writer.write(String.valueOf(row.get("Magnitude"))); |
|||
} |
|||
writer.write("];new Chart(document.getElementById('magnitudeChart'),{type:'bar',data:{labels:magnitudes.map((_,i)=>'EQ'+(i+1)),datasets:[{label:'Magnitude',data:magnitudes,backgroundColor:'rgba(231,76,60,0.8)'}]},options:{responsive:true}});</script></body></html>"); |
|||
} finally { |
|||
writer.close(); |
|||
} |
|||
} |
|||
|
|||
private void generateNewsVisualization() throws IOException { |
|||
List data = repository.loadCSV("news_rank_202605.csv"); |
|||
File file = new File("visualization", "news.html"); |
|||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); |
|||
try { |
|||
writer.write("<!DOCTYPE html>\n<html>\n<head>\n<meta charset='UTF-8'>\n<title>News Rank 2026</title>\n<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>\n<style>\nbody{font-family:Arial;margin:0;padding:20px;background:linear-gradient(135deg,#f093fb 0%,#f5576c 100%);}\n.container{max-width:1200px;margin:0 auto;background:#fff;padding:30px;border-radius:15px;box-shadow:0 10px 40px rgba(0,0,0,0.2);}\nh1{text-align:center;color:#333;margin-bottom:30px;}\n.item{padding:20px;margin:15px 0;border-radius:10px;background:linear-gradient(135deg,#ffecd2 0%,#fcb69f 100%);}\n.rank{font-size:28px;font-weight:bold;color:#e74c3c;display:inline-block;margin-right:15px;background:#fff;width:50px;height:50px;border-radius:50%;text-align:center;line-height:50px;}\n.title{font-size:18px;font-weight:bold;color:#333;}\n</style></head><body><div class='container'><h1>News Rank Top 10</h1><canvas id='newsChart'></canvas><h2 style='margin-top:40px;'>News Details</h2>"); |
|||
for (int i = 0; i < data.size(); i++) { |
|||
Map row = (Map) data.get(i); |
|||
writer.write("<div class='item'><span class='rank'>" + row.get("Rank") + "</span><span class='title'>" + row.get("Title") + "</span></div>"); |
|||
} |
|||
writer.write("</div><script>const titles=["); |
|||
for (int i = 0; i < data.size(); i++) { |
|||
Map row = (Map) data.get(i); |
|||
if (i > 0) writer.write(","); |
|||
String title = (String) row.get("Title"); |
|||
if (title.length() > 25) title = title.substring(0, 25) + "..."; |
|||
writer.write("'" + title + "'"); |
|||
} |
|||
writer.write("];const hots=["); |
|||
for (int i = 0; i < data.size(); i++) { |
|||
Map row = (Map) data.get(i); |
|||
if (i > 0) writer.write(","); |
|||
writer.write(String.valueOf(row.get("HotIndex"))); |
|||
} |
|||
writer.write("];new Chart(document.getElementById('newsChart'),{type:'bar',data:{labels:titles,datasets:[{label:'Hot Index',data:hots,backgroundColor:['rgba(255,99,132,0.8)','rgba(54,162,235,0.8)','rgba(255,206,86,0.8)','rgba(75,192,192,0.8)','rgba(153,102,255,0.8)','rgba(255,159,64,0.8)','rgba(199,199,199,0.8)','rgba(83,102,255,0.8)','rgba(40,167,69,0.8)','rgba(220,53,69,0.8)']}]},options:{indexAxis:'y',responsive:true}});</script></body></html>"); |
|||
} finally { |
|||
writer.close(); |
|||
} |
|||
} |
|||
|
|||
public void exit() { |
|||
this.running = false; |
|||
view.showGoodbye(); |
|||
} |
|||
|
|||
public boolean isRunning() { |
|||
return running; |
|||
} |
|||
} |
|||
|
|||
Loading…
Reference in new issue