void ocrImage( char *uuid, int docid, int page, int request_resolution, PIX *pix, char *lang ) { char *ocrText; char *ocrLang; ocrLang = getScanParam(uuid, SCAN_PARAM_DO_OCR); #ifdef CAN_OCR if(ocrLang && 0 != strcmp(ocrLang, "-") ) { if(request_resolution >= 300 && request_resolution <= 400) { char *ocrScanText; o_log(INFORMATION, "Attempting OCR in lang of %s", ocrLang); updateScanProgress(uuid, SCAN_PERFORMING_OCR, 10); ocrScanText = getTextFromImage(pix, request_resolution, ocrLang); ocrText = o_printf( getString("LOCAL_page_delimiter", lang), page, ocrScanText); free(ocrScanText); } else { o_log(DEBUGM, "OCR was requested, but the specified resolution means it's not safe to be attempted"); ocrText = o_printf( getString("LOCAL_resolution_outside_range_to_attempt_ocr", lang) ); } } else #endif /* CAN_OCR */ ocrText = o_strdup(""); free(ocrLang); updateScanProgress(uuid, SCAN_DB_WORKING, 0); updateNewScannedPage(docid, ocrText, page); free(ocrText); }
char *extractThumbnail(char *docid) { char *source_file, *target_file, *ocrText; source_file = o_printf("%s/scans/%s.pdf", BASE_DIR, docid); target_file = o_printf("%s/scans/%s_thumb.jpg", BASE_DIR, docid); ocrText = parse_pdf( source_file, target_file ); // pdf_plug.cc [create thumbnail and return body text] free(ocrText); free(source_file); free(target_file); return o_strdup("<?xml version='1.0' encoding='utf-8'?>\n<Response><RegenerateThumb><result>OK</result></RegenerateThumb></Response>"); }
int main (int argc, char **argv) { BASE_DIR = argv[1]; LOG_DIR = argv[2]; VERBOSITY = atoi(argv[3]); char *command = argv[4]; char *param = argv[5]; // Setup char *db = o_printf("%s/openDIAS.sqlite3", BASE_DIR); o_log(DEBUGM,"database file is %s",db); if(open_db (db)) { o_log(ERROR, "Could not connect to the database."); free(db); exit(EXIT_FAILURE); } free(db); locale_init( "en" ); // Let's do the work o_log( INFORMATION, "Worker started and ready to process: %s", command); sane_worker( command, param ); // Finish up now close_all(); exit(EXIT_SUCCESS); }
extern char *getTagId(char *tagname) { struct simpleLinkedList *vars, *rSet; char *sql2, *ret = NULL; char *sql = o_printf("SELECT tagid FROM tags WHERE tagname = '%s'", tagname); rSet = runquery_db(sql); if( rSet != NULL ) { ret = o_strdup(readData_db(rSet, "tagid")); } else { o_log(DEBUGM, "no tag was found. Adding a new one."); sql2 = o_strdup("INSERT INTO tags (tagname) VALUES (?)"); vars = sll_init(); sll_append(vars, DB_TEXT ); sll_append(vars, tagname ); runUpdate_db(sql2, vars); free(sql2); ret = itoa(last_insert(), 10); } free_recordset( rSet ); free(sql); o_log(DEBUGM, "Using tagid of %s", ret); return ret; }
extern int doUpdateDocValue (char *kkey, struct simpleLinkedList *vars) { char *sql; int rc = 0; sql = o_printf("UPDATE docs SET %s = ? WHERE docid = ?", kkey); rc = runUpdate_db(sql, vars); free(sql); return rc; }
void conCat(char **mainStr, const char *addStr) { if(addStr && 0 != strcmp(addStr, "")) { char *tmp2; tmp2 = *mainStr; char *tmp; tmp = o_printf("%s%s", tmp2, addStr); free(tmp2); *mainStr = tmp; } }
void xmlAllNodeGetContent(xmlNode *parent, char **str) { xmlNode *node = parent->children; //childs; char *text; while(node != 0) { if (node->type == XML_TEXT_NODE) { text = o_printf("%s ", (char *)xmlNodeGetContent(node)); conCat(str, text); free(text); } xmlAllNodeGetContent(node, str); node = node->next; } }
extern int countDocsWithTag( char *tagid ) { char *sql = o_printf("SELECT COUNT(tagid) ct FROM doc_tags WHERE tagid = '%s'", tagid); int ret = 0; struct simpleLinkedList *rSet = runquery_db(sql); if( rSet ) { ret = atoi(readData_db(rSet, "ct")); } free_recordset( rSet ); free(sql); o_log(DEBUGM, "Tag is being used on %i docs", ret); return ret; }
extern SANE_Status control_option (SANE_Handle handle, const SANE_Option_Descriptor *option, SANE_Int index, SANE_Action action, void *value, int *ret) { SANE_Status status; char *old_value; switch (option->type) { case SANE_TYPE_BOOL: old_value = o_printf (*((SANE_Bool *) value) ? "SANE_TRUE" : "SANE_FALSE"); break; case SANE_TYPE_INT: old_value = o_printf ("%d", *((SANE_Int *) value)); break; case SANE_TYPE_FIXED: old_value = o_printf ("%f", SANE_UNFIX (*((SANE_Fixed *) value))); break; case SANE_TYPE_STRING: old_value = o_printf ("\"%s\"", (char *) value); break; default: old_value = o_strdup ("?"); break; } status = sane_control_option (handle, index, action, value, ret); switch (option->type) { case SANE_TYPE_BOOL: o_log(DEBUGM, "sane_control_option (%d, %s, %s) -> (%s, %s)", index, get_action_string (action), *((SANE_Bool *) value) ? "SANE_TRUE" : "SANE_FALSE", get_status_string (status), old_value); break; case SANE_TYPE_INT: o_log(DEBUGM, "sane_control_option (%d, %s, %d) -> (%s, %s)", index, get_action_string (action), *((SANE_Int *) value), get_status_string (status), old_value); break; case SANE_TYPE_FIXED: o_log(DEBUGM, "sane_control_option (%d, %s, %f) -> (%s, %s)", index, get_action_string (action), SANE_UNFIX (*((SANE_Fixed *) value)), get_status_string (status), old_value); break; case SANE_TYPE_STRING: o_log(DEBUGM, "sane_control_option (%d, %s, \"%s\") -> (%s, %s)", index, get_action_string (action), (char *) value, get_status_string (status), old_value); break; default: break; } free (old_value); if (status != SANE_STATUS_GOOD) o_log(WARNING, "Error setting option %s: %s", option->name, sane_strstatus(status)); return status; }
void *backpopulate_phash_inner( void *u) { pthread_t thread[MAX_THREADS]; pthread_attr_t attr; int thread_pointer = 0; int avail_processors = 1; // We may have 16 processing cors, but only use what we need avail_processors = get_nprocs() - 1; if( avail_processors > MAX_THREADS ) { avail_processors = MAX_THREADS; } // initialise threading pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); for( thread_pointer = 0; thread_pointer < MAX_THREADS; thread_pointer++ ) { pthread_create( &thread[ thread_pointer], &attr, stub, (void *)NULL ); } thread_pointer = 0; // What tasks do we need to do struct simpleLinkedList *rSet; char *sql = o_strdup("SELECT filetype, docid FROM docs WHERE image_phash = 0"); rSet = runquery_db(sql, NULL); if( rSet != NULL ) { do { // Queue up the next task int docid = atoi( readData_db(rSet, "docid") ); char *docfilename; if( ( 0 == strcmp("2", readData_db(rSet, "filetype") ) ) || ( 0 == strcmp("4", readData_db(rSet, "filetype") ) ) ) { docfilename = o_printf("%s/scans/%d_1.jpg", BASE_DIR, docid); } else { docfilename = o_printf("%s/scans/%d_thumb.jpg", BASE_DIR, docid); } // Wait for an available worker while( thread_active[thread_pointer] == 1 ) { thread_pointer++; if( thread_pointer > avail_processors ) { thread_pointer = 0; } usleep(200); } // Wait for it to join back first pthread_join( thread[ thread_pointer ], NULL); // Give instructions to the next worker struct process_phash *data = malloc( sizeof( struct process_phash ) ); data->filename = docfilename; data->docid = docid; data->thread_id = thread_pointer; thread_active[thread_pointer] = 1; pthread_create( &thread[ thread_pointer], &attr, process_doc, (void *)data ); } while ( nextRow( rSet ) ); free_recordset( rSet ); } free(sql); // Wait for everything t ofinish for( thread_pointer = 0; thread_pointer < MAX_THREADS; thread_pointer++ ) { pthread_join( thread[ thread_pointer ], NULL); } // Set the config flag, so we don't try this again. o_log(INFORMATION, "Marking that the backpopulation of pHash is: complete" ); sql = o_strdup("UPDATE config SET config_value = 'complete' WHERE config_option = 'backpopulate_phash'"); runUpdate_db(sql, NULL); free(sql); return NULL; }
extern char *internalGetScannerDetails(char *device, char *lang) { char *answer = NULL; SANE_Status status; char *deviceList = o_strdup("");; int hlp = 0, resolution = 300, minRes=50, maxRes=50, phashAvailable=0; char *resolution_s, *maxRes_s, *minRes_s; SANE_Handle *openDeviceHandle; o_log(DEBUGM, "sane_open of \"%s\"", device); status = sane_open (device, (SANE_Handle)&openDeviceHandle); if(status != SANE_STATUS_GOOD) { o_log(ERROR, "Could not open: '%s' with error: %s", device, sane_strstatus(status)); free(deviceList); return NULL; } // // Find resolution ranges // for (hlp = 0; hlp < 9999; hlp++) { const SANE_Option_Descriptor *sod; sod = sane_get_option_descriptor (openDeviceHandle, hlp); if (sod == NULL) break; // Just a placeholder if (sod->type == SANE_TYPE_GROUP || sod->name == NULL || hlp == 0) continue; if ( 0 == strcmp(sod->name, SANE_NAME_SCAN_RESOLUTION) ) { // Some kind of sliding range if (sod->constraint_type == SANE_CONSTRAINT_RANGE) { o_log(DEBUGM, "Resolution setting detected as 'range'"); // Fixed resolution if (sod->type == SANE_TYPE_FIXED) maxRes = (int)SANE_UNFIX (sod->constraint.range->max); else maxRes = sod->constraint.range->max; } // A fixed list of options else if (sod->constraint_type == SANE_CONSTRAINT_WORD_LIST) { int lastIndex = sod->constraint.word_list[0]; o_log(DEBUGM, "Resolution setting detected as 'word list': lastIndex = %d",lastIndex); // maxRes = sod->constraint.word_list[lastIndex]; // resolution list cannot be treated as low to high ordered list // remark: impl capability to select scan resolution in webInterface int n=0; maxRes = 0; for (n=1; n<=lastIndex; n++ ) { o_log(DEBUGM, "index results %d --> %d", n ,(int)sod->constraint.word_list[n]); if ( maxRes < sod->constraint.word_list[n] ) { maxRes=sod->constraint.word_list[n]; } } } break; // we've found our resolution - no need to search more } } o_log(DEBUGM, "Determined max resultion to be %d", maxRes); // Define a default if(resolution >= maxRes) resolution = maxRes; if(resolution <= minRes) resolution = minRes; o_log(DEBUGM, "sane_cancel"); sane_cancel(openDeviceHandle); o_log(DEBUGM, "sane_close"); sane_close(openDeviceHandle); // // What languages can we OCR for? // char *availableLangs = o_strdup(""); #ifdef CAN_OCR struct simpleLinkedList *languages = getOCRAvailableLanguages(); while (languages != NULL ) { if ( checkOCRLanguage( languages->data ) == 0 ) { o_concatf(&availableLangs, "<lang>%s</lang>", languages->data); } languages = sll_getNext(languages); } sll_destroy( languages ); #endif /* CAN_OCR */ // // Can we give the option of doing 'find simmilar'? // #ifdef CAN_PHASH phashAvailable = 1; #endif /* CAN_PHASH */ // Build Reply // resolution_s = itoa(resolution,10); maxRes_s = itoa(maxRes,10); minRes_s = itoa(minRes,10); o_concatf(&deviceList, "<Resolution><max>%s</max><min>%s</min><default>%s</default></Resolution><OCRLanguages>%s</OCRLanguages><phash>%d</phash>", maxRes_s, minRes_s, resolution_s, availableLangs, phashAvailable); free(maxRes_s); free(minRes_s); free(resolution_s); free(availableLangs); // The escaped string placeholder will be interprited in the sane dispatcher client answer = o_printf("<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerDetails>%s</ScannerDetails></Response>", deviceList); free(deviceList); return answer; }
extern char *internalGetScannerList(char *lang) { char *answer = NULL; SANE_Status status; const SANE_Device **SANE_device_list; int scanOK = SANE_FALSE; char *deviceList; status = sane_get_devices (&SANE_device_list, SANE_TRUE); if(status == SANE_STATUS_GOOD) { if (SANE_device_list && SANE_device_list[0]) { scanOK = SANE_TRUE; o_log(DEBUGM, "device(s) found"); } else { o_log(INFORMATION, "No devices found"); } } else { o_log(WARNING, "Checking for devices failed"); } if(scanOK == SANE_TRUE) { int i = 0; char *replyTemplate; replyTemplate = o_strdup("<Device><vendor>%s</vendor><model>%s</model><type>%s</type><name>%s</name><host>%s</host></Device>"); deviceList = o_strdup(""); for (i=0 ; SANE_device_list[i] ; i++) { char *vendor, *model, *type, *name; char *scannerHost; vendor = o_strdup(SANE_device_list[i]->vendor); model = o_strdup(SANE_device_list[i]->model); type = o_strdup(SANE_device_list[i]->type); name = o_strdup(SANE_device_list[i]->name); propper(vendor); propper(model); propper(type); // Find location of the device if ( name && name == strstr(name, "net:") ) { struct sockaddr_in sa; char *ipandmore, *ip; char host[NI_MAXHOST]; char service[NI_MAXSERV]; int len; // Ignore the 'net:' part ipandmore = name + 4; // Find the length of the address part len = strstr(ipandmore, ":") - ipandmore; // Load 'ip' with the network addres ip = malloc(1+(size_t)len); (void) strncpy(ip,ipandmore,(size_t)len); ip[len] = '\0'; // Convert into an inet address memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr( ip ); // Lookup hostname from address o_log(DEBUGM, "Going to lookup: %s", ip); if ( getnameinfo((struct sockaddr *)&sa, sizeof sa, host, sizeof host, service, sizeof service, NI_NAMEREQD) == 0 ) { o_log(DEBUGM, "found host: %s", host); scannerHost = o_strdup(host); } else { o_log(DEBUGM, "Could not get hostname"); scannerHost = o_strdup(ip); } // Clean up free(ip); } else { scannerHost = o_strdup( getString("LOCAL_opendias_server", lang) ); } // Build Reply // o_concatf(&deviceList, replyTemplate, vendor, model, type, name, scannerHost); free(vendor); free(model); free(type); free(name); free(scannerHost); } free(replyTemplate); if(deviceList) { // The escaped string placeholder will be interprited in the sane dispatcher client answer = o_printf("<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerList%%s><Devices>%s</Devices></ScannerList></Response>", deviceList); free(deviceList); } else { // No devices // The escaped string placeholder will be interprited in the sane dispatcher client answer = o_strdup( "<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerList%s></ScannerList></Response>"); } } else { // sane failed. // The escaped string placeholder will be interprited in the sane dispatcher client answer = o_strdup( "<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerList%s></ScannerList></Response>"); } return answer; }
char *internalDoScanningOperation(char *uuid, char *lang) { int request_resolution = 0; int docid; int current_page = 0; int total_requested_pages; double totbytes = 0; SANE_Status status; SANE_Handle *openDeviceHandle; SANE_Byte *raw_image; SANE_Parameters pars; char *docid_s; char *total_requested_pages_s; char *devName; char *outFilename; char *raw_image_format; char *header; o_log(DEBUGM, "doScanningOperation: sane initialized uuid(%s)",(char *)uuid); updateScanProgress(uuid, SCAN_WAITING_ON_SCANNER, 0); // Open the device devName = getScanParam(uuid, SCAN_PARAM_DEVNAME); o_log(DEBUGM, "sane_open of \"%s\"",devName); status = sane_open ((SANE_String_Const) devName, (SANE_Handle)&openDeviceHandle); if(status != SANE_STATUS_GOOD) { handleSaneErrors("Cannot open device ", devName, status, 0); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); free(devName); return 0; } free(devName); /* ========================================================== */ if ( ! setOptions( (char *)uuid, openDeviceHandle, &request_resolution ) ) return 0; o_log(DEBUGM, "sane_start: setOptions returned request_resolution %d\n",request_resolution); int timeout = 5; while( 0 < timeout ) { status = sane_start (openDeviceHandle); if(status == SANE_STATUS_GOOD) { break; } else { if(status == SANE_STATUS_DEVICE_BUSY ) { // BUSY signal could be the scanner just having a // bit of lag - specially network connected devices timeout--; if ( timeout == 0 ) { handleSaneErrors("Cannot start scanning", "even after trying several time", status, 0); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); return 0; } else { o_log(WARNING, "Device reports not ready to 'start', waiting 500ms. Will try another %d times", timeout); usleep(500 * 1000); // 500ms or 0.5sec } } else { handleSaneErrors("Cannot start scanning", "", status, 0); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); return 0; } } } // Get scanning params (from the scanner) if( request_resolution == 0 ) { o_log(DEBUGM, "Resolution did not get set in scanner setup."); updateScanProgress(uuid, SCAN_INTERNAL_ERROR, 10004); return 0; } o_log(DEBUGM, "Get scanning params"); status = sane_get_parameters (openDeviceHandle, &pars); o_log(INFORMATION, "Scanner Parm : stat=%s form=%d,lf=%d,bpl=%d,pixpl=%d,lin=%d,dep=%d", sane_strstatus (status), pars.format, pars.last_frame, pars.bytes_per_line, pars.pixels_per_line, pars.lines, pars.depth); switch (pars.format) { case SANE_FRAME_GRAY: o_log(DEBUGM, "Expecting Gray data (1 channel only)."); raw_image_format = o_strdup( "P5" ); break; case SANE_FRAME_RGB: o_log(DEBUGM, "Expecting RGB data (3 channels)."); raw_image_format = o_strdup( "P6" ); break; default: o_log(DEBUGM, "backend returns three frames speratly. We do not currently support this."); updateScanProgress(uuid, SCAN_INTERNAL_ERROR, 10003); return 0; break; } header = o_printf ("%s\n# SANE data follows\n%d %d\n%d\n", raw_image_format, pars.pixels_per_line, pars.lines, (pars.depth <= 8) ? 255 : 65535); free( raw_image_format ); // Save Record // docid_s = getScanParam(uuid, SCAN_PARAM_DOCID); total_requested_pages_s = getScanParam(uuid, SCAN_PARAM_REQUESTED_PAGES); total_requested_pages = atoi(total_requested_pages_s); free(total_requested_pages_s); if( docid_s == NULL ) { o_log(DEBUGM, "Saving record"); updateScanProgress(uuid, SCAN_DB_WORKING, 0); docid_s = addNewScannedDoc(pars.lines, pars.pixels_per_line, request_resolution, total_requested_pages); setScanParam(uuid, SCAN_PARAM_DOCID, docid_s); setScanParam(uuid, SCAN_PARAM_ON_PAGE, "1"); current_page = 1; } else { char *current_page_s = getScanParam(uuid, SCAN_PARAM_ON_PAGE); current_page = atoi(current_page_s); free(current_page_s); current_page++; current_page_s = itoa(current_page, 10); setScanParam(uuid, SCAN_PARAM_ON_PAGE, current_page_s); free(current_page_s); } docid = atoi(docid_s); free(docid_s); totbytes = (double)((pars.bytes_per_line * pars.lines)); /* ========================================================== */ raw_image = collectData( (char *)uuid, openDeviceHandle, totbytes, pars.bytes_per_line, header ); o_log(INFORMATION, "Scanning done."); o_log(DEBUGM, "sane_cancel"); sane_cancel(openDeviceHandle); o_log(DEBUGM, "sane_close"); sane_close(openDeviceHandle); // Convert Raw into JPEG // updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 0); PIX *pix; if ( ( pix = pixReadMem( raw_image, (pars.bytes_per_line*pars.lines)+strlen(header) ) ) == NULL) { o_log(ERROR, "Could not load the image data into a PIX"); } updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 55); o_log(INFORMATION, "Convertion process: Loaded (depth: %d)", pixGetDepth(pix)); free(raw_image); free(header); outFilename = o_printf("%s/scans/%d_%d.jpg", BASE_DIR, docid, current_page); pixWrite(outFilename, pix, IFF_JFIF_JPEG); free(outFilename); updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 100); o_log(INFORMATION, "Conversion process: Complete"); // Do OCR - on this page // - OCR libs just wants the raw data and not the image header ocrImage( uuid, docid, current_page, request_resolution, pix, lang ); #ifdef CAN_PHASH // Calulate the pHash, so we can compare images later if( current_page == 1 ) { updateScanProgress(uuid, SCAN_CALULATING_PHASH, 0); unsigned long long hash = getImagePhash_px( pix ); savePhash( docid, hash ); } #endif /* CAN_PHASH */ pixDestroy( &pix ); // cleaup && What should we do next // o_log(DEBUGM, "mostly done."); if(current_page >= total_requested_pages) updateScanProgress(uuid, SCAN_FINISHED, docid); else updateScanProgress(uuid, SCAN_WAITING_ON_NEW_PAGE, ++current_page); o_log(DEBUGM, "Page scan done."); return o_strdup("OK"); }
void i_o_log(const char *file, const int line, const int verbosity, const char *message, va_list inargs) { FILE *fp; char *logFile; va_list ap; va_copy(ap,inargs); if( trigger_log_verbosity( verbosity ) ) { char *thumb; if( VERBOSITY >= DEBUGM ) { thumb = o_strdup("%s:%X:%s:%s:%d "); } else { thumb = o_strdup("%s:%X:%s "); } char *ltime = getTimeStr(); char *vb; if(verbosity == 1) { vb = o_strdup("ERR"); } else if(verbosity == 2) { vb = o_strdup("WRN"); } else if(verbosity == 3) { vb = o_strdup("INF"); } else if(verbosity == 4) { vb = o_strdup("DBG"); } else if(verbosity == 5) { vb = o_strdup("SQL"); } else vb = o_strdup("---"); if( message == strstr(message,"|") ) { vprintf((char *)message+1,inargs); printf("\n"); //need to reset inargs to saved ap. reason vprintf function do not do so. va_end(inargs); va_copy(inargs,ap); } // Output to file if( LOG_DIR ) { logFile = o_printf("%s/opendias.log", LOG_DIR); } else { logFile = o_printf("%s/log/opendias/opendias.log", VAR_DIR); } if((fp = fopen(logFile, "a"))==NULL) { fprintf(stderr,"Cannot open log file %s.\n",logFile); exit(1); } // if the apps debug level at DEBUGM or TRACE, then include // __FILE__ and __LINE__ detail in the log entry. if( VERBOSITY >= DEBUGM ) { fprintf(fp,thumb,ltime,pthread_self(),vb,file,line); } else { fprintf(fp,thumb,ltime,pthread_self(),vb); } vfprintf(fp,message,inargs); fprintf(fp,"\n"); fclose(fp); free(logFile); free(ltime); free(thumb); free(vb); } }
int setup (char *configFile) { struct simpleLinkedList *rSet; char *location, *conf, *sql; printf("entering setup\n"); // Defaults VERBOSITY = DEBUGM; LOG_DIR = o_printf("%s/log/opendias", VAR_DIR); // Get 'DB' location if (configFile != NULL) { conf = o_strdup(configFile); } else { conf = o_printf("%s/opendias/opendias.conf", ETC_DIR); if( 0 != access(conf, F_OK) ) { o_log(INFORMATION, "Config not in GNU location: %s. Attempting system config dir /etc/opendias/opendias.conf", conf); free(conf); conf = o_strdup("/etc/opendias/opendias.conf"); } } o_log(INFORMATION, "|Using config file: %s", conf); if( 0 == load_file_to_memory(conf, &location) ) { o_log(ERROR, "|Cannot find main config file: %s", conf); free(location); free(conf); return 1; } free(conf); chop(location); BASE_DIR = o_strdup(location); o_log(INFORMATION, "|Which says the database is at: %s", BASE_DIR); // Open (& maybe update) the database. if(connect_db (1)) { // 1 = create if required free(BASE_DIR); free(location); return 1; } free(location); o_log(INFORMATION, "|Current config is: "); sql = o_strdup("SELECT config_option, config_value FROM config"); rSet = runquery_db(sql, NULL); if( rSet != NULL ) { do { char *config_option, *config_value; config_option = o_strdup(readData_db(rSet, "config_option")); config_value = o_strdup(readData_db(rSet, "config_value")); if ( config_option == NULL || config_value == NULL ) { printf("either option or value is NULL\n"); } else { //o_log(INFORMATION, " %s = %s", config_option, config_value); //remark: the pipe in the message causes o_log i_o_log to crash // caused by debug.c i_o_log by double use of vprintf o_log(INFORMATION, "| %s = %s", config_option, config_value); } if( 0 == strcmp(config_option, "log_verbosity") ) { VERBOSITY = atoi(config_value); } free(config_option); free(config_value); } while ( nextRow( rSet ) ); } free_recordset( rSet ); free(sql); return 0; }
char *uploadfile(char *filename, char *lookForSimilar, char *lang) { #ifndef CAN_MAGIC o_log(ERROR, "Unable to determin the file type, aborting."); return NULL; #else int width = 0, height = 0, itype = PLACE_HOLDER; char *final_filename, *ocrText = NULL, *tmp; #ifdef CAN_PDF char *thumbext = NULL; #else #ifdef CAN_READODF char *thumbext = NULL; #endif /* CAN_READODF */ #endif /* CAN_PDF */ char *docid; char *ftype; char *datafile; char *thumbfile = NULL; PIX *pix; datafile = o_printf("/tmp/%s.dat", filename); magic_t cookie = magic_open(MAGIC_MIME_TYPE); magic_load( cookie, NULL ); const char *t = magic_file( cookie, datafile ); ftype = o_strdup( t ); o_log( ERROR, "Uploaded file looks to be of type: %s", ftype ); magic_close( cookie ); // -------------------------------------- if( 0 == strcmp("application/pdf", ftype) ) { itype = PDF_FILETYPE; #ifdef CAN_PDF thumbfile = o_printf("/tmp/%s.thumb", filename); ocrText = parse_pdf( datafile, thumbfile ); // pdf_plug.cc [create thumbnail and return body text] thumbext = o_strdup("jpg"); #endif /* CAN_PDF */ o_log( INFORMATION, "Processed PDF"); } // -------------------------------------- else if( 0 == strcmp("application/vnd.oasis.opendocument.text", ftype) ) { itype = ODF_FILETYPE; #ifdef CAN_READODF thumbfile = o_printf("/tmp/%s.thumb", filename); get_odf_Thumb( datafile, thumbfile ); ocrText = get_odf_Text( datafile ); // odf_plug.c thumbext = o_strdup("png"); #endif /* CAN_READODF */ o_log( INFORMATION, "Processed ODF doc"); } // -------------------------------------- else if( 0 == strcmp("image/jpeg", ftype) ) { itype = JPG_FILETYPE; #ifdef CAN_OCR PIX *pix_l; if ( ( pix_l = pixRead( datafile ) ) == NULL) { o_log(ERROR, "Could not load the image data into a PIX"); return NULL; } int depth; pixGetDimensions( pix_l, &width, &height, &depth ); o_log(INFORMATION, "Convertion process: Loaded (depth: %d)", depth ); pix = pixScaleRGBToGrayFast( pix_l, 1, COLOR_GREEN ); pixDestroy( &pix_l ); if (pix == NULL ) { o_log(ERROR,"Conversion process failed pixScaleRGBToGrayFast! skip ocr"); } else { o_log(INFORMATION, "Convertion process: Reduced depth to %d", pixGetDepth(pix)); ocrText = getTextFromImage(pix, 0, "eng"); } #endif /* CAN_OCR */ o_log( INFORMATION, "Processed JPG doc"); } // -------------------------------------- else { free( ftype ); free( datafile ); o_log(ERROR, "unknown file type."); return NULL; } free( ftype ); // Set a default OCR text string if( ocrText == NULL ) { ocrText = o_strdup( getString("LOCAL_ocr_default_text", lang ) ); } // Save the record to the DB o_log(DEBUGM, "Saving doc import record"); docid = addNewFileDoc(itype, width, height, ocrText); // ocrText get freed in this method // Move the main datafile to the file store location final_filename = o_printf("%s/scans/%s", BASE_DIR, docid); // none image imported docs, are stored with no "_x" postfix. if( itype == JPG_FILETYPE ) { conCat(&final_filename, "_1"); } addFileExt(&final_filename, itype); fcopy(datafile, final_filename); o_log( DEBUGM, "Moved data file"); // The original file will be unlinked by the HTTPD process free(datafile); // Move any thumbnail image to the file store location if( thumbfile ) { free(final_filename); // This currently holds the main PDG or ODF file. final_filename = o_printf("%s/scans/%s_thumb.%s", BASE_DIR, docid, thumbext); // any thumbnails are postfixed with "_thumb" fcopy(thumbfile, final_filename); o_log( DEBUGM, "Moved thumbnail file"); unlink(thumbfile); free(thumbfile); free(thumbext); #ifdef CAN_PHASH o_log( DEBUGM, "About to perform pHash on file"); unsigned long long hash = getImagePhash_fn( final_filename ); savePhash( atoi(docid), hash ); #endif /* CAN_PHASH */ } else { #ifdef CAN_PHASH o_log( DEBUGM, "About to perform pHash on pix"); unsigned long long hash = getImagePhash_px( pix ); savePhash( atoi(docid), hash ); #endif /* CAN_PHASH */ pixDestroy( &pix ); } free(final_filename); // Should we look for a similar doc, on opening? char *findSim = ""; #ifdef CAN_PHASH if( lookForSimilar != (void *)NULL ) { findSim = "&findSimilar=1"; } #endif /* CAN_PHASH */ // Open the document for editing. tmp = o_printf("<html><HEAD><META HTTP-EQUIV=\"refresh\" CONTENT=\"0;URL=/opendias/docDetail.html?docid=%s%s\"></HEAD><body></body></html>", docid, findSim); free(docid); return tmp; #endif /* CAN_MAGIC */ }