diff --git a/src/Python/SIP/Bindings.cpp b/src/Python/SIP/Bindings.cpp index 399365f8c..538be2472 100644 --- a/src/Python/SIP/Bindings.cpp +++ b/src/Python/SIP/Bindings.cpp @@ -93,7 +93,7 @@ Bindings::activities(QString filter) const // add datetime to the list QDate d = item->dateTime.date(); QTime t = item->dateTime.time(); - PyList_SET_ITEM(dates, idx++, PyDateTime_FromDateAndTime(d.year(), d.month(), d.day(), t.hour(), t.minute(), t.second(), t.msec())); + PyList_SET_ITEM(dates, idx++, PyDateTime_FromDateAndTime(d.year(), d.month(), d.day(), t.hour(), t.minute(), t.second(), t.msec()*10)); } return dates; @@ -102,14 +102,41 @@ Bindings::activities(QString filter) const return NULL; } -// get the data series for the currently selected ride -PythonDataSeries* -Bindings::series(int type) const +RideItem* +Bindings::fromDateTime(PyObject* activity) const { Context *context = python->contexts.value(threadid()); - if (context == NULL || context->currentRideItem()==NULL) return NULL; - RideFile* f = const_cast(context->currentRideItem())->ride(); + // import datetime if necessary + if (PyDateTimeAPI == NULL) PyDateTime_IMPORT; + + if (context !=NULL && activity != NULL && PyDate_Check(activity)) { + + // convert PyDateTime to QDateTime + QDateTime dateTime(QDate(PyDateTime_GET_YEAR(activity), PyDateTime_GET_MONTH(activity), PyDateTime_GET_DAY(activity)), + QTime(PyDateTime_DATE_GET_HOUR(activity), PyDateTime_DATE_GET_MINUTE(activity), PyDateTime_DATE_GET_SECOND(activity), PyDateTime_DATE_GET_MICROSECOND(activity)/10)); + + // search the RideCache + foreach(RideItem*item, context->athlete->rideCache->rides()) + if (item->dateTime.toUTC() == dateTime.toUTC()) + return const_cast(item); + } + + return NULL; +} + +// get the data series for the currently selected ride +PythonDataSeries* +Bindings::series(int type, PyObject* activity) const +{ + Context *context = python->contexts.value(threadid()); + if (context == NULL) return NULL; + + RideItem* item = fromDateTime(activity); + if (item == NULL) item = const_cast(context->currentRideItem()); + if (item == NULL) return NULL; + + RideFile* f = item->ride(); PythonDataSeries* ds = new PythonDataSeries(seriesName(type), f->dataPoints().count()); for(int i=0; icount; i++) ds->data[i] = f->dataPoints()[i]->value(static_cast(type)); @@ -129,12 +156,17 @@ Bindings::seriesName(int type) const } bool -Bindings::seriesPresent(int type) const +Bindings::seriesPresent(int type, PyObject* activity) const { Context *context = python->contexts.value(threadid()); - if (context == NULL || context->currentRideItem()==NULL) return false; - return const_cast(context->currentRideItem())->ride()->isDataPresent(static_cast(type)); + if (context == NULL) return false; + + RideItem* item = fromDateTime(activity); + if (item == NULL) item = const_cast(context->currentRideItem()); + if (item == NULL) return NULL; + + return item->ride()->isDataPresent(static_cast(type)); } PythonDataSeries::PythonDataSeries(QString name, Py_ssize_t count) : name(name), count(count), data(NULL) @@ -223,7 +255,7 @@ Bindings::activityMetrics(RideItem* item) const QDate d = item->dateTime.date(); PyDict_SetItemString(dict, "date", PyDate_FromDate(d.year(), d.month(), d.day())); QTime t = item->dateTime.time(); - PyDict_SetItemString(dict, "time", PyTime_FromTime(t.hour(), t.minute(), t.second(), t.msec())); + PyDict_SetItemString(dict, "time", PyTime_FromTime(t.hour(), t.minute(), t.second(), t.msec()*10)); // // METRICS @@ -389,7 +421,7 @@ Bindings::seasonMetrics(bool all, DateRange range, QString filter) const PyList_SET_ITEM(datelist, idx, PyDate_FromDate(d.year(), d.month(), d.day())); QTime t = ride->dateTime.time(); - PyList_SET_ITEM(timelist, idx, PyTime_FromTime(t.hour(), t.minute(), t.second(), t.msec())); + PyList_SET_ITEM(timelist, idx, PyTime_FromTime(t.hour(), t.minute(), t.second(), t.msec()*10)); // apply item color, remembering that 1,1,1 means use default (reverse in this case) QString color; diff --git a/src/Python/SIP/Bindings.h b/src/Python/SIP/Bindings.h index c0aeacbd2..ab9b4b44b 100644 --- a/src/Python/SIP/Bindings.h +++ b/src/Python/SIP/Bindings.h @@ -31,10 +31,10 @@ class Bindings { PyObject* activities(QString filter=QString()) const; // working with data series - bool seriesPresent(int type) const; + bool seriesPresent(int type, PyObject* activity=NULL) const; int seriesLast() const; QString seriesName(int type) const; - PythonDataSeries *series(int type) const; + PythonDataSeries *series(int type, PyObject* activity=NULL) const; // working with metrics PyObject* activityMetrics(bool compare=false) const; @@ -51,6 +51,9 @@ class Bindings { int webpage(QString url) const; private: + // find a RideItem by DateTime + RideItem* fromDateTime(PyObject* activity=NULL) const; + // get a dict populated with metrics and metadata PyObject* activityMetrics(RideItem* item) const; PyObject* seasonMetrics(bool all, DateRange range, QString filter) const; diff --git a/src/Python/SIP/goldencheetah.sip b/src/Python/SIP/goldencheetah.sip index 8729f1ece..36949dd2c 100644 --- a/src/Python/SIP/goldencheetah.sip +++ b/src/Python/SIP/goldencheetah.sip @@ -120,10 +120,10 @@ public: PyObject* activities(QString filter=QString()) /TransferBack/; // working with series - bool seriesPresent(int type=10) const; + bool seriesPresent(int type=10, PyObject* activity=NULL) const; QString seriesName(int type=10) const; int seriesLast() const; - PythonDataSeries series(int type=10) /TransferBack/; + PythonDataSeries series(int type=10, PyObject* activity=NULL) /TransferBack/; // working with metrics PyObject* activityMetrics(bool compare=false) /TransferBack/; diff --git a/src/Python/SIP/sipAPIgoldencheetah.h b/src/Python/SIP/sipAPIgoldencheetah.h index 913a12188..435ac2c3f 100644 --- a/src/Python/SIP/sipAPIgoldencheetah.h +++ b/src/Python/SIP/sipAPIgoldencheetah.h @@ -37,44 +37,46 @@ #define sipName_activities &sipStrings_goldencheetah[139] #define sipNameNr_measures 150 #define sipName_measures &sipStrings_goldencheetah[150] -#define sipNameNr_threadid 159 -#define sipName_threadid &sipStrings_goldencheetah[159] -#define sipNameNr_Bindings 168 -#define sipName_Bindings &sipStrings_goldencheetah[168] -#define sipNameNr_webpage 177 -#define sipName_webpage &sipStrings_goldencheetah[177] -#define sipNameNr_metrics 185 -#define sipName_metrics &sipStrings_goldencheetah[185] -#define sipNameNr_compare 193 -#define sipName_compare &sipStrings_goldencheetah[193] -#define sipNameNr_version 201 -#define sipName_version &sipStrings_goldencheetah[201] -#define sipNameNr_athlete 209 -#define sipName_athlete &sipStrings_goldencheetah[209] -#define sipNameNr___len__ 217 -#define sipName___len__ &sipStrings_goldencheetah[217] -#define sipNameNr___str__ 225 -#define sipName___str__ &sipStrings_goldencheetah[225] -#define sipNameNr_QString 233 -#define sipName_QString &sipStrings_goldencheetah[233] -#define sipNameNr_metric 241 -#define sipName_metric &sipStrings_goldencheetah[241] -#define sipNameNr_series 248 -#define sipName_series &sipStrings_goldencheetah[248] -#define sipNameNr_filter 255 -#define sipName_filter &sipStrings_goldencheetah[255] -#define sipNameNr_group 262 -#define sipName_group &sipStrings_goldencheetah[262] -#define sipNameNr_build 268 -#define sipName_build &sipStrings_goldencheetah[268] -#define sipNameNr_type 274 -#define sipName_type &sipStrings_goldencheetah[274] -#define sipNameNr_url 279 -#define sipName_url &sipStrings_goldencheetah[279] -#define sipNameNr_pmc 283 -#define sipName_pmc &sipStrings_goldencheetah[283] -#define sipNameNr_all 287 -#define sipName_all &sipStrings_goldencheetah[287] +#define sipNameNr_activity 159 +#define sipName_activity &sipStrings_goldencheetah[159] +#define sipNameNr_threadid 168 +#define sipName_threadid &sipStrings_goldencheetah[168] +#define sipNameNr_Bindings 177 +#define sipName_Bindings &sipStrings_goldencheetah[177] +#define sipNameNr_webpage 186 +#define sipName_webpage &sipStrings_goldencheetah[186] +#define sipNameNr_metrics 194 +#define sipName_metrics &sipStrings_goldencheetah[194] +#define sipNameNr_compare 202 +#define sipName_compare &sipStrings_goldencheetah[202] +#define sipNameNr_version 210 +#define sipName_version &sipStrings_goldencheetah[210] +#define sipNameNr_athlete 218 +#define sipName_athlete &sipStrings_goldencheetah[218] +#define sipNameNr___len__ 226 +#define sipName___len__ &sipStrings_goldencheetah[226] +#define sipNameNr___str__ 234 +#define sipName___str__ &sipStrings_goldencheetah[234] +#define sipNameNr_QString 242 +#define sipName_QString &sipStrings_goldencheetah[242] +#define sipNameNr_metric 250 +#define sipName_metric &sipStrings_goldencheetah[250] +#define sipNameNr_series 257 +#define sipName_series &sipStrings_goldencheetah[257] +#define sipNameNr_filter 264 +#define sipName_filter &sipStrings_goldencheetah[264] +#define sipNameNr_group 271 +#define sipName_group &sipStrings_goldencheetah[271] +#define sipNameNr_build 277 +#define sipName_build &sipStrings_goldencheetah[277] +#define sipNameNr_type 283 +#define sipName_type &sipStrings_goldencheetah[283] +#define sipNameNr_url 288 +#define sipName_url &sipStrings_goldencheetah[288] +#define sipNameNr_pmc 292 +#define sipName_pmc &sipStrings_goldencheetah[292] +#define sipNameNr_all 296 +#define sipName_all &sipStrings_goldencheetah[296] #define sipMalloc sipAPI_goldencheetah->api_malloc #define sipFree sipAPI_goldencheetah->api_free diff --git a/src/Python/SIP/sipgoldencheetahBindings.cpp b/src/Python/SIP/sipgoldencheetahBindings.cpp index 611957c37..06fa7e024 100644 --- a/src/Python/SIP/sipgoldencheetahBindings.cpp +++ b/src/Python/SIP/sipgoldencheetahBindings.cpp @@ -158,17 +158,19 @@ static PyObject *meth_Bindings_seriesPresent(PyObject *sipSelf, PyObject *sipArg { int a0 = 10; + PyObject * a1 = 0; const ::Bindings *sipCpp; static const char *sipKwdList[] = { sipName_type, + sipName_activity, }; - if (sipParseKwdArgs(&sipParseErr, sipArgs, sipKwds, sipKwdList, NULL, "B|i", &sipSelf, sipType_Bindings, &sipCpp, &a0)) + if (sipParseKwdArgs(&sipParseErr, sipArgs, sipKwds, sipKwdList, NULL, "B|iP0", &sipSelf, sipType_Bindings, &sipCpp, &a0, &a1)) { bool sipRes; - sipRes = sipCpp->seriesPresent(a0); + sipRes = sipCpp->seriesPresent(a0,a1); return PyBool_FromLong(sipRes); } @@ -243,17 +245,19 @@ static PyObject *meth_Bindings_series(PyObject *sipSelf, PyObject *sipArgs, PyOb { int a0 = 10; + PyObject * a1 = 0; ::Bindings *sipCpp; static const char *sipKwdList[] = { sipName_type, + sipName_activity, }; - if (sipParseKwdArgs(&sipParseErr, sipArgs, sipKwds, sipKwdList, NULL, "B|i", &sipSelf, sipType_Bindings, &sipCpp, &a0)) + if (sipParseKwdArgs(&sipParseErr, sipArgs, sipKwds, sipKwdList, NULL, "B|iP0", &sipSelf, sipType_Bindings, &sipCpp, &a0, &a1)) { ::PythonDataSeries*sipRes; - sipRes = new ::PythonDataSeries(sipCpp->series(a0)); + sipRes = new ::PythonDataSeries(sipCpp->series(a0,a1)); return sipConvertFromNewType(sipRes,sipType_PythonDataSeries,Py_None); } diff --git a/src/Python/SIP/sipgoldencheetahcmodule.cpp b/src/Python/SIP/sipgoldencheetahcmodule.cpp index 83c475911..439484a12 100644 --- a/src/Python/SIP/sipgoldencheetahcmodule.cpp +++ b/src/Python/SIP/sipgoldencheetahcmodule.cpp @@ -27,6 +27,7 @@ const char sipStrings_goldencheetah[] = { 's', 'e', 'r', 'i', 'e', 's', 'N', 'a', 'm', 'e', 0, 'a', 'c', 't', 'i', 'v', 'i', 't', 'i', 'e', 's', 0, 'm', 'e', 'a', 's', 'u', 'r', 'e', 's', 0, + 'a', 'c', 't', 'i', 'v', 'i', 't', 'y', 0, 't', 'h', 'r', 'e', 'a', 'd', 'i', 'd', 0, 'B', 'i', 'n', 'd', 'i', 'n', 'g', 's', 0, 'w', 'e', 'b', 'p', 'a', 'g', 'e', 0, diff --git a/src/Resources/python/library.py b/src/Resources/python/library.py index 2a8a3b6f4..9f02d0a20 100644 --- a/src/Resources/python/library.py +++ b/src/Resources/python/library.py @@ -7,11 +7,11 @@ #-------------------------------------------------- # basic activity data -def __GCactivity(): +def __GCactivity(activity=None): rd={} for x in range(0,GC.seriesLast()): - if (GC.seriesPresent(x)): - rd[GC.seriesName(x)] = GC.series(x) + if (GC.seriesPresent(x, activity)): + rd[GC.seriesName(x)] = GC.series(x, activity) return rd # add to main GC entrypoint