1 // XDrawChem
2 // Copyright (C) 2004-2005  Bryan Herger <bherger@users.sourceforge.net>
3 // Copyright (C) 2020  Yaman Qalieh <ybq987@gmail.com>
4 
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 
15 // You should have received a copy of the GNU General Public License
16 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 
18 #include <QBuffer>
19 #include <QDebug>
20 #include <QProgressDialog>
21 #include <QUrl>
22 
23 #include "http.h"
24 #include "netaccess.h"
25 
NetAccess()26 NetAccess::NetAccess() : QDialog() {
27     status = true;
28     sname = "unknown";
29     siupacname = "unknown";
30     scas = "unknown";
31     spccompound = "unknown";
32     buffer = 0;
33     // http = new QNetworkAccessManager( this );
34     // progressDialog = new QProgressDialog( this );
35     // connect( http, SIGNAL( dataReadProgress( int, int ) ), SLOT(
36     // slotUpdateDataReadProgress( int, int ) ) ); connect( http, SIGNAL(
37     // finished( QNetworkReply * ) ), SLOT( slotFinished( QNetworkReply * ) ) );
38     // connect( http, SIGNAL( done( bool ) ), SLOT( rf( bool ) ) );
39 }
40 
getChoices(QString server,QString key,QString value,bool exact)41 QStringList NetAccess::getChoices(QString server, QString key, QString value, bool exact) {
42     if (key == "formula") {
43         // put atoms in proper order
44         value = Rearrange(value);
45     }
46 
47     QString cmd;
48 
49     cmd.append(server);
50     cmd.append("/newdb.php?field=");
51     cmd.append(key);
52     cmd.append("&query=");
53     if (key == "name")
54         value = value.toUpper();
55     cmd.append(value);
56     cmd.append("&exact=");
57     if (exact)
58         cmd.append("on");
59     else
60         cmd.append("off");
61 
62     QUrl url = QUrl(cmd);
63 
64     qInfo() << "getChoices URL:" << cmd;
65 
66     HTTP if1(cmd);
67     if1.exec();
68     // httpRequestAborted = false;
69     // http->setHost( url.host(), url.port() != -1 ? url.port() : 80 );
70     qDebug() << Qt::endl << "Results:" << Qt::endl << if1.Data();
71 
72     // connect( progressDialog, SIGNAL( canceled() ), this, SLOT(
73     // slotCancelDownload() ) );
74 
75     // buffer = new QBuffer( this );
76     // buffer->open( QIODevice::WriteOnly );
77     QString testq = if1.Data();
78     // choicesId = http->get( url.path(), buffer );
79     //  QTextStream in1(buffer, QIODevice::ReadOnly);
80     // progressDialog->setLabelText( tr( "Getting choices" ) );
81     //    progressDialog->show();
82     // bool saveflag = false;
83 
84     QTextStream in1(&testq, QIODevice::ReadOnly);
85     QStringList results;
86 
87     // bool saveflag = false;
88     QString tmpl;
89     do {
90         tmpl = in1.readLine();
91         // if (tmpl == "XXX") { saveflag = true; continue; }
92         // if (tmpl == "YYY") { saveflag = false; continue; }
93         // if (saveflag) results.append(tmpl);
94         if (tmpl.length() > 5)
95             results.append(tmpl);
96     } while (!in1.atEnd());
97 
98     return results; // what a program should always do!
99 }
100 
getCanonicalSmiles(QString nserver,QString insmiles)101 QString NetAccess::getCanonicalSmiles(QString nserver, QString insmiles) {
102     qDebug() << "NetAccess::getCanonicalSMILES() is obsolete";
103     return QString();
104 }
105 
getFile(QString server,QString fn)106 QString NetAccess::getFile(QString server, QString fn) {
107     QString cmd, wholefile;
108 
109     cmd.append("http://");
110     cmd.append(server);
111     cmd.append("/cgi-bin/getfile?name=");
112     cmd.append(fn);
113 
114     HTTP if1(cmd);
115     if1.exec();
116 
117     wholefile = if1.Data();
118 
119     return wholefile;
120     return QString();
121 }
122 
runBuild3D(QString buildfile)123 bool NetAccess::runBuild3D(QString buildfile) {
124     QString cmd, wholefile;
125 
126     cmd.append("http://xdrawchem.sourceforge.net/cgi-bin/runbuild?buildfile=");
127     cmd.append(buildfile);
128 
129     HTTP if1(cmd);
130     if1.exec();
131 
132     // qDebug() << Qt::endl << "Results:" << Qt::endl << if1.Data() ;
133 
134     s3dmol = if1.Data();
135 
136     if (s3dmol.contains("can't write ") > 0)
137         return false;
138     if (s3dmol.contains("output file not found") > 0)
139         return false;
140 
141     return true;
142 }
143 
runInChI(QString buildfile)144 bool NetAccess::runInChI(QString buildfile) {
145     qDebug() << "obsolete function call: NetAccess::runInChI()";
146 
147     return true;
148 }
149 
Rearrange(QString key)150 QString NetAccess::Rearrange(QString key) {
151     QString key1, subkey, subnum;
152     int cc;
153     bool addflag;
154 
155     QStringList allatoms;
156 
157     do {
158         // qDebug() << key ;
159         // parse out element
160         subkey = "";
161         addflag = false;
162         subkey.append(key[0]);
163         for (cc = 1; cc < key.length(); cc++) {
164             if (key[cc].category() == QChar::Letter_Uppercase) {
165                 allatoms.append(subkey);
166                 key.remove(0, cc);
167                 addflag = true;
168                 break;
169             } else {
170                 subkey.append(key[cc]);
171             }
172         }
173         if (addflag == false) {
174             allatoms.append(subkey);
175             key.remove(0, cc);
176         }
177     } while (key.length() > 0);
178 
179     // qDebug() << allatoms.count() ;
180 
181     QString sym, n1;
182 
183     allatoms.sort();
184     if (allatoms.count() > 0) {
185         for (QStringList::Iterator ir = allatoms.begin(); ir != allatoms.end(); ++ir) {
186             n1 = *ir;
187             if (n1.contains("C") > 0)
188                 key1.append(n1);
189             if (n1.contains("H") > 0)
190                 key1.append(n1);
191         }
192         for (QStringList::Iterator ir = allatoms.begin(); ir != allatoms.end(); ++ir) {
193             n1 = *ir;
194             if ((n1.contains("C") == 0) && (n1.contains("H") == 0))
195                 key1.append(n1);
196         }
197     }
198 
199     return key1;
200 }
201 
slotData(const QByteArray & d1)202 void NetAccess::slotData(const QByteArray &d1) { htfile.append(d1); }
203 
slotUpdateDataReadProgress(int bytesRead,int totalBytes)204 void NetAccess::slotUpdateDataReadProgress(int bytesRead, int totalBytes) {
205     if (httpRequestAborted)
206         return;
207 
208     // progressDialog->setMaximum( totalBytes );
209     // progressDialog->setValue( bytesRead );
210 }
211 
slotCancelDownload()212 void NetAccess::slotCancelDownload() {
213     qDebug() << "slotCancelDownload";
214     httpRequestAborted = true;
215     // http->abort();
216     emit(choicesFinished(QStringList()));
217 }
218 
slotFinished(int httpId,bool)219 void NetAccess::slotFinished(int httpId, bool) {
220     qDebug() << "Finished network access";
221     status = false;
222 
223     if (httpId == choicesId) {
224         buffer->close();
225 
226         QString tmpl;
227         QStringList results = QStringList("test");
228 
229         buffer->open(QIODevice::ReadOnly);
230         do {
231             tmpl = buffer->readLine();
232             qDebug() << tmpl;
233             // if (tmpl == "XXX") { saveflag = true; continue; }
234             // if (tmpl == "YYY") { saveflag = false; continue; }
235             // if (saveflag) results.append(tmpl);
236             if (tmpl.length() > 5)
237                 results.append(tmpl);
238         } while (!buffer->atEnd());
239         emit(choicesFinished(results));
240         delete buffer;
241 
242         buffer = 0;
243     }
244 }
245 
getNameCAS(QString nserver,QString sinchi)246 bool NetAccess::getNameCAS(QString nserver, QString sinchi) {
247     qInfo() << "getNameCAS:" << nserver << "," << sinchi;
248     // don't waste bandwidth...
249     if (sinchi.length() < 2)
250         return false;
251 
252     // runInChI( ssmiles );  obsolete, we use OpenBabel now!
253     sinchi = sinchi.trimmed();
254 
255     QStringList choices = getChoices(nserver, "inchi", sinchi, true);
256 
257     QString tmp_str, tpc, tcas, tiname, tformula, tsyn;
258     int i1;
259 
260     for (QStringList::Iterator ir = choices.begin(); ir != choices.end(); ++ir) {
261         tmp_str = *ir;
262         qDebug() << ">>>" << tmp_str;
263         tmp_str.replace("\",\"", "~");
264         i1 = tmp_str.indexOf("~");
265         tpc = tmp_str.mid(0, i1);
266         tmp_str.remove(0, i1 + 1);
267         i1 = tmp_str.indexOf("~");
268         tcas = tmp_str.mid(0, i1);
269         tmp_str.remove(0, i1 + 1);
270         i1 = tmp_str.indexOf("~");
271         tiname = tmp_str.mid(0, i1);
272         tmp_str.remove(0, i1 + 1);
273         i1 = tmp_str.indexOf("~");
274         tformula = tmp_str.mid(0, i1);
275         tmp_str.remove(0, i1 + 1);
276         i1 = tmp_str.indexOf("~");
277         tsyn = tmp_str.mid(0, i1);
278         tmp_str.remove(0, i1 + 1);
279         // qDebug() << tcas << "," << tname <<","<< tformula << "," << tformat
280         //     ;
281         tpc.replace("\"", "");
282         tcas.replace("\"", "");
283         tsyn.replace("\"", "");
284         tiname.replace("\"", "");
285         qInfo() << "-- DB return: --";
286         qInfo() << tpc;
287         qInfo() << tcas;
288         qInfo() << tiname;
289         qInfo() << tsyn;
290         qInfo() << "-- DB end --";
291         spccompound = tpc;
292         scas = tcas;
293         siupacname = tiname;
294         sname = tsyn;
295         return true;
296     }
297 
298     return false;
299 }
300 
get3DMol(QString inmol)301 bool NetAccess::get3DMol(QString inmol) { return false; }
302 
rf(bool error)303 void NetAccess::rf(bool error) {}
304