Beispiel #1
0
/*--------------------------------------------------------------------------------*/
bool PostgresDatabase::TableExists(const AString& name)
{
	SQLQuery *query = NULL;

	if ((query = RunQuery(AString("select count(*) from %").Arg(name))) != NULL) {
		bool success = query->GetResult();
		delete query;
		return success;
	}

	return false;
}
Beispiel #2
0
	~SQLConn()
	{
		SQLerror err(SQL_BAD_DBID);
		if (qinprog.c)
		{
			qinprog.c->OnError(err);
			delete qinprog.c;
		}
		for(std::deque<QueueItem>::iterator i = queue.begin(); i != queue.end(); i++)
		{
			SQLQuery* q = i->c;
			q->OnError(err);
			delete q;
		}
	}
Beispiel #3
0
Dbaudiofile::Dbaudiofile(int id)
  : artist(""), album(""), title(""),
    year(0), bitrate(0), length(0), rating(0), track(0), playlist_id(-1)
{
  db_id = id;

  GraphicalAudio *ga = get_class<GraphicalAudio>(dgettext("mms-audio", "Audio"));

  ga->db_mutex.enterMutex();

  SQLQuery *q = ga->db.query("Folders", ("SELECT filename, is_folder FROM %t WHERE id='" + conv::itos(id) + "'").c_str());
  if (q && q->numberOfTuples() > 0) {
    path = (*q)[0]["filename"];
    if ((*q)[0]["is_folder"] == "0")
      get_info_from_db(path, ga);
  } else
    assert(false);

  ga->db_mutex.leaveMutex();
}
Beispiel #4
0
/*--------------------------------------------------------------------------------*/
bool PostgresDatabase::CreateTable(const AString& name, const AString& columns)
{
	AString sql;
	SQLQuery *query = NULL;
	uint_t i, n = columns.CountColumns();

	sql.printf("create table %s (", name.str());
	for (i = 0; i < n; i++) {
		AString column = columns.Column(i);
		if (i > 0) sql.printf(", ");
		sql.printf("%s %s", column.Word(0).str(), GetColumnType(column).str());
	}
	sql.printf(")");

	if ((query = RunQuery(sql)) != NULL) {
		bool success = query->GetResult();
		delete query;
		return success;
	}

	return false;
}
Beispiel #5
0
int
main(int argc, char* argv[])
{
  Collectors = NULL;

  HistorySnapshot *historySnapshot;
  SQLQuery queryhor;
  SQLQuery queryver;
  QuillErrCode st;

  void **parameters;
  char *dbconn=NULL;
  bool readfromfile = false,remotequill=false;

  char *dbIpAddr=NULL, *dbName=NULL,*queryPassword=NULL,*quillName=NULL;

  AttrList *ad=0;

  int flag = 1;

  MyString tmp;

  int i;
  parameters = (void **) malloc(NUM_PARAMETERS * sizeof(void *));
  myDistro->Init( argc, argv );

  queryhor.setQuery(HISTORY_ALL_HOR, NULL);
  queryver.setQuery(HISTORY_ALL_VER, NULL);

  longformat=TRUE;   
  for(i=1; i<argc; i++) {
    if(strcmp(argv[i], "-name")==0) {
		i++;
		if (argc <= i) {
			fprintf( stderr,
					 "Error: Argument -name requires the name of a quilld as a parameter\n" );
			exit(1);
		}
		
		if( !(quillName = get_daemon_name(argv[i])) ) {
			fprintf( stderr, "Error: unknown host %s\n",
					 get_host_part(argv[i]) );
			printf("\n");
			print_wrapped_text("Extra Info: The name given with the -name "
							   "should be the name of a condor_quilld process. "
							   "Normally it is either a hostname, or "
							   "\"name@hostname\". "
							   "In either case, the hostname should be the "
							   "Internet host name, but it appears that it "
							   "wasn't.",
							   stderr);
			exit(1);
		}
		tmp.sprintf ("%s == \"%s\"", ATTR_NAME, quillName);      		
		quillQuery.addORConstraint (tmp.Value());

                tmp.sprintf ("%s == \"%s\"", ATTR_SCHEDD_NAME, quillName);
                quillQuery.addORConstraint (tmp.Value());

		remotequill = true;
		readfromfile = false;
    }
    else if (strcmp(argv[i],"-help")==0) {
		Usage(argv[0],0);
    }
  }
  if (i<argc) Usage(argv[0]);
  
  config();
  
	/* This call must happen AFTER config() is called */
  if (checkDBconfig() == true && !readfromfile) {
  	readfromfile = false;
  } else {
		  /* couldn't get DB configuration, so bail out */
    printf("Error: Cannot use DB to get history information\n");
  	exit(1);
  }

  if(readfromfile == false) {
	  if(remotequill) {
		  if (Collectors == NULL) {
			  Collectors = CollectorList::create();
			  if(Collectors == NULL ) {
				  printf("Error: Unable to get list of known collectors\n");
				  exit(1);
			  }
		  }
		  result = Collectors->query ( quillQuery, quillList );
		  if(result != Q_OK) {
			  printf("Fatal Error querying collectors\n");
			  exit(1);
		  }

		  if(quillList.MyLength() == 0) {
			  printf("Error: Unknown quill server %s\n", quillName);
			  exit(1);
		  }
		  
		  quillList.Open();
		  while ((ad = quillList.Next())) {
				  // get the address of the database
			  dbIpAddr = dbName = queryPassword = NULL;
			  if (!ad->LookupString(ATTR_QUILL_DB_IP_ADDR, &dbIpAddr) ||
				  !ad->LookupString(ATTR_QUILL_DB_NAME, &dbName) ||
				  !ad->LookupString(ATTR_QUILL_DB_QUERY_PASSWORD, &queryPassword) || 
				  (ad->LookupBool(ATTR_QUILL_IS_REMOTELY_QUERYABLE,flag) && !flag)) {
				  printf("Error: The quill daemon \"%s\" is not set up "
						 "for database queries\n", 
						 quillName);
				  exit(1);
			  }
		  }
	  }
	  dbconn = getDBConnStr(quillName,dbIpAddr,dbName,queryPassword);
	  historySnapshot = new HistorySnapshot(dbconn);
		  //printf ("\n\n-- Quill: %s : %s : %s\n", quillName, dbIpAddr, dbName);
	  
	  st = historySnapshot->sendQuery(&queryhor, &queryver, longformat, true);
		  //if there's a failure here and if we're not posing a query on a 
		  //remote quill daemon, we should instead query the local file
	  if(st == QUILL_FAILURE) {
		  printf( "-- Database at %s not reachable\n", dbIpAddr);
	  }
		  // query history table
	  if (historySnapshot->isHistoryEmpty()) {
		  printf("No historical jobs in the database\n");
	  }
	  historySnapshot->release();
	  delete(historySnapshot);
  }
  
  
  if(parameters) free(parameters);
  if(dbIpAddr) free(dbIpAddr);
  if(dbName) free(dbName);
  if(queryPassword) free(queryPassword);
  if(quillName) free(quillName);
  if(dbconn) free(dbconn);
  return 0;
}
Beispiel #6
0
void Dbaudiofile::get_info_from_db(const string& path, GraphicalAudio *ga)
{
  SQLQuery *q = ga->db.query("Audio", ("SELECT * FROM %t WHERE filename='" + string_format::escape_db_string(path) + "'").c_str());
  if (q && q->numberOfTuples() > 0) {

    SQLRow &row = (*q)[0];

    title = row["Title"];
    bitrate = conv::atoi(row["Bitrate"]);
    length = conv::atoi(row["Length"]);
    track= conv::atoi(row["Track"]);

    SQLQuery *q2 = ga->db.query("Artist", ("SELECT name FROM %t WHERE id='" + row["Artist"] + "'").c_str());
    if (q2 && q2->numberOfTuples() > 0) {
      SQLRow &c_row = (*q2)[0];
      artist = c_row["name"];
    }
    delete q2;

    q2 = ga->db.query("Album", ("SELECT name FROM %t WHERE id='" + row["Album"] + "'").c_str());
    if (q2 && q2->numberOfTuples() > 0) {
      SQLRow &c_row = (*q2)[0];
      album = c_row["name"];
    }
    delete q2;

  } else {

    FileRef fileref(path.c_str(), true, AudioProperties::Accurate);

    if (!fileref.isNull() && fileref.tag()) {
      artist = fileref.tag()->artist().toCString(true);
      title = fileref.tag()->title().toCString(true);
      album = fileref.tag()->album().toCString(true);
      year = fileref.tag()->year();
      track = fileref.tag()->track();
    }

    if (!fileref.isNull() && fileref.audioProperties()) {
      length = fileref.audioProperties()->length();
      bitrate = fileref.audioProperties()->bitrate();
    }

    int artist_id = 0;

    SQLQuery *q2 = ga->db.query("Artist", ("SELECT id FROM %t WHERE name='" + string_format::escape_db_string(artist) + "'").c_str());
    if (q2 && q2->numberOfTuples() > 0) {
      SQLRow &row = (*q2)[0];
      artist_id = conv::atoi(row["id"]);
    }
    delete q2;

    if (artist_id == 0) {
      char *tmp = sqlite3_mprintf("INSERT INTO Artist VALUES(NULL, '%q', '%q')", artist.c_str(), string_format::lowercase(artist).c_str());
      ga->db.execute(tmp);
      sqlite3_free(tmp);

      q2 = ga->db.query("Artist", ("SELECT id FROM %t WHERE name='" + string_format::escape_db_string(artist) + "'").c_str());
      if (q2 && q2->numberOfTuples() > 0) {
	SQLRow &row = (*q2)[0];
	artist_id = conv::atoi(row["id"]);
      }
      delete q2;
    }

    int album_id = 0;

    q2 = ga->db.query("Album", ("SELECT id FROM %t WHERE name='" + string_format::escape_db_string(album) + "'").c_str());
    if (q2 && q2->numberOfTuples() > 0) {
      SQLRow &row = (*q2)[0];
      album_id = conv::atoi(row["id"]);
    }
    delete q2;

    if (album_id == 0) {
      char *tmp = sqlite3_mprintf("INSERT INTO Album VALUES(NULL, '%q', '%q')", album.c_str(), string_format::lowercase(album).c_str());
      ga->db.execute(tmp);
      sqlite3_free(tmp);

      q2 = ga->db.query("Album", ("SELECT id FROM %t WHERE name='" + string_format::escape_db_string(album) + "'").c_str());
      if (q2 && q2->numberOfTuples() > 0) {
	SQLRow &row = (*q2)[0];
	album_id = conv::atoi(row["id"]);
      }
      delete q2;
    }

    char *tmp = sqlite3_mprintf("INSERT INTO Audio VALUES(NULL, '%q', '%q', '%q', '%q', '%q', '%q', '%q', '%q')",
				conv::itos(artist_id).c_str(), conv::itos(album_id).c_str(),
				title.c_str(), string_format::lowercase(title).c_str(), path.c_str(),
				conv::ftos(bitrate).c_str(), conv::itos(length).c_str(),
				conv::itos(track).c_str());
    ga->db.execute(tmp);
    sqlite3_free(tmp);
  }

  delete q;

  fetched = true;

#ifdef use_imms
  rating = ga->imms->get_rating(path);
#endif
}
/**
 * if the connection is bad, disconnect
 * 
 * if the connection is established,
 *  call PQconsumeInput
 *  if PGisBusy returns != 0, a query is done, and we can process it
 *  while PQgetResult returns != NULL,
 *   we retrieve data and add it to our result
 *   we recognize bytea data by oid, and unescape it
 *   once this is done, we call the callback for the result
 *   while the callback is running
 *    we have to lock the connection, 
 *    to make sure the callback does not add a query 
 *    which could interfere with the current query.
 *   once the callback is done, check if there are queries to be sent, 
 *   if so, sent them
 *    
 * 
 * 
 * if the connection is pending,
 *  check if the previous call to PQconnectPoll
 *  told us we want to recv data, if so, call PQconnectPoll
 *  else, there is something wrong with the connection (connection refused)
 *  and we call PQconnectPoll and check for a dead connection.
 * 
 * @return 
 */
