PageRenderTime 39ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/src/hanyuu/managers/ThreadManager.java

https://bitbucket.org/Hanyuu/wipe
Java | 420 lines | 332 code | 56 blank | 32 comment | 56 complexity | bee61b469eca7a54612683e10455480d MD5 | raw file
  1. /*
  2. * To change this template, choose Tools | Templates
  3. * and open the template in the editor.
  4. */
  5. package hanyuu.managers;
  6. import hanyuu.managers.pictures.ImgManager;
  7. import hanyuu.net.wipe.AbstractWipe;
  8. import hanyuu.net.wipe.boards.WakabaWipe;
  9. import hanyuu.net.wipe.boards.KusabaWipe;
  10. import hanyuu.net.wipe.boards.HanabiraWipe;
  11. import hanyuu.net.wipe.boards.FutabaWipe;
  12. import hanyuu.parser.HornedParser;
  13. import hanyuu.net.proxy.ProxyManager;
  14. import hanyuu.net.proxy.HttpProxy;
  15. import utils.Constants;
  16. import hanyuu.chan.Chan;
  17. import hanyuu.chan.ChanManager;
  18. import config.Config;
  19. import java.io.PrintStream;
  20. import java.io.File;
  21. import java.util.ArrayList;
  22. import hanyuu.ext.ScriptManager;
  23. import hanyuu.net.wipe.Action;
  24. /**
  25. *
  26. * @author Hanyuu Furude
  27. */
  28. public class ThreadManager implements Runnable, Constants {
  29. private static ThreadManager _instance = null;
  30. private boolean work = false;
  31. private ProxyManager pmr;
  32. private ImgManager im;
  33. private UIManager uim;
  34. private Thread ManagerThread;
  35. private ChanManager cm;
  36. private CopyPasteManager cpm;
  37. private boolean console;
  38. private HornedParser parser;
  39. private MessageManager mm;
  40. private ScriptManager scripts;
  41. private ArrayList<AbstractWipe> notReady = new ArrayList<AbstractWipe>();
  42. private ArrayList<AbstractWipe> running = new ArrayList<AbstractWipe>();
  43. public static ThreadManager getInstance() {
  44. return _instance;
  45. }
  46. public boolean isWork() {
  47. return work;
  48. }
  49. @SuppressWarnings({"LeakingThisInConstructor", "CallToThreadStartDuringObjectConstruction"})
  50. public ThreadManager(boolean console) {
  51. _instance = this;
  52. ManagerThread = new Thread(this, "Thread Manager");
  53. this.console = console;
  54. ManagerThread.start();
  55. }
  56. public synchronized void handleError(AbstractWipe wipe) {
  57. if (!Config.smartErrorHandler) {
  58. return;
  59. }
  60. uim.getUI().logError("Called handleError() method in thread: [ " + wipe.toString() + " ]" + " Last action is: [ " + wipe.getLastAction() + " ] error is: " + wipe.getException().toString());
  61. wipe.incErrors();
  62. if (wipe.getErrors() == Config.smartErrorCount) {
  63. if (Config.smartErrorAction == 0) {
  64. wipe.setError(true);
  65. destroyThread(wipe, "Too many errors, see logs for details.");
  66. return;
  67. } else if (Config.smartErrorAction == 1) {
  68. uim.getUI().logInfo("Too many errors in thread [ " + wipe.toString() + " ], restarting...");
  69. reStart(wipe);
  70. }
  71. }
  72. switch (wipe.getLastAction()) {
  73. case RequestCaptcha:
  74. case Recognition:
  75. wipe.getOCR().recognizeCaptcha(wipe);
  76. break;
  77. case RequestThreads:
  78. wipe.getThreads();
  79. break;
  80. case Posting:
  81. case Sleeping:
  82. wipe.post();
  83. break;
  84. case DeletingPost:
  85. //wipe.delete(wipe.getMessages());
  86. break;
  87. }
  88. }
  89. @Override
  90. @SuppressWarnings({"CallToThreadDumpStack", "empty-statement"})
  91. public void run() {
  92. ManagerThread.setPriority(Thread.MAX_PRIORITY);
  93. try {
  94. System.setOut(new PrintStream(System.out, true, Config.EncodingConsole));
  95. System.setErr(new PrintStream(System.err, true, Config.EncodingConsole));
  96. pmr = new ProxyManager();
  97. cpm = new CopyPasteManager();
  98. cm = new ChanManager();
  99. cm.createAndLoad();
  100. Config.useGui = !console;
  101. scripts = new ScriptManager(this);
  102. im = new ImgManager(Config.path, this);
  103. uim = new UIManager(this);
  104. parser = new HornedParser();
  105. mm = new MessageManager(this);
  106. if (console) {
  107. StartStopManage();
  108. }
  109. } catch (Exception e) {
  110. e.printStackTrace();
  111. System.exit(-1);
  112. }
  113. }
  114. public MessageManager getMM() {
  115. return mm;
  116. }
  117. public HornedParser getParser() {
  118. return parser;
  119. }
  120. public ProxyManager getProxyManager() {
  121. return pmr;
  122. }
  123. public void deleteAllMessages() {
  124. /*if (work) {
  125. get(0).deletPost(getAllMessages());
  126. } else {
  127. uim.getUI().showMessage("Потоки остановленны.", 0);
  128. }*/
  129. }
  130. public ScriptManager getScripts() {
  131. return scripts;
  132. }
  133. public ImgManager getImgManager() {
  134. return im;
  135. }
  136. public void reBuildImgManager() {
  137. im = new ImgManager(Config.path, this);
  138. }
  139. public UIManager getUIManager() {
  140. return uim;
  141. }
  142. public ChanManager getChanManager() {
  143. return cm;
  144. }
  145. public CopyPasteManager getCopyPasteManager() {
  146. return cpm;
  147. }
  148. public void sleepWipe(long time, AbstractWipe wipe) {
  149. try {
  150. if (wipe.isSleeping()) {
  151. return;
  152. }
  153. wipe.setLastAction(Action.Sleeping);
  154. wipe.setSleeping(true);
  155. synchronized (wipe) {
  156. wipe.wait(time);
  157. }
  158. wipe.setSleeping(false);
  159. } catch (Exception e) {
  160. wipe.setSleeping(false);
  161. wipe.setException(e);
  162. handleError(wipe);
  163. }
  164. }
  165. @SuppressWarnings("CallToThreadDumpStack")
  166. public void StartStopManage() {
  167. try {
  168. if (!new File(Config.path).exists() && !Config.BokuNoFile) {
  169. uim.getUI().showMessage("File or folder " + Config.path + " not found", 0);
  170. uim.getUI().logError("File or folder " + Config.path + " not found");
  171. return;
  172. }
  173. if (work) {
  174. work = false;
  175. uim.getUI().SwitchStartStop();
  176. for (int i = 0; i < running.size();) {
  177. destroyThread(running.get(i), "Stopped.");
  178. i++;
  179. }
  180. } else {
  181. if (Config.chanName.contains("NoName")) {
  182. uim.getUI().logError("No chan selected");
  183. return;
  184. }
  185. work = true;
  186. uim.getUI().SwitchStartStop();
  187. int threads = uim.getUI().getThreads();
  188. HttpProxy[] proxys;
  189. if (Config.noProxy) {
  190. proxys = new HttpProxy[1];
  191. proxys[0] = new HttpProxy("no proxy", -1);
  192. threads = 1;
  193. } else {
  194. proxys = pmr.toArray(new HttpProxy[0]);
  195. }
  196. for (int i = 0; i < threads; i++) {
  197. runWipe(proxys[i]);
  198. }
  199. uim.getUI().setTitle("Рогатулечка. Чан: " + Config.chanName + ", Доска: " + Config.board + ". Потоков: " + running.size());
  200. }
  201. } catch (Exception e) {
  202. e.printStackTrace();
  203. work = false;
  204. uim.getUI().SwitchStartStop();
  205. uim.getUI().showMessage("Ошибка при запуске.\n" + e.toString(), 0);
  206. }
  207. }
  208. public boolean isReady() {
  209. return notReady.isEmpty();
  210. }
  211. public void removeFromNotReady(AbstractWipe wipe) {
  212. notReady.remove(wipe);
  213. if (running.contains(wipe)) {
  214. running.remove(wipe);
  215. }
  216. running.add(wipe);
  217. this.uim.getUI().logInfo("Ready threads: " + running.size());
  218. /*//System.out.println(notReady.size());
  219. if (notReady.isEmpty()) {
  220. if (running.isEmpty()) {
  221. uim.getUI().showMessage("Ошибка! Ни одного \"готового\" потока нету.", 0);
  222. StartStopManage();
  223. return;
  224. }
  225. for (AbstractWipe w : running) {
  226. uim.getUI().logInfo("Notifyng thread [ " + w.toString() + " ] ...");
  227. w.myNotify();
  228. }
  229. }*/
  230. }
  231. public void runThreads() {
  232. for (AbstractWipe w : running) {
  233. uim.getUI().logInfo("Notifyng thread [ " + w.toString() + " ] ...");
  234. w.myNotify();
  235. }
  236. running.clear();
  237. }
  238. public void runWipe(HttpProxy p) {
  239. AbstractWipe ww = null;
  240. Chan chan = cm.getByName(Config.chanName);
  241. if (chan == null || chan.ChanType == null) {
  242. uim.getUI().logError("unknown Chan: " + Config.chanName + " type: " + chan.ChanType.name());
  243. uim.getUI().SwitchStartStop();
  244. return;
  245. }
  246. switch (chan.ChanType) {
  247. case Wakaba:
  248. ww = new WakabaWipe(p, this, chan);
  249. break;
  250. case Kusaba:
  251. ww = new KusabaWipe(p, this, chan);
  252. break;
  253. case Hanabira:
  254. ww = new HanabiraWipe(p, this, chan);
  255. break;
  256. case Futaba:
  257. ww = new FutabaWipe(p, this, chan);
  258. break;
  259. }
  260. if (ww != null) {
  261. if (Config.waitForNotReady) {
  262. notReady.add(ww);
  263. } else {
  264. running.add(ww);
  265. }
  266. } else {
  267. uim.getUI().logError("Unknown Chan: " + Config.chanName + " type: " + chan.ChanType.name());
  268. uim.getUI().SwitchStartStop();
  269. return;
  270. }
  271. }
  272. public synchronized int getAllSuccessful() {
  273. int i = 0;
  274. for (int l = 0; l < running.size(); l++) {
  275. i += running.get(l).getSuccessful();
  276. }
  277. return i;
  278. }
  279. public synchronized int getAllFailed() {
  280. int i = 0;
  281. for (int l = 0; l < running.size(); l++) {
  282. i += running.get(l).getFailed();
  283. }
  284. return i;
  285. }
  286. public int size() {
  287. return running.size();
  288. }
  289. public void reStart(AbstractWipe ww) {
  290. running.remove(ww);
  291. switch (ww.getChan().ChanType) {
  292. case Wakaba:
  293. ww = new WakabaWipe(ww.getProxy(), this, ww.getChan());
  294. break;
  295. case Kusaba:
  296. ww = new KusabaWipe(ww.getProxy(), this, ww.getChan());
  297. break;
  298. case Hanabira:
  299. ww = new HanabiraWipe(ww.getProxy(), this, ww.getChan());
  300. break;
  301. case Futaba:
  302. ww = new FutabaWipe(ww.getProxy(), this, ww.getChan());
  303. break;
  304. }
  305. running.add(ww);
  306. }
  307. @SuppressWarnings("CallToThreadDumpStack")
  308. public void destroyThread(AbstractWipe ww, String reason) {
  309. try {
  310. synchronized (lock) {
  311. if (ww == null) {
  312. return;
  313. }
  314. /*
  315. if ((!Config.noProxy && ww.getProxy() != null) && reason.contains(ww.getProxy().getHost())) {
  316. getProxyManager().delete(ww.getProxy(), uim.getUI());
  317. }*/
  318. ww.myNotify();
  319. ww.stop();
  320. if (!running.contains(ww) || !notReady.contains(ww)) {
  321. return;
  322. }
  323. if (!running.remove(ww)) {
  324. notReady.remove(ww);
  325. }
  326. work = !(running.isEmpty());
  327. uim.getUI().SwitchStartStop();
  328. uim.getTray().switchState();
  329. if ((Config.useTmp || Config.randomPicGenerate) && ww.getFile().exists()) {
  330. ww.getFile().delete();
  331. }
  332. if (work) {
  333. uim.getUI().logInfo("Threads count is: " + running.size());
  334. }
  335. uim.getUI().setTitle("Рогатулечка. Чан: " + Config.chanName + ", Доска: " + Config.board + ". Потоков: " + running.size());
  336. if (!work) {
  337. uim.getUI().setTitle("Рогатулечка. Чан: " + Config.chanName + ", Доска: " + Config.board + ".");
  338. }
  339. if (ww.isError()) {
  340. uim.getUI().logError("Thread [" + ww.getThread().getName() + "] stoped by ThreadManager.\nReason: " + reason);
  341. if (Config.useGui) {
  342. uim.getTray().trayPrintError("Ханюша", "Поток " + ww.getThread().getName() + "\nЗавершён причина: " + reason);
  343. }
  344. } else {
  345. if (reason != null && reason.isEmpty()) {
  346. uim.getUI().logInfo("Thread [" + ww + "] stoped.");
  347. } else {
  348. uim.getUI().logInfo("Thread [" + ww + "] stoped.\nReason: " + reason);
  349. }
  350. if (reason != null && reason.isEmpty()) {
  351. uim.getTray().trayPrint("Ханюша", "Поток " + ww + " завершён.");
  352. } else {
  353. uim.getTray().trayPrint("Ханюша", "Поток " + ww + " завершён.\nПричина: " + reason);
  354. }
  355. }
  356. ww = null;
  357. }
  358. } catch (Exception e) {
  359. e.printStackTrace();
  360. }
  361. }
  362. }