├── .classpath ├── .gitignore ├── .project ├── CONTRIBUTORS.md ├── README.md ├── TODO.md ├── lib ├── json-simple-1.1.1.jar └── jsoup-1.8.2.jar ├── res ├── progress.gif └── tick.png └── src ├── com └── koldbyte │ └── codebackup │ ├── core │ ├── AppConfig.java │ ├── MainWindow.java │ ├── TestApp.java │ ├── entities │ │ ├── LanguagesEnum.java │ │ ├── Problem.java │ │ ├── Submission.java │ │ └── User.java │ └── tools │ │ ├── MessageConsole.java │ │ ├── PersistHandler.java │ │ └── PluginWorker.java │ ├── plugins │ ├── PluginEnum.java │ ├── PluginInterface.java │ ├── codechef │ │ ├── CodechefPluginImpl.java │ │ └── core │ │ │ └── entities │ │ │ ├── CodechefProblem.java │ │ │ ├── CodechefSubmission.java │ │ │ └── CodechefUser.java │ ├── codeforces │ │ ├── CodeforcesPluginImpl.java │ │ └── core │ │ │ └── entities │ │ │ ├── CodeforcesProblem.java │ │ │ ├── CodeforcesSubmission.java │ │ │ └── CodeforcesUser.java │ └── spoj │ │ ├── SpojPluginImpl.java │ │ └── core │ │ └── entities │ │ ├── SpojProblem.java │ │ ├── SpojSubmission.java │ │ └── SpojUser.java │ └── utils │ ├── HTTPRequest.java │ └── StringUtils.java └── org └── eclipse └── wb └── swing └── FocusTraversalOnArray.java /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | CodeBackup 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | - koldbyte 2 | - devanshdalal -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## CodeBack 2 | CodeBack is a tool to download all your code submissions from code contest sites — Codeforces, Spoj and Codechef 3 | 4 | GITHUB : [https://github.com/koldbyte/CodeBackup](https://github.com/koldbyte/CodeBackup) 5 | 6 | ## Features 7 | * Downloads Code submissions from Codeforces, Spoj and Codechef 8 | * Also fetches problem statements 9 | * Option to fetch only the first AC submission for a problem 10 | * Option to overwrite/not overwrite existing code 11 | * Http Proxy support. 12 | * Cross-platform 13 | 14 | ## Requirements 15 | * Java 7 & Above 16 | 17 | ## Usage 18 | 19 | 1. Enable the checkbox corresponding to Contest sites for which you want to fetch submissions. 20 | 2. Enter your handle(username) registered on the website. 21 | 3. Select a directory where you want to save the codes 22 | 4, Select other options as required. 23 | 5. Hit Run. 24 | 25 | 26 | Note:- CodeBack will save all the Codes and Problem Statement in following directory format : 27 | (Select Directory) / (Handle) / (ContestSite) / (ProblemName) / (ProblemName)-(SubmissionId).(Ext) 28 | 29 | ## Download 30 | [Download here](https://github.com/koldbyte/CodeBackup/releases/download/Codeback_v3.1/CodeBack_v3.1.jar) 31 | 32 | 33 | ## Screenshots 34 | 35 | ![ ](https://i.imgur.com/rBBY39l.png) 36 | 37 | ## Credits 38 | Used some idea from https://github.com/ideamonk/spojbackup for Spoj 39 | 40 | ## Contribute 41 | If you have found a bug or have an feature request, feel free to fork & code it. And don't forget to send pull requests. 42 | 43 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | 2 | * For fetching code of Codeforces gym submissions, password is also required. So currently, no gym submissions will be downloaded. 3 | * Add check to verify if the handle is valid. 4 | * Add support to download submissions from other sites like HackerRank, HackerEarth etc. -------------------------------------------------------------------------------- /lib/json-simple-1.1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koldbyte/CodeBackup/b07e649ce06e0a2c7a5aede2ff1b81a28c7589b9/lib/json-simple-1.1.1.jar -------------------------------------------------------------------------------- /lib/jsoup-1.8.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koldbyte/CodeBackup/b07e649ce06e0a2c7a5aede2ff1b81a28c7589b9/lib/jsoup-1.8.2.jar -------------------------------------------------------------------------------- /res/progress.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koldbyte/CodeBackup/b07e649ce06e0a2c7a5aede2ff1b81a28c7589b9/res/progress.gif -------------------------------------------------------------------------------- /res/tick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koldbyte/CodeBackup/b07e649ce06e0a2c7a5aede2ff1b81a28c7589b9/res/tick.png -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/core/AppConfig.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.core; 2 | /* 3 | * Stores the user selected options from the UI 4 | */ 5 | public class AppConfig { 6 | public static Boolean overWrite = false; 7 | public static Boolean fetchProblem = false; 8 | public static Boolean fetchAllAC = false; 9 | 10 | public static Boolean getOverWrite() { 11 | return overWrite; 12 | } 13 | 14 | public static Boolean getFetchProblem() { 15 | return fetchProblem; 16 | } 17 | 18 | public static Boolean getFetchAllAC() { 19 | return fetchAllAC; 20 | } 21 | 22 | public static void setFetchAllAC(Boolean fetchAllAC) { 23 | AppConfig.fetchAllAC = fetchAllAC; 24 | } 25 | 26 | public static void setOverWrite(Boolean overWrite) { 27 | AppConfig.overWrite = overWrite; 28 | } 29 | 30 | public static void setFetchProblem(Boolean fetchProblem) { 31 | AppConfig.fetchProblem = fetchProblem; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/core/MainWindow.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.core; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.Color; 5 | import java.awt.Component; 6 | import java.awt.EventQueue; 7 | import java.awt.Font; 8 | import java.awt.event.ActionEvent; 9 | import java.awt.event.ActionListener; 10 | import java.awt.event.WindowAdapter; 11 | import java.awt.event.WindowEvent; 12 | import java.io.File; 13 | import java.net.URL; 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | 17 | import javax.swing.ImageIcon; 18 | import javax.swing.JButton; 19 | import javax.swing.JCheckBox; 20 | import javax.swing.JFileChooser; 21 | import javax.swing.JFrame; 22 | import javax.swing.JLabel; 23 | import javax.swing.JOptionPane; 24 | import javax.swing.JPanel; 25 | import javax.swing.JPasswordField; 26 | import javax.swing.JScrollPane; 27 | import javax.swing.JTextField; 28 | import javax.swing.JTextPane; 29 | import javax.swing.SwingConstants; 30 | import javax.swing.UIManager; 31 | import javax.swing.UnsupportedLookAndFeelException; 32 | import javax.swing.WindowConstants; 33 | import javax.swing.border.EtchedBorder; 34 | import javax.swing.event.ChangeEvent; 35 | import javax.swing.event.ChangeListener; 36 | 37 | import org.eclipse.wb.swing.FocusTraversalOnArray; 38 | 39 | import com.koldbyte.codebackup.core.entities.User; 40 | import com.koldbyte.codebackup.core.tools.MessageConsole; 41 | import com.koldbyte.codebackup.core.tools.PluginWorker; 42 | import com.koldbyte.codebackup.plugins.PluginEnum; 43 | import com.koldbyte.codebackup.plugins.codechef.core.entities.CodechefUser; 44 | import com.koldbyte.codebackup.plugins.codeforces.core.entities.CodeforcesUser; 45 | import com.koldbyte.codebackup.plugins.spoj.core.entities.SpojUser; 46 | 47 | public class MainWindow { 48 | 49 | private JFrame frmCodeback; 50 | private JTextField handleCodechef; 51 | private JTextField handleCodeforces; 52 | private JTextField handleSpoj; 53 | private JPasswordField passSpoj; 54 | private JTextField proxyName; 55 | private JTextField proxyPort; 56 | private JTextField txtDir; 57 | private ImageIcon progress; 58 | private Map backupSystemSettings; 59 | 60 | /** 61 | * Launch the application. 62 | */ 63 | public static void main(String[] args) { 64 | EventQueue.invokeLater(new Runnable() { 65 | public void run() { 66 | try { 67 | MainWindow window = new MainWindow(); 68 | window.frmCodeback.setVisible(true); 69 | 70 | window.frmCodeback 71 | .setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 72 | } catch (Exception e) { 73 | System.err.println("Main: Error starting Application."); 74 | } 75 | } 76 | }); 77 | } 78 | 79 | /** 80 | * Create the application. 81 | */ 82 | public MainWindow() { 83 | initialize(); 84 | } 85 | 86 | /** 87 | * Initialize the contents of the frame. 88 | */ 89 | private void initialize() { 90 | try { 91 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 92 | } catch (ClassNotFoundException e1) { 93 | e1.printStackTrace(); 94 | } catch (InstantiationException e1) { 95 | e1.printStackTrace(); 96 | } catch (IllegalAccessException e1) { 97 | e1.printStackTrace(); 98 | } catch (UnsupportedLookAndFeelException e1) { 99 | e1.printStackTrace(); 100 | } 101 | progress = new ImageIcon(this.getClass().getResource("/progress.gif")); 102 | 103 | frmCodeback = new JFrame(); 104 | frmCodeback.setResizable(false); 105 | frmCodeback.setTitle("CodeBack v3"); 106 | frmCodeback.setBounds(100, 100, 675, 519); 107 | frmCodeback.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 108 | frmCodeback.getContentPane().setLayout(null); 109 | frmCodeback.addWindowListener(new WindowAdapter() { 110 | public void windowClosing(WindowEvent e) { 111 | int confirmed = JOptionPane.showConfirmDialog(null, 112 | "Are you sure you want to exit the program?", 113 | "Confirm Exit", JOptionPane.YES_NO_OPTION); 114 | 115 | if (confirmed == JOptionPane.YES_OPTION) { 116 | frmCodeback.dispose(); 117 | } 118 | } 119 | }); 120 | 121 | ////////////////////////// Codechef options 122 | 123 | final JCheckBox chckbxCodechef = new JCheckBox("Codechef"); 124 | chckbxCodechef.setHorizontalAlignment(SwingConstants.LEFT); 125 | 126 | chckbxCodechef.setBounds(10, 7, 218, 23); 127 | frmCodeback.getContentPane().add(chckbxCodechef); 128 | 129 | final JPanel panelCodechef = new JPanel(); 130 | panelCodechef.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, 131 | null)); 132 | panelCodechef.setBounds(10, 36, 248, 41); 133 | frmCodeback.getContentPane().add(panelCodechef); 134 | panelCodechef.setLayout(null); 135 | panelCodechef.setVisible(false); 136 | 137 | JLabel lblHandle = new JLabel("Handle"); 138 | lblHandle.setBounds(10, 11, 74, 14); 139 | panelCodechef.add(lblHandle); 140 | 141 | handleCodechef = new JTextField(); 142 | handleCodechef.setBounds(94, 8, 145, 20); 143 | panelCodechef.add(handleCodechef); 144 | handleCodechef.setColumns(10); 145 | 146 | ////////////////////////// Codeforces options 147 | 148 | final JCheckBox chckbxCodeforces = new JCheckBox("Codeforces"); 149 | chckbxCodeforces.setHorizontalAlignment(SwingConstants.LEFT); 150 | 151 | chckbxCodeforces.setBounds(10, 84, 218, 23); 152 | frmCodeback.getContentPane().add(chckbxCodeforces); 153 | 154 | final JPanel panelCodeforces = new JPanel(); 155 | panelCodeforces.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, 156 | null)); 157 | panelCodeforces.setLayout(null); 158 | panelCodeforces.setBounds(10, 113, 248, 41); 159 | frmCodeback.getContentPane().add(panelCodeforces); 160 | panelCodeforces.setVisible(false); 161 | 162 | JLabel label = new JLabel("Handle"); 163 | label.setBounds(10, 11, 77, 14); 164 | panelCodeforces.add(label); 165 | 166 | handleCodeforces = new JTextField(); 167 | handleCodeforces.setColumns(10); 168 | handleCodeforces.setBounds(94, 8, 145, 20); 169 | panelCodeforces.add(handleCodeforces); 170 | 171 | ////////////////////////// Spoj options 172 | 173 | final JCheckBox chckbxSpoj = new JCheckBox("Spoj"); 174 | chckbxSpoj.setHorizontalAlignment(SwingConstants.LEFT); 175 | 176 | chckbxSpoj.setBounds(10, 161, 218, 23); 177 | frmCodeback.getContentPane().add(chckbxSpoj); 178 | 179 | final JPanel panelSpoj = new JPanel(); 180 | panelSpoj.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null)); 181 | panelSpoj.setLayout(null); 182 | panelSpoj.setBounds(10, 190, 248, 73); 183 | frmCodeback.getContentPane().add(panelSpoj); 184 | panelSpoj.setVisible(false); 185 | 186 | JLabel label_1 = new JLabel("Handle"); 187 | label_1.setBounds(10, 11, 74, 14); 188 | panelSpoj.add(label_1); 189 | 190 | handleSpoj = new JTextField(); 191 | handleSpoj.setColumns(10); 192 | handleSpoj.setBounds(94, 8, 145, 20); 193 | panelSpoj.add(handleSpoj); 194 | 195 | JLabel lblPass = new JLabel("Pass"); 196 | lblPass.setBounds(10, 40, 74, 14); 197 | panelSpoj.add(lblPass); 198 | 199 | passSpoj = new JPasswordField(); 200 | passSpoj.setBounds(94, 39, 145, 20); 201 | panelSpoj.add(passSpoj); 202 | passSpoj.setColumns(10); 203 | 204 | ////////////////////////// Proxy options 205 | 206 | //Backup original proxy settings of the system 207 | backupSystemSettings = new HashMap(); 208 | backupSystemSettings.put("http.proxyHost", System.getProperty("http.proxyHost")); 209 | backupSystemSettings.put("http.proxyPort", System.getProperty("http.proxyPort")); 210 | backupSystemSettings.put("http.proxySet", System.getProperty("http.proxySet")); 211 | 212 | final JCheckBox chckbxProxy = new JCheckBox("Use Proxy"); 213 | chckbxProxy.setHorizontalAlignment(SwingConstants.LEFT); 214 | 215 | chckbxProxy.setBounds(286, 161, 218, 23); 216 | frmCodeback.getContentPane().add(chckbxProxy); 217 | 218 | final JPanel panelProxy = new JPanel(); 219 | panelProxy.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null)); 220 | panelProxy.setLayout(null); 221 | panelProxy.setBounds(296, 190, 248, 73); 222 | frmCodeback.getContentPane().add(panelProxy); 223 | panelProxy.setVisible(false); 224 | 225 | JLabel labelName = new JLabel("Proxy"); 226 | labelName.setBounds(10, 11, 74, 14); 227 | panelProxy.add(labelName); 228 | 229 | proxyName = new JTextField(); 230 | proxyName.setColumns(10); 231 | proxyName.setBounds(94, 8, 145, 20); 232 | panelProxy.add(proxyName); 233 | 234 | JLabel labelPort = new JLabel("Port"); 235 | labelPort.setBounds(10, 40, 74, 14); 236 | panelProxy.add(labelPort); 237 | 238 | proxyPort = new JTextField(); 239 | proxyPort.setColumns(10); 240 | proxyPort.setBounds(94, 39, 145, 20); 241 | panelProxy.add(proxyPort); 242 | 243 | ////////////////////////// Status Panel 244 | 245 | JPanel statusPanel = new JPanel(new BorderLayout()); 246 | statusPanel.setToolTipText("Status"); 247 | statusPanel.setBounds(10, 320, 649, 158); 248 | frmCodeback.getContentPane().add(statusPanel); 249 | 250 | JTextPane statusLabel = new JTextPane(); 251 | statusLabel.setBackground(Color.DARK_GRAY); 252 | statusLabel.setForeground(Color.BLACK); 253 | statusLabel.setFont(new Font("SansSerif", Font.BOLD, 11)); 254 | statusLabel.setBounds(10, 274, 620, 124); 255 | statusLabel.setEditable(false); 256 | statusLabel.setSize(620, 124); 257 | // statusLabel.setLineWrap(true); 258 | // statusLabel.setRows(6); 259 | // statusLabel.setColumns(78); 260 | statusPanel.add(statusLabel); 261 | 262 | JScrollPane scrollPane = new JScrollPane(statusLabel, 263 | JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 264 | JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 265 | statusPanel.add(scrollPane, 266 | BorderLayout.CENTER); 267 | 268 | 269 | ////////////////////////// Redirect out and Err to status label 270 | 271 | MessageConsole mc = new MessageConsole(statusLabel); 272 | mc.redirectOut(Color.GREEN, null); 273 | mc.redirectErr(Color.RED, null); 274 | // mc.redirectOut(null, System.out); 275 | 276 | ////////////////////////// Select Directory 277 | JLabel lblDirectory = new JLabel("Directory"); 278 | lblDirectory.setBounds(286, 15, 373, 14); 279 | frmCodeback.getContentPane().add(lblDirectory); 280 | 281 | txtDir = new JTextField(); 282 | txtDir.setEditable(false); 283 | txtDir.setColumns(10); 284 | txtDir.setBounds(286, 37, 324, 20); 285 | frmCodeback.getContentPane().add(txtDir); 286 | 287 | JButton btnDirectory = new JButton("\u00BB"); 288 | 289 | btnDirectory.setBounds(620, 36, 39, 23); 290 | frmCodeback.getContentPane().add(btnDirectory); 291 | 292 | JButton btnRun = new JButton("Run"); 293 | 294 | btnRun.setBounds(385, 275, 111, 23); 295 | frmCodeback.getContentPane().add(btnRun); 296 | 297 | JButton btnExit = new JButton("Exit"); 298 | btnExit.addActionListener(new ActionListener() { 299 | public void actionPerformed(ActionEvent e) { 300 | frmCodeback.dispatchEvent(new WindowEvent(frmCodeback, 301 | WindowEvent.WINDOW_CLOSING)); 302 | } 303 | }); 304 | btnExit.setBounds(596, 275, 59, 23); 305 | frmCodeback.getContentPane().add(btnExit); 306 | 307 | URL url = this.getClass().getResource("/progress.gif"); 308 | ImageIcon progressIcon = new ImageIcon(url); 309 | 310 | final JLabel progressCodechef = new JLabel(); 311 | progressCodechef.setBounds(234, 7, 24, 24); 312 | progressCodechef.setIcon(progressIcon); 313 | frmCodeback.getContentPane().add(progressCodechef); 314 | progressCodechef.setVisible(false); 315 | 316 | final JLabel progressCodeforces = new JLabel(); 317 | progressCodeforces.setBounds(234, 83, 24, 24); 318 | progressCodeforces.setIcon(progressIcon); 319 | frmCodeback.getContentPane().add(progressCodeforces); 320 | progressCodeforces.setVisible(false); 321 | 322 | final JLabel progressSpoj = new JLabel(); 323 | progressSpoj.setBounds(234, 160, 24, 24); 324 | progressSpoj.setIcon(progressIcon); 325 | frmCodeback.getContentPane().add(progressSpoj); 326 | 327 | final JCheckBox chkOverwrite = new JCheckBox("Overwrite if Code Exist"); 328 | chkOverwrite.setBounds(286, 84, 373, 23); 329 | frmCodeback.getContentPane().add(chkOverwrite); 330 | 331 | final JCheckBox chkProblem = new JCheckBox( 332 | "Also Fetch Problem statements"); 333 | chkProblem.setBounds(286, 111, 373, 23); 334 | frmCodeback.getContentPane().add(chkProblem); 335 | 336 | ////////////////////////// Show a messageDialog on About click 337 | 338 | JButton btnInfo = new JButton("About"); 339 | btnInfo.addActionListener(new ActionListener() { 340 | public void actionPerformed(ActionEvent e) { 341 | String msg = "CodeBack - Developed by Koldbyte (Bhaskar Divya)\n"; 342 | msg += "CodeBack is a tool to backup all your code submissions on contest sites - Spoj, Codeforces and Codechef.\n\n"; 343 | msg += "GITHUB : https://github.com/koldbyte/CodeBackup\n\n"; 344 | msg += "How to use it?\n\n"; 345 | msg += "1. Enable the checkboxes for which you want to fetch submissions.\n"; 346 | msg += "2. Enter your handle(username) registered on the website.\n"; 347 | msg += "3. Select a directory where you want to save the codes\n"; 348 | msg += "4, Select other options as required.\n"; 349 | msg += "5. Hit Run.\n"; 350 | msg += "\n"; 351 | msg += "CodeBack will save all the Codes and Problem Statement in following directory format :\n"; 352 | msg += "(Select Directory) / (Handle) / (ContestSite) / (PROBLEMNAME) / (PROBLEMNAME)-(SUBMISSIONID).(EXT)\n\n"; 353 | msg += "Feature added by Devansh Dalal( https://github.com/devanshdalal )\n"; 354 | msg += "UPDATE: new proxy feature added. You can download the codes via proxy now as well\n"; 355 | 356 | JOptionPane.showMessageDialog(frmCodeback, msg, 357 | "About CodeBack", JOptionPane.INFORMATION_MESSAGE); 358 | } 359 | }); 360 | btnInfo.setBounds(508, 275, 76, 23); 361 | frmCodeback.getContentPane().add(btnInfo); 362 | 363 | final JCheckBox chkFetchAllAccepted = new JCheckBox( 364 | "Fetch All Accepted Submissions"); 365 | chkFetchAllAccepted.setBounds(286, 138, 373, 23); 366 | frmCodeback.getContentPane().add(chkFetchAllAccepted); 367 | frmCodeback.getContentPane().setFocusTraversalPolicy(new FocusTraversalOnArray(new Component[]{chckbxCodechef, handleCodechef, chckbxCodeforces, handleCodeforces, chckbxSpoj, handleSpoj, passSpoj, lblDirectory, txtDir, btnDirectory, chkOverwrite, chkProblem, chkFetchAllAccepted, btnInfo, btnRun, btnExit, statusLabel, panelCodechef, lblHandle, panelCodeforces, label, panelSpoj, label_1, lblPass, statusPanel, scrollPane, statusLabel, progressCodechef, progressCodeforces, progressSpoj})); 368 | progressSpoj.setVisible(false); 369 | 370 | ////////////////////////// Show hide options based on checkboxes 371 | chckbxCodechef.addChangeListener(new ChangeListener() { 372 | public void stateChanged(ChangeEvent e) { 373 | Boolean status = ((JCheckBox) e.getSource()).isSelected(); 374 | panelCodechef.setVisible(status); 375 | } 376 | }); 377 | 378 | chckbxCodeforces.addChangeListener(new ChangeListener() { 379 | public void stateChanged(ChangeEvent e) { 380 | Boolean status = ((JCheckBox) e.getSource()).isSelected(); 381 | panelCodeforces.setVisible(status); 382 | } 383 | }); 384 | 385 | chckbxSpoj.addChangeListener(new ChangeListener() { 386 | public void stateChanged(ChangeEvent e) { 387 | Boolean status = ((JCheckBox) e.getSource()).isSelected(); 388 | panelSpoj.setVisible(status); 389 | } 390 | }); 391 | 392 | chckbxProxy.addChangeListener(new ChangeListener() { 393 | public void stateChanged(ChangeEvent e) { 394 | Boolean status = ((JCheckBox) e.getSource()).isSelected(); 395 | panelProxy.setVisible(status); 396 | } 397 | }); 398 | 399 | btnDirectory.addActionListener(new ActionListener() { 400 | public void actionPerformed(ActionEvent e) { 401 | // choose directory 402 | JFileChooser fc = new JFileChooser(); 403 | fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 404 | fc.setAcceptAllFileFilterUsed(false); 405 | int returnVal = fc.showOpenDialog(frmCodeback); 406 | if (returnVal == JFileChooser.APPROVE_OPTION) { 407 | File yourFolder = fc.getSelectedFile(); 408 | txtDir.setText(yourFolder.getAbsolutePath()); 409 | System.out.println("Selected Directory :- " 410 | + yourFolder.toPath()); 411 | } 412 | } 413 | }); 414 | 415 | btnRun.addActionListener(new ActionListener() { 416 | public void actionPerformed(ActionEvent e) { 417 | // Disable the run button for now 418 | ((JButton) e.getSource()).setEnabled(false); 419 | 420 | // Initialize Appconfig 421 | AppConfig.setOverWrite(chkOverwrite.isSelected()); 422 | AppConfig.setFetchProblem(chkProblem.isSelected()); 423 | AppConfig.setFetchAllAC(chkFetchAllAccepted.isSelected()); 424 | 425 | 426 | Boolean codechefStatus = chckbxCodechef.isSelected(); 427 | Boolean codeforcesStatus = chckbxCodeforces.isSelected(); 428 | Boolean spojStatus = chckbxSpoj.isSelected(); 429 | 430 | ////////////////////////// Proxy settings 431 | Boolean proxyStatus = chckbxProxy.isSelected(); 432 | if(proxyStatus){ 433 | //System.setProperty("http.proxySet", "true"); 434 | System.setProperty("http.proxyHost", proxyName.getText() ); 435 | System.setProperty("http.proxyPort", proxyPort.getText() ); 436 | }else{ 437 | //use original settings which were retrieved on the first run 438 | //It might be overwritten by the above code in previous runs 439 | if(backupSystemSettings.get("http.proxySet") != null) 440 | System.setProperty("http.proxySet", backupSystemSettings.get("http.proxySet")); 441 | if(backupSystemSettings.get("http.proxyHost") != null) 442 | System.setProperty("http.proxyHost", backupSystemSettings.get("http.proxyHost") ); 443 | if(backupSystemSettings.get("http.proxyPort") != null) 444 | System.setProperty("http.proxyPort", backupSystemSettings.get("http.proxyPort") ); 445 | } 446 | 447 | String msg = ""; 448 | String succesMsg = ""; 449 | String dir = txtDir.getText(); 450 | if (dir == null || dir.isEmpty()) { 451 | msg += "Please provide an output Directory.\n"; 452 | } else { 453 | /* 454 | * Check for codechef 455 | */ 456 | if (codechefStatus) { 457 | String codechefHandle = handleCodechef.getText(); 458 | if (codechefHandle == null || codechefHandle.isEmpty()) { 459 | msg += "Please provide a Codechef handle.\n"; 460 | } else { 461 | User user = new CodechefUser(codechefHandle); 462 | if (!user.isValidUser()) { 463 | msg += "Entered Codechef handle is invalid.\n"; 464 | } else { 465 | PluginWorker runnable = new PluginWorker(dir, 466 | user, PluginEnum.CODECHEF, 467 | progressCodechef); 468 | progressCodechef.setIcon(progress); 469 | progressCodechef.setVisible(true); 470 | 471 | runnable.execute(); 472 | } 473 | } 474 | } 475 | /* 476 | * Check for Codeforces 477 | */ 478 | if (codeforcesStatus) { 479 | String codeforceHandle = handleCodeforces.getText(); 480 | if (codeforceHandle == null 481 | || codeforceHandle.isEmpty()) { 482 | msg += "Please provide a Codeforces handle.\n"; 483 | } else { 484 | User user = new CodeforcesUser(codeforceHandle); 485 | if (!user.isValidUser()) { 486 | msg += "Entered Codeforces handle is invalid.\n"; 487 | } else { 488 | PluginWorker runnable = new PluginWorker(dir, 489 | user, PluginEnum.CODEFORCES, 490 | progressCodeforces); 491 | progressCodeforces.setIcon(progress); 492 | progressCodeforces.setVisible(true); 493 | 494 | runnable.execute(); 495 | } 496 | } 497 | } 498 | 499 | /* 500 | * Check for Spoj 501 | */ 502 | if (spojStatus) { 503 | String spojHandle = handleSpoj.getText(); 504 | String spojPass = String.valueOf(passSpoj.getPassword()); 505 | if (spojHandle == null || spojHandle.isEmpty()) { 506 | msg += "Please provide a Spoj handle.\n"; 507 | } else if (spojPass == null || spojPass.isEmpty()) { 508 | msg += "Please provide password for the Spoj handle.\n"; 509 | } else { 510 | User user = new SpojUser(spojHandle); 511 | ((SpojUser) user).setUsername(spojHandle); 512 | ((SpojUser) user).setPass(spojPass); 513 | if (!user.isValidUser()) { 514 | msg += "Entered Spoj handle is invalid.\n"; 515 | } else { 516 | PluginWorker runnable = new PluginWorker(dir, 517 | user, PluginEnum.SPOJ, progressSpoj); 518 | progressSpoj.setIcon(progress); 519 | progressSpoj.setVisible(true); 520 | 521 | runnable.execute(); 522 | } 523 | } 524 | } 525 | } 526 | if (!msg.isEmpty()) { 527 | JOptionPane.showMessageDialog(frmCodeback, msg, "Error", 528 | JOptionPane.ERROR_MESSAGE); 529 | } 530 | if (!succesMsg.isEmpty()) { 531 | JOptionPane.showMessageDialog(frmCodeback, succesMsg, 532 | "Success", JOptionPane.INFORMATION_MESSAGE); 533 | } 534 | 535 | // Reenable the run button 536 | ((JButton) e.getSource()).setEnabled(true); 537 | } 538 | }); 539 | } 540 | } 541 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/core/TestApp.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.core; 2 | 3 | import java.util.List; 4 | 5 | import com.koldbyte.codebackup.core.entities.Problem; 6 | import com.koldbyte.codebackup.core.entities.Submission; 7 | import com.koldbyte.codebackup.core.entities.User; 8 | import com.koldbyte.codebackup.plugins.PluginInterface; 9 | import com.koldbyte.codebackup.plugins.codechef.CodechefPluginImpl; 10 | import com.koldbyte.codebackup.plugins.codechef.core.entities.CodechefProblem; 11 | import com.koldbyte.codebackup.plugins.codechef.core.entities.CodechefUser; 12 | import com.koldbyte.codebackup.plugins.codeforces.CodeforcesPluginImpl; 13 | import com.koldbyte.codebackup.plugins.codeforces.core.entities.CodeforcesProblem; 14 | import com.koldbyte.codebackup.plugins.codeforces.core.entities.CodeforcesUser; 15 | import com.koldbyte.codebackup.plugins.spoj.SpojPluginImpl; 16 | import com.koldbyte.codebackup.plugins.spoj.core.entities.SpojProblem; 17 | import com.koldbyte.codebackup.plugins.spoj.core.entities.SpojSubmission; 18 | import com.koldbyte.codebackup.plugins.spoj.core.entities.SpojUser; 19 | 20 | public class TestApp { 21 | public static void main(String[] args) { 22 | // test1(); //passed //test explode function 23 | 24 | /* 25 | * Testing Codechef 26 | */ 27 | // test2(); //passed //test fetch list of submissions - codechef 28 | // test3(); //passed //test fetch of code - codechef 29 | // test6(); //passed but output contains some extra contents like 30 | // comments //test fetch of problem Statement Codechef 31 | 32 | /* 33 | * Testing Codeforces 34 | */ 35 | // test4(); //passed //test fetch list of submissions - codeforces 36 | // test5(); //passed //test fetch of code - codeforces 37 | // test7(); //passed //test fetch of problem Statement Codeforces 38 | 39 | /* 40 | * Testing Spoj 41 | */ 42 | 43 | // test8(); //passed //test fetch of problem Statement SPoj 44 | //test9(); // //test fetch list of submissions - spoj 45 | // test10(); // passed //test fetch of code - Spoj 46 | } 47 | 48 | public static void test1() { 49 | // System.out.println(StringUtils.explode(new StringBuffer("abcbcbd"), 50 | // "a", "d")); 51 | } 52 | 53 | public static void test2() { 54 | User u = new CodechefUser("bhaskardivya", 55 | "http://www.codechef.com/users/bhaskardivya"); 56 | PluginInterface plugin = new CodechefPluginImpl(); 57 | List list = plugin.getSolvedList(u); 58 | for (Submission s : list) { 59 | System.out.println("Sub->" + s.getSubmissionId() + " ,problem->" 60 | + s.getProblem().getProblemId() + ", url->" 61 | + s.getSubmissionUrl()); 62 | } 63 | } 64 | 65 | public static void test3() { 66 | User u = new CodechefUser("bhaskardivya", 67 | "http://www.codechef.com/users/bhaskardivya"); 68 | PluginInterface plugin = new CodechefPluginImpl(); 69 | List list = plugin.getSolvedList(u); 70 | for (Submission s : list) { 71 | System.out.println("Sub->" + s.getSubmissionId() + " ,problem->" 72 | + s.getProblem().getProblemId() + ", url->" 73 | + s.getSubmissionUrl()); 74 | System.out.println(s.getCode()); 75 | } 76 | } 77 | 78 | public static void test4() { 79 | User u = new CodeforcesUser("koldbyte", 80 | "http://codeforces.com/profile/koldbyte"); 81 | PluginInterface plugin = new CodeforcesPluginImpl(); 82 | List list = plugin.getSolvedList(u); 83 | for (Submission s : list) { 84 | System.out.println("Sub->" + s.getSubmissionId() + " ,problem->" 85 | + s.getProblem().getProblemId() + ", url->" 86 | + s.getSubmissionUrl()); 87 | // System.out.println(s.getCode()); 88 | } 89 | } 90 | 91 | public static void test5() { 92 | User u = new CodeforcesUser("koldbyte", 93 | "http://codeforces.com/profile/koldbyte"); 94 | PluginInterface plugin = new CodeforcesPluginImpl(); 95 | List list = plugin.getSolvedList(u); 96 | for (Submission s : list) { 97 | System.out.println("Sub->" + s.getSubmissionId() + " ,problem->" 98 | + s.getProblem().getProblemId() + ", url->" 99 | + s.getSubmissionUrl()); 100 | System.out.println(s.getCode()); 101 | } 102 | } 103 | 104 | public static void test6() { 105 | Problem problem = new CodechefProblem( 106 | "http://www.codechef.com/problems/AGENTS"); 107 | System.out.println(problem.getProblemStatement()); 108 | } 109 | 110 | public static void test7() { 111 | Problem problem = new CodeforcesProblem( 112 | "http://codeforces.com/contest/2/problem/B"); 113 | System.out.println(problem.getProblemStatement()); 114 | } 115 | 116 | public static void test8() { 117 | Problem problem = new SpojProblem("https://www.spoj.com/problems/FCTRL/"); 118 | System.out.println(problem.getProblemStatement()); 119 | } 120 | 121 | public static void test9() { 122 | User u = new SpojUser("koldbyte", "https://www.spoj.com/users/koldbyte/"); 123 | PluginInterface plugin = new SpojPluginImpl(); 124 | List list = plugin.getSolvedList(u); 125 | for (Submission s : list) { 126 | System.out.println("Sub->" + s.getSubmissionId() + " ,problem->" 127 | + s.getProblem().getProblemId() + ", url->" 128 | + s.getSubmissionUrl()); 129 | // System.out.println(s.getCode()); 130 | } 131 | } 132 | 133 | public static void test10() { 134 | User u = new SpojUser("koldbyte", "https://www.spoj.com/users/koldbyte/"); 135 | Problem p = new SpojProblem("https://www.spoj.com/problems/BITMAP/"); 136 | ((SpojUser) u).setUsername("koldbyte"); 137 | ((SpojUser) u).setPass("thisisrandompass"); 138 | Submission s = new SpojSubmission("11808446", 139 | "www.spoj.com/files/src/save/11808446", p, u); 140 | System.out.println("Sub->" + s.getSubmissionId() + " ,problem->" 141 | + s.getProblem().getProblemId() + ", url->" 142 | + s.getSubmissionUrl()); 143 | System.out.println("Code is "); 144 | System.out.println(s.getCode()); 145 | 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/core/entities/LanguagesEnum.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.core.entities; 2 | 3 | public enum LanguagesEnum { 4 | C("c"), CPP("cpp"), JAVA("java"), PYTHON("py"), RUBY("rb"), PASCAL("pas"), TEXT( 5 | "txt"); 6 | 7 | private String extension; 8 | 9 | LanguagesEnum(String ext) { 10 | setExtension(ext); 11 | } 12 | 13 | public String getExtension() { 14 | return extension; 15 | } 16 | 17 | public void setExtension(String extension) { 18 | this.extension = extension; 19 | } 20 | 21 | public static LanguagesEnum findExtension(String ext) { 22 | String e = ext.toLowerCase(); 23 | if (e.contains("c++")) { 24 | return CPP; 25 | } 26 | if (e.contains("java")) { 27 | return JAVA; 28 | } 29 | if (e.contains("python")) { 30 | return PYTHON; 31 | } 32 | if (e.contains("ruby")) { 33 | return RUBY; 34 | } 35 | if (e.contains("pascal")) { 36 | return PASCAL; 37 | } 38 | if (e.contains("gcc") || e.contains("c")) { 39 | return C; 40 | } 41 | 42 | return TEXT; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/core/entities/Problem.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.core.entities; 2 | 3 | public abstract class Problem { 4 | protected String problemId; 5 | protected String url; 6 | protected String problemStatement; 7 | 8 | public Problem() { 9 | super(); 10 | } 11 | 12 | public Problem(String url) { 13 | super(); 14 | this.url = url; 15 | } 16 | 17 | public Problem(String problemId, String url) { 18 | super(); 19 | this.problemId = problemId; 20 | this.url = url; 21 | } 22 | 23 | public String getProblemId() { 24 | return problemId; 25 | } 26 | 27 | public String getUrl() { 28 | return url; 29 | } 30 | 31 | public String getProblemStatement() { 32 | if (problemStatement == null || problemStatement.isEmpty()) { 33 | problemStatement = fetchProblemStatement(); 34 | } 35 | return problemStatement; 36 | } 37 | 38 | public void setProblemId(String problemId) { 39 | this.problemId = problemId; 40 | } 41 | 42 | public void setUrl(String url) { 43 | this.url = url; 44 | } 45 | 46 | public void setProblemStatement(String problemStatement) { 47 | this.problemStatement = problemStatement; 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return "Problem [problemId=" + problemId + ", url=" + url + "]"; 53 | } 54 | 55 | @Override 56 | public int hashCode() { 57 | final int prime = 31; 58 | int result = 1; 59 | result = prime * result 60 | + ((problemId == null) ? 0 : problemId.hashCode()); 61 | result = prime * result + ((url == null) ? 0 : url.hashCode()); 62 | return result; 63 | } 64 | 65 | @Override 66 | public boolean equals(Object obj) { 67 | if (this == obj) 68 | return true; 69 | if (obj == null) 70 | return false; 71 | if (getClass() != obj.getClass()) 72 | return false; 73 | Problem other = (Problem) obj; 74 | if (problemId == null) { 75 | if (other.problemId != null) 76 | return false; 77 | } else if (!problemId.equals(other.problemId)) 78 | return false; 79 | if (url == null) { 80 | if (other.url != null) 81 | return false; 82 | } else if (!url.equals(other.url)) 83 | return false; 84 | return true; 85 | } 86 | 87 | public abstract String fetchProblemStatement(); 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/core/entities/Submission.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.core.entities; 2 | 3 | public abstract class Submission { 4 | protected String submissionId; 5 | protected String submissionUrl; 6 | protected String timestamp; 7 | protected String code; 8 | protected LanguagesEnum language; 9 | protected Problem problem; 10 | protected User user; 11 | 12 | public Submission() { 13 | super(); 14 | } 15 | 16 | public Submission(String submissionUrl) { 17 | super(); 18 | this.submissionUrl = submissionUrl; 19 | this.submissionId = getSubmissionIdFromUrl(); 20 | } 21 | 22 | public Submission(String submissionId, Problem problem) { 23 | super(); 24 | this.submissionId = submissionId; 25 | this.submissionUrl = getSubmissionUrlFromId(); 26 | this.problem = problem; 27 | } 28 | 29 | public Submission(String submissionId, String submissionUrl, 30 | Problem problem, User user) { 31 | super(); 32 | this.submissionId = submissionId; 33 | this.submissionUrl = submissionUrl; 34 | this.problem = problem; 35 | this.user = user; 36 | 37 | if(submissionId == null || submissionId.isEmpty()) 38 | this.submissionId = getSubmissionId(); 39 | 40 | if(submissionUrl == null || submissionUrl.isEmpty()) 41 | this.submissionUrl = getSubmissionUrlFromId(); 42 | } 43 | 44 | public String getSubmissionUrl() { 45 | if (submissionUrl == null || submissionUrl.isEmpty()) { 46 | submissionUrl = getSubmissionUrlFromId(); 47 | } 48 | return submissionUrl; 49 | } 50 | 51 | public User getUser() { 52 | return user; 53 | } 54 | 55 | public String getSubmissionId() { 56 | return submissionId; 57 | } 58 | 59 | public String getTimestamp() { 60 | return timestamp; 61 | } 62 | 63 | public String getCode() { 64 | if (code == null || code.isEmpty()) { 65 | code = fetchSubmittedCode(); 66 | } 67 | return code; 68 | } 69 | 70 | public LanguagesEnum getLanguage() { 71 | return language; 72 | } 73 | 74 | public Problem getProblem() { 75 | return problem; 76 | } 77 | 78 | public void setSubmissionUrl(String submissionUrl) { 79 | this.submissionUrl = submissionUrl; 80 | } 81 | 82 | public void setUser(User user) { 83 | this.user = user; 84 | } 85 | 86 | public void setSubmissionId(String submissionId) { 87 | this.submissionId = submissionId; 88 | } 89 | 90 | public void setTimestamp(String timestamp) { 91 | this.timestamp = timestamp; 92 | } 93 | 94 | public void setCode(String code) { 95 | this.code = code; 96 | } 97 | 98 | public void setLanguage(LanguagesEnum language) { 99 | this.language = language; 100 | } 101 | 102 | public void setProblem(Problem problem) { 103 | this.problem = problem; 104 | } 105 | 106 | public abstract String fetchSubmittedCode(); 107 | 108 | public abstract String getSubmissionIdFromUrl(); 109 | 110 | public abstract String getSubmissionUrlFromId(); 111 | } 112 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/core/entities/User.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.core.entities; 2 | 3 | public abstract class User { 4 | protected String handle; 5 | protected String profileUrl; 6 | 7 | public User() { 8 | super(); 9 | } 10 | 11 | public User(String handle) { 12 | super(); 13 | this.handle = handle; 14 | this.profileUrl = getProfileUrlFromHandle(); 15 | } 16 | 17 | public User(String handle, String profileUrl) { 18 | super(); 19 | this.handle = handle; 20 | this.profileUrl = profileUrl; 21 | } 22 | 23 | public String getHandle() { 24 | if (handle == null || handle.isEmpty()) { 25 | if (profileUrl != null && !profileUrl.isEmpty()) { 26 | handle = getHandleFromProfileUrl(); 27 | } 28 | } 29 | return handle; 30 | } 31 | 32 | public String getProfileUrl() { 33 | if (profileUrl == null || profileUrl.isEmpty()) { 34 | if (handle != null && !handle.isEmpty()) { 35 | profileUrl = getProfileUrlFromHandle(); 36 | } 37 | } 38 | return profileUrl; 39 | } 40 | 41 | public void setHandle(String handle) { 42 | this.handle = handle; 43 | } 44 | 45 | public void setProfileUrl(String profileUrl) { 46 | this.profileUrl = profileUrl; 47 | } 48 | 49 | public abstract String getHandleFromProfileUrl(); 50 | 51 | public abstract String getProfileUrlFromHandle(); 52 | 53 | public abstract Boolean isValidUser(); 54 | } 55 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/core/tools/MessageConsole.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.core.tools; 2 | 3 | import java.awt.Color; 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.PrintStream; 6 | 7 | import javax.swing.text.BadLocationException; 8 | import javax.swing.text.Document; 9 | import javax.swing.text.JTextComponent; 10 | import javax.swing.text.SimpleAttributeSet; 11 | import javax.swing.text.StyleConstants; 12 | 13 | /* 14 | * Author: Rob Camick 15 | * url : https://tips4java.wordpress.com/2008/11/08/message-console/ 16 | */ 17 | 18 | /* 19 | * Create a simple console to display text messages. 20 | * 21 | * Messages can be directed here from different sources. Each source can 22 | * have its messages displayed in a different color. 23 | * 24 | * Messages can either be appended to the console or inserted as the first 25 | * line of the console 26 | * 27 | * You can limit the number of lines to hold in the Document. 28 | */ 29 | public class MessageConsole { 30 | private JTextComponent textComponent; 31 | private Document document; 32 | private boolean isAppend; 33 | 34 | // private DocumentListener limitLinesListener; 35 | 36 | public MessageConsole(JTextComponent textComponent) { 37 | this(textComponent, true); 38 | } 39 | 40 | /* 41 | * Use the text component specified as a simply console to display text 42 | * messages. 43 | * 44 | * The messages can either be appended to the end of the console or inserted 45 | * as the first line of the console. 46 | */ 47 | public MessageConsole(JTextComponent textComponent, boolean isAppend) { 48 | this.textComponent = textComponent; 49 | this.document = textComponent.getDocument(); 50 | this.isAppend = isAppend; 51 | textComponent.setEditable(false); 52 | } 53 | 54 | /* 55 | * Redirect the output from the standard output to the console using the 56 | * default text color and null PrintStream 57 | */ 58 | public void redirectOut() { 59 | redirectOut(null, null); 60 | } 61 | 62 | /* 63 | * Redirect the output from the standard output to the console using the 64 | * specified color and PrintStream. When a PrintStream is specified the 65 | * message will be added to the Document before it is also written to the 66 | * PrintStream. 67 | */ 68 | public void redirectOut(Color textColor, PrintStream printStream) { 69 | ConsoleOutputStream cos = new ConsoleOutputStream(textColor, 70 | printStream); 71 | System.setOut(new PrintStream(cos, true)); 72 | } 73 | 74 | /* 75 | * Redirect the output from the standard error to the console using the 76 | * default text color and null PrintStream 77 | */ 78 | public void redirectErr() { 79 | redirectErr(null, null); 80 | } 81 | 82 | /* 83 | * Redirect the output from the standard error to the console using the 84 | * specified color and PrintStream. When a PrintStream is specified the 85 | * message will be added to the Document before it is also written to the 86 | * PrintStream. 87 | */ 88 | public void redirectErr(Color textColor, PrintStream printStream) { 89 | ConsoleOutputStream cos = new ConsoleOutputStream(textColor, 90 | printStream); 91 | System.setErr(new PrintStream(cos, true)); 92 | } 93 | 94 | /* 95 | * To prevent memory from being used up you can control the number of lines 96 | * to display in the console 97 | * 98 | * This number can be dynamically changed, but the console will only be 99 | * updated the next time the Document is updated. 100 | */ 101 | /* 102 | * public void setMessageLines(int lines) { if (limitLinesListener != null) 103 | * document.removeDocumentListener( limitLinesListener ); 104 | * 105 | * limitLinesListener = new LimitLinesDocumentListener(lines, isAppend); 106 | * document.addDocumentListener( limitLinesListener ); } 107 | */ 108 | /* 109 | * Class to intercept output from a PrintStream and add it to a Document. 110 | * The output can optionally be redirected to a different PrintStream. The 111 | * text displayed in the Document can be color coded to indicate the output 112 | * source. 113 | */ 114 | class ConsoleOutputStream extends ByteArrayOutputStream { 115 | private final String EOL = System.getProperty("line.separator"); 116 | private SimpleAttributeSet attributes; 117 | private PrintStream printStream; 118 | private StringBuffer buffer = new StringBuffer(80); 119 | private boolean isFirstLine; 120 | 121 | /* 122 | * Specify the option text color and PrintStream 123 | */ 124 | public ConsoleOutputStream(Color textColor, PrintStream printStream) { 125 | if (textColor != null) { 126 | attributes = new SimpleAttributeSet(); 127 | StyleConstants.setForeground(attributes, textColor); 128 | } 129 | 130 | this.printStream = printStream; 131 | 132 | if (isAppend) 133 | isFirstLine = true; 134 | } 135 | 136 | /* 137 | * Override this method to intercept the output text. Each line of text 138 | * output will actually involve invoking this method twice: 139 | * 140 | * a) for the actual text message b) for the newLine string 141 | * 142 | * The message will be treated differently depending on whether the line 143 | * will be appended or inserted into the Document 144 | */ 145 | public void flush() { 146 | String message = toString(); 147 | 148 | if (message.length() == 0) 149 | return; 150 | 151 | if (isAppend) 152 | handleAppend(message); 153 | else 154 | handleInsert(message); 155 | 156 | reset(); 157 | } 158 | 159 | /* 160 | * We don't want to have blank lines in the Document. The first line 161 | * added will simply be the message. For additional lines it will be: 162 | * 163 | * newLine + message 164 | */ 165 | private void handleAppend(String message) { 166 | // This check is needed in case the text in the Document has been 167 | // cleared. The buffer may contain the EOL string from the previous 168 | // message. 169 | 170 | if (document.getLength() == 0) 171 | buffer.setLength(0); 172 | 173 | if (EOL.equals(message)) { 174 | buffer.append(message); 175 | } else { 176 | buffer.append(message); 177 | clearBuffer(); 178 | } 179 | 180 | } 181 | 182 | /* 183 | * We don't want to merge the new message with the existing message so 184 | * the line will be inserted as: 185 | * 186 | * message + newLine 187 | */ 188 | private void handleInsert(String message) { 189 | buffer.append(message); 190 | 191 | if (EOL.equals(message)) { 192 | clearBuffer(); 193 | } 194 | } 195 | 196 | /* 197 | * The message and the newLine have been added to the buffer in the 198 | * appropriate order so we can now update the Document and send the text 199 | * to the optional PrintStream. 200 | */ 201 | private void clearBuffer() { 202 | // In case both the standard out and standard err are being 203 | // redirected 204 | // we need to insert a newline character for the first line only 205 | 206 | if (isFirstLine && document.getLength() != 0) { 207 | buffer.insert(0, "\n"); 208 | } 209 | 210 | isFirstLine = false; 211 | String line = buffer.toString(); 212 | 213 | try { 214 | if (isAppend) { 215 | int offset = document.getLength(); 216 | document.insertString(offset, line, attributes); 217 | textComponent.setCaretPosition(document.getLength()); 218 | } else { 219 | document.insertString(0, line, attributes); 220 | textComponent.setCaretPosition(0); 221 | } 222 | } catch (BadLocationException ble) { 223 | } 224 | 225 | if (printStream != null) { 226 | printStream.print(line); 227 | } 228 | 229 | buffer.setLength(0); 230 | } 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/core/tools/PersistHandler.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.core.tools; 2 | 3 | import java.io.File; 4 | import java.io.FileWriter; 5 | import java.io.IOException; 6 | 7 | import com.koldbyte.codebackup.core.AppConfig; 8 | import com.koldbyte.codebackup.core.entities.Submission; 9 | 10 | /* 11 | * This class is responsible to save the submission in a proper directory 12 | */ 13 | public class PersistHandler { 14 | public static void save(String pluginName, String dir, Submission sub) { 15 | /* 16 | * final destination will look like dir / handle / ContestSite / 17 | * problemId / problemId-submissionId.ext 18 | */ 19 | String sep = File.separator; 20 | // TODO: Allow user to specify custom format for the final destination 21 | String finalDestination = dir + sep + sub.getUser().getHandle() + sep 22 | + pluginName + sep + sub.getProblem().getProblemId() + sep; 23 | String fileName = sub.getProblem().getProblemId() + "-" 24 | + sub.getSubmissionId() + "." 25 | + sub.getLanguage().getExtension(); 26 | // Handle file name extensions for code 27 | File file = new File(finalDestination + fileName); 28 | 29 | // now make sure whole path is created 30 | file.getParentFile().mkdirs(); 31 | if (!AppConfig.overWrite && file.exists() && file.length() != 0) { 32 | // skip this file 33 | System.out.println(pluginName + ": skipped overwriting code " 34 | + sub.getSubmissionId()); 35 | } else { 36 | // Saved the file 37 | try (FileWriter writer = new FileWriter(file)) { 38 | System.out.println(pluginName + ": saving code " 39 | + sub.getSubmissionId()); 40 | writer.write(sub.getCode()); 41 | } catch (IOException e) { 42 | System.err.println(pluginName + ": Error saving code " 43 | + sub.getSubmissionId() + "-> " + e.getMessage()); 44 | // e.printStackTrace(); 45 | } 46 | } 47 | } 48 | 49 | public static void saveProblem(String pluginName, String dir, Submission sub) { 50 | /* 51 | * final destination will look like dir / handle / ContestSite / 52 | * problemId / problemId-submissionId.ext 53 | */ 54 | String sep = File.separator; 55 | // TODO: Allow user to specify custom format for the final destination 56 | String finalDestination = dir + sep + sub.getUser().getHandle() + sep 57 | + pluginName + sep + sub.getProblem().getProblemId() + sep; 58 | String fileName = sub.getProblem().getProblemId().trim() + "-Statement.html"; 59 | System.out.println(fileName); 60 | File file = new File(finalDestination + fileName); 61 | // now make sure whole path is created 62 | file.getParentFile().mkdirs(); 63 | if (!AppConfig.overWrite && file.exists() && file.length() != 0) { 64 | // skip this file 65 | // Will not skip if the file size is 0 66 | System.out.println(pluginName + ": skipped overwriting statement " 67 | + sub.getProblem().getProblemId()); 68 | } else { 69 | try (FileWriter writer = new FileWriter(file)) { 70 | System.out.println(pluginName + ": saving problem statement " 71 | + sub.getSubmissionId()); 72 | writer.write(sub.getProblem().getProblemStatement()); 73 | } catch (IOException e) { 74 | System.err.println(pluginName 75 | + ": Error saving problem statement " 76 | + sub.getProblem().getProblemId() + " -> " 77 | + e.getMessage()); 78 | // e.printStackTrace(); 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/core/tools/PluginWorker.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.core.tools; 2 | 3 | import java.util.List; 4 | 5 | import javax.swing.ImageIcon; 6 | import javax.swing.JLabel; 7 | import javax.swing.SwingWorker; 8 | 9 | import com.koldbyte.codebackup.core.AppConfig; 10 | import com.koldbyte.codebackup.core.entities.Submission; 11 | import com.koldbyte.codebackup.core.entities.User; 12 | import com.koldbyte.codebackup.plugins.PluginEnum; 13 | import com.koldbyte.codebackup.plugins.PluginInterface; 14 | 15 | /* 16 | * This class will interface with all the plugins 17 | * as defined in the PluginEnum.java to fetch their 18 | * respective submission list. 19 | * 20 | */ 21 | public class PluginWorker extends SwingWorker { 22 | private User user; 23 | private PluginEnum pluginEnum; 24 | private String dir; 25 | private ImageIcon tick; 26 | private JLabel progressIcon; 27 | 28 | public PluginWorker(String dir, User user, PluginEnum pluginEnum, 29 | JLabel progress) { 30 | super(); 31 | this.dir = dir; 32 | this.user = user; 33 | this.pluginEnum = pluginEnum; 34 | this.tick = new ImageIcon(this.getClass().getResource("/tick.png")); 35 | this.progressIcon = progress; 36 | } 37 | 38 | public String getDir() { 39 | return dir; 40 | } 41 | 42 | public void setDir(String dir) { 43 | this.dir = dir; 44 | } 45 | 46 | public PluginWorker() { 47 | super(); 48 | } 49 | 50 | public User getUser() { 51 | return user; 52 | } 53 | 54 | public void setUser(User user) { 55 | this.user = user; 56 | } 57 | 58 | public PluginEnum getPluginEnum() { 59 | return pluginEnum; 60 | } 61 | 62 | public void setPluginEnum(PluginEnum pluginEnum) { 63 | this.pluginEnum = pluginEnum; 64 | } 65 | 66 | @Override 67 | protected Integer doInBackground() throws Exception { 68 | PluginInterface plugin = pluginEnum.getPlugin(); 69 | if (user != null) { 70 | System.out.println("Started " + pluginEnum.name()); 71 | List subs; 72 | if (AppConfig.getFetchAllAC()) { 73 | System.out.println(pluginEnum.name() + ": Mode-> Fetch All Accepted submissions."); 74 | subs = plugin.getAllSolvedList(user); 75 | } else { 76 | System.out.println(pluginEnum.name() + ": Mode-> Fetch only the last Accepted submissions."); 77 | subs = plugin.getSolvedList(user); 78 | } 79 | for (Submission sub : subs) { 80 | sub.fetchSubmittedCode(); 81 | PersistHandler.save(pluginEnum.getName(), dir, sub); 82 | if (AppConfig.fetchProblem == true) { 83 | PersistHandler.saveProblem(pluginEnum.getName(), dir, sub); 84 | } 85 | } 86 | 87 | } 88 | return 0; 89 | } 90 | 91 | @Override 92 | protected void done() { 93 | progressIcon.setIcon(tick); 94 | // Mark the status of the Plugin as finished successfully 95 | System.out.println("Finished " + pluginEnum.name()); 96 | super.done(); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/PluginEnum.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins; 2 | 3 | import com.koldbyte.codebackup.plugins.codechef.CodechefPluginImpl; 4 | import com.koldbyte.codebackup.plugins.codeforces.CodeforcesPluginImpl; 5 | import com.koldbyte.codebackup.plugins.spoj.SpojPluginImpl; 6 | 7 | public enum PluginEnum { 8 | CODECHEF("codechef"), CODEFORCES("codeforces"), SPOJ("spoj"); 9 | 10 | private String name; 11 | 12 | public String getName() { 13 | return name; 14 | } 15 | 16 | public void setName(String name) { 17 | this.name = name; 18 | } 19 | 20 | private PluginEnum(String name) { 21 | this.name = name; 22 | } 23 | 24 | public PluginInterface getPlugin() { 25 | switch (name) { 26 | case "codechef": 27 | return new CodechefPluginImpl(); 28 | case "codeforces": 29 | return new CodeforcesPluginImpl(); 30 | case "spoj": 31 | return new SpojPluginImpl(); 32 | default: 33 | return null; 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/PluginInterface.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins; 2 | 3 | import java.util.List; 4 | 5 | import com.koldbyte.codebackup.core.entities.Submission; 6 | import com.koldbyte.codebackup.core.entities.User; 7 | /* 8 | * This is the interface which every plugin has to implement. 9 | */ 10 | public interface PluginInterface { 11 | public List getSolvedList(User user); 12 | public List getAllSolvedList(User user); 13 | } 14 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/codechef/CodechefPluginImpl.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins.codechef; 2 | 3 | import java.io.IOException; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import org.jsoup.Jsoup; 8 | import org.jsoup.nodes.Document; 9 | import org.jsoup.nodes.Element; 10 | import org.jsoup.select.Elements; 11 | 12 | import com.koldbyte.codebackup.core.entities.LanguagesEnum; 13 | import com.koldbyte.codebackup.core.entities.Problem; 14 | import com.koldbyte.codebackup.core.entities.Submission; 15 | import com.koldbyte.codebackup.core.entities.User; 16 | import com.koldbyte.codebackup.plugins.PluginInterface; 17 | import com.koldbyte.codebackup.plugins.codechef.core.entities.CodechefProblem; 18 | import com.koldbyte.codebackup.plugins.codechef.core.entities.CodechefSubmission; 19 | 20 | public class CodechefPluginImpl implements PluginInterface { 21 | private static final String PROBLEMS_SOLVED_CONTAINER_DIV_CLASS = "problems-solved"; 22 | private static final String LISTPAGE = "http://www.codechef.com/users/"; 23 | 24 | @Override 25 | public List getSolvedList(User user) { 26 | return fetchSubmissionsPrivate(user, false); 27 | } 28 | 29 | @Override 30 | public List getAllSolvedList(User user) { 31 | return fetchSubmissionsPrivate(user, true); 32 | } 33 | 34 | private List fetchSubmissionsPrivate(User user, Boolean fetchAll) { 35 | String url = LISTPAGE + user.getHandle(); 36 | ArrayList submissions = new ArrayList(); 37 | 38 | try { 39 | 40 | // fetch the main page 41 | Document doc = Jsoup.connect(url).timeout(10000).get(); 42 | 43 | // fetch the div which contains the list of solved problems 44 | Elements elems = doc.getElementsByClass(PROBLEMS_SOLVED_CONTAINER_DIV_CLASS); 45 | Elements links = elems.select("a[href]"); 46 | 47 | System.out.println("codechef: Found " + links.size() 48 | + " Problems linked in your profile page"); 49 | 50 | for (Element link : links) { 51 | 52 | try { 53 | String linkurl = link.attr("abs:href"); 54 | 55 | if (linkurl.contains("status")) { 56 | System.out.println("Processing: " + linkurl); 57 | 58 | String problemId = link.text(); 59 | Problem problem = new CodechefProblem(problemId, ""); 60 | 61 | // if it is a proper "status" page, fetch this page 62 | Document page = Jsoup.connect(linkurl).get(); 63 | 64 | Elements rows = page.getElementsByAttributeValueContaining("class", "kol");//page.select(".\"kol\""); 65 | 66 | // loop through the rows to find the first Accepted 67 | // submissions 68 | int count = 0; 69 | for (Element tr : rows) { 70 | Elements tds = tr.getElementsByTag("td"); 71 | 72 | //TODO: Add a check to stop processing when encountering "No Recent Activity" 73 | if (!tds.text().contains("No Recent Activity")) { 74 | 75 | String result = tds.get(3).select("img").get(0) 76 | .attr("src"); 77 | 78 | if (result.contains("tick")) { // is a accepted solution 79 | String id = tds.get(0).text(); 80 | String time = tds.get(1).text(); 81 | String lang = tds.get(6).text(); 82 | 83 | String solUrl = tds.get(7).select("a[href]") 84 | .attr("abs:href"); 85 | // the solUrl is of pattern 86 | // http://www.codechef.com/viewsolution/2078521 87 | // It should be 88 | // http://www.codechef.com/viewplaintext/2078521 89 | solUrl = solUrl.replace("viewsolution", 90 | "viewplaintext"); 91 | 92 | Submission sub = new CodechefSubmission(id, solUrl, 93 | problem, user); 94 | 95 | sub.setLanguage(LanguagesEnum.findExtension(lang)); 96 | sub.setTimestamp(time); 97 | 98 | submissions.add(sub); 99 | count++; 100 | 101 | if (!fetchAll) { 102 | // We have found the AC submission for the current 103 | // problem break now from the for loop to avoid 104 | // adding more submissions of the same problem. 105 | break; 106 | } 107 | } 108 | } 109 | } 110 | //System.out.println("Fetch " + count + " AC solutions."); 111 | } 112 | } catch (Exception e) { 113 | System.err.println("Codechef: Error fetching Problem solution. Error: " 114 | + e.getMessage() + ". Continuing processing next."); 115 | } 116 | 117 | } 118 | 119 | } catch (IOException e) { 120 | System.err.println("Codechef: Error fetching list. Error: " 121 | + e.getMessage()); 122 | // e.printStackTrace(); 123 | } 124 | 125 | System.out.println("Codechef: Found " + submissions.size() 126 | + " Submissions"); 127 | 128 | return submissions; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/codechef/core/entities/CodechefProblem.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins.codechef.core.entities; 2 | 3 | import java.io.IOException; 4 | 5 | import org.jsoup.Jsoup; 6 | import org.jsoup.nodes.Document; 7 | import org.jsoup.select.Elements; 8 | 9 | import com.koldbyte.codebackup.core.entities.Problem; 10 | 11 | public class CodechefProblem extends Problem { 12 | private final String HTTP = "http://"; 13 | private final String PROBLEMURLPREFIX = "www.codechef.com/problems/"; 14 | 15 | public CodechefProblem(String url) { 16 | super(url); 17 | } 18 | 19 | public CodechefProblem(String problemId, String url) { 20 | super(problemId, url); 21 | } 22 | 23 | @Override 24 | public String fetchProblemStatement() { 25 | /*- 26 | * Codechef problem page looks like 27 | * 28 | *
29 | * ...... 30 | *
31 | */ 32 | Document doc; 33 | 34 | try { 35 | String u = getUrl(); 36 | doc = Jsoup.connect(u).timeout(10000).get(); 37 | 38 | Elements problems = doc 39 | .getElementsByClass("primary-colum-width-left"); 40 | 41 | this.setProblemStatement(problems.html()); 42 | } catch (IOException e) { 43 | System.err.println("codechef: Error fetching Problem Statement " 44 | + problemId + " -> " + e.getMessage()); 45 | // e.printStackTrace(); 46 | } 47 | 48 | System.out.println("codechef: fetched problem " + problemId); 49 | 50 | return this.problemStatement; 51 | } 52 | 53 | @Override 54 | public String getUrl() { 55 | if (url == null || url.isEmpty()) { 56 | url = HTTP + PROBLEMURLPREFIX + problemId; 57 | } 58 | return url; 59 | } 60 | 61 | @Override 62 | public String getProblemId() { 63 | if (problemId == null || problemId.isEmpty()) { 64 | String u = getUrl(); 65 | u = u.replace(HTTP, ""); 66 | u = u.replace(PROBLEMURLPREFIX, ""); 67 | this.setProblemId(u); 68 | } 69 | return super.getProblemId(); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/codechef/core/entities/CodechefSubmission.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins.codechef.core.entities; 2 | 3 | import org.jsoup.Jsoup; 4 | import org.jsoup.nodes.Document; 5 | import org.jsoup.nodes.Entities.EscapeMode; 6 | 7 | import com.koldbyte.codebackup.core.entities.Problem; 8 | import com.koldbyte.codebackup.core.entities.Submission; 9 | import com.koldbyte.codebackup.core.entities.User; 10 | 11 | public class CodechefSubmission extends Submission { 12 | 13 | private final String HTTP = "http://"; 14 | private final String SOLUTIONURLPREFIX = "www.codechef.com/viewplaintext/"; 15 | 16 | public CodechefSubmission(String submissionId, String submissionUrl, 17 | Problem problem, User user) { 18 | super(submissionId, submissionUrl, problem, user); 19 | } 20 | 21 | @Override 22 | public String fetchSubmittedCode() { 23 | String subUrl = getSubmissionUrl(); 24 | String code = ""; 25 | 26 | try { 27 | Document doc = Jsoup.connect(subUrl).timeout(10000).get(); 28 | 29 | // remove html entities from the code 30 | doc.outputSettings().escapeMode(EscapeMode.xhtml); 31 | 32 | code = doc.select("pre").text(); 33 | 34 | System.out.println("codechef: fetched code " + submissionId); 35 | 36 | setCode(code.toString()); 37 | } catch (Exception e) { 38 | System.err.println("codechef: Error Fetching code " + submissionId 39 | + " -> " + e.getMessage()); 40 | // e.printStackTrace(); 41 | } 42 | 43 | return code.toString(); 44 | } 45 | 46 | @Override 47 | public String getSubmissionIdFromUrl() { 48 | // format http://www.codechef.com/viewplaintext/5189360 49 | String url = submissionUrl; 50 | url = url.replace(HTTP, ""); 51 | url = url.replace(SOLUTIONURLPREFIX, ""); 52 | 53 | this.submissionId = url; 54 | 55 | return url; 56 | } 57 | 58 | @Override 59 | public String getSubmissionUrlFromId() { 60 | return HTTP + SOLUTIONURLPREFIX + submissionId; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/codechef/core/entities/CodechefUser.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins.codechef.core.entities; 2 | 3 | import com.koldbyte.codebackup.core.entities.User; 4 | 5 | public class CodechefUser extends User { 6 | private final String HTTP = "http://"; 7 | private final String PROFILEURLPREFIX = "www.codechef.com/users/"; 8 | 9 | public CodechefUser(String handle) { 10 | super(handle); 11 | } 12 | 13 | public CodechefUser(String handle, String profileUrl) { 14 | super(handle, profileUrl); 15 | } 16 | 17 | @Override 18 | public String getHandleFromProfileUrl() { 19 | String handle = profileUrl; 20 | handle = handle.replace(HTTP, ""); 21 | handle = handle.replace(PROFILEURLPREFIX, ""); 22 | return handle; 23 | } 24 | 25 | @Override 26 | public String getProfileUrlFromHandle() { 27 | return HTTP + PROFILEURLPREFIX + this.handle; 28 | } 29 | 30 | @Override 31 | public Boolean isValidUser() { 32 | return true; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/codeforces/CodeforcesPluginImpl.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins.codeforces; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import org.json.simple.JSONArray; 9 | import org.json.simple.JSONObject; 10 | import org.json.simple.parser.JSONParser; 11 | 12 | import com.koldbyte.codebackup.core.entities.LanguagesEnum; 13 | import com.koldbyte.codebackup.core.entities.Problem; 14 | import com.koldbyte.codebackup.core.entities.Submission; 15 | import com.koldbyte.codebackup.core.entities.User; 16 | import com.koldbyte.codebackup.plugins.PluginInterface; 17 | import com.koldbyte.codebackup.plugins.codeforces.core.entities.CodeforcesProblem; 18 | import com.koldbyte.codebackup.plugins.codeforces.core.entities.CodeforcesSubmission; 19 | import com.koldbyte.codebackup.utils.HTTPRequest; 20 | 21 | public class CodeforcesPluginImpl implements PluginInterface { 22 | 23 | private final String url = "http://codeforces.com/api/user.status"; 24 | private final String SUBMISSIONURL = "http://codeforces.com/contest/:c/submission/:s"; 25 | private final String GYMSUBMISSIONURL = "http://codeforces.com/gym/:c/submission/:s"; 26 | 27 | public List getSolvedList(User user) { 28 | String urlParameters = "handle=" + user.getHandle(); 29 | HTTPRequest request = new HTTPRequest(url + "?" + urlParameters, ""); 30 | 31 | List list = new ArrayList(); 32 | 33 | try { 34 | StringBuffer response = request.sendGet(); 35 | 36 | JSONParser parser = new JSONParser(); 37 | JSONObject responseObject = (JSONObject) parser.parse(response 38 | .toString()); 39 | JSONArray submissions = (JSONArray) responseObject.get("result"); 40 | 41 | Map problemsDone = new HashMap(); 42 | 43 | for (Object o : submissions) { 44 | JSONObject submission = (JSONObject) o; 45 | String verdict = (String) submission.get("verdict"); 46 | 47 | if (verdict.compareToIgnoreCase("ok") == 0) { 48 | JSONObject prob = (JSONObject) submission.get("problem"); 49 | 50 | Long contestId = (Long) prob.get("contestId"); 51 | String problemId = contestId.toString() + "-" 52 | + (String) prob.get("index"); 53 | if (!problemsDone.containsKey(problemId)) { 54 | Problem problem = new CodeforcesProblem(problemId, ""); 55 | 56 | Long sId = (Long) submission.get("id"); 57 | String submissionId = sId.toString(); 58 | 59 | String submissionUrl; 60 | if (contestId.toString().length() > 3) { 61 | submissionUrl = GYMSUBMISSIONURL.replace(":c", 62 | contestId.toString()).replace(":s", 63 | submissionId); 64 | } else { 65 | submissionUrl = SUBMISSIONURL.replace(":c", 66 | contestId.toString()).replace(":s", 67 | submissionId); 68 | } 69 | // System.out.println("URL -> " + submissionUrl); 70 | String time = ((Long) submission 71 | .get("creationTimeSeconds")).toString(); 72 | 73 | 74 | String lang = (String) submission 75 | .get("programmingLanguage"); 76 | 77 | Submission theSubmission = new CodeforcesSubmission( 78 | submissionId, submissionUrl, problem, user); 79 | 80 | theSubmission.setTimestamp(time); 81 | theSubmission.setLanguage(LanguagesEnum 82 | .findExtension(lang)); 83 | 84 | list.add(theSubmission); 85 | 86 | problemsDone.put(problemId, true); 87 | } 88 | } 89 | } 90 | 91 | } catch (Exception e) { 92 | System.err.println("codeforces: Error fetching list. " + " -> " 93 | + e.getMessage()); 94 | // e.printStackTrace(); 95 | } 96 | System.out.println("codeforces: fetched List " + list.size()); 97 | return list; 98 | } 99 | 100 | @Override 101 | public List getAllSolvedList(User user) { 102 | String urlParameters = "handle=" + user.getHandle(); 103 | 104 | HTTPRequest request = new HTTPRequest(url + "?" + urlParameters, ""); 105 | List list = new ArrayList(); 106 | 107 | try { 108 | StringBuffer response = request.sendGet(); 109 | 110 | JSONParser parser = new JSONParser(); 111 | JSONObject responseObject = (JSONObject) parser.parse(response 112 | .toString()); 113 | JSONArray submissions = (JSONArray) responseObject.get("result"); 114 | 115 | for (Object o : submissions) { 116 | JSONObject submission = (JSONObject) o; 117 | String verdict = (String) submission.get("verdict"); 118 | 119 | if (verdict.compareToIgnoreCase("ok") == 0) { 120 | JSONObject prob = (JSONObject) submission.get("problem"); 121 | 122 | Long contestId = (Long) prob.get("contestId"); 123 | String problemId = contestId.toString() + "-" 124 | + (String) prob.get("index"); 125 | 126 | Problem problem = new CodeforcesProblem(problemId, ""); 127 | 128 | Long sId = (Long) submission.get("id"); 129 | String submissionId = sId.toString(); 130 | 131 | String submissionUrl; 132 | if (contestId.toString().length() > 3) { 133 | submissionUrl = GYMSUBMISSIONURL.replace(":c", 134 | contestId.toString()).replace(":s", 135 | submissionId); 136 | } else { 137 | submissionUrl = SUBMISSIONURL.replace(":c", 138 | contestId.toString()).replace(":s", 139 | submissionId); 140 | } 141 | // System.out.println("URL -> " + submissionUrl); 142 | String time = ((Long) submission.get("creationTimeSeconds")) 143 | .toString(); 144 | 145 | String lang = (String) submission 146 | .get("programmingLanguage"); 147 | 148 | Submission theSubmission = new CodeforcesSubmission( 149 | submissionId, submissionUrl, problem, user); 150 | 151 | theSubmission.setTimestamp(time); 152 | theSubmission 153 | .setLanguage(LanguagesEnum.findExtension(lang)); 154 | 155 | list.add(theSubmission); 156 | 157 | } 158 | } 159 | 160 | } catch (Exception e) { 161 | System.err.println("codeforces: Error fetching list. " + " -> " 162 | + e.getMessage()); 163 | // e.printStackTrace(); 164 | } 165 | System.out.println("codeforces: fetched List " + list.size()); 166 | return list; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/codeforces/core/entities/CodeforcesProblem.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins.codeforces.core.entities; 2 | 3 | import java.io.IOException; 4 | 5 | import org.jsoup.Jsoup; 6 | import org.jsoup.nodes.Document; 7 | import org.jsoup.nodes.Entities.EscapeMode; 8 | import org.jsoup.select.Elements; 9 | 10 | import com.koldbyte.codebackup.core.entities.Problem; 11 | 12 | /* 13 | * 14 | * example of problemId -> 545-B 15 | */ 16 | public class CodeforcesProblem extends Problem { 17 | private final String HTTP = "http://"; 18 | private final String PROBLEMURL = "codeforces.com/contest/:c/problem/:p"; 19 | private final String GYMPROBLEMURL = "codeforces.com/gym/:c/problem/:p"; 20 | 21 | @Override 22 | public String fetchProblemStatement() { 23 | 24 | /*- 25 | * Codeforces problem page look like this 26 | *
27 | *
28 | *
.....
29 | *
30 | *
31 | */ 32 | 33 | // fetch the page containing the problem statement 34 | Document doc; 35 | String url = getUrl(); 36 | 37 | try { 38 | doc = Jsoup.connect(url).timeout(10000).get(); 39 | 40 | // remove html entities from the code 41 | doc.outputSettings().escapeMode(EscapeMode.xhtml); 42 | 43 | Elements problems = doc.getElementsByClass("problemindexholder"); 44 | 45 | System.out.println("codeforces: fetched problem " + problemId); 46 | 47 | this.setProblemStatement(problems.html()); 48 | } catch (IOException e) { 49 | System.err.println("codeforces: Error fetching Problem Statement " 50 | + problemId + " -> " + e.getMessage()); 51 | // e.printStackTrace(); 52 | } 53 | 54 | return this.problemStatement; 55 | } 56 | 57 | @Override 58 | public String getUrl() { 59 | if (url == null || url.isEmpty()) { 60 | String[] id = problemId.split("-"); 61 | String problemUrl = PROBLEMURL; 62 | if (id[0].length() > 3) { 63 | problemUrl = GYMPROBLEMURL; 64 | } 65 | 66 | // replace ":c" with the contest id(like 67 | problemUrl = problemUrl.replace(":c", id[0]); 68 | 69 | // replace ":p" with the problem id (like A,B,C etc) 70 | problemUrl = problemUrl.replace(":p", id[1]); 71 | 72 | url = HTTP + problemUrl; 73 | this.setUrl(url); 74 | } 75 | return url; 76 | } 77 | 78 | @Override 79 | public String getProblemId() { 80 | if (problemId == null || problemId.isEmpty()) { 81 | String u = getUrl(); 82 | u = u.replace("codeforces.com/contest/", ""); 83 | u = u.replace("/problem/", "-"); 84 | this.setProblemId(u); 85 | } 86 | return this.problemId; 87 | } 88 | 89 | public CodeforcesProblem(String problemId, String url) { 90 | super(problemId, url); 91 | } 92 | 93 | public CodeforcesProblem(String url) { 94 | super(url); 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/codeforces/core/entities/CodeforcesSubmission.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins.codeforces.core.entities; 2 | 3 | import java.io.IOException; 4 | 5 | import org.jsoup.Jsoup; 6 | import org.jsoup.nodes.Document; 7 | import org.jsoup.nodes.Entities.EscapeMode; 8 | import org.jsoup.select.Elements; 9 | 10 | import com.koldbyte.codebackup.core.entities.Problem; 11 | import com.koldbyte.codebackup.core.entities.Submission; 12 | import com.koldbyte.codebackup.core.entities.User; 13 | 14 | public class CodeforcesSubmission extends Submission { 15 | private final String SUBMISSIONURL = "http://codeforces.com/contest/:c/submission/:s"; 16 | private final String GYMSUBMISSIONURL = "http://codeforces.com/gym/:c/submission/:s"; 17 | 18 | @Override 19 | public String fetchSubmittedCode() { 20 | String url = submissionUrl; 21 | if (url == null || url.isEmpty()) { 22 | url = getSubmissionUrlFromId(); 23 | } 24 | 25 | try { 26 | Document doc = Jsoup.connect(url).timeout(10000).get(); 27 | 28 | // remove html entities from the code 29 | doc.outputSettings().escapeMode(EscapeMode.xhtml); 30 | 31 | Elements elem = doc.select("pre.program-source"); 32 | String code = elem.text(); 33 | 34 | System.out.println("codeforces: fetched code " + submissionId); 35 | 36 | setCode(code); 37 | } catch (IOException e) { 38 | System.err.println("codeforces: Error Fetching code " + submissionId 39 | + " -> " + e.getMessage()); 40 | // e.printStackTrace(); 41 | } 42 | 43 | return code; 44 | } 45 | 46 | @Override 47 | public String getSubmissionIdFromUrl() { 48 | String submissionId = submissionUrl.substring(11 + submissionUrl 49 | .indexOf("submission/", 0)); 50 | return submissionId; 51 | } 52 | 53 | @Override 54 | public String getSubmissionUrlFromId() { 55 | String contestId = problem.getProblemId(); 56 | String submissionUrl; 57 | if (contestId.length() > 3) { 58 | submissionUrl = GYMSUBMISSIONURL 59 | .replace(":c", contestId.toString()).replace(":s", 60 | submissionId); 61 | } else { 62 | submissionUrl = SUBMISSIONURL.replace(":c", contestId.toString()) 63 | .replace(":s", submissionId); 64 | } 65 | return submissionUrl; 66 | } 67 | 68 | public CodeforcesSubmission(String submissionId, String submissionUrl, 69 | Problem problem, User user) { 70 | super(submissionId, submissionUrl, problem, user); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/codeforces/core/entities/CodeforcesUser.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins.codeforces.core.entities; 2 | 3 | import com.koldbyte.codebackup.core.entities.User; 4 | 5 | public class CodeforcesUser extends User { 6 | private final String HTTP = "http://"; 7 | private final String PROFILEURLPREFIX = "codeforces.com/profile/"; 8 | 9 | public CodeforcesUser(String handle) { 10 | super(handle); 11 | } 12 | 13 | public CodeforcesUser(String handle, String profileUrl) { 14 | super(handle, profileUrl); 15 | } 16 | 17 | @Override 18 | public String getHandleFromProfileUrl() { 19 | String handle = profileUrl; 20 | handle = handle.replace(HTTP, ""); 21 | handle = handle.replace(PROFILEURLPREFIX, ""); 22 | return handle; 23 | } 24 | 25 | @Override 26 | public String getProfileUrlFromHandle() { 27 | return HTTP + PROFILEURLPREFIX + this.handle; 28 | } 29 | 30 | @Override 31 | public Boolean isValidUser() { 32 | return true; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/spoj/SpojPluginImpl.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins.spoj; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import org.jsoup.Connection; 9 | import org.jsoup.Jsoup; 10 | 11 | import com.koldbyte.codebackup.core.entities.LanguagesEnum; 12 | import com.koldbyte.codebackup.core.entities.Problem; 13 | import com.koldbyte.codebackup.core.entities.Submission; 14 | import com.koldbyte.codebackup.core.entities.User; 15 | import com.koldbyte.codebackup.plugins.PluginInterface; 16 | import com.koldbyte.codebackup.plugins.spoj.core.entities.SpojProblem; 17 | import com.koldbyte.codebackup.plugins.spoj.core.entities.SpojSubmission; 18 | import com.koldbyte.codebackup.plugins.spoj.core.entities.SpojUser; 19 | 20 | public class SpojPluginImpl implements PluginInterface { 21 | 22 | private final String HTTPS = "https://"; 23 | private final String SUBMISSIONLIST = "www.spoj.com/status/:u/signedlist/"; 24 | 25 | private final String LOGINURL = HTTPS + "www.spoj.com/login"; 26 | 27 | @Override 28 | public List getSolvedList(User user) { 29 | List subs = new ArrayList(); 30 | String url = HTTPS + SUBMISSIONLIST.replace(":u", user.getHandle()); 31 | 32 | try { 33 | //TODO: Add login to fetch the spoj signedlist 34 | Connection.Response loginForm = Jsoup.connect(LOGINURL) 35 | .timeout(10000).method(Connection.Method.GET).execute(); 36 | 37 | System.out.println("Spoj username - "+ ((SpojUser) 38 | user).getUsername()); 39 | loginForm = Jsoup.connect(LOGINURL).data("next", "/") 40 | .data("login_user", ((SpojUser) user).getUsername()) 41 | .data("password", ((SpojUser) user).getPass()) 42 | .data("autologin", "1").cookies(loginForm.cookies()) 43 | .method(Connection.Method.POST).execute(); 44 | 45 | 46 | Connection.Response response = Jsoup.connect(url).timeout(10000) 47 | .cookies(loginForm.cookies()).method(Connection.Method.GET).execute(); 48 | 49 | String lines[] = response.body().split("\n"); 50 | 51 | // ignore first 9 lines 0...1...2......8 52 | if (lines.length < 9) { 53 | System.out.println("Error! Invalid Format of Spoj signedlist"); 54 | } else { 55 | int i = 9; // start from 9th line 56 | String end = "\\------------------------------------------------------------------------------/"; 57 | 58 | Map problemsDone = new HashMap(); 59 | 60 | while (i < lines.length && lines[i].compareTo(end) != 0) { 61 | String subEntry[] = lines[i].split("\\|"); 62 | 63 | // if solution is AC or status is a score 64 | String status = subEntry[4].trim(); 65 | if (status.compareToIgnoreCase("AC") == 0 66 | || status.matches("-?\\d+(\\.\\d+)?")) { 67 | String problem = subEntry[3].trim(); 68 | 69 | if (!problemsDone.containsKey(problem)) { 70 | String sId = subEntry[1].trim(); 71 | Problem p = new SpojProblem(problem, ""); 72 | 73 | String lang = subEntry[7].trim(); 74 | String time = subEntry[2].trim(); 75 | 76 | Submission submission = new SpojSubmission(sId, "", 77 | p, user); 78 | 79 | submission.setTimestamp(time); 80 | submission.setLanguage(LanguagesEnum 81 | .findExtension(lang)); 82 | 83 | subs.add(submission); 84 | 85 | problemsDone.put(problem, true); 86 | } 87 | } 88 | i++; 89 | } 90 | } 91 | } catch (Exception e) { 92 | System.out.println("spoj: Error fetching list. " + " -> " 93 | + e.getMessage()); 94 | // e.printStackTrace(); 95 | } 96 | System.out.println("spoj: fetched List " + subs.size()); 97 | return subs; 98 | } 99 | 100 | @Override 101 | public List getAllSolvedList(User user) { 102 | List subs = new ArrayList(); 103 | String url = HTTPS + SUBMISSIONLIST.replace(":u", user.getHandle()); 104 | 105 | try { 106 | //TODO: Add login to fetch the spoj signedlist 107 | Connection.Response loginForm = Jsoup.connect(LOGINURL) 108 | .timeout(10000).method(Connection.Method.GET).execute(); 109 | 110 | System.out.println("Spoj username - "+ ((SpojUser) 111 | user).getUsername()); 112 | loginForm = Jsoup.connect(LOGINURL).data("next", "/") 113 | .data("login_user", ((SpojUser) user).getUsername()) 114 | .data("password", ((SpojUser) user).getPass()) 115 | .data("autologin", "1").cookies(loginForm.cookies()) 116 | .method(Connection.Method.POST).execute(); 117 | 118 | 119 | Connection.Response response = Jsoup.connect(url).timeout(10000) 120 | .cookies(loginForm.cookies()).method(Connection.Method.GET).execute(); 121 | 122 | String lines[] = response.body().split("\n"); 123 | // ignore first 9 lines 0...1...2......8 124 | if (lines.length < 9) { 125 | System.out.println("Error! Invalid Format of Spoj signedlist"); 126 | } else { 127 | int i = 9; // start from 9th line 128 | String end = "\\------------------------------------------------------------------------------/"; 129 | 130 | while (i < lines.length && lines[i].compareTo(end) != 0) { 131 | String subEntry[] = lines[i].split("\\|"); 132 | 133 | // if solution is AC or status is a score 134 | String status = subEntry[4].trim(); 135 | if (status.compareToIgnoreCase("AC") == 0 136 | || status.matches("-?\\d+(\\.\\d+)?")) { 137 | String problem = subEntry[3].trim(); 138 | 139 | String sId = subEntry[1].trim(); 140 | Problem p = new SpojProblem(problem, ""); 141 | 142 | String lang = subEntry[7].trim(); 143 | String time = subEntry[2].trim(); 144 | 145 | Submission submission = new SpojSubmission(sId, "", p, 146 | user); 147 | 148 | submission.setTimestamp(time); 149 | submission.setLanguage(LanguagesEnum 150 | .findExtension(lang)); 151 | 152 | subs.add(submission); 153 | } 154 | i++; 155 | } 156 | } 157 | } catch (Exception e) { 158 | System.out.println("spoj: Error fetching list. " + " -> " 159 | + e.getMessage()); 160 | // e.printStackTrace(); 161 | } 162 | System.out.println("spoj: fetched List " + subs.size()); 163 | return subs; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/spoj/core/entities/SpojProblem.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins.spoj.core.entities; 2 | 3 | import java.io.IOException; 4 | 5 | import org.jsoup.Jsoup; 6 | import org.jsoup.nodes.Document; 7 | import org.jsoup.nodes.Element; 8 | import org.jsoup.nodes.Entities.EscapeMode; 9 | 10 | import com.koldbyte.codebackup.core.entities.Problem; 11 | 12 | public class SpojProblem extends Problem { 13 | private final String HTTPS = "https://"; 14 | private final String PROBLEMURL = "www.spoj.com/problems/:p/"; 15 | 16 | @Override 17 | public String fetchProblemStatement() { 18 | String problem = getProblemId(); 19 | String url = HTTPS + PROBLEMURL.replace(":p", problem); 20 | /*- 21 | * Spoj Problem Page looks like this 22 | * 23 | *
24 | * ....... 25 | *
26 | */ 27 | 28 | Document doc; 29 | 30 | try { 31 | doc = Jsoup.connect(url).timeout(10000).get(); 32 | 33 | // remove html entities from the code 34 | doc.outputSettings().escapeMode(EscapeMode.xhtml); 35 | 36 | Element problemBody = doc.getElementById("problem-body"); 37 | 38 | System.out.println("spoj: fetched problem " + problemId); 39 | 40 | this.setProblemStatement(problemBody.html()); 41 | } catch (IOException e) { 42 | System.err.println("spoj: Error fetching Problem Statement " 43 | + problemId + " -> " + e.getMessage()); 44 | // e.printStackTrace(); 45 | } 46 | 47 | return this.problemStatement; 48 | } 49 | 50 | @Override 51 | public String getUrl() { 52 | if (url == null || url.isEmpty()) { 53 | 54 | String problemUrl = PROBLEMURL; 55 | 56 | // replace ":p" with the problem id 57 | problemUrl.replace(":p", problemId); 58 | 59 | url = HTTPS + PROBLEMURL; 60 | this.setUrl(url); 61 | } 62 | return url; 63 | } 64 | 65 | @Override 66 | public String getProblemId() { 67 | if (problemId == null || problemId.isEmpty()) { 68 | String u = getUrl(); 69 | u = u.replace(HTTPS, ""); 70 | u = u.replace("www.spoj.com/problems/", ""); 71 | u = u.replace("/", ""); 72 | this.setProblemId(u); 73 | } 74 | return this.problemId; 75 | } 76 | 77 | public SpojProblem(String problemId, String url) { 78 | super(problemId, url); 79 | } 80 | 81 | public SpojProblem(String url) { 82 | super(url); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/spoj/core/entities/SpojSubmission.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins.spoj.core.entities; 2 | 3 | import java.io.IOException; 4 | 5 | import org.jsoup.Connection; 6 | import org.jsoup.Jsoup; 7 | 8 | import com.koldbyte.codebackup.core.entities.Problem; 9 | import com.koldbyte.codebackup.core.entities.Submission; 10 | import com.koldbyte.codebackup.core.entities.User; 11 | 12 | public class SpojSubmission extends Submission { 13 | private final String HTTPS = "https://"; 14 | private final String SUBMITTEDURL = "www.spoj.com/files/src/save/:s/"; 15 | private final String LOGINURL = HTTPS + "www.spoj.com/login"; 16 | 17 | @Override 18 | public String fetchSubmittedCode() { 19 | /* 20 | * Requires username and password to get the source code so simulate 21 | * login 22 | */ 23 | 24 | try { 25 | Connection.Response loginForm = Jsoup.connect(LOGINURL) 26 | .timeout(10000).method(Connection.Method.GET).execute(); 27 | 28 | // System.out.println("Spoj username - "+ ((SpojUser) 29 | // user).getUsername()); 30 | loginForm = Jsoup.connect(LOGINURL).data("next", "/") 31 | .data("login_user", ((SpojUser) user).getUsername()) 32 | .data("password", ((SpojUser) user).getPass()) 33 | .data("autologin", "1").cookies(loginForm.cookies()) 34 | .method(Connection.Method.POST).execute(); 35 | 36 | // login done...now use the cookies to whenever u are fetching code 37 | String url = HTTPS + SUBMITTEDURL.replace(":s", submissionId); 38 | String code = Jsoup.connect(url).ignoreContentType(true) 39 | .cookies(loginForm.cookies()).method(Connection.Method.GET) 40 | .execute().body(); 41 | 42 | if (code.isEmpty()) { 43 | System.err.println("Error! Invalid Spoj Credentials"); 44 | } else { 45 | System.out.println("spoj: fetched code " + submissionId); 46 | setCode(code); 47 | } 48 | } catch (IOException e) { 49 | System.err.println("spoj: Error Fetching code" + submissionId 50 | + " -> " + e.getMessage()); 51 | // e.printStackTrace(); 52 | } 53 | 54 | return code; 55 | } 56 | 57 | @Override 58 | public String getSubmissionIdFromUrl() { 59 | String url = getSubmissionUrl(); 60 | url = url.replace(HTTPS, ""); 61 | url = url.replace("www.spoj.com/files/src/save/", ""); 62 | url = url.replace("/", ""); 63 | return url; 64 | } 65 | 66 | @Override 67 | public String getSubmissionUrlFromId() { 68 | String subId = HTTPS + SUBMITTEDURL.replace(":s", getSubmissionId()); 69 | return subId; 70 | } 71 | 72 | public SpojSubmission(String submissionId, String submissionUrl, 73 | Problem problem, User user) { 74 | super(submissionId, submissionUrl, problem, user); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/plugins/spoj/core/entities/SpojUser.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.plugins.spoj.core.entities; 2 | 3 | import com.koldbyte.codebackup.core.entities.User; 4 | 5 | public class SpojUser extends User { 6 | private final String HTTPS = "https://"; 7 | private final String PROFILEURL = "www.spoj.com/users/:u/"; 8 | 9 | private String username; 10 | private String pass; 11 | 12 | public String getUsername() { 13 | return username; 14 | } 15 | 16 | public String getPass() { 17 | return pass; 18 | } 19 | 20 | public void setUsername(String username) { 21 | this.username = username; 22 | } 23 | 24 | public void setPass(String pass) { 25 | this.pass = pass; 26 | } 27 | 28 | public SpojUser(String handle) { 29 | super(handle); 30 | } 31 | 32 | public SpojUser(String handle, String profileUrl) { 33 | super(handle, profileUrl); 34 | } 35 | 36 | @Override 37 | public String getHandleFromProfileUrl() { 38 | String handle = profileUrl; 39 | handle = handle.replace(HTTPS, ""); 40 | handle = handle.replace("www.spoj.com/users/", ""); 41 | handle = handle.replace("/", ""); 42 | return handle; 43 | } 44 | 45 | @Override 46 | public String getProfileUrlFromHandle() { 47 | return HTTPS + PROFILEURL.replace(":u", this.handle); 48 | } 49 | 50 | @Override 51 | public Boolean isValidUser() { 52 | return true; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/utils/HTTPRequest.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.utils; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.DataOutputStream; 5 | import java.io.InputStreamReader; 6 | import java.net.HttpURLConnection; 7 | import java.net.URL; 8 | 9 | public class HTTPRequest { 10 | private String userAgent = "Mozilla/5.0"; 11 | private String url = "http://www.google.com/search?q=mkyong"; 12 | private String urlParameters = "sn=C02G8416DRJM&cn=&locale=&caller=&num=12345"; 13 | private int connectTimeout = 10000; 14 | private int socketTimeout = 10000; 15 | 16 | public HTTPRequest(String userAgent, String url, String urlParameters) { 17 | super(); 18 | this.userAgent = userAgent; 19 | this.url = url; 20 | this.urlParameters = urlParameters; 21 | } 22 | 23 | public HTTPRequest(String url, String urlParameters) { 24 | super(); 25 | this.url = url; 26 | this.urlParameters = urlParameters; 27 | } 28 | 29 | public String getUserAgent() { 30 | return userAgent; 31 | } 32 | 33 | public void setUserAgent(String userAgent) { 34 | this.userAgent = userAgent; 35 | } 36 | 37 | public String getUrl() { 38 | return url; 39 | } 40 | 41 | public void setUrl(String url) { 42 | this.url = url; 43 | } 44 | 45 | public String getUrlParameters() { 46 | return urlParameters; 47 | } 48 | 49 | public void setUrlParameters(String urlParameters) { 50 | this.urlParameters = urlParameters; 51 | } 52 | 53 | // HTTP GET request 54 | public StringBuffer sendGet() throws Exception { 55 | URL obj = new URL(url); 56 | HttpURLConnection con = (HttpURLConnection) obj.openConnection(); 57 | 58 | // set Timeouts 59 | con.setConnectTimeout(connectTimeout); 60 | con.setReadTimeout(socketTimeout); 61 | 62 | // optional default is GET 63 | con.setRequestMethod("GET"); 64 | 65 | // add request header 66 | con.setRequestProperty("User-Agent", userAgent); 67 | 68 | // int responseCode = con.getResponseCode(); 69 | // System.out.println("\nSending 'GET' request to URL : " + url); 70 | // System.out.println("Response Code : " + responseCode); 71 | 72 | BufferedReader in = new BufferedReader(new InputStreamReader( 73 | con.getInputStream())); 74 | String inputLine; 75 | StringBuffer response = new StringBuffer(); 76 | 77 | while ((inputLine = in.readLine()) != null) { 78 | response.append(inputLine); 79 | } 80 | in.close(); 81 | 82 | // print result 83 | // System.out.println(response.toString()); 84 | 85 | return response; 86 | } 87 | 88 | // HTTP POST request 89 | public StringBuffer sendPost() throws Exception { 90 | 91 | URL obj = new URL(url); 92 | HttpURLConnection con = (HttpURLConnection) obj.openConnection(); 93 | 94 | // set Timeouts 95 | con.setConnectTimeout(connectTimeout); 96 | con.setReadTimeout(socketTimeout); 97 | 98 | // add request header 99 | con.setRequestMethod("POST"); 100 | con.setRequestProperty("User-Agent", userAgent); 101 | con.setRequestProperty("Accept-Language", "en-US,en;q=0.5"); 102 | 103 | // Send post request 104 | con.setDoOutput(true); 105 | DataOutputStream wr = new DataOutputStream(con.getOutputStream()); 106 | wr.writeBytes(urlParameters); 107 | wr.flush(); 108 | wr.close(); 109 | 110 | // int responseCode = con.getResponseCode(); 111 | // System.out.println("\nSending 'POST' request to URL : " + url); 112 | // System.out.println("Post parameters : " + urlParameters); 113 | // System.out.println("Response Code : " + responseCode); 114 | 115 | BufferedReader in = new BufferedReader(new InputStreamReader( 116 | con.getInputStream())); 117 | String inputLine; 118 | StringBuffer response = new StringBuffer(); 119 | 120 | while ((inputLine = in.readLine()) != null) { 121 | response.append(inputLine); 122 | } 123 | in.close(); 124 | 125 | 126 | return response; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/com/koldbyte/codebackup/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.koldbyte.codebackup.utils; 2 | 3 | import org.jsoup.Jsoup; 4 | import org.jsoup.nodes.Document; 5 | import org.jsoup.safety.Whitelist; 6 | 7 | public class StringUtils { 8 | public static StringBuffer explode(StringBuffer content, String pre, 9 | String post) { 10 | String result = content.substring(content.indexOf(pre) + 1, 11 | content.indexOf(post)); 12 | return new StringBuffer(result); 13 | } 14 | 15 | public static String br2nl(String html) { 16 | if (html == null) 17 | return html; 18 | Document document = Jsoup.parse(html); 19 | document.outputSettings(new Document.OutputSettings() 20 | .prettyPrint(false));// makes html() preserve linebreaks and 21 | // spacing 22 | document.select("br").append("\\n"); 23 | document.select("p").prepend("\\n\\n"); 24 | String s = document.html().replaceAll("\\\\n", "\n"); 25 | return Jsoup.clean(s, "", Whitelist.none(), 26 | new Document.OutputSettings().prettyPrint(false)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/org/eclipse/wb/swing/FocusTraversalOnArray.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2011 Google, Inc. 3 | * All rights reserved. This program and the accompanying materials 4 | * are made available under the terms of the Eclipse Public License v1.0 5 | * which accompanies this distribution, and is available at 6 | * http://www.eclipse.org/legal/epl-v10.html 7 | * 8 | * Contributors: 9 | * Google, Inc. - initial API and implementation 10 | *******************************************************************************/ 11 | package org.eclipse.wb.swing; 12 | 13 | import java.awt.Component; 14 | import java.awt.Container; 15 | import java.awt.FocusTraversalPolicy; 16 | 17 | /** 18 | * Cyclic focus traversal policy based on array of components. 19 | *

20 | * This class may be freely distributed as part of any application or plugin. 21 | * 22 | * @author scheglov_ke 23 | */ 24 | public class FocusTraversalOnArray extends FocusTraversalPolicy { 25 | private final Component m_Components[]; 26 | //////////////////////////////////////////////////////////////////////////// 27 | // 28 | // Constructor 29 | // 30 | //////////////////////////////////////////////////////////////////////////// 31 | public FocusTraversalOnArray(Component components[]) { 32 | m_Components = components; 33 | } 34 | //////////////////////////////////////////////////////////////////////////// 35 | // 36 | // Utilities 37 | // 38 | //////////////////////////////////////////////////////////////////////////// 39 | private int indexCycle(int index, int delta) { 40 | int size = m_Components.length; 41 | int next = (index + delta + size) % size; 42 | return next; 43 | } 44 | private Component cycle(Component currentComponent, int delta) { 45 | int index = -1; 46 | loop : for (int i = 0; i < m_Components.length; i++) { 47 | Component component = m_Components[i]; 48 | for (Component c = currentComponent; c != null; c = c.getParent()) { 49 | if (component == c) { 50 | index = i; 51 | break loop; 52 | } 53 | } 54 | } 55 | // try to find enabled component in "delta" direction 56 | int initialIndex = index; 57 | while (true) { 58 | int newIndex = indexCycle(index, delta); 59 | if (newIndex == initialIndex) { 60 | break; 61 | } 62 | index = newIndex; 63 | // 64 | Component component = m_Components[newIndex]; 65 | if (component.isEnabled() && component.isVisible() && component.isFocusable()) { 66 | return component; 67 | } 68 | } 69 | // not found 70 | return currentComponent; 71 | } 72 | //////////////////////////////////////////////////////////////////////////// 73 | // 74 | // FocusTraversalPolicy 75 | // 76 | //////////////////////////////////////////////////////////////////////////// 77 | public Component getComponentAfter(Container container, Component component) { 78 | return cycle(component, 1); 79 | } 80 | public Component getComponentBefore(Container container, Component component) { 81 | return cycle(component, -1); 82 | } 83 | public Component getFirstComponent(Container container) { 84 | return m_Components[0]; 85 | } 86 | public Component getLastComponent(Container container) { 87 | return m_Components[m_Components.length - 1]; 88 | } 89 | public Component getDefaultComponent(Container container) { 90 | return getFirstComponent(container); 91 | } 92 | } --------------------------------------------------------------------------------