Operaciones.cpp

Ir a la documentación de este archivo.
00001 // vim: set expandtab tabstop=8 shiftwidth=8 foldmethod=marker:
00012 #include <iostream>
00013 #include <iomanip>
00014 #include <list>
00015 #include <vector>
00016 #include <fstream>
00017 #include <istream>
00018 
00019 #include <sys/stat.h>
00020 #include <time.h>
00021 
00022 #include "RamDisco.hpp"
00023 #include "Operaciones.hpp"
00024 #include "sha256.hpp"
00025 #include "leeODT.hpp"
00026 #include "leeXML.hpp"
00027 #include "leeHTML.hpp"
00028 #include "leePDF.hpp"
00029 
00030 using namespace std;
00031 
00032 
00033 string prefijoASitio(const char *pref)
00034 {
00035         ASSERT(pref != NULL);
00036         //cout << "OJO prefijoASitio(" << pref << ")" << endl;
00037         string o = "";
00038         if (strlen(pref)>7 && (strncmp(pref, "https://", 8) == 0
00039                                || strncmp(pref, "http://", 7) == 0)) {
00040                 unsigned int i = strncmp(pref, "https://", 8) == 0 ? 8 : 7;
00041                 for (; pref[i] != '\0' && i < (MAXCAD - 10) &&
00042                                 //pref[i] != '.' &&
00043                                 pref[i] != '/' && pref[i] != ':'; i++) {
00044                         o += pref[i];
00045                         //cout << "OJO " << i << o << endl;
00046                 }
00047 
00048         }
00049         if (o == "") {
00050                 o = "localhost";
00051         }
00052         return o;
00053 }
00054 
00055 string determinaFormato(string narch)
00056 {
00057         string f = "";
00058         if (narch.substr(narch.length() - 4) == ".txt") {
00059                 f = "texto";
00060         } else if (narch.substr(narch.length() - 4) == ".odt") {
00061                 f = "odf";
00062         } else if (narch.substr(narch.length() - 6) == ".xrlat") {
00063                 f = "relato";
00064         } else if (narch.substr(narch.length() - 4) == ".xml") {
00065                 f = "xml";
00066         } else if (narch.substr(narch.length() - 4) == ".ogv") { // Video Theora
00067                 f = "ogv";
00068         } else if (narch.substr(narch.length() - 4) == ".ogg") { // Audio OGG
00069                 f = "ogg";
00070         } else if (narch.substr(narch.length() - 4) == ".jpg") {
00071                 f = "jpg";
00072         } else if (narch.substr(narch.length() - 4) == ".png") {
00073                 f = "png";
00074         } else if (narch.substr(narch.length() - 4) == ".gif") {
00075                 f = "gif";
00076         } else if (narch.substr(narch.length() - 4) == ".pdf") {
00077                 f = "pdf";
00078         } else if (narch.substr(narch.length() - 5) == ".html" ||
00079                         narch.substr(narch.length() - 4) == ".htm") {
00080                 f = "html";
00081         } else {
00082                 f = "otro";
00083         }
00084 
00085         return f;
00086 }
00087 
00088 
00089 
00090 /*
00091  * Indexa contenido del archivo noma en RAM
00092  */
00093 void
00094 indexa(Doc &d, long numdoc, bool metainformacion, const char *pref,
00095        NodoTrieS &t, string &tipo, string &formato)
00096 {
00097         //clog << "OJO indexa(d.URL=" << d.URL << ", " << numdoc << ", " << metainformacion << ", " << pref << ", t," << tipo << "," << formato << ")" << endl;
00098         ASSERT(numdoc >= 1);
00099         string sitio = prefijoASitio(pref);
00100         //clog << "OJO sitio=" << sitio << endl;
00101         tipo = "otro";
00102         char nom[MAXLURL];
00103         snprintf(nom, MAXLURL, "%s", d.URL.c_str());
00104         //Si es XML y/o relato emplear otra función
00105         formato = determinaFormato(nom);
00106         //clog << "OJO formato= "<< formato << endl;
00107         try {
00108                 if (formato == "texto") {
00109                         leeTexto(nom, numdoc, t, metainformacion);
00110                         tipo = "documento";
00111                 } else if (formato == "xml") {
00112                         leeXML(nom, numdoc, t);
00113                         tipo = "documento";
00114                 } else if (formato == "relato") {
00115                         leeXML(nom, numdoc, t);
00116                         tipo = "relato";
00117                 } else if (formato == "odf") {
00118                         leeODT(nom, numdoc, t, metainformacion);
00119                         tipo = "documento";
00120                 } else if (formato == "html") {
00121                         leeHTML(nom, numdoc, t, metainformacion);
00122                         tipo = "documento";
00123                 } else if (formato == "pdf") {
00124                         leePDF(nom, numdoc, t, metainformacion);
00125                         tipo = "documento";
00126                 } else if (formato == "ogv") {
00127                         tipo = "vídeo";
00128                 } else if (formato == "ogg") {
00129                         tipo = "audio";
00130                 } else if (formato == "jpg" || formato == "png" || formato == "gif") {
00131                         tipo = "imagen";
00132                 }
00133                 //clog << "OJO tipo= "<< tipo<< endl;
00134                 if (metainformacion) {
00135                         // Insertamos titulo también como palabra
00136                         t.insertaConEtiqueta(nom, "titulo", numdoc, 1);
00137                         string tt = normaliza(nom);
00138                         if (tt != "") {
00139                                 t.inserta(tt, Pos(numdoc, 1));
00140                         }
00141                         // Insertamos la extensión como titulo
00142                         vector<string> bext = estalla(".", nom);
00143                         if (bext.size() > 1) {
00144                                 //clog << "OJO Insertando extensión " << bext[bext.size() -1] << endl;
00145                                 t.insertaConEtiqueta(bext[bext.size() - 1],
00146                                                      "titulo", numdoc, 1);
00147                         }
00148 
00149                         t.insertaConEtiqueta(sitio, "sitio", numdoc, 1);
00150                         t.insertaConEtiqueta(tipo, "tipo", numdoc, 1);
00151                 }
00152 
00153                 struct tm* rel;
00154                 struct stat atr;
00155                 stat(nom, &atr);
00156                 rel = gmtime(&(atr.st_mtime));
00157                 char fecha[11];
00158                 snprintf(fecha, 11, "%04i-%02i-%02i",
00159                          1900 + rel->tm_year,
00160                          rel->tm_mon + 1, rel->tm_mday);
00161                 string hash = sha256archivo(string(nom));
00162                 //clog << "OJO hash= " << hash << endl;
00163                 d.cond = hash;
00164                 d.fecha = string(fecha);
00165                 if (d.URL.substr(0, 3) == "../") {
00166                         d.URL = pref + d.URL.substr(3);
00167                 } else {
00168                         d.URL = pref + d.URL;
00169                 }
00170         } catch (string m) {
00171                 cerr << m << endl;
00172         }
00173 
00174 }
00175 
00176 
00177 void
00178 muestraStream(std::istream &is, string pre) //throw(char *)
00179 {
00180         string cad, npre;
00181         set<Pos> *cpos;
00182         long hijo, her;
00183 
00184         cad = leeCad(is);
00185         if (cad != "")
00186         {
00187                 her = lee128b(is);
00188                 hijo = lee128b(is);
00189                 cpos = leePos(is, NULL);
00190                 if (cpos->size()>0) {
00191                         cout << pre << cad << " " << cpos->size() << endl;
00192                 }
00193                 long pac = is.tellg();
00194                 if (hijo > 0) {
00195                         is.seekg(hijo);
00196                         npre = pre;
00197                         npre += cad;
00198                         muestraStream(is, npre);
00199                 }
00200                 is.seekg(pac);
00201                 muestraStream(is, pre);
00202         }
00203 }
00204 
00205 
00206 void listaPalabras(char *noma, char *nrel)
00207 {
00208         ASSERT(noma != NULL);
00209         ASSERT(nrel != NULL);
00210 
00211         vector<Doc> idocs;
00212         leeRelacion(nrel, idocs);
00213 
00214         for (unsigned int i = 0; i< idocs.size(); i++) {
00215                 cout << (i+1) << " " << idocs[i].URL << endl;
00216         }
00217 
00218         fstream is(noma, ios_base::in);
00219         verificaIndice(is);
00220         muestraStream(is, "");
00221         is.close();
00222 }
00223 
00224 
00225 void
00226 eliminaDoc(char *noma, char *nomind, long nd)
00227 {
00228         ASSERT(nd > 0);
00229         char nrel1[MAXLURL];
00230         char nrel[MAXLURL];
00231         verificaNombre(noma, nrel);
00232         verificaNombre(nomind, nrel1);
00233         /*long nd = atoi(argv[4]); */
00234         if (nd <= 0) {
00235                 stringstream ss;
00236                 ss << "n debe ser mayor o igual a 1";
00237                 throw ss.str();
00238         }
00239         vector<Doc> docs;
00240         vector<Doc> sdocs;
00241         long td = leeRelacion(nrel1, docs);
00242         if (nd > td) {
00243                 stringstream ss;
00244                 ss << "n debe ser menor o igual a " << td;
00245                 throw ss.str();
00246         }
00247         unsigned int i;
00248         vector<long> renum;
00249         for(i = 0; i < nd - 1; i++) {
00250                 renum.push_back(i);
00251                 sdocs.push_back(docs[i]);
00252         }
00253         /* 0  1  2  3 -elim tercero -> 0 1 3
00254            0  1 -1  2 */
00255         renum.push_back(-1);
00256         for(i = nd; i < td; i++) {
00257                 renum.push_back(i - 1);
00258                 sdocs.push_back(docs[i]);
00259         }
00260         fstream os(noma, ios_base::out);
00261         fstream is(nomind, ios_base::in);
00262 
00263         verificaIndice(is);
00264         is.clear();
00265 
00266         os << MARCAIND << endl;
00267         escribeCopiaSubarbol(os, is, true, &renum);
00268         is.close();
00269         os.close();
00270 
00271         // Escribe relación sin el borrado
00272         escribeRelacion(nrel, sdocs);
00273 }
00274 
00275 
00276 void
00277 calcRenum(long td1, long td2, long nd, vector<long> *reord,
00278           vector<long> *renum1,
00279           vector<long> &renum2)
00280 {
00281         //clog << "OJO calcRenum(td1=" << td1 << ", td2=" << td2 << ", nd=" << nd << ", reord=" << reord << ", renum1=" << renum1 << ", renum2.size=" << renum2.size() << endl;
00282         if (reord != NULL) {
00283                 //clog << "OJO reord.size() =" << reord->size() << endl;
00284         }
00285         if (renum1 != NULL) {
00286                 //clog << "OJO renum1.size() =" << renum1->size() << endl;
00287         }
00288 
00289         if (nd > 0 && nd <= td1) {
00290 
00291                 // renum2 0 -> 2, 1 -> 3 2 -> 4 y docs1 quedará a b c d e
00292 
00293                 // queremos renum2 en
00294                 // 0 -> 1, 1 -> 2, 2 -> 3  i->i+(nd-1)
00295                 // Los indices de docs1 final deben ser
00296                 // 0 -> 0, 1 -> 4, 2 -> 1, 3 -> 2, 4 -> 3
00297                 // que se dejan invertidos en reord
00298                 // 0 de 0, 1 de 2, 2 de 3, 3 de 4, 4 de 1
00299 
00300                 unsigned int j;
00301                 for(j = 0; j < renum2.size(); j++) {
00302                         renum2[j] = (nd - 1) + j;
00303                 }
00304 
00305                 // renum1 0 -> 0, 1->3  i->i si i<nd i->i+docs.size() si i>nd
00306                 for(j = 0; j < nd - 1; j++) {
00307                         renum1->push_back(j);
00308                 }
00309                 for(j = nd - 1 ; j < td1; j++) {
00310                         renum1->push_back(j + td2);
00311                 }
00312 
00313                 for(j = 0; j < nd - 1; j++) {
00314                         reord->push_back(j);
00315                 }
00316                 for(j = 0; j < renum2.size(); j++) {
00317                         reord->push_back(td1 + j);
00318                 }
00319                 for(j = nd - 1 ; j < td1; j++) {
00320                         reord->push_back(j);
00321                 }
00322         }
00323 }
00324 
00325 
00326 void
00327 mezclaDosDisco(const char *indsal, const char *ind1, const char *ind2,
00328                long nd)
00329 {
00330         ASSERT(nd >= 0);
00331         char nrel[MAXLURL], nrel1[MAXLURL], nrel2[MAXLURL];
00332 
00333         //clog << "OJO mezclaDosDisco(" << indsal << ", " << ind1 << ", " << ind2 << ", " << nd << ")" << endl;
00334         verificaNombre(indsal, nrel);
00335         verificaNombre(ind1, nrel1);
00336         verificaNombre(ind2, nrel2);
00337 
00338         vector<Doc> docs;
00339         vector<Doc> sdocs;
00340         // Leer y mezclar relación de documentos 1 y 2
00341         vector<Doc> docs1;
00342         vector<Doc> docs2;
00343         long td1;
00344         try {
00345                 td1 = leeRelacion(nrel1, docs1);
00346                 //clog << "OJO td1= " << td1 << ", docs1.size()=" << docs1.size() << endl;
00347                 if (nd > td1 + 1) {
00348                         cerr << "n debe ser menor o igual a " <<
00349                         td1 + 1 << endl;
00350                         exit(1);
00351                 }
00352                 leeRelacion(nrel2, docs2);
00353                 //clog << "OJO docs2.size= " << docs2.size() << endl;
00354         } catch (std::string s) {
00355                 cerr << s << endl;
00356                 exit(1);
00357         }
00358 
00359         vector<long> *reord = NULL;
00360         vector<long> *renum1 = NULL;
00361         vector<long> renum2 =
00362                 mezclaDocs(docs2, docs1);
00363         //clog << "OJO tras mezclaDocs renum2.size= " << renum2.size() << endl;
00364         if (nd > 0 && nd <= td1) {
00365                 renum1 = new vector<long>();
00366                 reord = new vector<long>();
00367         }
00368         calcRenum(td1, docs2.size(), nd, reord, renum1, renum2);
00369         if (reord != NULL) {
00370                 //clog << "OJO reord.size=" << reord->size() << ", renum1.size=" << renum1->size() << ", renum2.size=" << renum2.size() << endl;
00371         }
00372         try {
00373                 fstream os(indsal, ios_base::out);
00374                 fstream is1(ind1, ios_base::in);
00375                 fstream is2(ind2, ios_base::in);
00376 
00377                 verificaIndice(is1);
00378                 is1.clear();
00379                 verificaIndice(is2);
00380                 is2.clear();
00381 
00382                 os << MARCAIND << endl;
00383                 mezclaRec(is1, is2, os, true, true, renum1, &renum2);
00384                 is1.close();
00385                 is2.close();
00386                 os.close();
00387 
00388                 // Escribe relación de documentos de mezcla
00389                 escribeRelacion(nrel, docs1, reord);
00390         } catch (std::string s) {
00391                 cerr << s << endl;
00392                 exit(1);
00393         }
00394 }
00395 
00396 void
00397 agregaDoc(const char *indsal, const char *inden, const char *nom,
00398           bool metainformacion, const char *pref, long nd)
00399 {
00400         char nrel[MAXLURL], nrel1[MAXLURL];
00401         //clog << "agregaDoc(indsal=" << indsal << ", inden=" << inden << ", nom=" << nom << ", metainformacion=" << metainformacion << ", pref=" << pref << ", nd=" << nd << endl;
00402 
00403         verificaNombre(indsal, nrel);
00404         verificaNombre(inden, nrel1);
00405 
00406         // Leer y mezclar relación de documentos
00407         vector<Doc> docs1;
00408         vector<Doc> docs2;
00409         long td1 = 0;
00410         try {
00411                 td1 = leeRelacion(nrel1, docs1);
00412                 //clog << "OJO docs1.size()=" << docs1.size() << endl;
00413         } catch (std::string s) {
00414                 cerr << s << endl;
00415                 exit(1);
00416         }
00417         if (nd > td1 + 1) {
00418                 cerr << "n debe ser menor o igual a " <<
00419                 td1 + 1 << endl;
00420                 exit(1);
00421         }
00422 
00423         Doc d(nom, "", "1960-01-01");
00424         docs2.push_back(d);
00425 
00426         vector<long> *reord = NULL;
00427         vector<long> *renum1 = NULL;
00428         vector<long> renum2 =
00429                 mezclaDocs(docs2, docs1);
00430         //clog << "OJO tras mezclaDocs docs2.size=" << docs2.size() << ", docs1.size=" << docs1.size() << ", renum2.size=" << renum2.size() << endl;
00431         if (nd > 0 && nd <= td1) {
00432 
00433                 renum1 = new vector<long>();
00434                 reord = new vector<long>();
00435         }
00436         calcRenum(td1, docs2.size(), nd, reord, renum1, renum2);
00437         //clog << "OJO tras calcRenum: ";
00438         string sep="";
00439         for (unsigned int i=0; i < renum2.size(); i++) {
00440                 //clog << sep << "renum2[" << i << "]=" << renum2[i];
00441                 sep=", ";
00442         }
00443         //clog << endl;
00444 
00445         NodoTrieS t;
00446         string tipo, formato;
00447         try {
00448                 indexa(docs1[docs1.size() - 1], 1, metainformacion, pref,
00449                        t, tipo, formato);
00450                 //clog << "OJO tras indexa tipo=" << tipo << ", formato=" << formato << endl;
00451 
00452                 fstream os(indsal, ios_base::out);
00453                 fstream is1(inden, ios_base::in);
00454 
00455                 verificaIndice(is1);
00456                 is1.clear();
00457 
00458                 os << MARCAIND << endl;
00459                 mezclaDiscoRam(is1, &t, 0, os, true, true, renum1, &renum2);
00460                 is1.close();
00461                 os.close();
00462 
00463                 // Escribe relación de documentos de mezcla
00464                 escribeRelacion(nrel, docs1, reord);
00465                 //clog << "OJO tras escribeRelacion" << endl;
00466         } catch (std::string s) {
00467                 cerr << s << endl;
00468                 exit(1);
00469         }
00470 }
00471 
00472 
00473 
00474 
00475 
00476 

Generado el Wed Jan 6 06:58:22 2010 para Mt77 por  doxygen 1.5.4