int32_t SQLHandlerPostgres::doRecv()
{
	logPF();

	switch ( PQstatus(m_PGConnection) )
	{
	case CONNECTION_BAD:
		disconnected();
		break;

	case CONNECTION_OK:
		{

			if ( PQconsumeInput(m_PGConnection) != 1 )
			{
				logInfo("PQcomsumeInput() failed %s\n",PQerrorMessage(m_PGConnection));
				disconnected();
				return 1;
			}

			if ( PQisBusy(m_PGConnection) != 0 )
				return 1;

			if ( PQstatus(m_PGConnection) == CONNECTION_BAD )
			{
				logInfo("PQstatus() says BAD %s\n",PQerrorMessage(m_PGConnection));
				disconnected();
				return 1;
			}

			if ( m_Queries.size() == 0 )
			{
//				logCrit("Why did I end up here %s:%i?\n status %i \n message %s? \n",__FILE__,__LINE__, PQstatus(m_PGConnection),PQerrorMessage(m_PGConnection));
				return 1;
			}

			PGresult   *res=NULL;
			PGSQLResult *sqlresult = NULL;
			SQLQuery *sqlquery = m_Queries.front();
			m_Queries.pop_front();

//	int foo = rand()%1024;

			vector< map<string,string> >        result;
			bool broken_query=false;

			while ( (res = PQgetResult(m_PGConnection)) != NULL )
			{
//		logCrit("README %i %x %x\n",foo,res,sqlquery);
				switch ( PQresultStatus(res) )
				{
				
				case PGRES_COMMAND_OK:
					break;

				case PGRES_TUPLES_OK:
					if ( sqlquery->getCallback() != NULL )
					{
						int i,j;
						for ( j = 0;  j < PQntuples(res); j++ )
						{
							map<string,string> foo;
							string bar;
							string baz;

							for ( i=0;i<PQnfields(res);i++ )
							{
								switch ( PQftype(res,i) )
								{
								case 17: // BYTEAOID
									bar = PQgetvalue(res, j, i);
									baz = unescapeBinary(&bar);
									foo[PQfname(res,i)] = string(baz.data(),baz.size());
									break;

								default:
									foo[PQfname(res,i)] = PQgetvalue(res, j, i);
								}
							}
							result.push_back(foo);
						}
					}
					break;

				default:
					logCrit("Query failure. Query'%s' Error '%s' ('%s')\n",
							sqlquery->getQuery().c_str(),
							PQresStatus(PQresultStatus(res)),
							PQresultErrorMessage(res));
					broken_query = true;
				}

				PQclear(res);

			}
			if ( sqlquery->getCallback() != NULL )
			{
				m_LockSend = true;

				sqlresult = new PGSQLResult(&result,sqlquery->getQuery(),sqlquery->getObject());
				if ( broken_query == true )
				{
					sqlquery->getCallback()->sqlFailure(sqlresult);
				}
				else
				{
					sqlquery->getCallback()->sqlSuccess(sqlresult);
				}

				delete sqlresult;
				m_LockSend = false;

			}

			delete sqlquery;



			if ( m_Queries.size() > 0 )
			{
				logInfo("sending query %s\n",m_Queries.front()->getQuery().c_str());
				int ret = PQsendQuery(m_PGConnection, m_Queries.front()->getQuery().c_str());
				if ( ret != 1 )
					logCrit("ERROR %i %s\n",ret,PQerrorMessage(m_PGConnection));
			}
		}
		break;

	default:
		if (m_PollingStatusType == PGRES_POLLING_READING)
		{
        		m_PollingStatusType = PQconnectPoll(m_PGConnection);
				if (PQstatus(m_PGConnection) == CONNECTION_OK)
					connected();
				else 
				if (PQstatus(m_PGConnection) == CONNECTION_BAD)
					logCrit("ERROR %s\n",PQerrorMessage(m_PGConnection));

		}else
		{
			m_PollingStatusType = PQconnectPoll(m_PGConnection);
			if (PQstatus(m_PGConnection) == CONNECTION_BAD)
			{
				logCrit("ERROR %s\n",PQerrorMessage(m_PGConnection));
			}
		}
	}

	m_LastAction = time(NULL);
	return 1;
}
Beispiel #8
0
SQLQuery::SQLQuery(const SQLQuery &q) {
    *this << q.str();
    Success = q.Success;
    def = q.def;
}
Beispiel #9
0
bool CUPnPSearch::prepareSQL()
{
	if(m_query.length() > 0 && m_queryCount.length() > 0) {
		return true;
	}

  string sOpenBr;
	string sProp;
	string sOp;
	string sVal;
	string sCloseBr;
	string sLogOp;
  string sPrevLog;
	bool   bNumericProp = false;
	bool   bLikeOp  = false;
  bool   bBuildOK = false;
  bool   bVirtualSearch = false;
  bool   bFirst = true;
  
  stringstream sSql;
  SQLQuery qry;
  
  string sDevice = virtualFolderLayout();
  bVirtualSearch = !sDevice.empty();

  stringstream tmp;
  
  unsigned int nContainerId = GetObjectIDAsUInt(); //GetContainerIdAsUInt();
  if(nContainerId > 0) {
    
    if(m_sParentIds.length() == 0) {
      stringstream sIds;
      sIds << nContainerId;    
      BuildParentIdList(&qry, sIds.str(), sDevice, &m_sParentIds);      
      m_sParentIds = m_sParentIds + sIds.str();      
      //cout << "PARENT ID LIST: " << m_sParentIds << endl; fflush(stdout);
    }
  }
  
  
	m_query = qry.build(SQL_SEARCH_PART_SELECT_FIELDS, 0, sDevice); //"select * ";
	m_queryCount  = qry.build(SQL_SEARCH_PART_SELECT_COUNT, 0, sDevice); //"select count(*) as COUNT ";


  
  /*sSql <<
    "from " <<
    "  MAP_OBJECTS m, OBJECTS o " <<
    "  left join OBJECT_DETAILS d on (d.ID = o.DETAIL_ID) " <<
    "where " <<
    "  o.DEVICE " << sDevice << " and " <<
    "  m.DEVICE " << sDevice << " and " <<
    "  o.OBJECT_ID = m.OBJECT_ID "; */


  sSql << qry.build(SQL_SEARCH_PART_FROM, 0, sDevice);
  
  if(m_sParentIds.length() > 0) {
    sSql << " and " <<
      "  PARENT_ID in (" << m_sParentIds << ") ";        
  }
  
	m_sSearchCriteria = StringReplace(m_sSearchCriteria, "&quot;", "\"");
  m_sSearchCriteria = StringReplace(m_sSearchCriteria, "@", ":");


  RegEx rxSearch("(\\(*) *([\\w+:*\\w*]+) ([=|!=|<|<=|>|>=|contains|doesNotContain|derivedfrom|exists]+) (\".*?[^\\\\]\"|true|false) *(\\)*) *([and|or]*)");
	if(rxSearch.Search(m_sSearchCriteria.c_str())) {
	  do {
		  //cout <<  rxSearch.Match(1) << " X " << rxSearch.Match(2) << " X " << rxSearch.Match(3) << " X " << rxSearch.Match(4) << " X " << rxSearch.Match(5) << " X " << rxSearch.Match(6) << endl;
		
		  sOpenBr  = rxSearch.Match(1);
			sProp    = rxSearch.Match(2);
		  sOp      = rxSearch.Match(3);
			sVal     = rxSearch.Match(4);
			sCloseBr = rxSearch.Match(5);
			sLogOp   = rxSearch.Match(6);
			
			if(sOp.compare("exists") == 0) {
				bBuildOK = false;

				if(sProp.compare(":refID") == 0) {
					bBuildOK = true;

					sProp = "REF_ID";
						
					if(sVal.compare("true") == 0)
					  sOp = ">";
				  else if (sVal.compare("false") == 0)
						sOp = "=";
				
					sVal = "0";
				}
        
			}
			else {
				
				bBuildOK = true;
				
				// replace property
				if(sProp.compare("upnp:class") == 0) {
				  sProp = "TYPE";
					bNumericProp = true;
				}
				else if(sProp.compare("dc:title") == 0) {
				  sProp = "TITLE";
					bNumericProp = false;
				}
        else if(sProp.compare("upnp:artist") == 0) {
				  sProp = "AV_ARTIST";
					bNumericProp = false;
				}
				else if(sProp.compare("upnp:genre") == 0) {
				  sProp = "AV_GENRE";
					bNumericProp = false;
				}
				else if(sProp.compare("upnp:album") == 0) {
				  sProp = "AV_ALBUM";
					bNumericProp = false;
				}
        else if(sProp.compare("res:protocolInfo") == 0) {
				  sPrevLog = sLogOp;
					continue;
				}
				else {
				  bBuildOK = false;
				}
				
				
				// replace operator
				bLikeOp = false;
				if(sOp.compare("contains") == 0) {
				  if(bNumericProp)
					  sOp = "in";
					else
					  sOp = "like";
						
					bLikeOp = true;
				}
				else if(sOp.compare("derivedfrom") == 0) {
				  sOp = "in";
				}
        else if(sOp.compare("=") == 0) {          
        }
				else {
				  bBuildOK = false;
				}

				// trim value
				//cout << "Val: " << sVal << " => ";
			  sVal = sVal.substr(1, sVal.length() - 2);
				//cout << sVal << endl;
				
				// replace value
				if(sProp.compare("TYPE") == 0) { 
          sOp = "in";

          tmp.str("");

				  if(sVal.compare("object.item") == 0) {
						sOp = ">=";
            tmp << ITEM;
					}
					else if(sVal.compare("object.item.imageItem") == 0) {
            sOp = "between";
					  tmp << ITEM_IMAGE_ITEM << " and " << (ITEM_IMAGE_ITEM_MAX - 1); //sVal = "(110, 111)";
          }
					else if(sVal.compare("object.item.audioItem") == 0) {
            sOp = "between";
					  tmp << ITEM_AUDIO_ITEM << " and " << (ITEM_AUDIO_ITEM_MAX - 1); //sVal = "(120, 121, 122)";	
          }
					else if(sVal.compare("object.item.videoItem") == 0){
            sOp = "between";
					  tmp << ITEM_VIDEO_ITEM << " and " << (ITEM_VIDEO_ITEM_MAX - 1); //sVal = "(130, 131, 132, 133)";
          }
					else if(sVal.compare("object.container.person.musicArtist") == 0) {
            sOp = "=";
					  tmp << CONTAINER_PERSON_MUSIC_ARTIST; //sVal = "(11)";
          }
					else if(sVal.compare("object.container.album.musicAlbum") == 0) {
            sOp = "=";
					  tmp << CONTAINER_ALBUM_MUSIC_ALBUM; //sVal = "(31)";
          }          
          else if(sVal.compare("object.container.genre.musicGenre") == 0) {
            sOp = "=";
					  tmp << CONTAINER_GENRE_MUSIC_GENRE; //sVal = "(41)";
          }
          else if(sVal.compare("object.container.genre.movieGenre") == 0) {
            sOp = "=";
					  tmp << CONTAINER_GENRE_MOVIE_GENRE;
          }
          else if (sVal.compare("object.container.playlistContainer") == 0) {
            sOp = "=";
					  tmp << CONTAINER_PLAYLIST_CONTAINER; //sVal = "201)";
          }
					else
					  bBuildOK = false;

          if(bBuildOK)
            sVal = tmp.str();
          tmp.str("");          
				} 
				else if (!bNumericProp) {
				  if(bLikeOp)
				    sVal = "'%" + sVal + "%'";
					else
						sVal = "'" + sVal + "'";
				}
				
			} // != exists
		
		  if(bBuildOK) {
        if(bFirst) {
          sSql << " and ";
          bFirst = false;
        }        
  			sSql << sPrevLog << " " << sOpenBr << sProp << " " << sOp << " " << sVal << sCloseBr << " ";
        sPrevLog = sLogOp;
      }
			else {
			  cout << "error parsing search request!" << endl <<
          "please file a bugreport containing the following lines: " << endl << endl <<
          "=== CUT ===" << endl <<
          m_sSearchCriteria << endl <<
          "=== CUT ===" << endl;
      }
			  
			
		}	while (rxSearch.SearchAgain());
	}
	
	m_query += sSql.str();
	m_queryCount += sSql.str();
	
	sSql.str("");
  
  // order by
  sSql << " order by " << m_sortCriteriaSQL << " ";

  // limit
	if((m_nRequestedCount > 0) || (m_nStartingIndex > 0)) {
    sSql << " limit " << m_nStartingIndex << ", ";
    if(m_nRequestedCount == 0)
      sSql << "-1";
    else
      sSql << m_nRequestedCount;
	}

  // order by and limit are not needed
  // in a count request  
	m_query += sSql.str();

  //cout << m_query << endl;
  
  return true;
}
Beispiel #10
0
int
main(int argc, char* argv[])
{
  Collectors = NULL;

#ifdef HAVE_EXT_POSTGRESQL
  HistorySnapshot *historySnapshot;
  SQLQuery queryhor;
  SQLQuery queryver;
  QuillErrCode st;
  bool remotequill=false;
  char *quillName=NULL;
  AttrList *ad=0;
  int flag = 1;
  void **parameters;
  char *dbconn=NULL;
  char *completedsince = NULL;
  char *dbIpAddr=NULL, *dbName=NULL,*queryPassword=NULL;
  bool remoteread = false;
#endif /* HAVE_EXT_POSTGRESQL */

  const char *owner=NULL;
  bool readfromfile = true;
  bool fileisuserlog = false;

  char* JobHistoryFileName=NULL;
  const char * pcolon=NULL;


  GenericQuery constraint; // used to build a complex constraint.
  ExprTree *constraintExpr=NULL;

  std::string tmp;

  int i;
  myDistro->Init( argc, argv );

  config();

#ifdef HAVE_EXT_POSTGRESQL
  parameters = (void **) malloc(NUM_PARAMETERS * sizeof(void *));
  queryhor.setQuery(HISTORY_ALL_HOR, NULL);
  queryver.setQuery(HISTORY_ALL_VER, NULL);
#endif /* HAVE_EXT_POSTGRESQL */

  for(i=1; i<argc; i++) {
    if (is_dash_arg_prefix(argv[i],"long",1)) {
      longformat=TRUE;   
    }
    
    else if (is_dash_arg_prefix(argv[i],"xml",3)) {
		use_xml = true;	
		longformat = true;
	}
    
    else if (is_dash_arg_prefix(argv[i],"backwards",1)) {
        backwards=TRUE;
    }

	// must be at least -forw to avoid conflict with -f (for file) and -format
    else if (is_dash_arg_prefix(argv[i],"nobackwards",3) ||
			 is_dash_arg_prefix(argv[i],"forwards",4)) {
        backwards=FALSE;
    }

    else if (is_dash_arg_colon_prefix(argv[i],"wide", &pcolon, 1)) {
        wide_format=TRUE;
        if (pcolon) {
            wide_format_width = atoi(++pcolon);
            if ( ! mask.IsEmpty()) mask.SetOverallWidth(getDisplayWidth()-1);
            if (wide_format_width <= 80) wide_format = FALSE;
        }
    }

    else if (is_dash_arg_prefix(argv[i],"match",1) || is_dash_arg_prefix(argv[i],"limit",3)) {
        i++;
        if (argc <= i) {
            fprintf(stderr,
                    "Error: Argument -match requires a number value "
                    " as a parameter.\n");
            exit(1);
        }
        specifiedMatch = atoi(argv[i]);
    }

#ifdef HAVE_EXT_POSTGRESQL
    else if(is_dash_arg_prefix(argv[i], "dbname",1)) {
		i++;
		if (argc <= i) {
			fprintf( stderr,
					 "Error: Argument -dbname requires the name of a quilld as a parameter\n" );
			exit(1);
		}
		

/*
		if( !(quillName = get_daemon_name(argv[i])) ) {
			fprintf( stderr, "Error: unknown host %s\n",
					 get_host_part(argv[i]) );
			printf("\n");
			print_wrapped_text("Extra Info: The name given with the -dbname "
							   "should be the name of a condor_quilld process. "
							   "Normally it is either a hostname, or "
							   "\"name@hostname\". "
							   "In either case, the hostname should be the "
							   "Internet host name, but it appears that it "
							   "wasn't.",
							   stderr);
			exit(1);
		}
		sprintf (tmp, "%s == \"%s\"", ATTR_NAME, quillName);      		
		quillQuery.addORConstraint (tmp);

*/
		quillName = argv[i];

		sprintf (tmp, "%s == \"%s\"", ATTR_SCHEDD_NAME, quillName);
		quillQuery.addORConstraint (tmp.c_str());

		remotequill = false;
		readfromfile = false;
    }
#endif /* HAVE_EXT_POSTGRESQL */
    else if (is_dash_arg_prefix(argv[i],"file",2)) {
		if (i+1==argc || JobHistoryFileName) break;
		i++;
		JobHistoryFileName=argv[i];
		readfromfile = true;
    }
	else if (is_dash_arg_prefix(argv[i],"userlog",1)) {
		if (i+1==argc || JobHistoryFileName) break;
		i++;
		JobHistoryFileName=argv[i];
		readfromfile = true;
		fileisuserlog = true;
	}
    else if (is_dash_arg_prefix(argv[i],"help",1)) {
		Usage(argv[0],0);
    }
    else if (is_dash_arg_prefix(argv[i],"format",1)) {
		if (argc <= i + 2) {
			fprintf(stderr,
					"Error: Argument -format requires a spec and "
					"classad attribute name as parameters.\n");
			fprintf(stderr,
					"\t\te.g. condor_history -format '%%d' ClusterId\n");
			exit(1);
		}
		mask.registerFormat(argv[i + 1], argv[i + 2]);
		customFormat = true;
		i += 2;
    }
	else if (*(argv[i]) == '-' && 
				(is_arg_colon_prefix(argv[i]+1,"af", &pcolon, 2) ||
				 is_arg_colon_prefix(argv[i]+1,"autoformat", &pcolon, 5))) {
		// make sure we have at least one argument to autoformat
		if (argc <= i+1 || *(argv[i+1]) == '-') {
			fprintf (stderr, "Error: Argument %s requires at last one attribute parameter\n", argv[i]);
			fprintf(stderr, "\t\te.g. condor_history %s ClusterId\n", argv[i]);
			exit(1);
		}
		if (pcolon) ++pcolon; // if there are options, skip over the colon to the options.
		int ixNext = parse_autoformat_args(argc, argv, i+1, pcolon, mask, diagnostic);
		if (ixNext > i)
			i = ixNext-1;
		customFormat = true;
	}
	else if (is_dash_arg_colon_prefix(argv[i], "print-format", &pcolon, 2)) {
		if ( (argc <= i+1)  || (*(argv[i+1]) == '-' && (argv[i+1])[1] != 0)) {
			fprintf( stderr, "Error: Argument -print-format requires a filename argument\n");
			exit( 1 );
		}
		// hack allow -pr ! to disable use of user-default print format files.
		if (MATCH == strcmp(argv[i+1], "!")) {
			++i;
			disable_user_print_files = true;
			continue;
		}
		if ( ! wide_format) mask.SetOverallWidth(getDisplayWidth()-1);
		customFormat = true;
		++i;
		std::string where_expr;
		if (set_print_mask_from_stream(mask, where_expr, argv[i], true) < 0) {
			fprintf(stderr, "Error: cannot execute print-format file %s\n", argv[i]);
			exit (1);
		}
		if ( ! where_expr.empty()) {
			constraint.addCustomAND(where_expr.c_str());
		}
	}
    else if (is_dash_arg_prefix(argv[i],"constraint",1)) {
		// make sure we have at least one more argument
		if (argc <= i+1) {
			fprintf( stderr, "Error: Argument %s requires another parameter\n", argv[i]);
			exit(1);
		}
		i++;
		constraint.addCustomAND(argv[i]);
    }
#ifdef HAVE_EXT_POSTGRESQL
    else if (is_dash_arg_prefix(argv[i],"completedsince",3)) {
		i++;
		if (argc <= i) {
			fprintf(stderr,
					"Error: Argument -completedsince requires a date and "
					"optional timestamp as a parameter.\n");
			fprintf(stderr,
					"\t\te.g. condor_history -completedsince \"2004-10-19 10:23:54\"\n");
			exit(1);
		}
		
		if (constraint!="") break;
		completedsince = strdup(argv[i]);
		parameters[0] = completedsince;
		queryhor.setQuery(HISTORY_COMPLETEDSINCE_HOR,parameters);
		queryver.setQuery(HISTORY_COMPLETEDSINCE_VER,parameters);
    }
#endif /* HAVE_EXT_POSTGRESQL */

    else if (sscanf (argv[i], "%d.%d", &cluster, &proc) == 2) {
		std::string jobconst;
		formatstr (jobconst, "%s == %d && %s == %d", 
				 ATTR_CLUSTER_ID, cluster,ATTR_PROC_ID, proc);
		constraint.addCustomOR(jobconst.c_str());
		#ifdef HAVE_EXT_POSTGRESQL
		parameters[0] = &cluster;
		parameters[1] = &proc;
		queryhor.setQuery(HISTORY_CLUSTER_PROC_HOR, parameters);
		queryver.setQuery(HISTORY_CLUSTER_PROC_VER, parameters);
		#endif /* HAVE_EXT_POSTGRESQL */
    }
    else if (sscanf (argv[i], "%d", &cluster) == 1) {
		std::string jobconst;
		formatstr (jobconst, "%s == %d", ATTR_CLUSTER_ID, cluster);
		constraint.addCustomOR(jobconst.c_str());
		#ifdef HAVE_EXT_POSTGRESQL
		parameters[0] = &cluster;
		queryhor.setQuery(HISTORY_CLUSTER_HOR, parameters);
		queryver.setQuery(HISTORY_CLUSTER_VER, parameters);
		#endif /* HAVE_EXT_POSTGRESQL */
    }
    else if (is_dash_arg_prefix(argv[i],"debug",1)) {
          // dprintf to console
          dprintf_set_tool_debug("TOOL", 0);
    }
    else if (is_dash_arg_prefix(argv[i],"diagnostic",4)) {
          // dprintf to console
          diagnostic = true;
    }
    else if (is_dash_arg_prefix(argv[i], "name", 1)) {
        i++;
        if (argc <= i)
        {
            fprintf(stderr,
                "Error: Argument -name requires name of a remote schedd\n");
            fprintf(stderr,
                "\t\te.g. condor_history -name submit.example.com \n");
            exit(1);
        }
        g_name = argv[i];
        readfromfile = false;
       #ifdef HAVE_EXT_POSTGRESQL
        remoteread = true;
       #endif
    }
    else if (is_dash_arg_prefix(argv[i], "pool", 1)) {
        i++;    
        if (argc <= i)
        {
            fprintf(stderr,
                "Error: Argument -name requires name of a remote schedd\n");
            fprintf(stderr,
                "\t\te.g. condor_history -name submit.example.com \n");
            exit(1);    
        }       
        g_pool = argv[i];
        readfromfile = false;
       #ifdef HAVE_EXT_POSTGRESQL
        remoteread = true;
       #endif
    }
    else {
		std::string ownerconst;
		owner = argv[i];
		formatstr(ownerconst, "%s == \"%s\"", ATTR_OWNER, owner);
		constraint.addCustomOR(ownerconst.c_str());
#ifdef HAVE_EXT_POSTGRESQL
		parameters[0] = owner;
		queryhor.setQuery(HISTORY_OWNER_HOR, parameters);
		queryver.setQuery(HISTORY_OWNER_VER, parameters);
#endif /* HAVE_EXT_POSTGRESQL */
    }
  }
  if (i<argc) Usage(argv[0]);
  
  
  MyString my_constraint;
  constraint.makeQuery(my_constraint);
  if (diagnostic) {
	  fprintf(stderr, "Using effective constraint: %s\n", my_constraint.c_str());
  }
  if ( ! my_constraint.empty() && ParseClassAdRvalExpr( my_constraint.c_str(), constraintExpr ) ) {
	  fprintf( stderr, "Error:  could not parse constraint %s\n", my_constraint.c_str() );
	  exit( 1 );
  }

#ifdef HAVE_EXT_POSTGRESQL
	/* This call must happen AFTER config() is called */
  if (checkDBconfig() == true && !readfromfile) {
  	readfromfile = false;
  } else {
  	readfromfile = true;
  }
#endif /* HAVE_EXT_POSTGRESQL */

#ifdef HAVE_EXT_POSTGRESQL
  if(!readfromfile && !remoteread) {
	  if(remotequill) {
		  if (Collectors == NULL) {
			  Collectors = CollectorList::create();
			  if(Collectors == NULL ) {
				  printf("Error: Unable to get list of known collectors\n");
				  exit(1);
			  }
		  }
		  result = Collectors->query ( quillQuery, quillList );
		  if(result != Q_OK) {
			  printf("Fatal Error querying collectors\n");
			  exit(1);
		  }

		  if(quillList.MyLength() == 0) {
			  printf("Error: Unknown quill server %s\n", quillName);
			  exit(1);
		  }
		  
		  quillList.Open();
		  while ((ad = quillList.Next())) {
				  // get the address of the database
			  dbIpAddr = dbName = queryPassword = NULL;
			  if (!ad->LookupString(ATTR_QUILL_DB_IP_ADDR, &dbIpAddr) ||
				  !ad->LookupString(ATTR_QUILL_DB_NAME, &dbName) ||
				  !ad->LookupString(ATTR_QUILL_DB_QUERY_PASSWORD, &queryPassword) || 
				  (ad->LookupBool(ATTR_QUILL_IS_REMOTELY_QUERYABLE,flag) && !flag)) {
				  printf("Error: The quill daemon \"%s\" is not set up "
						 "for database queries\n", 
						 quillName);
				  exit(1);
			  }
		  }
	  } else {
			// they just typed 'condor_history' on the command line and want
			// to use quill, so get the schedd ad for the local machine if
			// we can, figure out the name of the schedd and the 
			// jobqueuebirthdate
		Daemon schedd( DT_SCHEDD, 0, 0 );

        if ( schedd.locate(Daemon::LOCATE_FULL) ) {
			char *scheddname = quillName;	
			if (scheddname == NULL) {
				// none set explictly, look it up in the daemon ad
				scheddname = schedd.name();
				ClassAd *daemonAd = schedd.daemonAd();
				int scheddbirthdate;
				if(daemonAd) {
					if(daemonAd->LookupInteger( ATTR_JOB_QUEUE_BIRTHDATE, 	
								scheddbirthdate) ) {
						queryhor.setJobqueuebirthdate( (time_t)scheddbirthdate);	
						queryver.setJobqueuebirthdate( (time_t)scheddbirthdate);	
					}
				}
			} else {
				queryhor.setJobqueuebirthdate(0);	
				queryver.setJobqueuebirthdate(0);	
			}
			queryhor.setScheddname(scheddname);	
			queryver.setScheddname(scheddname);	
			
		}
	  }
	  dbconn = getDBConnStr(quillName,dbIpAddr,dbName,queryPassword);
	  historySnapshot = new HistorySnapshot(dbconn);
	  if (!customFormat) {
		  printf ("\n\n-- Quill: %s : %s : %s\n", quillName, 
			  dbIpAddr, dbName);
		}		

	  queryhor.prepareQuery();  // create the query strings before sending off to historySnapshot
	  queryver.prepareQuery();
	  
	  st = historySnapshot->sendQuery(&queryhor, &queryver, longformat,
		false, customFormat, &mask, constraint.c_str());

		  //if there's a failure here and if we're not posing a query on a 
		  //remote quill daemon, we should instead query the local file
	  if(st == QUILL_FAILURE) {
	        printf( "-- Database at %s not reachable\n", dbIpAddr);
		if(!remotequill) {
			char *tmp_hist = param("HISTORY");
			if (!customFormat) {
				printf( "--Failing over to the history file at %s instead --\n",
						tmp_hist ? tmp_hist : "(null)" );
			}
			if(!tmp_hist) {
				free(tmp_hist);
			}
			readfromfile = true;
	  	}
	  }
		  // query history table
	  if (historySnapshot->isHistoryEmpty()) {
		  printf("No historical jobs in the database match your query\n");
	  }
	  historySnapshot->release();
	  delete(historySnapshot);
  }
#endif /* HAVE_EXT_POSTGRESQL */
  
  if(readfromfile == true) {
      readHistoryFromFiles(fileisuserlog, JobHistoryFileName, my_constraint.c_str(), constraintExpr);
  }
  else {
      readHistoryRemote(constraintExpr);
  }
  
  
#ifdef HAVE_EXT_POSTGRESQL
  if(completedsince) free(completedsince);
  if(parameters) free(parameters);
  if(dbIpAddr) free(dbIpAddr);
  if(dbName) free(dbName);
  if(queryPassword) free(queryPassword);
  if(dbconn) free(dbconn);
#endif
  return 0;
}
Beispiel #11
0
void
CondorQ::rawDBQuery(const char *dbconn, CondorQQueryType qType)
{
#ifndef HAVE_EXT_POSTGRESQL
	(void) dbconn;
	(void) qType;
#else

	JobQueueDatabase *DBObj = NULL;
	const char    *rowvalue;
	int           ntuples;
	SQLQuery      sqlquery;
	char *tmp;
	dbtype dt;

	tmp = param("QUILL_DB_TYPE");
	if (tmp) {
		if (strcasecmp(tmp, "PGSQL") == 0) {
			dt = T_PGSQL;
		}
	} else {
		dt = T_PGSQL; // assume PGSQL by default
	}

	free(tmp);

	switch (dt) {				
	case T_PGSQL:
		DBObj = new PGSQLDatabase(dbconn);
		break;
	default:
		break;;
	}

	if (!DBObj || (DBObj->connectDB() == QUILL_FAILURE))
	{
		fprintf(stderr, "\n-- Failed to connect to the database\n");
		return;
	}

	switch (qType) {
	case AVG_TIME_IN_QUEUE:

		sqlquery.setQuery(QUEUE_AVG_TIME, NULL);		
		sqlquery.prepareQuery();

		DBObj->execQuery(sqlquery.getQuery(), ntuples);

			/* we expect exact one row out of the query */
		if (ntuples != 1) {
			fprintf(stderr, "\n-- Failed to execute the query\n");
			return;
		}
		
		rowvalue = DBObj -> getValue(0, 0);

		if(strcmp(rowvalue,"") == 0) // result from empty job queue in pgsql
			{ 
			printf("\nJob queue is curently empty\n");
		} else {
			printf("\nAverage time in queue for uncompleted jobs (in days hh:mm:ss)\n");
			printf("%s\n", rowvalue);		 
		}
		
		DBObj -> releaseQueryResult();
		break;
	default:
		fprintf(stderr, "Error: type of query not supported\n");
		return;
		break;
	}

	if(DBObj) {
		delete DBObj;
	}	
#endif /* HAVE_EXT_POSTGRESQL */
}
Beispiel #12
0
bool CHTTPRequestHandler::handleImageRequest(std::string p_sObjectId, CHTTPMessage* pRequest, CHTTPMessage* pResponse)
{
	/*cout << "image request" << endl;
	cout << pRequest->getVarAsInt("width") << "x" << pRequest->getVarAsInt("height") << endl;*/
	
  std::stringstream sSql;
  //OBJECT_TYPE       nObjectType;
  std::string       sExt;
  std::string       sPath;
  std::string       sMimeType;
  SQLQuery  				qry;

  
  string sDevice = pRequest->virtualFolderLayout();
  if(pRequest->GetVarExists("vfolder")) {
    sDevice = pRequest->getGetVar("vfolder");
    if(sDevice == "none")
      sDevice = "";
  }

  object_id_t objectId = HexToInt(p_sObjectId);  
  DbObject* tmp = DbObject::createFromObjectId(objectId, &qry, sDevice);
  if(tmp == NULL) {
		CSharedLog::Log(L_EXT, __FILE__, __LINE__, "unknown object id: %s", p_sObjectId.c_str());
    return false;
  }

  DbObject obj = *tmp;
  delete tmp;

/*
  bool result = false;

  // real image
  if(obj->type() >= ITEM_IMAGE_ITEM && obj->type() < ITEM_IMAGE_ITEM_MAX) {
    result = handleRealImageRequest(obj, pRequest, pResponse);
  }
  // audio file embedded image
  else if(obj->type() >= ITEM_AUDIO_ITEM && obj->type() < ITEM_AUDIO_ITEM_MAX) {
    result = handleAudioEmbeddedImageRequest(obj, pRequest, pResponse);
  }
  // video file thumbnail image
  else if(obj->type() >= ITEM_VIDEO_ITEM && obj->type() < ITEM_VIDEO_ITEM_MAX) {
    result = handleVideoImageRequest(obj, pRequest, pResponse);
  }
  else {
		CSharedLog::Log(L_EXT, __FILE__, __LINE__, "unsupported image request on object type %d", obj->type());
	}

  delete obj;
  return result;
  */
  

  
  
  string sql = qry.build(SQL_GET_OBJECT_DETAILS, objectId, sDevice);
  qry.select(sql);
    
  if(qry.eof()) {
		CSharedLog::Log(L_EXT, __FILE__, __LINE__, "unknown object id: %s", p_sObjectId.c_str());
		return false;
	}

	sPath = qry.result()->asString("PATH") + qry.result()->asString("FILE_NAME");
  sExt  = ExtractFileExt(sPath);
  sMimeType = pRequest->DeviceSettings()->MimeType(sExt);
    
	bool audioFile = false;
	bool videoFile = false;
  bool hasCached = false;
	
	//OBJECT_TYPE type = (OBJECT_TYPE)qry.result()->asInt("TYPE");
	if(obj.type() >= ITEM_IMAGE_ITEM && obj.type() < ITEM_IMAGE_ITEM_MAX) {
		//cout << "request image file " << sPath << endl;
	}
	else if(obj.type() >= ITEM_AUDIO_ITEM && obj.type() < ITEM_AUDIO_ITEM_MAX) {
		//cout << "request image from audio file " << sPath << endl;
		audioFile = true;
	}
	else if(obj.type() >= ITEM_VIDEO_ITEM && obj.type() < ITEM_VIDEO_ITEM_MAX) {
		//cout << "request image from video file " << sPath << endl;
		videoFile = true;

    if(qry.result()->asUInt("ALBUM_ART_ID") > 0) {
      sPath = PathFinder::findThumbnailsDir() + qry.result()->asString("ALBUM_ART_ID") + ".jpg";
      hasCached = fuppes::File::exists(sPath);
      sExt = "jpg";
      sMimeType = pRequest->DeviceSettings()->MimeType(sExt);
    }
	}
	else {
		CSharedLog::Log(L_EXT, __FILE__, __LINE__, "unsupported image request on object type %d", obj.type());
		return false;
	}
    
  if(!fuppes::File::exists(sPath)) {
    CSharedLog::Log(L_EXT, __FILE__, __LINE__, "file: %s not found", sPath.c_str());
    return false;
  }
	//cout << "image request: " << sPath << endl;

	
	int width = pRequest->getVarAsInt("width");
	int height = pRequest->getVarAsInt("height");
	/*int less = pRequest->getVarAsInt("less");
	int greater = pRequest->getVarAsInt("greater");*/
	
	// transcode | scale request via GET
	// and/or embedded image from audio file
	if((width > 0 || height > 0 || audioFile || videoFile) && !hasCached) {
		CSharedLog::Log(L_EXT, __FILE__, __LINE__, "GET transcode %s - %dx%d",  sPath.c_str(), width, height);
		
		size_t inSize = 0;
		size_t outSize = 0;
		unsigned char* inBuffer = (unsigned char*)malloc(1);
		unsigned char* outBuffer = (unsigned char*)malloc(1);
		char tmpMime[100];
		//memset(tmpMime, 0, 1);
		
		// embedded image from audio or video file
		bool transcode = true;
		if(audioFile || videoFile) {

      string plugin;
			if(audioFile) {
        plugin = "taglib";
			}
      else if(videoFile) {
        plugin = "ffmpegthumbnailer";
				transcode = false;
			}

			CMetadataPlugin* metadata = CPluginMgr::metadataPlugin(plugin);
			if(!metadata) {
				CSharedLog::Log(L_EXT, __FILE__, __LINE__, "metadata plugin %s not found", plugin.c_str());
				free(inBuffer);
				free(outBuffer);
				//free(tmpMime);
			  return false;
      }
      
      
			metadata->openFile(sPath);
			inSize = 0;
			if(!metadata->readImage(&tmpMime[0], &inBuffer, &inSize)) {
				metadata->closeFile();
				CSharedLog::Log(L_EXT, __FILE__, __LINE__, "metadata plugin %s failed to read embedded image", "taglib");
				free(inBuffer);
				free(outBuffer);
				//free(tmpMime);
		    return false;
			}
			metadata->closeFile();

      // get the mime type and the extension of the extracted file      
      sMimeType = tmpMime;
      sExt = pRequest->DeviceSettings()->extensionByMimeType(sMimeType);        
			delete metadata;
		} // embedded image



    // an actual image file or a cached image is requested
		else {

      if(hasCached) {
				transcode = false;        
      }
      
			std::fstream fsImg;
			fsImg.open(sPath.c_str(), ios::binary|ios::in);
		  if(fsImg.fail() == 1) {
				CSharedLog::Log(L_EXT, __FILE__, __LINE__, "failed to load image file %s", sPath.c_str());
				free(inBuffer);
				free(outBuffer);
				//free(tmpMime);
			  return false;
			}
			fsImg.seekg(0, ios::end); 
  		inSize = streamoff(fsImg.tellg()); 
  		fsImg.seekg(0, ios::beg);
			inBuffer = (unsigned char*)realloc(inBuffer, inSize);
			fsImg.read((char*)inBuffer, inSize);
			fsImg.close();
		} // image file

		if(transcode) {
			CTranscoderBase* transcoder = CPluginMgr::transcoderPlugin("magickWand");
			if(transcoder == NULL) {
				CSharedLog::Log(L_EXT, __FILE__, __LINE__, "image magick transcoder not available");
				free(inBuffer);
				free(outBuffer);
				//free(tmpMime);
			  return false;
			}
		
			CFileSettings* settings = new CFileSettings(pRequest->DeviceSettings()->FileSettings(sExt));
		
			// TODO fixme. Robert: What are we supposed to be fixing?
			if(!settings->pImageSettings) {
				settings->pImageSettings = new CImageSettings();
			}
			settings->pImageSettings->nHeight = height;
			settings->pImageSettings->nWidth = width;
			settings->pImageSettings->bGreater = true;
			settings->pImageSettings->bLess = true;
		
			transcoder->TranscodeMem(settings,
															 (const unsigned char**)&inBuffer, inSize, &outBuffer, &outSize);
			delete settings;
			delete transcoder;

			pResponse->SetBinContent((char*)outBuffer, outSize);

      // todo: get the actual image dimensions
      //width = width;
      //height = height:
      sMimeType = pRequest->DeviceSettings()->MimeType(sExt);


		} else { // transcode
			pResponse->SetBinContent((char*)inBuffer, inSize);

      width = obj.details()->width();
      height = obj.details()->height();
		}

    
/*
		pResponse->SetMessageType(HTTP_MESSAGE_TYPE_200_OK);
#warning todo: set correct mime type 
    // the current mimeType variable only holds a dummy mime type set above
		pResponse->SetContentType(sMimeType);
*/
		free(inBuffer);
		free(outBuffer);
		//free(tmpMime);
		//return true;
	} // embedded audio or width|height via GET
	

  // a real image file
  else {

    width = obj.details()->width();
    height = obj.details()->height();
    
	  if(pRequest->DeviceSettings()->DoTranscode(sExt, qry.result()->asString("AUDIO_CODEC"), qry.result()->asString("VIDEO_CODEC"))) {
		  CSharedLog::Log(L_EXT, __FILE__, __LINE__, "transcode %s",  sPath.c_str());
   
		  sMimeType = pRequest->DeviceSettings()->MimeType(sExt, qry.result()->asString("AUDIO_CODEC"), qry.result()->asString("VIDEO_CODEC"));
		  if(pRequest->GetMessageType() == HTTP_MESSAGE_TYPE_GET) {          
			  DbObject object(qry.result());
			  if(!pResponse->TranscodeContentFromFile(sPath, &object)) {
				  return false;
			  }
		  }
		  else if(pRequest->GetMessageType() == HTTP_MESSAGE_TYPE_HEAD) {
			  // mark the head response as chunked so
			  // the correct header will be build
			  pResponse->SetIsBinary(true);
				
			  if(pRequest->DeviceSettings()->TranscodingHTTPResponse(sExt) == RESPONSE_CHUNKED) {
				  pResponse->SetTransferEncoding(HTTP_TRANSFER_ENCODING_CHUNKED);
			  }
			  else if(pRequest->DeviceSettings()->TranscodingHTTPResponse(sExt) == RESPONSE_STREAM) {
				  pResponse->SetTransferEncoding(HTTP_TRANSFER_ENCODING_NONE);
			  }
		  }
	  }
	  else {
		  sMimeType = pRequest->DeviceSettings()->MimeType(sExt, qry.result()->asString("AUDIO_CODEC"), qry.result()->asString("VIDEO_CODEC"));
		  pResponse->LoadContentFromFile(sPath);
	  }

  } // a real image file



  
  // dlna
  if(//(pRequest->dlnaGetContentFeatures() == true) &&
     (pRequest->DeviceSettings()->dlnaVersion() != CMediaServerSettings::dlna_none)) {

    std::string mimeType;
    std::string profile;
    DLNA::getImageProfile(sExt, width, height, profile, mimeType);
    sMimeType = mimeType;

    std::string dlnaFeatures = CContentDirectory::buildDlnaInfo(false, profile);
    std::string dlnaMode = "Interactive";

    pResponse->dlnaContentFeatures(dlnaFeatures);
    pResponse->dlnaTransferMode(dlnaMode);        
  }
  
	// we always set the response type to "200 OK"
	// if the message should be a "206 partial content" 
	// CHTTPServer will change the type
	pResponse->SetMessageType(HTTP_MESSAGE_TYPE_200_OK);
	pResponse->SetContentType(sMimeType);

  return true;
}
Beispiel #13
0
bool CHTTPRequestHandler::handleAVItemRequest(std::string p_sObjectId, CHTTPMessage* pRequest, CHTTPMessage* pResponse, bool audio, std::string requestExt)
{
  std::stringstream sSql;
  //OBJECT_TYPE       nObjectType;
  std::string       sExt;
  std::string       sPath;
  std::string       sMimeType;
  string            targetExt;
  SQLQuery				  qry;
  bool              bResult = true;  
  bool              transcode = false;
  
  unsigned int      objectId = HexToInt(p_sObjectId);
  
  string sDevice = pRequest->virtualFolderLayout();
  string sql = qry.build(SQL_GET_OBJECT_DETAILS, objectId, sDevice);
  qry.select(sql);
  if(qry.eof()) {
    CSharedLog::Log(L_EXT, __FILE__, __LINE__, "unknown object id: %s", p_sObjectId.c_str());
    return false;
  }
  
  // TODO Object Types are still on the todo list
  //nObjectType = (OBJECT_TYPE)atoi(pDb->GetResult()->asString("TYPE").c_str());
  //cout << "OBJECT_TYPE: " << nObjectType << endl;
      
  sPath = qry.result()->asString("PATH") + qry.result()->asString("FILE_NAME");
  sExt  = ExtractFileExt(sPath);
  
  if(!fuppes::File::exists(sPath)) {
    CSharedLog::Log(L_EXT, __FILE__, __LINE__, "file: %s not found", sPath.c_str());
    return false;
  }


  // check for subtitles
  if(!audio && requestExt.compare("srt") == 0) {
    sPath = TruncateFileExt(sPath) + "." + requestExt;
    cout << "SUB REQUEST: " << sPath << "*" << endl;
    if(!fuppes::File::exists(sPath))
      return false;

    pResponse->LoadContentFromFile(sPath);
    pResponse->SetMessageType(HTTP_MESSAGE_TYPE_200_OK);
    pResponse->SetContentType("application/x-subrip");
    return true;
  }

  transcode = pRequest->DeviceSettings()->DoTranscode(sExt, qry.result()->asString("AUDIO_CODEC"), qry.result()->asString("VIDEO_CODEC"));
  sMimeType = pRequest->DeviceSettings()->MimeType(sExt, qry.result()->asString("AUDIO_CODEC"), qry.result()->asString("VIDEO_CODEC"));
  targetExt = pRequest->DeviceSettings()->Extension(sExt, qry.result()->asString("AUDIO_CODEC"), qry.result()->asString("VIDEO_CODEC"));


  if(!transcode) {
    pResponse->LoadContentFromFile(sPath);
  }  
  else {
    CSharedLog::Log(L_EXT, __FILE__, __LINE__, "transcode %s",  sPath.c_str());
 
    if(pRequest->GetMessageType() == HTTP_MESSAGE_TYPE_GET) {  
      DbObject object(qry.result());
      bResult = pResponse->TranscodeContentFromFile(sPath, &object);
    }
    else if(pRequest->GetMessageType() == HTTP_MESSAGE_TYPE_HEAD) {
      // mark the head response as chunked so
      // the correct header will be build
      pResponse->SetIsBinary(true);
      bResult = true;

      if(pRequest->DeviceSettings()->TranscodingHTTPResponse(sExt) == RESPONSE_CHUNKED) {
        pResponse->SetTransferEncoding(HTTP_TRANSFER_ENCODING_CHUNKED);
      }
      else if(pRequest->DeviceSettings()->TranscodingHTTPResponse(sExt) == RESPONSE_STREAM) {
        pResponse->SetTransferEncoding(HTTP_TRANSFER_ENCODING_NONE);
      }
    }
  }
  
  

  // dlna
  if(//(CPluginMgr::dlnaPlugin() != NULL) &&
     //(pRequest->dlnaGetContentFeatures() == true) &&
     (pRequest->DeviceSettings()->dlnaVersion() != CMediaServerSettings::dlna_none)) {

    bool hasProfile = false;
    std::string profile;
    if(audio) {

      int channels = 0;
      int bitrate = 0;
      if(!transcode) {
        channels = qry.result()->asInt("A_CHANNELS");
        bitrate = qry.result()->asInt("A_BITRATE");
      }

      if(audio) {
        hasProfile = DLNA::getAudioProfile(targetExt, channels, bitrate, profile, sMimeType);
      }
      else {
        //hasProfile = CPluginMgr::dlnaPlugin()->getVideoProfile(targetExt, channels, bitrate, &profile, &sMimeType);
      }
    }
    else {
      //CPluginMgr::dlnaPlugin()->getVideoProfile();
    }

    //if(hasProfile) {
      std::string dlnaFeatures = CContentDirectory::buildDlnaInfo(transcode, profile);
      std::string dlnaMode = (transcode ? "Streaming" : "Interactive");

      pResponse->dlnaContentFeatures(dlnaFeatures);
      pResponse->dlnaTransferMode(dlnaMode);
    //}
  } // end dlna
  
  // we always set the response type to "200 OK"
  // if the message should be a "206 partial content" 
  // CHTTPServer will change the type
  pResponse->SetMessageType(HTTP_MESSAGE_TYPE_200_OK);
  pResponse->SetContentType(sMimeType);
  
  bResult = true;
    
  
  return bResult;
}